k8s 之 滚动更新
背景
公司做的是医院的院内系统,医院存在24小时的急诊,所以需要程序7*24小时不间断;
在程序更新的时候,就需要滚动更新。
Docker Swarm中的滚动更新
目前公司部署使用的是docker swarm,对滚动更新的支持相当不友好;
假设某个服务需要同时启动5个实例才能保证上午高峰期的访问,
一般来说只需要部署一个service加5个replicas即可
version: '3.3'
services:
svc:
image: xxx:1.0.0
deploy:
# 部署5个副本
replicas: 5
但是这种部署方式,当我们将服务升级到1.0.1时,会一次性全部重启所有的容器,达不到滚动更新的效果;
不得不将部署方式修改为5个service
version: '3.3'
services:
svc1:
image: xxx:1.0.0
svc2:
image: xxx:1.0.0
svc3:
image: xxx:1.0.0
svc4:
image: xxx:1.0.0
svc5:
image: xxx:1.0.0
在配合nginx反向代理
upstream svc {
server:port1 down;
server:port2;
server:port3;
server:port4;
server:port5;
}
server {
listen 80;
location / {
proxy_pass http://svc/;
}
}
在升级svc1时,先修改nginx配置将svc1 down掉,然后修改版本,启动成功后在恢复,在down掉svc2,升级恢复,以此内推。
缺点:需要消耗多个端口且更新过程繁琐。
优点:过程相对可控,假设升级第一个时发现问题,可及时回退。
k8s 滚动升级
k8s滚动升级配置相当简单
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-svc
spec:
replicas: 5
selector:
matchLabels:
app: svc
# 服务启动到就绪需要的时间
minReadySeconds: 30
strategy:
rollingUpdate:
# Pod 数量可以超过定义的数量
maxSurge: 1
# 和期望ready的副本数比,不可用副本数最大比例(或最大值)
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: svc
spec:
restartPolicy: Always
containers:
- name: svc
image: xxx:1.0.0
升级时只需要修改版本号即可,k8s将自动进行滚动更新。
缺点:过程不太可控,假设升级第一个时发现问题,不能及时回退(这个缺点只是我没发现怎么解决,相信有解决方式)。
优点:操作非常简单