应用服务升级部署时候在Kubernetes不停止原有服务情况下,发布应用服务最新版本,达到用户无感知。在Kubernetes中称为滚动更新。
Kubernetes 滚动更新过程中最大程度地减少服务的中断,一旦新的 Pod 处于活动状态并准备就绪后,Kubernetes 就将会停止就的 Pod,从而将 Pod 的状态更新为 “Terminating”,然后从 Endpoints 对象中移除,并且发送一个 SIGTERM 信号给 Pod 的主进程。SIGTERM 信号就会让容器以正常的方式关闭,并且不接受任何新的连接。Pod 从 Endpoints 对象中被移除后,前面的负载均衡器就会将流量路由到其他新的Pod 中去。因为在负责均衡器注意到变更并更新其配置之前,终止信号就会去停用 Pod,这个重新配置过程又是异步发生的,所以并不能保证正确的顺序,所以就可能导致很少的请求会被路由到终止的 Pod 上去。
- 创建滚动更新 部署文件
k8s.cloud-communal.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cloud-communal-service
namespace: cloud
spec:
selector:
matchLabels:
app: cloud-communal-service
# 副本数 根据实际情况设置
replicas: 1
minReadySeconds: 10 # pod启动后等待10秒才就绪,方便查看回滚效果
revisionHistoryLimit: 10 # 设置可记录的版本数
strategy:
type: RollingUpdate # 滚动更新
rollingUpdate:
maxSurge: 25% # 滚动更新期间可以创建的pod的最大数量超过指定数量的pod。1表示当一个新的pod被创建才会删除一个pod,以此类推。可以是具体的整数,也可以是百分百 默认值为25%
maxUnavailable: 1 # 默认值为25%;maxSurge和maxUnavailable值不能同时为零。
template:
metadata:
labels:
app: cloud-communal-service
spec:
hostNetwork: true
containers:
- name: cloud-communal-service
image: registry.cn-shanghai.aliyuncs.com/jbk/cloud-communal:v1.0.0 #你自己镜像库的镜像名称+版本
ports:
- containerPort: 18080
protocol: TCP
imagePullPolicy: Always # 拉取策略 Always:总是拉取 pull IfNotPresent:默认值,本地有则使用本地镜像,不拉取
---
# --- 是必须的,否则无法执行 kind: Service 代码
# 创建 Service
apiVersion: v1
kind: Service
metadata:
name: cloud-communal-service
namespace: cloud
labels:
app: cloud-communal-service
spec:
type: NodePort # 指定service类型
ports:
- port: 18080 # 供集群中其它服务访问的端口
targetPort: 18080 # 后端pod中container暴露的端口
nodePort: 30080 # 节点暴露的端口
protocol: TCP
name: http
selector:
app: cloud-communal-service # 选择的pod的label
- 部署k8s.cloud-communal.yaml
root@master:/home/ljy/桌面# kubectl apply -f k8s-cloud-communal.yaml
- 设置新版本镜像滚动更新
将deployment中的cloud-communal-service容器镜像设置为“cloud-communal:v1.0.1”
kubectl set image deployment/自己的deployment名称 -n 命名空间 镜像名称=镜像
root@master:/home/ljy/桌面# kubectl set image deployment/cloud-communal-service -n cloud cloud-communal-service=registry.cn-shanghai.aliyuncs.com/jbk/cloud-communal:v1.0.1
- 查看滚动更新是否成功
root@master:/home/ljy/桌面# kubectl rollout status deployment/cloud-communal-service -n cloud
deployment "cloud-communal-service" successfully rolled out
root@master:/home/ljy/桌面# kubectl get pod -n cloud -w | grep cloud-communal-service
cloud-communal-service-79ddd45bb8-r86bp 1/1 Running 0 18m
root@master:/home/ljy/桌面# kubectl get pods -n cloud -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
cloud-communal-service-79ddd45bb8-r86bp 1/1 Running 67 2d22h 10.0.2.15 master <none> <none>
- 回滚
- 查看历史信息
root@master:/home/ljy/桌面# kubectl rollout history deployment cloud-communal-service -n cloud
deployment.apps/cloud-communal-service
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
- 回滚
回滚到上一个版本
root@master:/home/ljy/桌面# kubectl rollout undo deployment cloud-communal-service -n cloud
deployment.apps/cloud-communal-service rolled back
使用 --revision参数指定回滚某个历史版本; 版本号通过kubectl rollout history deployment cloud-communal-service -n cloud 查看
root@master:/home/ljy/桌面# kubectl rollout undo cloud-communal-service -n cloud --to-revision=2
- 回滚结果确认
root@master:/home/ljy/桌面# kubectl get deployment -n cloud -o wide
root@master:/home/ljy/桌面# kubectl get pods -n cloud -o wide