在生产的环境中,当我们需要给某个服务升级时候,需要停止与该服务相关的所有应用Pod,然后下载最新应用的镜像并创建新Pod,这样当我们服务的规模很大的时候,会照成长时间的服务不可用,对于这种情况Kubernetes提出了滚动升级和滚动回滚概念来帮助我们解决该问题。
Deployment升级这里我们采用案例驱动的方式来一步一步了解Kubernetes滚动升级。
清空所有的Pod;
kubectl delete pods --all这里我们采用最开始使用nginx-deployment.yaml文件;
apiVersion: apps/v1kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
resources:
limits:
memory: "128Mi"
cpu: "128m"
ports:
- containerPort: 80
创建deployment资源;
kubectl apply -f nginx-deployment.yaml查看Pod执行情况;
kubectl get podsimage.png
切换镜像版本为1.9.1,这里触发滚动更新的方式有两种:一种使用kubectl edit,另外一种使用kubectl set image;
#第一种方式kubectl edit deployment/nginx-deployment
#第二种方式
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
查看deployment更新过程;
kubectl rollout status deployment/nginx-deploymentimage.png
再次查看Pod状况,会发现Pod,名称已经发生改变;
image.png查看Pod使用的镜像版本,我们会发现nginx的镜像版本已经被替换为1.9.1;
kubectl describe pod/nginx-deployment-79fbcd54b4-j9n62image.png
查看Pod更新过程,我们会发现Deployment资源的本质就是ReplicaSet,当我们创建Deployment系统会创建3个ReplicaSet,更新Deployment资源的时候会创建一个新ReplicaSet,减少一个旧版本的ReplicaSet,后续慢慢替换为新版本ReplicaSet;
kubectl describe deployment/nginx-deploymentimage.pngimage.png
查看ReplicaSet版本;
kubectl get rs总结:Deployment实际上是一个两层控制器。首先,它通过 ReplicaSet 来控制应用的版本;然后,它再通过 ReplicaSet 的属性,来保证 Pod 的副本数量。
在Deployment定义中,可以通过spec.strategy指定Pod的更新策略,目前支持两种策略:
Recrate(重建): 更新Pod的时候会杀掉所有在运行的Pod,然后重新创建Pod;
RollingUpdate(滚动更新): 默认选项,以滚动更新的方式来逐个更新Pod,可以通过spec.strategy.rollingUpdate下面两个参数maxUnavailable和maxSurge来控制滚动更新;
maxUnavailable: 用于指定Deployment在更新过程中不可用状态Pod的上限,可以是百分比也可以是绝对值;
maxSurge: 用于指定在Deployment更新过程中Pod总数量超过期望副本的最大值,可以是百分比也可以是绝对值;从Kubernetes1.6版本开始,以上两个值的默认为25%;
Deployment回滚生产环境中可能由于一些原因,导致需要回滚操作,这个时候我们就可以使用Deployment回滚操作,这里我们还是以更新nginx镜像为案例:
将nginx镜像版本更新为Nginx:1.99,在镜像仓库中是不存在该镜像版本的;
kubectl set image deployment/nginx-deployment nginx=nginx:1.99