前言
实现灰度发布通常需要在集群中额外部署其他开源工具,例如Nginx Ingress,或将业务部署至服务网格,利用服务网格的能力实现。
如果灰度发布需求比较简单,且不希望引入过多的插件或复杂的用法,则可以利用Kubernetes原生的特性实现简单的灰度发布和蓝绿发布。
原理
用户使用Deployment、StatefulSet来部署业务,以Deployment为例。
灰度发布
用户创建Deployment和Service,但Kubernetes并未限制Service需与Deployment一一对应。
Service通过selector匹配后端Pod,若不同Deployment的Pod被同一selector选中,即可实现一个Service对应多个版本Deployment。
调整不同版本Deployment的副本数,即可调整不同版本服务的权重,实现灰度发布。
蓝绿发布
集群中已部署两个不同版本的Deployment,其Pod拥有共同的label。但有一个label值不同,用于区分不同的版本。
Service使用selector选中了其中一个版本的Deployment的Pod,此时通过修改Service的selector中决定服务版本的label的值来改变Service后端对应的Pod,即可实现让服务从一个版本直接切换到另一个版本。
实现
部署两个版本的nignx
老版本old-nginx
apiVersion: apps/v1
kind: Deployment
metadata:
name: old-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
version: v1
template:
metadata:
labels:
app: nginx
version: v1
spec:
containers:
- image: old-nginx
name: old-nginx
ports:
- containerPort: 80
protocol: TCP
新版本new-nginx
apiVersion: apps/v1
kind: Deployment
metadata:
name: new-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
version: v2
template:
metadata:
labels:
app: nginx
version: v2
spec:
containers:
- image: new-nginx
name: new-nginx
ports:
- containerPort: 80
protocol: TCP
实现灰度发布
创建Service
selector中不指定版本,让Service同时选中两个版本的Deployment的Pod。
apiVersion: v1
kind: Service
metadata:
name: huidu-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: ClusterIP
测试访问
for i in {1..10}; do curl 10.96.59.5; done;
可以看到一半是old,一半是new。
修改副本数,调整流量比例
kubectl scale deployment old-nginx --replicas=1
kubectl scale deployment new-nginx --replicas=4
再次测试访问
流量比例为4:1,通过控制不同版本服务的副本数就实现了灰度发布。
实现蓝绿发布
创建service,指定使用v1版本的服务
apiVersion: v1
kind: Service
metadata:
name: lanlv-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
version: v1
type: ClusterIP
测试访问
for i in {1..10}; do curl 10.96.239.146; done;
修改Service的selector,指定v2版本的服务
kubectl patch service lanlv-nginx -p '{"spec":{"selector":{"version":"v2"}}}'
再次测试访问
成功实现了蓝绿发布。