kubernetes基于Service实现灰度发布

灰度发布

灰度发布也叫金丝雀发布,是指一种平滑过渡的发布方式,可以实现两个版本的共存,服务的新版本先在小范围内上线,可以避免很多风险。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

基于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>

上一篇:FreeHttp (a fiddler add in to temper the http)


下一篇:iOS开发中UILocalNotification本地通知实现简单的提醒功能