# Deployment

一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。

你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller)以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。

apiVersion: apps/v1 # 版本号 
kind: Deployment # 类型 
metadata: # 元数据 
  name: # rs名称 
  namespace: # 所属命名空间 
  labels: #标签 
    controller: deploy 
spec: # 详情描述 
  replicas: 3 # 副本数量 
  revisionHistoryLimit: 3 # 保留历史版本,默认为10 
  paused: false # 暂停部署,默认是false 
  progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600 
  strategy: # 策略 
    type: RollingUpdate # 滚动更新策略 
    rollingUpdate: # 滚动更新 
      maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数 
      maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数 
  selector: # 选择器,通过它指定该控制器管理哪些pod 
    matchLabels: # Labels匹配规则 
      app: nginx-pod 
    matchExpressions: # Expressions匹配规则 
      - {key: app, operator: In, values: [nginx-pod]} 
  template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 
    metadata: 
      labels: 
        app: nginx-pod 
    spec: 
      containers: 
      - name: nginx 
        image: nginx:1.17.1 
        ports: 
        - containerPort: 80

# 一、创建 Deployment

下面是 Deployment 示例。其中创建了一个 ReplicaSet,负责启动三个 nginx Pods:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

在该例中:

  • 创建名为 nginx-deployment(由 .metadata.name 字段标明)的 Deployment。

  • 该 Deployment 创建三个(由 replicas 字段标明)Pod 副本。

  • selector 字段定义 Deployment 如何查找要管理的 Pods。 在这里,你选择在 Pod 模板中定义的标签(app: nginx)。 不过,更复杂的选择规则是也可能的,只要 Pod 模板本身满足所给规则即可。

    说明:

    spec.selector.matchLabels 字段是 {key,value} 键值对映射。 在 matchLabels 映射中的每个 {key,value} 映射等效于 matchExpressions 中的一个元素, 即其 key 字段是 “key”,operator 为 “In”,values 数组仅包含 “value”。 在 matchLabelsmatchExpressions 中给出的所有条件都必须满足才能匹配。

字段包含以下子字段:

  • Pod 被使用 labels 字段打上 app: nginx 标签。
  • Pod 模板规约(即 .template.spec 字段)指示 Pods 运行一个 nginx 容器, 该容器运行版本为 1.14.2 的 nginx Docker Hub (opens new window)镜像。
  • 创建一个容器并使用 name 字段将其命名为 nginx

1. 确保 k8s 已启动

$ kubectl cluster-info
Kubernetes control plane is running at https://kubernetes.docker.internal:6443
CoreDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

有返回一个链接的话,就说明 k8s 已经启动了。

2. 编写上述 yaml 文件,命名为 nginx-deployment.yaml

3. 运行以下命令创建 Deployment

$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created

4. 查看当前拥有的 Deployment

$ kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           4m

在检查集群中的 Deployment 时,所显示的字段有:

  • NAME 列出了集群中 Deployment 的名称。
  • READY 显示应用程序的可用的 副本 数。显示的模式是“就绪个数/期望个数”。
  • UP-TO-DATE 显示为了达到期望状态已经更新的副本数。
  • AVAILABLE 显示应用可供用户使用的副本数。
  • AGE 显示应用程序运行的时间。

请注意期望副本数是根据 .spec.replicas 字段设置 3。

5. 查看 Deployment 上线状态

$ kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out

6. 查看由 Deployment 创建的 ReplicaSet

$ deployments % kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-66b6c48dd5   3         3         3       7m29s

ReplicaSet 输出中包含以下字段:

  • NAME 列出名字空间中 ReplicaSet 的名称;
  • DESIRED 显示应用的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态;
  • CURRENT 显示当前运行状态中的副本个数;
  • READY 显示应用中有多少副本可以为用户提供服务;
  • AGE 显示应用已经运行的时间长度。

注意:

ReplicaSet 的名称始终被格式化为[Deployment名称]-[随机字符串]。 其中的随机字符串是使用 pod-template-hash 作为种子随机生成的。

7. 查看每个 Pod 自动生成的标签

$ kubectl get pod --show-labels
NAME                                READY   STATUS    RESTARTS   AGE     LABELS
nginx-deployment-66b6c48dd5-98kch   1/1     Running   0          8m24s   app=nginx,pod-template-hash=66b6c48dd5
nginx-deployment-66b6c48dd5-nzmvs   1/1     Running   0          8m24s   app=nginx,pod-template-hash=66b6c48dd5
nginx-deployment-66b6c48dd5-wrdt7   1/1     Running   0          8m24s   app=nginx,pod-template-hash=66b6c48dd5

