Kubernetes中Pod的升级和回滚

news2024/11/26 6:03:12

Kubernetes中Pod的升级和回滚

本文说说 Pod 的升级和回滚问题。

当集群中的某个服务需要升级时,我们需要停止目前与该服务相关的所有 Pod,然后下载新版本镜像并创建新的

Pod。如果集群规模比较大,则这个工作变成了一个挑战,而且先全部停止然后逐步升级的方式会导致较长时间的

服务不可用。Kubernetes 提供了滚动升级功能来解决上述问题。

如果 Pod 是通过 Deployment 创建的,则用户可以在运行时修改 Deployment 的 Pod 定义(spec.template)或镜

像名称,并应用到 Deployment 对象上,系统即可完成 Deployment 的自动更新操作。如果在更新过程中发生了

错误,则还可以通过回滚操作恢复 Pod 的版本。

1、Deployment的升级

配置文件 034-nginx-deployment.yaml 的内容为:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-deployment
  template:
    metadata:
      labels:
        app: nginx-deployment
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80 
[root@master cha3]# kubectl create -f 034-nginx-deployment.yaml
deployment.apps/nginx-deployment created
[root@master cha3]# kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           14s

已运行的 Pod 副本数量有 3 个:

[root@master cha3]# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
nginx-deployment-5c5f6c4496-2ctkg   1/1     Running   0          44s   10.244.140.66    slave2   <none>           <none>
nginx-deployment-5c5f6c4496-tz9wr   1/1     Running   0          44s   10.244.140.193   slave1   <none>           <none>
nginx-deployment-5c5f6c4496-vs2rk   1/1     Running   0          44s   10.244.140.67    slave2   <none>           <none>

现在 Pod 镜像需要被更新为 Nginx:1.9.1 ,我们可以通过 kubectl set image 命令为 Deployment 设置新的镜

像名称:

[root@master cha3]# kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment.apps/nginx-deployment image updated

另一种更新的方法是使用 kubectl edit 命令修改 Deployment 的配置,将

spec.template.spec.containers[0].imageNginx:1.7.9 更改为 Nginx:1.9.1

[root@master cha3]# kubectl edit deployment/nginx-deployment
......
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx-deployment
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-deployment
    spec:
      containers:
      - image: nginx:1.9.1
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
......

一旦镜像名(或 Pod 定义)发生了修改,则将触发系统完成 Deployment 所有运行 Pod 的滚动升级操作。可以使用

kubectl rollout status 命令查看 Deployment 的更新过程:

[root@master cha3]# kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out

查看当前运行的 Pod,名称已经更新了:

[root@master cha3]# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
nginx-deployment-76478869c8-tgmfp   1/1     Running   0          3m25s   10.244.140.69    slave2   <none>           <none>
nginx-deployment-76478869c8-wrqnw   1/1     Running   0          3m29s   10.244.140.194   slave1   <none>           <none>
nginx-deployment-76478869c8-xfw25   1/1     Running   0          3m27s   10.244.140.68    slave2   <none>           <none>

查看 Pod 使用的镜像,已经更新为 Nginx:1.9.1了:

[root@master cha3]# kubectl describe pod/nginx-deployment-76478869c8-xfw25
Name:         nginx-deployment-76478869c8-xfw25
Namespace:    default
Priority:     0
Node:         slave2/192.168.226.202
Start Time:   Mon, 10 Jul 2023 20:22:00 +0800
Labels:       app=nginx-deployment
              pod-template-hash=76478869c8
Annotations:  <none>
Status:       Running
IP:           10.244.140.68
IPs:
  IP:           10.244.140.68
Controlled By:  ReplicaSet/nginx-deployment-76478869c8
Containers:
  nginx:
    Container ID:   docker://e02663da607b87a595ca02a250a6e7732f8fdb9778d37bdc30a6298927bab857
    Image:          nginx:1.9.1
    Image ID:       docker-pullable://nginx@sha256:2f68b99bc0d6d25d0c56876b924ec20418544ff28e1fb89a4c27679a40da811b
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 10 Jul 2023 20:22:01 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-vj2v7 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-vj2v7:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m15s  default-scheduler  Successfully assigned default/nginx-deployment-76478869c8-xfw25 to slave2
  Normal  Pulled     4m15s  kubelet            Container image "nginx:1.9.1" already present on machine
  Normal  Created    4m15s  kubelet            Created container nginx
  Normal  Started    4m15s  kubelet            Started container nginx

