K8S发布策略-蓝绿部署(Blue/Green Deployment)
现在很多公司都使用K8S(kubernetes)进行容器管理和编排,今天来说下k8s的发布策略: 蓝绿部署。
蓝绿发布通过使用额外的机器资源来解决服务发布期间的不可用问题,当服务新版本出现故障时,也可以快速将流量切回旧版本。
蓝绿部署的优点:
1、部署结构简单,运维方便;
2、服务升级过程操作简单,周期短。
3、回滚方便,只需要更改路由或者切换 DNS 服务器,效率较高.
蓝绿部署的缺点:
1、资源冗余,需要部署两套生产环境;
2、新版本故障影响范围大。
3、负载均衡器/反向代理/路由/DNS 处理不当,将导致流量没有切换过来情况出现
我们需要准备两个版本,一个蓝版本,一个绿蓝本,这两个版本同时存在,且两个版本是独立的,这个时候可以瞬间对两个版本的切换。上图:
接下来,我们采用svc的方式,通过label selector来进行版本之间的选择。
selector:
app: fffmo.com-app
version: v1.0.0
我们创建一下 fffmo.com-app-v1-svc.yaml文件,我们首先创建一个svc服务,然后通过label selector来指定一下版本。
apiVersion: v1
kind: Service
metadata:
name: fffmo.com-app
labels:
app: fffmo.com-app
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: http
# 注意这里我们匹配 app 和 version 标签,当要切换流量的时候,我们更新 version 标签的值,比如:v2.0.0
selector:
app: fffmo.com-app
version: v1.0.0
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fffmo.com-app-v1
labels:
app: fffmo.com-app
spec:
replicas: 3
selector:
matchLabels:
app: fffmo.com-app
version: v1.0.0
template:
metadata:
labels:
app: fffmo.com-app
version: v1.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9101"
spec:
containers:
- name: fffmo.com-app
image: containersol/k8s-deployment-strategies
ports:
- name: http
containerPort: 8080
- name: probe
containerPort: 8086
env:
- name: VERSION
value: v1.0.0
livenessProbe:
httpGet:
path: /live
port: probe
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: probe
periodSeconds: 5
接下来,我们再创建另一个版本 fffmo.com-app-v2-svc.yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: fffmo.com-app-v2
labels:
app: fffmo.com-app
spec:
replicas: 3
selector:
matchLabels:
app: fffmo.com-app
version: v2.0.0
template:
metadata:
labels:
app: fffmo.com-app
version: v2.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9101"
spec:
containers:
- name: fffmo.com-app
image: containersol/k8s-deployment-strategies
ports:
- name: http
containerPort: 8080
- name: probe
containerPort: 8086
env:
- name: VERSION
value: v2.0.0
livenessProbe:
httpGet:
path: /live
port: probe
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: probe
periodSeconds: 5
接下来,我们执行一下操作步骤:
1. 启动版本1服务
2. 启动版本2服务
3. 将版本1服务切换到版本2,观察服务情况
启动版本的服务并观察,没有问题。
kubectl apply -f fffmo.com-app-v1-svc.yaml
kubectl get pods -l app=fffmo.com-app
watch kubectl get pods -l app=fffmo.com-app
while sleep 0.1; do curl http://127.0.0.1:31539; done
Host: fffmo.com-app-v1-7b4874cd75-dmq8f, Version: v1.0.0
Host: fffmo.com-app-v1-7b4874cd75-dmq8f, Version: v1.0.0
启动版本2的服务, 因为版本2没有挂到SVC,所以没有办法观察,但是我们可以先启动。
kubectl apply -f fffmo.com-app-v2-svc.yaml
这个时候我们进行版本的切换,通过切换标签的方式
使用 kubectl patch 更新 API 对象
kubctl patch service fffmo.com-app '{"spec":{"selector":{"version":"v2.0.0"}}}'
while sleep 0.1; do curl http://127.0.0.1:31539; done
Host: fffmo.com-app-v2-f885c8d45-r5m6z, Version: v2.0.0
Host: fffmo.com-app-v2-f885c8d45-r5m6z, Version: v2.0.0
同时,当发现问题的时候,我们再把版本切回到v1.0.0即可。
总结:
1. k8s蓝绿部署需要准备两套资源,相对有的时候需要的资源会多。
2. 这种情况可以快速还原版本,不会出现滚动更新那样,回滚需要的时间会很久。