注意:

要避免集群中重复定义 label 。

# 二、更新 Deployment

仅当 Deployment Pod 模板(即 .spec.template)发生改变时,例如模板的标签或容器镜像被更新, 才会触发 Deployment 上线。 其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。

Deployment 支持两种镜像更新的策略:

  • 重建更新
  • 滚动更新(默认),可以通过strategy选项进行配置
strategy: 指定新的Pod替代旧的Pod的策略,支持两个属性
  type: 指定策略类型,支持两种策略
    Recreate: 在创建出新的Pod之前会先杀掉所有已经存在的Pod
    RollingUpdate: 滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本的Pod
  rollingUpdate: 当type为RollingUpdate的时候生效,用于为rollingUpdate设置参数,支持两个属性:
    maxUnavailable: 用来指定在升级过程中不可用的Pod的最大数量,默认为25%。
    maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。

# 1. 重建更新

1.1 创建 pc-deployment.yaml 文件

apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
  name: pc-deployment # deployment的名称
spec: # 详细描述
  replicas: 3 # 副本数量
  strategy: # 镜像更新策略
    type: Recreate #重建更新:在创建出新的Pod之前会先杀死掉所有已经存在的Pod
  selector: # 选择器,通过它指定该Deployment可以管理哪些Pod
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80

1.2 创建 Deployment

[root@k8s-master deploy]# kubectl apply -f pc-deployment.yaml 
deployment.apps/pc-deployment created

1.3 更新镜像

[root@k8s-master deploy]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2
deployment.apps/pc-deployment image updated

1.4 查看升级过程

[root@k8s-master deploy]# kubectl get pod -w
NAME                               READY   STATUS              RESTARTS   AGE
pc-deployment-7bbbd589d5-468tz     0/1     ContainerCreating   0          9s
pc-deployment-7bbbd589d5-cw7ql     0/1     ContainerCreating   0          9s
pc-deployment-7bbbd589d5-x7z66     0/1     ContainerCreating   0          9s
pc-deployment-7bbbd589d5-cw7ql     1/1     Running             0          31s
pc-deployment-7bbbd589d5-468tz     1/1     Running             0          40s
pc-deployment-7bbbd589d5-x7z66     1/1     Running             0          53s

重建更新会先杀死旧的 Pod,然后再创建新的 Pod。

# 2. 滚动更新

2.1 编辑 pc-deployment.yaml 文件,修改更新策略

apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: pc-deployment 
spec: 
  replicas: 3 # 副本数量
  strategy: # 镜像更新策略
    type: RollingUpdate #滚动更新:杀死一部分,启动一部分
    rollingUpdate:
     maxUnavailable: 25%
     maxSurge: 25% 
  selector: # 选择器,通过它指定该Deployment可以管理哪些Pod
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80

2.2 更新 deployment

[root@k8s-master deploy]# kubectl apply -f pc-deployment.yaml
deployment.apps/pc-deployment configured

2.3 镜像升级

[root@k8s-master deploy]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2
deployment.apps/pc-deployment image updated

2.4 查看升级过程

[root@k8s-master deploy]# kubectl get pods -w
NAME                               READY   STATUS              RESTARTS   AGE
pc-deployment-7bbbd589d5-f9nj2     1/1     Running             0          33s
pc-deployment-7bbbd589d5-nhn8z     1/1     Running             0          31s
pc-deployment-7bbbd589d5-ppggw     1/1     Running             0          34s
pc-deployment-866fdcbd54-dfwcg     0/1     ContainerCreating   0          2s
pc-deployment-866fdcbd54-dfwcg     1/1     Running             0          41s
pc-deployment-7bbbd589d5-nhn8z     1/1     Terminating         0          70s
pc-deployment-866fdcbd54-hqjnl     0/1     Pending             0          0s
pc-deployment-866fdcbd54-hqjnl     0/1     Pending             0          0s
pc-deployment-866fdcbd54-hqjnl     0/1     ContainerCreating   0          0s
pc-deployment-7bbbd589d5-nhn8z     0/1     Terminating         0          71s
pc-deployment-7bbbd589d5-nhn8z     0/1     Terminating         0          77s
pc-deployment-7bbbd589d5-nhn8z     0/1     Terminating         0          77s
pc-deployment-866fdcbd54-hqjnl     1/1     Running             0          37s
pc-deployment-7bbbd589d5-f9nj2     1/1     Terminating         0          109s
pc-deployment-866fdcbd54-gbn2c     0/1     Pending             0          0s
pc-deployment-866fdcbd54-gbn2c     0/1     Pending             0          0s
pc-deployment-866fdcbd54-gbn2c     0/1     ContainerCreating   0          0s
pc-deployment-7bbbd589d5-f9nj2     0/1     Terminating         0          110s
pc-deployment-866fdcbd54-gbn2c     1/1     Running             0          2s
pc-deployment-7bbbd589d5-ppggw     1/1     Terminating         0          112s
pc-deployment-7bbbd589d5-f9nj2     0/1     Terminating         0          111s
pc-deployment-7bbbd589d5-f9nj2     0/1     Terminating         0          111s
pc-deployment-7bbbd589d5-f9nj2     0/1     Terminating         0          111s
pc-deployment-7bbbd589d5-ppggw     0/1     Terminating         0          113s
pc-deployment-7bbbd589d5-ppggw     0/1     Terminating         0          2m
pc-deployment-7bbbd589d5-ppggw     0/1     Terminating         0          2m

