蓝绿发布

软件世界比以往任何时候都更快。为了保持竞争力,需要尽快推出新的软件版本,而不会中断活跃用户访问,影响用户体验。越来越多企业已将其应用迁移到 Kubernetes。 在 Kubernetes 中有几种不同的方式发布应用,所以为了让应用在升级期间依然平稳提供服务,选择一个正确的发布策略就非常重要了,本篇文章将讲解在 Kubernetes 使用蓝绿更新的方式更新镜像。 原理 蓝绿发布是版本 1 与版本 2 会同时存在,通过控制 Service 来决定使用具体哪一个版本,也称为红黑部署。蓝绿发布与滚动更新不同,版本 2 (绿) 与版本 1(蓝)一起部署,在测试新版本满足要求后,然后更新 Service 对象,通过替换 label selector 中的版本标签来将流量发送到新版本。 创建两个不同版本的pod demo v1 与 demo v2实例,yaml文件内容如下: ``` [root@master version]# cat v1.yaml  apiVersion: apps/v1 kind: Deployment metadata:   name: demo-dp-v1 spec:   selector:     matchLabels:       app: demo       version: v1   replicas: 1   template:     metadata:       labels:         app: demo         version: v1     spec:        containers:       - name: demo         image: bebullish/demo:v1         ports:         - containerPort: 8080 ``` 本例使用局域网镜像仓库: ``` apiVersion: apps/v1 kind: Deployment metadata:   name: demo-dp-v1 spec:   selector:     matchLabels:       app: demo       version: v1   replicas: 1   template:     metadata:       labels:         app: demo         version: v1     spec:        containers:       - name: demo         image: 192.168.5.160/library/nginx:v1         command: ["/usr/sbin/nginx","-g","daemon off;"]         ports:         - containerPort: 80 ``` ``` [root@master version]# cat v2.yaml  apiVersion: apps/v1 kind: Deployment metadata:   name: demo-dp-v2 spec:   selector:     matchLabels:       app: demo       version: v2   replicas: 1   template:     metadata:       labels:         app: demo         version: v2     spec:        containers:       - name: demo         image: bebullish/demo:v2         ports:         - containerPort: 8080 [root@master version]#  ``` 本地仓库实例: ``` [root@k8s-master-01 ~]# cat v2.yaml  apiVersion: apps/v1 kind: Deployment metadata:   name: demo-dp-v2 spec:   selector:     matchLabels:       app: demo       version: v2   replicas: 1   template:     metadata:       labels:         app: demo         version: v2     spec:        containers:       - name: demo         image: 192.168.5.160/library/nginx:v2         command: ["/usr/sbin/nginx","-g","daemon off;"]         ports:         - containerPort: 80 [root@k8s-master-01 ~]#  ``` 启动两个不同版本的pod ``` kubectl apply -f v1.yaml  kubectl apply -f v2.yaml  ``` 创建服务发布第一个pod: ``` [root@master version]# cat service1.yaml  apiVersion: v1 kind: Service metadata:   name: demo-service spec:   selector:     app: demo     version: v1   type: LoadBalancer   ports:   - port: 80     targetPort: 8080     protocol: TCP [root@master version]#  ``` 本地服务实例: ``` [root@k8s-master-01 ~]# cat service.yaml  apiVersion: v1 kind: Service metadata:   name: demo-service spec:   selector:     app: demo     version: v1   type: LoadBalancer   ports:   - port: 8080     targetPort: 80     protocol: TCP ``` 注:8080为cluster ip地址端口, 80为node开放端口, 运行服务: `kubectl apply -f service1.yaml` 查看服务nodeport端口 `kubectl get svc -o wide` 测试蓝绿发布效果 例如端口为32174如下: `while true; do sleep 1; curl -X GET http://192.168.5.150:30285 ; done` 修改服务发布对于pod的标签测试蓝绿发布注意红色字体部分: `kubectl edit svc demo-service` ``` apiVersion: v1 kind: Service metadata:   annotations:     kubectl.kubernetes.io/last-applied-configuration: |       {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"demo-service","namespace":"default"},"spec":{"ports":[{"port":80,"protocol":"TCP","targetPort":8080}],"selector":{"app":"demo","version":"v1"},"type":"LoadBalancer"}}   creationTimestamp: "2021-05-10T06:54:56Z"   name: demo-service   namespace: default   resourceVersion: "19060"   selfLink: /api/v1/namespaces/default/services/demo-service   uid: f845d9b4-16f3-4039-a6f1-43bf00fac7d6 spec:   clusterIP: 10.96.128.151   externalTrafficPolicy: Cluster   ports:   - nodePort: 32174     port: 80     protocol: TCP     targetPort: 8080   selector:     app: demo     version: v2   sessionAffinity: None   type: LoadBalancer status:   loadBalancer: {} ~                                                                                                                             "/tmp/kubectl-edit-9bqu8.yaml" 31L, 1043C ```