K8S部署lnmp项目全过程
作者:跳跃音符#3712
这篇文章主要介绍了K8S部署lnmp项目全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
LNMP为什么要迁移到k8s
将LNMP迁移到k8s架构上会使得应用的启动、迁移、部署变得即简单又安全。
不必担心应用迁移后工作出现问题,也不用担心一台服务器无法应付突发的用户量。
架构设计
MySQL是一种有状态服务,MySQL在某些情况下如果发生故障性退出可能会出现服务无法再次启动的情况,所以使用StorageClass(NFS)来挂载,并使用Deployments来保证应用的持续,这里设置replicas为1,后期部署主从后再行修改
PVC设置
[root@master lnmp]# kubectl create ns lnmp namespace/lnmp created [root@master lnmp]# cat lnmp-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc namespace: lnmp spec: resources: requests: storage: 5Gi accessModes: - ReadWriteMany storageClassName: mysc1 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: php-pvc namespace: lnmp spec: resources: requests: storage: 5Gi accessModes: - ReadWriteMany storageClassName: mysc1 [root@master lnmp]# kubectl apply -f lnmp-pvc.yaml persistentvolumeclaim/mysql created persistentvolumeclaim/php created ### 已部署sc,这边状态已经变更为 Bound [root@master lnmp]# kubectl get pvc -n lnmp NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mysql-pvc Bound pvc-bb57ddc7-ae5e-4652-880a-08d8260314bb 5Gi RWX mysc1 29s php-pvc Bound pvc-53c2880e-c383-41f1-8e09-c7106ea8c18f 5Gi RWX mysc1 29s
Mysql 配置
1. 创建mysql密码的认证 (secret)
[root@master lnmp]# kubectl create secret generic mysql-pass --from-literal=password=Aa123456 -n lnmp secret/mysql-pass created # 或者 [root@master ~]# vim mysql-secret.yaml apiVersion: v1 data: password: QWExMjM0NTY= kind: Secret metadata: creationTimestamp: null name: mysql-pass namespace: lnmp [root@master ~]# kubectl apply -f mysql-secret.yaml secret/mysql-pass created
2. 创建mysql的Service、deployment
2.1 这边使用了自建的harbor镜像仓库,配置dockerconfigjson类型的secret
kubectl create secret docker-registry --dry-run=client docker-harbor --docker-server=registry.bianminchang.com:5001 --docker-username=admin --docker-password=li*****4 -o yaml > docker-secret.yaml [root@master lnmp]# vim docker-secret.yaml apiVersion: v1 data: .dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS5iaWFubWluY2hhbmcuY29tOjUwMDEiOnsidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoi************oiWVdSdGFXNDZiR2x3Y0dSd2NEUT0ifX19 kind: Secret metadata: creationTimestamp: null name: docker-harbor type: kubernetes.io/dockerconfigjson [root@master lnmp]# kubectl apply -f docker-secret.yaml secret/docker-harbor created
2.2 mysql的Service、deployment
[root@master lnmp]# cat mysql-deploy.yaml #apiVersion: v1 # 这边由于项目数据库连接无法读取集群内的svc,使用服务器的hostPort #kind: Service #metadata: # name: lnmp-mysql # namespace: lnmp # labels: # app: lnmp-mysql #spec: # type: # ports: # - protocol: TCP # port: 3306 # nodePort: 3306 # selector: # app: lnmp-mysql --- apiVersion: apps/v1 kind: Deployment metadata: name: lnmp-mysql namespace: lnmp spec: selector: matchLabels: app: lnmp-mysql strategy: type: Recreate template: metadata: labels: app: lnmp-mysql spec: nodeName: master containers: - name: mysql image: registry.bianminchang.com:5001/lnmp/mysql:5.6 imagePullPolicy: IfNotPresent env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password ports: - containerPort: 3306 hostPort: 3306 # 服务器3306 端口 name: mysql livenessProbe: tcpSocket: port: 3306 initialDelaySeconds: 90 periodSeconds: 15 volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql - name: etc-localtime mountPath: /etc/localtime imagePullSecrets: # 指定镜像仓库拉取信息 - name: docker-harbor volumes: - name: etc-localtime hostPath: path: /etc/localtime - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pvc
创建文件并检测
[root@master lnmp]# kubectl apply -f mysql-deploy.yaml service/lnmp-mysql created deployment.apps/lnmp-mysql created [root@master lnmp]# kubectl get secrets NAME TYPE DATA AGE default-token-2cqf5 kubernetes.io/service-account-token 3 54m docker-harbor kubernetes.io/dockerconfigjson 1 6m16s [root@master lnmp]# kubectl get pod NAME READY STATUS RESTARTS AGE lnmp-mysql-5df7b46bcd-fk76k 1/1 Running 0 6m1s
PHP配置
创建php的service,hpa(水平自动伸缩),deployment
[root@master lnmp]# cat php-deploy.yaml apiVersion: v1 kind: Service metadata: name: lnmp-php namespace: lnmp spec: ports: - port: 9000 selector: app: lnmp-php --- apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: lnmp-php spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: lnmp-php minReplicas: 1 maxReplicas: 10 targetCPUUtilizationPercentage: 85 # 当容器的CPU使用量超过85%时,调度器创建新的pod --- apiVersion: apps/v1 kind: Deployment metadata: name: lnmp-php namespace: lnmp labels: app: php spec: replicas: 1 selector: matchLabels: app: lnmp-php strategy: type: Recreate template: metadata: labels: app: lnmp-php spec: containers: - name: php image: registry.bianminchang.com:5001/lnmp/php-fpm:7.0.4 #image: php:test imagePullPolicy: IfNotPresent ports: - containerPort: 9000 name: php volumeMounts: - name: php-persistent-storage mountPath: /usr/share/nginx/html - name: etc-localtime mountPath: /etc/localtime imagePullSecrets: # 指定镜像仓库拉取信息 - name: docker-harbor volumes: - name: etc-localtime # docker 时区挂载 hostPath: path: /etc/localtime - name: php-persistent-storage persistentVolumeClaim: claimName: php-pvc [root@master lnmp]# kubectl apply -f php-deploy.yaml service/lnmp-php unchanged horizontalpodautoscaler.autoscaling/lnmp-php created deployment.apps/lnmp-php unchanged [root@master lnmp]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE lnmp-php Deployment/lnmp-php <unknown>/85% 1 10 3 17s
Nginx配置
创建nginx的configmap,service,deployment
api deployment
[root@master nginx]# vim api-deploy.yaml # HPA Pod 水平自动扩缩 apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: nginx-hpa namespace: lnmp spec: maxReplicas: 5 minReplicas: 2 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: api targetCPUUtilizationPercentage: 80 --- apiVersion: v1 kind: Service metadata: name: api namespace: lnmp labels: app: nginx spec: ports: - name: nginx port: 80 targetPort: 80 selector: app: api --- apiVersion: apps/v1 kind: Deployment metadata: name: api labels: app: nginx spec: replicas: 1 selector: matchLabels: app: api strategy: type: Recreate template: metadata: labels: app: api spec: containers: - name: nginx image: registry.bianminchang.com:5001/lnmp/nginx:1.16.1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: nginx livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 20 periodSeconds: 10 volumeMounts: - name: nginx-persistent-storage mountPath: /usr/share/nginx/html - name: factory-api-config mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf volumes: - name: nginx-persistent-storage persistentVolumeClaim: claimName: php-pvc - name: factory-api-config configMap: name: factory-api-config
factory deployment 项目后台
[root@master nginx]# cat factory-deploy.yaml apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: factory-hpa namespace: lnmp spec: maxReplicas: 5 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: factory targetCPUUtilizationPercentage: 80 --- apiVersion: v1 kind: Service metadata: name: factory namespace: lnmp labels: app: nginx spec: ports: - name: nginx port: 80 targetPort: 80 selector: app: factory --- apiVersion: apps/v1 kind: Deployment metadata: name: factory labels: app: nginx spec: replicas: 1 selector: matchLabels: app: factory strategy: type: Recreate template: metadata: labels: app: factory spec: containers: - name: nginx image: registry.bianminchang.com:5001/lnmp/nginx:1.16.1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: nginx livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 20 periodSeconds: 10 volumeMounts: - name: nginx-persistent-storage mountPath: /usr/share/nginx/html - name: factory-config mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf volumes: - name: nginx-persistent-storage persistentVolumeClaim: claimName: php-pvc - name: factory-config configMap: name: factory-config
factory-front. deployment. 项目前端
[root@master nginx]# cat factory-front-deploy.yaml apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: nginx-hpa namespace: lnmp spec: maxReplicas: 5 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: factory-front targetCPUUtilizationPercentage: 80 --- apiVersion: v1 kind: Service metadata: name: factory-front namespace: lnmp labels: app: nginx spec: ports: - name: nginx port: 80 targetPort: 80 selector: app: factory-front --- apiVersion: apps/v1 kind: Deployment metadata: name: factory-front labels: app: nginx spec: replicas: 1 selector: matchLabels: app: factory-front strategy: type: Recreate template: metadata: labels: app: factory-front spec: containers: - name: nginx image: registry.bianminchang.com:5001/lnmp/nginx:1.16.1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: nginx livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 20 periodSeconds: 10 volumeMounts: - name: nginx-persistent-storage mountPath: /usr/share/nginx/html - name: factory-front-config mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf volumes: - name: nginx-persistent-storage persistentVolumeClaim: claimName: php-pvc - name: factory-front-config configMap: name: factory-front-config
nginx 配置
注意:
php与nginx不在同一个pod内,集群内通讯用svc, fastcgi_pass lnmp-php:9000;
lnmp-php 为php的svc
[root@master nginx]# cat factory-config.yaml apiVersion: v1 kind: ConfigMap metadata: name: nginx-wp-config namespace: lnmp data: default.conf: |- server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html index.php; location ~ \.php$ { root /usr/local/nginx/html; fastcgi_pass lnmp-php:9000; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name; include fastcgi_params; fastcgi_connect_timeout 60s; fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; } } --- apiVersion: v1 kind: ConfigMap metadata: name: factory-config namespace: lnmp data: default.conf: |- server { listen 80; server_name localhost; root /usr/share/nginx/html/jingtai_factory/backend/web; index index.php index.html index.htm default.php default.htm default.html; location ~ \.php$ { root /usr/share/nginx/html/jingtai_factory/backend/web; fastcgi_pass lnmp-php:9000; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/jingtai_factory/backend/web$fastcgi_script_name; include fastcgi_params; fastcgi_connect_timeout 60s; fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; } location / { if (!-e $request_filename) { rewrite ^/(.*) /index.php last; break; } } access_log /usr/share/nginx/html/factory.log; error_log /usr/share/nginx/html/factory-err.log; } --- apiVersion: v1 kind: ConfigMap metadata: name: factory-front-config namespace: lnmp data: default.conf: |- server { listen 80; server_name localhost; root /usr/share/nginx/html/jingtai_factory_frontend; index index.php index.html index.htm default.php default.htm default.html; location ~ \.php$ { root /usr/share/nginx/html/jingtai_factory_frontend; fastcgi_pass lnmp-php:9000; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/jingtai_factory_frontend$fastcgi_script_name; include fastcgi_params; fastcgi_connect_timeout 60s; fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; } location / { if (!-e $request_filename) { rewrite ^/(.*) /index.html last; break; } } } --- apiVersion: v1 kind: ConfigMap metadata: name: factory-api-config namespace: lnmp data: default.conf: |- server { listen 80; server_name localhost; root /usr/share/nginx/html/jingtai_factory/cloud; index index.php index.html index.htm default.php default.htm default.html; location ~ \.php$ { root /usr/share/nginx/html/jingtai_factory/cloud; fastcgi_pass lnmp-php:9000; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/jingtai_factory/cloud$fastcgi_script_name; include fastcgi_params; fastcgi_connect_timeout 60s; fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; } location / { if (!-e $request_filename) { rewrite ^/(.*) /index.html last; break; } } }
执行结果
[root@master nginx]# kubectl get pod NAME READY STATUS RESTARTS AGE api-59c5b5ddbc-nbcb9 1/1 Running 0 16h factory-574c54f796-qzfnw 1/1 Running 0 16h factory-front-694779bbd8-55tgc 1/1 Running 0 16h lnmp-mysql-57445b5c4b-mpl62 1/1 Running 0 16h lnmp-php-5d7d5896b7-9sqtb 1/1 Running 0 16h
Ingress配置
[root@master ingress]# cat ingress-lnmp.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: lnmp-ingress namespace: lnmp annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx rules: - host: backend.k8s.com http: paths: - path: / pathType: Prefix backend: service: name: factory port: number: 80 - host: api.k8s.com http: paths: - path: / pathType: Prefix backend: service: name: api port: number: 80 - host: factory.k8s.com http: paths: - path: / pathType: Prefix backend: service: name: factory-front port: number: 80 [root@master ingress]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE lnmp-ingress nginx backend.k8s.com,api.k8s.com,factory.k8s.com 10.99.132.137 80 16h
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。