1. 前言
容器服务官网提供的分批发布基于 StatefulSet 开发,有状态副本集部署 POD 是按照顺序一台一台的发布重启,需要消耗很长的时间,并且控制台不尽人意,存在不少坑。
StatefulSet 分批发布不支持任意数目任意批数的发布,实际操作中往往需要先发布一台线上服务做灰度,然后逐步放大。
因而采用无状态副本集 Deployment 对象分批部署,并通过同一个 labels指向统一一个 Service 暴露给访问者,成为大应用中最合适的分批发布。
2. 配置过程
1. 首先建立一个副本数目为1的初始灰度 Deployment,yaml 如下:
apiVersion: apps/v1beta2
kind: Deployment
metadata:
# service 选择标签
labels:
app: {app_name}-aone
name: {app_name}-aone-1
namespace: {app_name}
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: {app_name}-aone
template:
metadata:
labels:
app: {app_name}-aone
spec:
containers:
- image: >-
registry-vpc.cn-north-2-gov-1.aliyuncs.com/app-cloud/{app_name}:20190101191052
imagePullPolicy: Always
# 在应用停止前调用优雅下线脚本,摘除 hsf,lwp 服务
lifecycle:
preStop:
exec:
command:
- sudo
- '-u'
- admin
- /home/admin/appconf/bin/appctl.sh
- {app_name}
- stop
# 就绪检查和存活检查
livenessProbe:
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 508
timeoutSeconds: 1
name: {app_name}-aone
readinessProbe:
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 508
timeoutSeconds: 1
resources:
limits:
cpu: '4'
memory: 8196Mi
requests:
cpu: '4'
memory: 8196Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /home/admin/logs
name: volume-1553680362129
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
# 日志统一写到映射的宿主机数据盘日志目录
volumes:
- hostPath:
path: /var/lib/docker/logs/{app_name}
type: ''
name: volume-1553680362129
2. 第二批,比如设置为16台,分4次发布,每次25%,只需要复制上面脚本,编写 yaml 的 name 为{app_name}-aone-2, 注意保持labels 一致,确保 pod 为同一个Service 配置提供服务,并修改副本数为16,增加更新策略配置,同理同法建立第三批,第四批...。
metadata:
# service 选择标签
labels:
app: {app_name}-aone
name: {app_name}-aone-2
namespace: {app_name}
spec:
progressDeadlineSeconds: 600
replicas: 16
revisionHistoryLimit: 10
selector:
matchLabels:
app: {app_name}-aone
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
3. 建立 Service 服务,通过 labels 标签映射指向以上每批 Deployment,使用 NodePort 结合 SLB 方式,解耦 SLB 负载均衡与 k8s service 关系,房子 Cloud controller manager 同步删除 Service 与 SLB 负载均衡。
apiVersion: v1
kind: Service
metadata:
name: {app_name}-http
namespace: {app_name}
spec:
clusterIP: 133.33.33.33
externalTrafficPolicy: Cluster
ports:
- nodePort: 32168
port: 80
protocol: TCP
targetPort: 7001
selector:
app: {app_name}-aone
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
配置好后,可以在容器服务的 Service 控制台这里点击服务名称,可以看到该服务对应以上4批部署(Deployment)。
至此,使用多个 Deployment 配置分批发布完成。
3. 使用多个 Deployment 分批发布优缺点
- 优点:
- 无状态部署速度快,回滚,重启速度也非常快,可以自己控制重启每批多少台机器;
- 无状态部署可控性好,容器服务控制台在该类型操作坑少。
- 缺点:
- 云监控按照 Deployment 分组,监控信息变为在多个组查看;
- 云效,EDAS 都不支持此种分批发布模式,需要自己二次开发运维发布来实现。