原文连接nginx
当集群中某个服务须要升级时,咱们可能须要中止目前与该服务相关的全部Pod,而后下载新版本镜像并建立新的Pod。 然而这个升级/回滚方案在集群较大的时候代价是巨大的,会致使较长时间的服务不可用。K8S提供了滚动升级功能来解决这些问题。git
不一样的管理对象的更新配置和操做是不一样的github
对于Deployment来说,更新的过程以下json
Deployment的ReplicaSet本来有3个Pod副本api
在更新开始前,建立一个新的ReplicaSet对象,配置与旧的ReplicaSet一致bash
根据更新规则,逐渐扩容新的RS、缩容旧的RS,直到新的RS容量与旧的一致、旧的RS容量为0markdown
根据存储历史版本配置决定是否删除超出存储数量的历史ReplicaSetapp
type DeploymentSpec struct { // Deployment对于已经存在的Pod的替换策略 Strategy DeploymentStrategy `json:"strategy,omitempty"` // 存储的历史版本数量,用于回滚,默认是10 RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` } type DeploymentStrategy struct { // 替换策略,值为Recreate或RollingUpdate,默认为RollingUpate // Recreate会先中止全部的旧Pod,而后建立新的 Type DeploymentStrategyType `json:"type,omitempty"` // 更新回滚配置参数,只在RollingUpdate下生效 RollingUpdate *RollingUpdateDeployment `json:"rollingUpdate,omitempty"` } type RollingUpdateDeployment struct { // 滚动升级过程当中,容许不可用的Pod数量或比例 // 默认为25%,此时升级过程当中可用的Pod数量始终为75% // 每成功升级一个,则容许开始升级下一个 // MaxUnavailable为0时,MaxSurge不能为0 MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` // 滚动升级过程当中,容许最多同时建立Pod的数量或比例 // 默认为25%,此时升级过程当中新旧Pod数量总和最多为正常值的125% // 每删除一个旧的Pod则容许建立一个新的 // MaxSurge为0时,MaxUnavailable不能为0 MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"` } 复制代码
当前拥有一个名为nginx-deployment的Deployment对象oop
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.13.0 ports: - containerPort: 80 复制代码
假如要将其nginx版本从1.13.0升级到最新的1.14.0post
有两种方案能够进行升级,效果同样
经过执行 kubectl edit (RESOURCE/NAME | -f FILENAME) [options]
具体用法能够经过 kubectl edit --help
查看
经过执行 kubectl set SUBCOMMAND [options]
具体用法能够经过 kubectl set --help
查看
咱们使用第二种方案进行升级
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.14.0 deployment.apps/nginx-deployment image updated $ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-58cdcbb467 3 3 3 8m32s nginx-deployment-7f555c9b4b 1 1 0 9s $ kubectl describe deployment nginx-deployment Name: nginx-deployment Namespace: default CreationTimestamp: Sat, 28 Dec 2019 21:58:02 +0800 Labels: <none> Annotations: deployment.kubernetes.io/revision: 2 kubernetes.io/change-cause: kubectl create --filename=nginx-old.yaml --record=true Selector: app=nginx Replicas: 3 desired | 2 updated | 4 total | 3 available | 1 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.14.0 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True ReplicaSetUpdated OldReplicaSets: nginx-deployment-58cdcbb467 (2/2 replicas created) NewReplicaSet: nginx-deployment-7f555c9b4b (2/2 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 8m53s deployment-controller Scaled up replica set nginx-deployment-58cdcbb467 to 3 Normal ScalingReplicaSet 30s deployment-controller Scaled up replica set nginx-deployment-7f555c9b4b to 1 Normal ScalingReplicaSet 17s deployment-controller Scaled down replica set nginx-deployment-58cdcbb467 to 2 Normal ScalingReplicaSet 17s deployment-controller Scaled up replica set nginx-deployment-7f555c9b4b to 2 复制代码
咱们能够根据上面的信息看到
Annotations: deployment.kubernetes.io/revision: 2
当前Deployment的版本是2
RollingUpdateStrategy: 25% max unavailable, 25% max surge
此Deployment对象的滚动升级策略为最多25%不可用,最多同时升级25%的Pod,Events信息中的行为与配置要求行为彻底一致
Replicas: 3 desired | 2 updated | 4 total | 3 available | 1 unavailable
当前的更新进度,也能够经过 kubectl rollout status deployments nginx-deployment
来监听
Conditions:
当前Deployment可用,正在进行ReplicaSet升级
OldReplicaSets: ... NewReplicaSet: ... 存在的新旧ReplicaSets信息
Events: ...
当前Deployment对象发生的事件
最终状态下,原来的 nginx-deployment-7f555c9b4b
中Pod的数量将会变成0,而新的 nginx-deployment-58cdcbb467
中的Pod数量将会变为3
因为Deployment的配置中保留历史版本数使用了默认的10,因此旧的RS会与新的同时存在,用于回滚
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-58cdcbb467 0 0 0 15m
nginx-deployment-7f555c9b4b 3 3 3 6m43s
复制代码
可使用 kubectl rollout
命令来对Deployment进行回滚,经过 kubectl rollout --help
查看具体用法
在回滚版本前,能够经过 kubectl rollout history
来查看当前存在的版本
若是在建立Deployment的时候,使用了 --record
参数,每次Deployment被修改的时候,还会记录下来修改的命令
$ kubectl rollout history deployment/nginx-deployment deployment.apps/nginx-deployment REVISION CHANGE-CAUSE 1 kubectl create --filename=nginx-old.yaml --record=true 2 kubectl create --filename=nginx-old.yaml --record=true 复制代码
此处能够看到当前有两个版本,能够在后面加参数 --revision=<REVISION>
来查看指定版本的PotTemplate
$ kubectl rollout history deployment/nginx-deployment --revision=1 deployment.apps/nginx-deployment with revision #1 Pod Template: Labels: app=nginx pod-template-hash=58cdcbb467 Annotations: kubernetes.io/change-cause: kubectl create --filename=nginx-old.yaml --record=true Containers: nginx: Image: nginx:1.13.0 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> 复制代码
在回滚的时候有两种方案
kubectl rollout undo (TYPE NAME | TYPE/NAME)
kubectl rollout undo (TYPE NAME | TYPE/NAME) --to-revision=<REVISION>
使用第2中方法进行回滚,回滚到1个版本
$ kubectl rollout undo deployment/nginx-deployment --to-revision=1 deployment.apps/nginx-deployment rolled back $ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-58cdcbb467 3 3 3 30m nginx-deployment-7f555c9b4b 0 0 0 22m $ kubectl describe deployment nginx-deployment OldReplicaSets: <none> NewReplicaSet: nginx-deployment-58cdcbb467 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 22m deployment-controller Scaled up replica set nginx-deployment-7f555c9b4b to 1 Normal ScalingReplicaSet 22m deployment-controller Scaled down replica set nginx-deployment-58cdcbb467 to 2 Normal ScalingReplicaSet 22m deployment-controller Scaled up replica set nginx-deployment-7f555c9b4b to 2 Normal ScalingReplicaSet 22m deployment-controller Scaled down replica set nginx-deployment-58cdcbb467 to 1 Normal ScalingReplicaSet 22m deployment-controller Scaled up replica set nginx-deployment-7f555c9b4b to 3 Normal ScalingReplicaSet 21m deployment-controller Scaled down replica set nginx-deployment-58cdcbb467 to 0 Normal ScalingReplicaSet 14s deployment-controller Scaled up replica set nginx-deployment-58cdcbb467 to 1 Normal ScalingReplicaSet 10s deployment-controller Scaled down replica set nginx-deployment-7f555c9b4b to 2 Normal ScalingReplicaSet 10s deployment-controller Scaled up replica set nginx-deployment-58cdcbb467 to 2 Normal ScalingReplicaSet 7s (x2 over 30m) deployment-controller Scaled up replica set nginx-deployment-58cdcbb467 to 3 Normal ScalingReplicaSet 7s deployment-controller Scaled down replica set nginx-deployment-7f555c9b4b to 1 Normal ScalingReplicaSet 3s deployment-controller Scaled down replica set nginx-deployment-7f555c9b4b to 0 复制代码
信息上能够看到,经过缩容和扩容的操做,已经逐步切换到旧版本 nginx-deployment-58cdcbb467
上了
而且没有更旧的版本了 OldReplicaSets: <none>
当有比较复杂的修改需求的时候,能够先暂停Deployment的更新能力,在对Deployment进行修改完成以后,从新启用更新,从而避免Deployment进行屡次更新
kubectl rolout pause (TYPE NAME | TYPE/NAME)
kubectl rolout resume (TYPE NAME | TYPE/NAME)