蓝绿发布
软件世界比以往任何时候都更快。为了保持竞争力,需要尽快推出新的软件版本,而不会中断活跃用户访问,影响用户体验。越来越多企业已将其应用迁移到 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
```