那么,Deployment 是如何完成 Pod 更新的呢?

我们可以使用 kubectl describe deployments/nginx-deployment 命令仔细观察 Deployment 的更新过程。

初始创建 Deployment 时,系统创建了一个 ReplicaSet(nginx-deployment-5c5f6c4496),并按用户的需求创建

了 3 个 Pod 副本。当更新 Deployment 时,系统创建了一个新的 ReplicaSet(nginx-deployment-76478869c8),

并将其副本数量扩展到 1,然后将旧的 ReplicaSet 缩减为 2。之后,系统继续按照相同的更新策略对新旧两个

ReplicaSet 进行逐个调整。最后,新的 ReplicaSet 运行了 3 个新版本 Pod 副本,旧的 ReplicaSet 副本数量则缩

减为0。如图所示。

在这里插入图片描述

下面列出 Deployment nginx-deployment 的详细事件信息:

[root@master cha3]# kubectl describe deployments/nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Mon, 10 Jul 2023 20:20:12 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 2
Selector:               app=nginx-deployment
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-deployment
  Containers:
   nginx:
    Image:        nginx:1.9.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-76478869c8 (3/3 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  10m   deployment-controller  Scaled up replica set nginx-deployment-5c5f6c4496 to 3
  Normal  ScalingReplicaSet  9m6s  deployment-controller  Scaled up replica set nginx-deployment-76478869c8 to 1
  Normal  ScalingReplicaSet  9m4s  deployment-controller  Scaled down replica set nginx-deployment-5c5f6c4496 to 2
  Normal  ScalingReplicaSet  9m4s  deployment-controller  Scaled up replica set nginx-deployment-76478869c8 to 2
  Normal  ScalingReplicaSet  9m2s  deployment-controller  Scaled down replica set nginx-deployment-5c5f6c4496 to 1
  Normal  ScalingReplicaSet  9m2s  deployment-controller  Scaled up replica set nginx-deployment-76478869c8 to 3
  Normal  ScalingReplicaSet  9m    deployment-controller  Scaled down replica set nginx-deployment-5c5f6c4496 to 0

运行 kubectl get rs 命令,查看两个 ReplicaSet 的最终状态:

[root@master cha3]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5c5f6c4496   0         0         0       11m
nginx-deployment-76478869c8   3         3         3       9m42s

在整个升级的过程中,系统会保证至少有两个 Pod 可用,并且最多同时运行 4 个 Pod,这是 Deployment 通过复

杂的算法完成的。Deployment 需要确保在整个更新过程中只有一定数量的 Pod 可能处于不可用状态。在默认情

况下,Deployment 确保可用的 Pod 总数至少为所需的副本数量 DESIRED 减1,也就是最多1个不可用

maxUnavailable=1。Deployment 还需要确保在整个更新过程中 Pod 的总数量不会超过所需的副本数量太多。在

默认情况下,Deployment 确保 Pod 的总数最多比所需的 Pod 数多1个,也就是最多1个浪涌值 maxSurge=1。

Kubernetes 从 1.6 版本开始,maxUnavailable 和 maxSurge 的默认值将从1、1更新为所需副本数量的25%、

25%。这样,在升级过程中,Deployment 就能够保证服务不中断,并且副本数量始终维持为用户指定的数量

DESIRED。

对更新策略的说明如下。

在 Deployment 的定义中,可以通过 spec.strategy 指定 Pod 更新的策略,目前支持两种策略:

Recreate(重建)和 RollingUpdate(滚动更新),默认值为 RollingUpdate

在前面的例子中使用的就是 RollingUpdate 策略。

  • Recreate:设置spec.strategy.type=Recreate,表示Deployment在更新Pod时,会先杀掉所有正在运行的

    Pod,然后创建新的Pod。

  • RollingUpdate:设置spec.strategy.type=RollingUpdate,表示Deployment会以滚动更新的方式来逐个更

    新Pod。同时,可以通过设置spec.strategy.rollingUpdate下的两个参数(maxUnavailable和maxSurge)来

    控制滚动更新的过程。

下面对滚动更新时两个主要参数的说明如下。

  • spec.strategy.rollingUpdate.maxUnavailable:用于指定Deployment在更新过程中不可用状态的Pod

    数量的上限。该maxUnavailable的数值可以是绝对值(例如5)或Pod期望的副本数的百分比(例如10%),

    如果被设置为百分比,那么系统会先以向下取整的方式计算出绝对值(整数)。而当另一个参数maxSurge被

    设置为0时,maxUnavailable则必须被设置为绝对数值大于0(从Kubernetes 1.6开始,maxUnavailable的默

    认值从1改为25%)。举例来说,当maxUnavailable被设置为30%时,旧的ReplicaSet可以在滚动更新开始时

    立即将副本数缩小到所需副本总数的70%。一旦新的Pod创建并准备好,旧的ReplicaSet会进一步缩容,新的

    ReplicaSet又继续扩容,整个过程中系统在任意时刻都可以确保可用状态的Pod总数至少占Pod期望副本总数

    的70%。

  • spec.strategy.rollingUpdate.maxSurge:用于指定在Deployment更新Pod的过程中Pod总数超过Pod期

    望副本数部分的最大值。该maxSurge的数值可以是绝对值(例如5)或Pod期望副本数的百分比(例如

    10%)。如果设置为百分比,那么系统会先按照向上取整的方式计算出绝对数值(整数)。从Kubernetes 1.6

    开始,maxSurge的默认值从1改为25%。举例来说,当maxSurge的值被设置为30%时,新的ReplicaSet可以

    在滚动更新开始时立即进行副本数扩容,只需要保证新旧ReplicaSet的Pod副本数之和不超过期望副本数的

    130%即可。一旦旧的Pod被杀掉,新的ReplicaSet就会进一步扩容。在整个过程中系统在任意时刻都能确保

    新旧ReplicaSet的Pod副本总数之和不超过所需副本数的130%。

这里需要注意多重更新(Rollover)的情况。如果Deployment的上一次更新正在进行,此时用户再次发起

Deployment的更新操作,那么Deployment会为每一次更新都创建一个ReplicaSet,而每次在新的ReplicaSet创建

成功后,会逐个增加Pod副本数,同时将之前正在扩容的ReplicaSet停止扩容(更新),并将其加入旧版本

ReplicaSet列表中,然后开始缩容至0的操作。

例如,假设我们创建一个 Deployment,这个 Deployment 开始创建 5 个 Nginx:1.7.9 的 Pod 副本,在这个创建

Pod 动作尚未完成时,我们又将 Deployment 进行更新,在副本数不变的情况下将 Pod 模板中的镜像修改为

Nginx:1.9.1,又假设此时 Deployment 已经创建了 3 个 Nginx:1.7.9 的 Pod 副本,则 Deployment 会立即杀掉已

创建的 3 个 Nginx:1.7.9 Pod,并开始创建 Nginx:1.9.1 Pod。Deployment 不会在等待 Nginx:1.7.9 的 Pod 创建

到 5 个之后再进行更新操作。

还需要注意更新 Deployment 的标签选择器(Label Selector)的情况。通常来说,不鼓励更新 Deployment 的标

签选择器,因为这样会导致 Deployment 选择的 Pod 列表发生变化,也可能与其他控制器产生冲突。如果一定要

更新标签选择器,那么请务必谨慎,确保不会出现其他问题。

关于 Deployment 标签选择器的更新的注意事项如下。

(1)添加选择器标签时,必须同步修改 Deployment 配置的 Pod 的标签,为 Pod 添加新的标签,否则

Deployment 的更新会报验证错误而失败:

[root@master cha3]# kubectl edit deployment/nginx-deployment

spec.template.metadata.labels 的值 app=nginx-deployment 改为 app=nginx

......
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx-deployment
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx # 修改nginx-deployment为nginx
......

会报错而退出修改:

# deployments.apps "nginx-deployment" was not valid:
# * spec.template.metadata.labels: Invalid value: map[string]string{"app":"nginx"}: `selector` does not match template `labels`

添加标签选择器是无法向后兼容的,这意味着新的标签选择器不会匹配和使用旧选择器创建的 ReplicaSets 和

Pod,因此添加选择器将会导致所有旧版本的 ReplicaSets 和由旧 ReplicaSets 创建的 Pod 处于孤立状态(不会被

系统自动删除,也不受新的 ReplicaSet 控制)。

为标签选择器和Pod模板添加新的标签(使用kubectl edit deployment命令)。

[root@master cha3]# kubectl edit deployment/nginx-deployment

ReplicaSet 会创建 3 个新的 Pod。

[root@master cha3]# kubectl get rs
[root@master cha3]# kubectl get pod

(2)更新标签选择器,即更改选择器中标签的键或者值,也会产生与添加选择器标签类似的效果。

(3)删除标签选择器,即从Deployment的标签选择器中删除一个或者多个标签,该Deployment的ReplicaSet和

Pod不会受到任何影响。但需要注意的是,被删除的标签仍会存在于现有的Pod和ReplicaSets上。

Deployment 标签更改的情况很少,这里我们就不详细介绍了。

2、Deployment的回滚

有时(例如新的 Deployment 不稳定时)我们可能需要将 Deployment 回滚到旧版本。在默认情况下,所有

Deployment 的发布历史记录都被保留在系统中,以便于我们随时进行回滚(可以配置历史记录数量)。

# 现在的环境
[root@master cha3]# kubectl create -f 034-nginx-deployment.yaml
deployment.apps/nginx-deployment created

[root@master cha3]# kubectl get rs,deploy,pod
NAME                                          DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-5c5f6c4496   3         3         3       22s

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment   3/3     3            3           22s

NAME                                    READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-5c5f6c4496-22gfk   1/1     Running   0          22s
pod/nginx-deployment-5c5f6c4496-4ddxd   1/1     Running   0          22s
pod/nginx-deployment-5c5f6c4496-rkqzq   1/1     Running   0          22s

假设在更新 Deployment 镜像时,将容器镜像名误设置成 Nginx:1.91(一个不存在的镜像):

[root@master cha3]# kubectl set image deployment/nginx-deployment nginx=nginx:1.91
deployment.apps/nginx-deployment image updated

则这时 Deployment 的部署过程会卡住:

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

由于执行过程卡住,所以需要执行 Ctrl-C 命令来终止这个查看命令。

查看 ReplicaSet,可以看到新建的 ReplicaSet(nginx-deployment-85d8cdd6f7):

[root@master cha3]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5c5f6c4496   3         3         3       70s
nginx-deployment-77f88687b6   1         1         0       31s

再查看创建的 Pod,会发现新的 ReplicaSet 创建的 1 个 Pod 被卡在镜像拉取过程中。

[root@master cha3]# kubectl get pods
NAME                                READY   STATUS             RESTARTS   AGE
nginx-deployment-5c5f6c4496-22gfk   1/1     Running            0          83s
nginx-deployment-5c5f6c4496-4ddxd   1/1     Running            0          83s
nginx-deployment-5c5f6c4496-rkqzq   1/1     Running            0          83s
nginx-deployment-77f88687b6-sqg6w   0/1     ImagePullBackOff   0          44s

为了解决上面这个问题,我们需要回滚到之前稳定版本的 Deployment。

首先,用kubectl rollout history命令检查这个 Deployment 部署的历史记录:

[root@master cha3]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

注意,在创建 Deployment 时使用 --record 参数,就可以在 CHANGE-CAUSE 列看到每个版本使用的命令了。另

外,Deployment 的更新操作是在 Deployment 进行部署(Rollout)时被触发的,这意味着当且仅当Deployment的

Pod模板(即spec.template)被更改时才会创建新的修订版本,例如更新模板标签或容器镜像。其他更新操作

(如扩展副本数)将不会触发Deployment的更新操作,这也意味着我们将Deployment回滚到之前的版本时,只

有Deployment的Pod模板部分会被修改。

如果需要查看特定版本的详细信息,则可以加上--revision=<N>参数:

[root@master cha3]# kubectl rollout history deployment/nginx-deployment --revision=0
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
[root@master cha3]# kubectl rollout history deployment/nginx-deployment --revision=1
deployment.apps/nginx-deployment with revision #1
Pod Template:
  Labels:       app=nginx-deployment
        pod-template-hash=5c5f6c4496
  Containers:
   nginx:
    Image:      nginx:1.7.9
    Port:       80/TCP
    Host Port:  0/TCP
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>
[root@master cha3]# kubectl rollout history deployment/nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
  Labels:       app=nginx-deployment
        pod-template-hash=77f88687b6
  Containers:
   nginx:
    Image:      nginx:1.91
    Port:       80/TCP
    Host Port:  0/TCP
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>

现在我们决定撤销本次发布并回滚到上一个部署版本:

[root@master cha3]# kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back

当然,也可以使用 --to-revision 参数指定回滚到的部署版本号:

[root@master cha3]# kubectl rollout undo deployment/nginx-deployment --to-revision=1

这样,该Deployment就回滚到之前的稳定版本了,可以从Deployment的事件信息中查看到回滚到版本1的操作过

程:

[root@master cha3]# kubectl describe deployment/nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Mon, 10 Jul 2023 21:43:07 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 3
Selector:               app=nginx-deployment
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-deployment
  Containers:
   nginx:
    Image:        nginx:1.7.9
    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-5c5f6c4496 (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  5m24s  deployment-controller  Scaled up replica set nginx-deployment-5c5f6c4496 to 3
  Normal  ScalingReplicaSet  4m45s  deployment-controller  Scaled up replica set nginx-deployment-77f88687b6 to 1
  Normal  ScalingReplicaSet  73s    deployment-controller  Scaled down replica set nginx-deployment-77f88687b6 to 0 

查看回滚历史:

[root@master cha3]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

3、暂停和恢复Deployment的部署操作以完成复杂的修改

对于一次复杂的Deployment配置修改,为了避免频繁触发Deployment的更新操作,可以先暂停Deployment的

更新操作,然后进行配置修改,再恢复Deployment,一次性触发完整的更新操作,就可以避免不必要的

Deployment更新操作了。

以之前创建的 Nginx 为例:

[root@master cha3]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           8m43s

[root@master cha3]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5c5f6c4496   3         3         3       9m22s
nginx-deployment-77f88687b6   0         0         0       8m43s

[root@master cha3]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5c5f6c4496-22gfk   1/1     Running   0          9m30s
nginx-deployment-5c5f6c4496-4ddxd   1/1     Running   0          9m30s
nginx-deployment-5c5f6c4496-rkqzq   1/1     Running   0          9m30s

通过 kubectl rollout pause 命令暂停 Deployment 的更新操作:

[root@master cha3]# kubectl rollout pause deployment/nginx-deployment
deployment.apps/nginx-deployment paused

然后修改Deployment的镜像信息:

[root@master cha3]# kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment.apps/nginx-deployment image updated

查看Deployment的历史记录,发现并没有触发新的Deployment部署操作(停止和重启):

[root@master cha3]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

在暂停Deployment部署之后,可以根据需要进行任意次数的配置更新。例如,再次更新容器的资源限制:

[root@master cha3]# kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
deployment.apps/nginx-deployment resource requirements update

最后,恢复这个Deployment的部署操作:

[root@master cha3]# kubectl rollout resume deployment/nginx-deployment
deployment.apps/nginx-deployment resumed

可以看到一个新的ReplicaSet被创建出来了:

[root@master cha3]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5c5f6c4496   0         0         0       11m
nginx-deployment-77f88687b6   0         0         0       11m
nginx-deployment-889d8b75d    3         3         3       13s

查看 Deployment 的事件信息,可以看到 Deployment 完成了更新:

[root@master cha3]# kubectl describe deployment/nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Mon, 10 Jul 2023 21:43:07 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 4
Selector:               app=nginx-deployment
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-deployment
  Containers:
   nginx:
    Image:      nginx:1.9.1
    Port:       80/TCP
    Host Port:  0/TCP
    Limits:
      cpu:        200m
      memory:     512Mi
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-deployment-889d8b75d (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  12m    deployment-controller  Scaled up replica set nginx-deployment-5c5f6c4496 to 3
  Normal  ScalingReplicaSet  11m    deployment-controller  Scaled up replica set nginx-deployment-77f88687b6 to 1
  Normal  ScalingReplicaSet  8m16s  deployment-controller  Scaled down replica set nginx-deployment-77f88687b6 to 0
  Normal  ScalingReplicaSet  60s    deployment-controller  Scaled up replica set nginx-deployment-889d8b75d to 1
  Normal  ScalingReplicaSet  59s    deployment-controller  Scaled down replica set nginx-deployment-5c5f6c4496 to 2
  Normal  ScalingReplicaSet  59s    deployment-controller  Scaled up replica set nginx-deployment-889d8b75d to 2
  Normal  ScalingReplicaSet  57s    deployment-controller  Scaled down replica set nginx-deployment-5c5f6c4496 to 1
  Normal  ScalingReplicaSet  57s    deployment-controller  Scaled up replica set nginx-deployment-889d8b75d to 3
  Normal  ScalingReplicaSet  55s    deployment-controller  Scaled down replica set nginx-deployment-5c5f6c4496 to 0

注意,在恢复暂停的 Deployment 之前,无法回滚该 Deployment。

4、使用kubectl rolling-update命令完成RC的滚动升级

高版本已经移除了该命令。

对于RC的滚动升级,Kubernetes还提供了一个kubectl rolling-update命令进行实现。该命令创建了一个新的

RC,然后自动控制旧的RC中的Pod副本数量逐渐减少到0,同时新的RC中的Pod副本数量从0逐步增加到目标值,

来完成Pod的升级。需要注意的是,系统要求新的RC与旧的RC都在相同的命名空间内。

以redis-master为例,假设当前运行的redis-master Pod是1.0版本,现在需要升级到2.0版本。

配置文件 035-redis-master-controller.yaml 的内容为:

apiVersion: v1
kind: ReplicationController 
metadata:
  name: redis-master
  labels:
    name: redis-master 
spec:
  replicas: 3
  selector:
    name: redis-master
  template:
    metadata:
      labels:
        name: redis-master
    spec:
      containers:
      - name: master
        image: kubeguide/redis-master
        ports:
        - containerPort: 6379

创建 036-redis-master-controller.yaml 的配置文件如下:

apiVersion: v1
kind: ReplicationController
metadata:
  name: redis-master-v2
  labels:
    name: redis-master
    version: v2
spec:
  replicas: 3
  selector:
    name: redis-master
    version: v2
  template:
    metadata:
      labels:
        name: redis-master
        version: v2
    spec:
      containers:
      - name: master
        image: kubeguide/redis-master:2.0
        ports:
        - containerPort: 6379

在配置文件中需要注意以下两点。

  • RC 的名字不能与旧 RC 的名字相同。

  • 在 selector 中应至少有一个 Label 与旧 RC 的 Label 不同,以标识其为新 RC。在本例中新增了一个名为

    version 的 Label,以与旧 RC 进行区分。

首先,先创建v1版本的redis:

[root@master cha3]# kubectl create -f 035-redis-master-controller.yaml
replicationcontroller/redis-master created
[root@master cha3]# kubectl get rc,pod -o wide
NAME                                 DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                   SELECTOR
replicationcontroller/redis-master   3         3         3       81s   master       kubeguide/redis-master   name=redis-master

NAME                     READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
pod/redis-master-tpnfr   1/1     Running   0          81s   10.244.140.84    slave2   <none>           <none>
pod/redis-master-w8qdq   1/1     Running   0          81s   10.244.140.203   slave1   <none>           <none>
pod/redis-master-ws7d5   1/1     Running   0          81s   10.244.140.83    slave2   <none>           <none>

运行 kubectl rolling-update 命令完成 Pod 的滚动升级:

$ kubectl rolling-update redis-master -f 036-redis-master-controller.yaml

等所有新的 Pod 都启动完成后,旧的 Pod 也被全部销毁,这样就完成了容器集群的更新工作。

另一种方法是不使用配置文件,直接用 kubectl rolling-update 命令,加上--image参数指定新版镜像名称来

完成Pod的滚动升级:

$ kubectl rolling-update redis-master --image=redis-master:2.0

与使用配置文件的方式不同,执行的结果是旧 RC 被删除,新 RC 仍将使用旧 RC 的名称。

kubectl 通过新建一个新版本 Pod,停掉一个旧版本 Pod,如此逐步迭代来完成整个 RC 的更新。

更新完成后,查看RC:

$ kubectl get rc

kubectl 给 RC 增加了一个key为 deployment 的Label(这个key的名字可通过 --deployment-label-

key 参数进行修改),Label 的值是 RC 的内容进行 Hash 计算后的值,相当于签名,这样就能很方便地比较RC里

的 Image 名字及其他信息是否发生了变化。

如果在更新过程中发现配置有误,则用户可以中断更新操作,并通过执行

kubectl rolling-update --rollback 完成 Pod 版本的回滚:

$ kubectl rolling-update redis-master --image=kubeguide/redis-master:2.0 --rollback

至此,Pod 恢复到更新前的版本了。

可以看出,RC 的滚动升级不具有 Deployment 在应用版本升级过程中的历史记录、新旧版本数量的精细控制等功

能,在 Kubernetes 的演进过程中,RC 将逐渐被 RS 和 Deployment 所取代,建议用户优先考虑使用

Deployment 完成 Pod 的部署和升级操作。

5、其他管理对象的更新策略

Kubernetes从 1.6 版本开始,对 DaemonSet 和 StatefulSet 的更新策略也引入类似于 Deployment 的滚动升

级,通过不同的策略自动完成应用的版本升级。

5.1 DaemonSet的更新策略

目前 DaemonSet 的升级策略包括两种:OnDeleteRollingUpdate

(1)OnDelete:DaemonSet的默认升级策略,与1.5及以前版本的Kubernetes保持一致。当使用OnDelete作为

升级策略时,在创建好新的DaemonSet配置之后,新的Pod并不会被自动创建,直到用户手动删除旧版本的

Pod,才触发新建操作。

(2)RollingUpdate:从Kubernetes 1.6版本开始引入。当使用RollingUpdate作为升级策略对DaemonSet进

行更新时,旧版本的Pod将被自动杀掉,然后自动创建新版本的DaemonSet Pod。整个过程与普通Deployment

的滚动升级一样是可控的。不过有两点不同于普通Pod的滚动升级:一是目前Kubernetes还不支持查看和管理

DaemonSet的更新历史记录;二是DaemonSet的回滚(Rollback)并不能如同Deployment一样直接通过kubectl

rollback命令来实现,必须通过再次提交旧版本配置的方式实现。

5.2 StatefulSet的更新策略

Kubernetes从1.6版本开始,针对StatefulSet的更新策略逐渐向Deployment和DaemonSet的更新策略看齐,也将

实现RollingUpdate、Paritioned和OnDelete这几种策略,以保证StatefulSet中各Pod有序地、逐个地更新,并且

能够保留更新历史,也能回滚到某个历史版本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/740399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】 Linus世界,WIndows VS Linux

文章目录 前言WindowsLinux操作系统Windows VS Linux收费情况技术支持安全性开源 区别 前言 在电脑世界有两种十分常见的电脑操作系统——Linux与和Windows&#xff0c;相信对电脑有一定了解的人对它们一定并不陌生&#xff01;但是在我们的使用过程中&#xff0c;是否有什么事…

大公司为什么禁止在 Spring Boot 项目中使用 @Autowired 注解?

1、说明 最近公司升级框架&#xff0c;由原来的spring framerwork 3.0升级到5.0&#xff0c;然后写代码的时候突然发现idea在属性注入的 Autowired 注解上给出警告提示&#xff0c;就像下面这样的&#xff0c;也挺懵逼的&#xff0c;毕竟这么写也很多年了。 Field injection i…

leetcode 147.对链表进行插入排序

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;对链表进行插入排序 思路与图解&#xff1a; 遍历链表&#xff0c;当前结点依次与前面的结点比较&#xff0c;选择插入位置。每次与前面的结点比较需要从头开始比较&#xff0c;所以定义一个 tempHead 指针&#xff0c;…

Python实现PSO粒子群优化算法优化LightGBM回归模型(LGBMRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 PSO是粒子群优化算法&#xff08;Particle Swarm Optimization&#xff09;的英文缩写&#xff0c;是一…

CopyRE关系抽取

CopyRE 模型包括编码器和解码器两部分 编码器&#xff1a;将输入的句子&#xff08;源句子&#xff09;转换为固定长度的语义向量 解码器&#xff1a;读取该矢量并直接生成三元组 Encoder 编码器使用Bi-RNN对输入句子进行编码。 Decoder 解码器会直接生成三元组。 1、 解码…

仅用js代码实现模态框

很多时候我们经常会用ui框架实现模态框的使用&#xff0c;但是&#xff0c;如果哪一天告诉我们&#xff0c;如何仅用js代码实现一个模态框该怎么办呢&#xff1f; 这里就要用到很多js中的基础方法运用了&#xff0c;我们先看如下代码 var logDiv document.createElement(&quo…

Java版本电子招标采购系统源码:—实现多寻源比价,风险预警

营造全面规范安全的电子招投标环境&#xff0c;促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标…

vue2跨组件传值、透明传输($attrs 和 $listeners )

当在 Vue.js 组件中使用 $attrs 和 $listeners 时&#xff0c;它们提供了一种方便的方式来处理传递给组件的属性和事件监听器。 1.$attrs 是一个对象&#xff0c;包含了父组件传递给当前组件但未被当前组件声明的 props。这对于实现“透明传输”非常有用。 2.$listeners 也是…

EMQ 联合英特尔、云轴科技 ZStack 推出泛工业物联网联合解决方案

近日,EMQ 携手英特尔与云轴科技 ZStack 推出泛工业物联网联合解决方案,基于云原生超融合,在挖掘生产数据价值的同时有效降低综合建设成本,为用户提供一站式数据链路及 IT 基础设施解决方案。 工业能耗大户面临的关键挑战 工业正迈入一个全新的物联网时代,海量数据计算需求涌现…

实验三 交换机基本配置

文章目录 实验目的实验原理实验内容实验总结 实验目的 掌握 Cisco Packet Tracer 模拟软件的基本使用方法&#xff1b;掌握交换机的基本配置方法和命令&#xff1b;掌握交换机 telnet 配置方法&#xff1b;理解交换机不同配置视图的作用&#xff1b; 实验原理 &#xff08;一…

Linux Shell 脚本编程学习之【第1章 Shell脚本编程概述】

《第1章 Shell脚本编程概述》 1 Linux简介2 Shell 简介3 Linux登录方式4 脚本编程优势4.1 shell脚本编程优势 5 shell脚本基本元素6 执行shell脚本 1 Linux简介 1991年芬兰赫尔辛基大型学生Linus Torvals开发了Linux内核。 2 Shell 简介 1、Shell是一种具备特殊功能的程序。…

【Java基础教程】(十)面向对象篇 · 第四讲:解析Java中的this关键字,引用传递印象加强:理解与实践~

Java基础教程之面向对象 第四讲 本节学习目标1️⃣ this 关键字1.1 调用本类属性1.2 调用本类方法1.3 表示当前对象 2️⃣ 引用传递2.1 基本概念2.2 实际应用 &#x1f33e; 总结 本节学习目标 掌握关键字this的特征以及使用&#xff1b;掌握引用传递分析思维&#xff1b; …

UMS攸信技术是厦门市工业互联网园区建设的积极参与者与推动者,为数字化转型与工业互联网建设注入新动力

7月6日&#xff0c;厦门市工业互联网一体化进园区“百城千园行”活动第二站走进同安区常青藤科技园&#xff0c;与现场企业共话产业数字化创新发展。 本次活动以“工赋园区 数智未来”为主题&#xff0c;由厦门市工业和信息化局、厦门市同安区人民政府、厦门市同安区工业和信息…

809. 最小公倍数

链接&#xff1a; 链接 题目&#xff1a; 输入两个整数 aa 和 bb&#xff0c;请你编写一个函数&#xff0c;int lcm(int a, int b)&#xff0c;计算并输出 aa 和 bb 的最小公倍数。 输入格式 共一行&#xff0c;包含两个整数 aa 和 bb。 输出格式 共一行&#xff0c;包含一个整…

【ELK集群】

ELK集群部署环境准备 配置ELK日志分析系统 192.168.108.67 elk-node1 es、logstash、kibana 192.168.108.189 elk-node2 es、logstash 192.168.108.32 apache logstash 三台虚拟机配置调高 三台机关闭防火墙 改名 1、2台机配置hosts解析文件 1&#xff0c;2台都用系…

Web入门-SpringBoot

SpringBootweb快速入门 需求&#xff1a;使用Spring Boot开发一个web项目&#xff0c;浏览器发起请求/hello后&#xff0c;给浏览器返回字符串”Hello World~“开发步骤 创建SpringBoot工程&#xff0c;并勾选web开发的相关依赖 根据自己idea的版本的不同创建模块即可 &#x…

Day39: 70. 爬楼梯 (进阶),322. 零钱兑换,279.完全平方数

目录 70. 爬楼梯 &#xff08;进阶&#xff09; 322. 零钱兑换 思路 代码 279.完全平方数 思路 70. 爬楼梯 &#xff08;进阶&#xff09; 70. 爬楼梯 - 力扣&#xff08;LeetCode&#xff09; // 版本一 class Solution { public:int climbStairs(int n) {if (n …

汽配行业数字工厂管理系统解决方案

随着汽车行业的快速发展&#xff0c;汽配行业作为汽车产业链的重要组成部分&#xff0c;也面临着日益增长的市场需求和竞争压力。然而&#xff0c;传统行业在管理方面存在一系列问题&#xff0c;如管理效率低下、业务流程不优化、供应链不透明等。为了应对这些挑战&#xff0c;…

更快更复杂之—Mendix如何支持多种AI部署模式

在过去十年&#xff0c;LCAP市场逐渐崛起的同时&#xff0c;计算能力不断提高、大数据可用性不断增强&#xff0c;预计未来数年&#xff0c;低代码应用平台&#xff08;LCAP&#xff09;的市场将增长30%左右&#xff0c;并带动人工智能&#xff08;AI&#xff09;迎来新的春天。…

【Spring Boot】单元测试

单元测试 单元测试在日常项目开发中必不可少&#xff0c;Spring Boot提供了完善的单元测试框架和工具用于测试开发的应用。接下来介绍Spring Boot为单元测试提供了哪些支持&#xff0c;以及如何在Spring Boot项目中进行单元测试。 1.Spring Boot集成单元测试 单元测试主要用…