背景
在发布应用时, 经常需要先上线一个新版本, 用较小的流量去测试一下该新版本的可用性. 但是 Kubernetes 的 ingress resource 并没有实现流量控制与切分的功能, 导致针对同一个域名下的路径, 只能有一个 service 来进行服务. 这样对于灰度发布十分不利, 下面我们就来介绍一下阿里云容器服务的蓝绿发布功能, 轻松实现流量切分.
前置条件
既然需要进行蓝绿发布, 那么应该已经有一个老服务在正常的对外提供服务中. 我们这里以 nginx 为例, 假定已经有一个 nginx deployment 通过 NodePort 对外暴露端口, 并且有一个 ingress 正在对外提供服务. 我们使用的模板如下:
- apiVersion: extensions/v1beta1
- kind: Deployment
- metadata:
- labels:
- run: old-nginx
- name: old-nginx
- spec:
- replicas: 1
- selector:
- matchLabels:
- run: old-nginx
- template:
- metadata:
- labels:
- run: old-nginx
- spec:
- containers:
- - image: registry.cn-hangzhou.aliyuncs.com/xianlu/old-nginx
- imagePullPolicy: Always
- name: old-nginx
- ports:
- - containerPort: 80
- protocol: TCP
- restartPolicy: Always
- ---
- apiVersion: v1
- kind: Service
- metadata:
- labels:
- run: old-nginx
- name: old-nginx
- spec:
- ports:
- - port: 80
- protocol: TCP
- targetPort: 80
- selector:
- run: old-nginx
- sessionAffinity: None
- type: NodePort
- ---
- apiVersion: extensions/v1beta1
- kind: Ingress
- metadata:
- name: echo
- spec:
- backend:
- serviceName: default-http-backend
- servicePort: 80
- rules:
- - host: mini-echo.io
- http:
- paths:
- - path: /
- backend:
- serviceName: old-nginx
- servicePort: 80
可以看到已经创建好的 ingrsss 地址
[root@iZwz91e2au5xvyw5jdpqp7Z manifests]# kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
echo mini-echo.io 47.106.45.47 80 3m
我们在本机通过 curl 访问可以看到如下效果
~ curl -H "Host: mini-echo.io" http://47.106.45.47
old
进行蓝绿发布
创建新的 deployment 与 service
- apiVersion: extensions/v1beta1
- kind: Deployment
- metadata:
- labels:
- run: new-nginx
- name: new-nginx
- spec:
- replicas: 1
- selector:
- matchLabels:
- run: new-nginx
- template:
- metadata:
- labels:
- run: new-nginx
- spec:
- containers:
- - image: registry.cn-hangzhou.aliyuncs.com/xianlu/new-nginx
- imagePullPolicy: Always
- name: new-nginx
- ports:
- - containerPort: 80
- protocol: TCP
- restartPolicy: Always
- ---
- apiVersion: v1
- kind: Service
- metadata:
- labels:
- run: new-nginx
- name: new-nginx
- spec:
- ports:
- - port: 80
- protocol: TCP
- targetPort: 80
- selector:
- run: new-nginx
- sessionAffinity: None
- type: NodePort
可以看到, 唯一的变化就是, 所有的 old-nginx 都变成了 new-nginx.
修改 ingress
主要增加两个地方:
增加 annotations, 标签
ingress.aliyun.weight/new-nginx: "50"
代表,/ 后面为新服务的服务名, 也就是新的 service name. 后面的 50 代表百分比, 以 % 为单位, 50 代表新服务占领百分之 50 的流量. 此标签的完整含义为, 将流量的百分之 50 打到新的服务的 pod 里面.
第二处为指定对应的新的 serviceName. 这里是和上面老服务并列, 即在相同的 Path 下, 挂两个不同的 service , 分别对应于两个新老应用.
效果
~ curl -H "Host: mini-echo.io" http://47.106.45.47
- old
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- old
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- old
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
可以看到, 执行六次请求, 分别得到三次新服务, 三次老服务的返回, 这表明权重设置生效了.
流量完全切换到新服务
只需要将新服务的百分比写到 100 就可以, 再看一下效果.
~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
可以看到, 流量都打到了新服务.
完成蓝绿发布
只需要将设置权重的 annotation 删除即可, 然后将下面对应的 serviceName 也删除, 这样就恢复了原本 ingress 的原貌, 同时将原来的老服务改成了新的服务. 下面再来看一下效果:
~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
- ~ curl -H "Host: mini-echo.io" http://47.106.45.47
- new
可以看到, 新的服务已经上线, 这就完成了整个蓝绿发布的完整生命周期.
来源: https://yq.aliyun.com/articles/578086