灰度发布
灰度发布也叫金丝雀发布,是指一种平滑过渡的发布方式,可以实现两个版本的共存,服务的新版本先在小范围内上线,可以避免很多风险。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
基于Service实现的灰度发布的原理
Service是基于标签去选择负载均衡的Pod的范围,Deployment也是基于标签选择控制的Pod的范围,两个版本的Deployment部署的时候可以都使用两个标签,一个标签用来保证控制的Pod都可以被Service选中,另外一个标签用来标识版本号,然后可以调整这两个版本的replicas来实现两个版本在整个对外服务中占有的权重。
具体实现
创建一个service
这个service选中标签为grayscale的Pod进行负载均衡,在Pod上面开放的端口为80。
[root@k8s-master data]# cat svc.yaml
apiVersion: v1
kind: Service
metadata:
name: grayscale-svc
namespace: test
spec:
selector:
app: grayscale
type: NodePort
ports:
- name: grayscale-test
port: 80
targetPort: 80
protocol: TCP
nodePort: 31111
[root@k8s-master 1225]# kubectl apply -f svc.yaml
service/grayscale-svc created
[root@k8s-master 1225]# kubectl get svc -n test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grayscale-svc NodePort 10.96.102.213 <none> 80:31111/TCP 2m31s
创建v1版本Deployment
这个Deployment使用的是nginx镜像,创建了两个副本,标签app=grayscale保证可以被上面创建的Service负载均衡。
[root@k8s-master 1225]# cat deploy-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grayscale-deploy-v1
namespace: test
spec:
selector:
matchLabels:
app: grayscale
version: v1
replicas: 2
template:
metadata:
labels:
app: grayscale
version: v1
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
[root@k8s-master 1225]# kubectl apply -f deploy-v1.yaml
deployment.apps/grayscale-deploy-v1 created
创建v2版本的Deployment
这个Deployment使用了一个初始化容器,在初始化容器中通过挂载volumes修改了nginx的默认页,以便分辨和v1版本的区别。
[root@k8s-master 1225]# cat deploy-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grayscale-deploy-v2
namespace: test
spec:
selector:
matchLabels:
app: grayscale
version: v2
replicas: 1
template:
metadata:
labels:
app: grayscale
version: v2
spec:
volumes:
- name: for-input
emptyDir: {}
initContainers:
- name: init
image: alpine
volumeMounts:
- name: for-input
mountPath: /test
command: ["/bin/sh","-c","echo this is version 2 > /test/index.html;"]
containers:
- name: nginx
image: nginx
volumeMounts:
- name: for-input
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
[root@k8s-master 1225]# kubectl apply -f deploy-v2.yaml
deployment.apps/grayscale-deploy-v2 created
实现效果
先查看一下目前Pod的状态,都已经就绪
[root@k8s-master 1225]# kubectl get all -n test
NAME READY STATUS RESTARTS AGE
pod/grayscale-deploy-v1-649fb966f9-7mk2x 1/1 Running 0 4m55s
pod/grayscale-deploy-v1-649fb966f9-vm5qg 1/1 Running 0 4m55s
pod/grayscale-deploy-v2-7bc797d8d9-lbhkc 1/1 Running 0 2m31s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/grayscale-svc NodePort 10.96.102.213 <none> 80:31111/TCP 11m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/grayscale-deploy-v1 2/2 2 2 4m55s
deployment.apps/grayscale-deploy-v2 1/1 1 1 2m31s
通过集群ip访问发现响应有v1版本的nginx的默认页,也有v2版本修改后的内容。
[root@k8s-master 1225]# curl 10.96.102.213
this is version 2
[root@k8s-master 1225]# curl 10.96.102.213
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>