# 3. 官方案例

3.1 更新 nginx Pod 以使用 nginx:1.16.1 镜像,而不是 nginx:1.14.2

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record
deployment.apps/nginx-deployment image updated

3.2 查看上线状态

$ kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out

3.3 查询 RS 状态

$ deployments % kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-559d658b74   3         3         3       94s
nginx-deployment-66b6c48dd5   0         0         0       14m

可以看到 Deployment 通过创建新的 ReplicaSet 并将其扩容到 3 个副本并将旧 ReplicaSet 缩容到 0 个副本完成了 Pod 的更新操作。

3.4 查看 Pod 状态

$ deployments % kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-559d658b74-2wvkr   1/1     Running   0          2m15s
nginx-deployment-559d658b74-4z4dv   1/1     Running   0          109s
nginx-deployment-559d658b74-j4dm9   1/1     Running   0          105s

可以看到只显示新的 Pod。

下次要更新这些 Pods 时,只需再次更新 Deployment Pod 模板即可。

Deployment 可确保在更新时仅关闭一定数量的 Pod。默认情况下,它确保至少所需 Pods 75% 处于运行状态(最大不可用比例为 25%)。

Deployment 还确保仅所创建 Pod 数量只可能比期望 Pods 数高一点点。 默认情况下,它可确保启动的 Pod 个数比期望个数最多多出 25%(最大峰值 25%)。

例如,如果仔细查看上述 Deployment ,将看到它首先创建了一个新的 Pod,然后删除了一些旧的 Pods, 并创建了新的 Pods。它不会杀死老 Pods,直到有足够的数量新的 Pods 已经出现。 在足够数量的旧 Pods 被杀死前并没有创建新 Pods。它确保至少 2 个 Pod 可用,同时最多总共 4 个 Pod 可用。

3.5 查看 Deployment 的详细信息

$ kubectl describe deployment/nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Thu, 24 Jun 2021 11:19:19 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 2
                        kubernetes.io/change-cause: kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record=true
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx:1.16.1
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-deployment-559d658b74 (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  16m    deployment-controller  Scaled up replica set nginx-deployment-66b6c48dd5 to 3
  Normal  ScalingReplicaSet  3m57s  deployment-controller  Scaled up replica set nginx-deployment-559d658b74 to 1
  Normal  ScalingReplicaSet  3m31s  deployment-controller  Scaled down replica set nginx-deployment-66b6c48dd5 to 2
  Normal  ScalingReplicaSet  3m31s  deployment-controller  Scaled up replica set nginx-deployment-559d658b74 to 2
  Normal  ScalingReplicaSet  3m27s  deployment-controller  Scaled down replica set nginx-deployment-66b6c48dd5 to 1
  Normal  ScalingReplicaSet  3m27s  deployment-controller  Scaled up replica set nginx-deployment-559d658b74 to 3
  Normal  ScalingReplicaSet  3m22s  deployment-controller  Scaled down replica set nginx-deployment-66b6c48dd5 to 0

# 4. 金丝雀发布

Deployment 支持更新过程中的控制,如暂停更新操作(pause)或继续更新操作(resume)。

例如有一批新的 Pod 资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求到新版本的 Pod 应用,继续观察能够稳定的按照期望的方式运行,如果没有问题之后再继续完成余下的 Pod 资源的滚动更新,否则立即回滚操作。

4.1 更新 Deployment 版本,并暂停它

[root@k8s-master deploy]# kubectl set image deployment pc-deployment nginx=nginx:1.17.4  && kubectl rollout pause deployment pc-deployment
deployment.apps/pc-deployment image updated
deployment.apps/pc-deployment paused

4.2 观察更新状态

[root@k8s-master deploy]# kubectl rollout status deployment pc-deployment
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...

[root@k8s-master deploy]# kubectl get rs
NAME                         DESIRED   CURRENT   READY   AGE
pc-deployment-56f77b8695     1         1         1       60s
pc-deployment-866fdcbd54     3         3         3       7m22s

[root@k8s-master deploy]# kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
pc-deployment-56f77b8695-q2cm6     1/1     Running   0          95s
pc-deployment-866fdcbd54-dfwcg     1/1     Running   0          7m57s
pc-deployment-866fdcbd54-gbn2c     1/1     Running   0          6m39s
pc-deployment-866fdcbd54-hqjnl     1/1     Running   0          7m16s
  • 监控更新的过程,可以看到已经新增了一个资源,但是并没有按照预期的状态去删除一个旧的资源,因为使用了 pause 暂停命令。

4.3 确保 Pod 没问题后,继续更新

[root@k8s-master deploy]# kubectl rollout resume deployment pc-deployment
deployment.apps/pc-deployment resumed

# 三、回滚 Deployment

Deployment 被触发上线时,系统就会创建 Deployment 的新的修订版本。

这意味着仅当 Deployment 的 Pod 模板(.spec.template)发生更改时,才会创建新修订版本 -- 例如,模板的标签或容器镜像发生变化。

其他更新,如 Deployment 的扩缩容操作不会创建 Deployment 修订版本。

这是为了方便同时执行手动缩放或自动缩放。

换言之,当你回滚到较早的修订版本时,只有 Deployment 的 Pod 模板部分会被回滚

1. 故意错设 nginx 版本为 1.161

$ deployments % kubectl set image deployment/nginx-deployment nginx=nginx:1.161 --record
deployment.apps/nginx-deployment image updated

2. 查看上线状态

$ deployments % kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...

此时会发现上线进程一直处于停滞状态。按 Command + C 退出。

3. 查看 RS 状态

$ deployments % kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-559d658b74   3         3         3       27m
nginx-deployment-66b6c48dd5   0         0         0       40m
nginx-deployment-66bc5d6c8    1         1         0       107s

可以看到旧的副本有两个(nginx-deployment-1564180365nginx-deployment-2035384211), 新的副本有 1 个(nginx-deployment-3066724191)。

4. 查看 Pod 状态

$ deployments % kubectl get pods
NAME                                READY   STATUS         RESTARTS   AGE
nginx-deployment-559d658b74-2wvkr   1/1     Running        0          28m
nginx-deployment-559d658b74-4z4dv   1/1     Running        0          27m
nginx-deployment-559d658b74-j4dm9   1/1     Running        0          27m
nginx-deployment-66bc5d6c8-d94kw    0/1     ErrImagePull   0          2m31s

可以注意到新 ReplicaSet 所创建的 1 个 Pod 卡顿在镜像拉取循环中。

Deployment 控制器自动停止有问题的上线过程,并停止对新的 ReplicaSet 扩容。 这行为取决于所指定的 rollingUpdate 参数(具体为 maxUnavailable)。 默认情况下,Kubernetes 将此值设置为 25%。

5. 查看 Deployment 详细信息

$ deployments % kubectl describe deployment/nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Thu, 24 Jun 2021 11:19:19 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 3
                        kubernetes.io/change-cause: kubectl set image deployment/nginx-deployment nginx=nginx:1.161 --record=true
Selector:               app=nginx
Replicas:               3 desired | 1 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.161
    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-559d658b74 (3/3 replicas created)
NewReplicaSet:   nginx-deployment-66bc5d6c8 (1/1 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  41m    deployment-controller  Scaled up replica set nginx-deployment-66b6c48dd5 to 3
  Normal  ScalingReplicaSet  28m    deployment-controller  Scaled up replica set nginx-deployment-559d658b74 to 1
  Normal  ScalingReplicaSet  28m    deployment-controller  Scaled down replica set nginx-deployment-66b6c48dd5 to 2
  Normal  ScalingReplicaSet  28m    deployment-controller  Scaled up replica set nginx-deployment-559d658b74 to 2
  Normal  ScalingReplicaSet  28m    deployment-controller  Scaled down replica set nginx-deployment-66b6c48dd5 to 1
  Normal  ScalingReplicaSet  28m    deployment-controller  Scaled up replica set nginx-deployment-559d658b74 to 3
  Normal  ScalingReplicaSet  28m    deployment-controller  Scaled down replica set nginx-deployment-66b6c48dd5 to 0
  Normal  ScalingReplicaSet  3m22s  deployment-controller  Scaled up replica set nginx-deployment-66bc5d6c8 to 1

可以看到有一个 unavailable 的 ReplicaSet。下面来进行回滚。

6. 检查 Deployment 上线历史

$ deployments % kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record=true
3         kubectl set image deployment/nginx-deployment nginx=nginx:1.161 --record=true

CHANGE-CAUSE 的内容是从 Deployment 的 kubernetes.io/change-cause 注解复制过来的。 复制动作发生在修订版本创建时。你可以通过以下方式设置 CHANGE-CAUSE 消息:

  • 使用 kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1" 为 Deployment 添加注解。
  • 追加 --record 命令行标志以保存正在更改资源的 kubectl 命令。
  • 手动编辑资源的清单。

7. 查看修订历史的详细信息

$ kubectl rollout history deployment/nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
  Labels:	app=nginx
	pod-template-hash=559d658b74
  Annotations:	kubernetes.io/change-cause: kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record=true
  Containers:
   nginx:
    Image:	nginx:1.16.1
    Port:	80/TCP
    Host Port:	0/TCP
    Environment:	<none>
    Mounts:	<none>
  Volumes:	<none>

8. 回滚

使用 undo 就可以回滚到当前版本的上一个版本:

$ kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back

也可以使用 --to-revision 来回滚到特定的版本:

$ kubectl rollout undo deployment/nginx-deployment --to-revision=4
deployment.apps/nginx-deployment rolled back

9. 检查是否回滚成功

$ kubectl get deployment nginx-deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           23h

成功。

# 四、缩放 Deployment

# 1. 正常缩放

使用如下指令缩放 Deployment:

kubectl scale deployment/nginx-deployment --replicas=10

输出:

deployment.apps/nginx-deployment scaled

假设集群启用了Pod 的水平自动缩放 (opens new window), 你可以为 Deployment 设置自动缩放器,并基于现有 Pods 的 CPU 利用率选择要运行的 Pods 个数下限和上限:

kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80

输出:

horizontalpodautoscaler.autoscaling/nginx-deployment autoscaled

# 2. 比例缩放

RollingUpdate 的 Deployment 支持同时运行应用程序的多个版本。 当自动缩放器缩放处于上线进程(仍在进行中或暂停)中的 RollingUpdate Deployment 时, Deployment 控制器会平衡现有的活跃状态的 ReplicaSets(含 Pods 的 ReplicaSets)中的额外副本, 以降低风险。这称为 比例缩放(Proportional Scaling)

例如,你正在运行一个 10 个副本的 Deployment,其 maxSurge=3,maxUnavailable=2。

  • 确保 Deployment 的这 10 个副本都在运行:

    $ kubectl get deploy
    NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment     10        10        10           10          50s
    
  • 更新 Deployment 使用新镜像,碰巧该镜像无法从集群内部解析:

  • $ kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:sometag
    deployment.apps/nginx-deployment image updated
    
  • 镜像更新使用 ReplicaSet nginx-deployment-559d658b74 启动新的上线过程, 但由于上面提到的 maxUnavailable 要求,该进程被阻塞了。检查上线状态:

  • $ kubectl get rs
    NAME                          DESIRED   CURRENT   READY     AGE
    nginx-deployment-1989198191   5         5         0         9s
    nginx-deployment-618515232    8         8         8         1m
    
  • 然后,出现了新的 Deployment 扩缩请求。自动缩放器将 Deployment 副本增加到 15。 Deployment 控制器需要决定在何处添加 5 个新副本。如果未使用比例缩放,所有 5 个副本 都将添加到新的 ReplicaSet 中。使用比例缩放时,可以将额外的副本分布到所有 ReplicaSet。 较大比例的副本会被添加到拥有最多副本的 ReplicaSet,而较低比例的副本会进入到 副本较少的 ReplicaSet。所有剩下的副本都会添加到副本最多的 ReplicaSet。 具有零副本的 ReplicaSets 不会被扩容。

在上面的示例中,3 个副本被添加到旧 ReplicaSet 中,2 个副本被添加到新 ReplicaSet。 假定新的副本都很健康,上线过程最终应将所有副本迁移到新的 ReplicaSet 中。 要确认这一点,请运行:

$ kubectl get deploy
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment     15        18        7            8           7m

上线状态确认了副本是如何被添加到每个 ReplicaSet 的。

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-1989198191   7         7         0         7m
nginx-deployment-618515232    11        11        11        7m

# 五、暂停 Deployment

使用如下指令暂停运行:

$ kubectl rollout pause deployment/nginx-deployment
deployment.apps/nginx-deployment paused

# 六、恢复 Deployment

$ kubectl rollout resume deployment/nginx-deployment
deployment.apps/nginx-deployment resumed
上次更新: 7/8/2021, 11:28:32 AM