暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

kubernetes - 控制器 -Deployment

小朱哥的技术人生 2020-05-28
174


控制器 - Deployment

目标

  • 了解 Deployment
  • 创建 Deployment
  • 更新 Deployment
  • 回滚 Deployment
  • 伸缩 Deployment
  • 暂停和继续 Deployment
  • 查看 Deployment 状态
  • 清理策略
  • 部署策略
  • 金丝雀发布(灰度发布)

Deployment 概述

Deployment 是最常用的用于部署无状态服务的方式,Deployment 控制器使得你可以以声明式的方式更新 Pod 和 ReplicaSet

声明式配置 声明式的方式是相对非声明式的方式而言的,例如,以滚动更新为例,假设有 3 个容器组,现在需要将他们的容器镜像更新为新的版本

  • 非声明式的方式,你需要手动逐步执行下面的过程
    • 使用 kubectl 创建一个新版本的容器组
    • 使用 kubectl 观察新容器组的状态
    • 新建的容器组就绪后,使用 kubectl 删除旧的容器组
    • 重复执行上述的过程,直到所有的容器组都被替换为新的版本
  • 声明式的方式,你只需要执行
    • 使用 kubectl 更新 Deployment 中定义的 .spec.template.spec.containers[].image
      字段即可

以声明式的方式管理 Pod 和 ReplicaSet,其本质就是将一些特定的场景和一系列的运维步骤固化的下来,以便快速无误的执行

创建 Deployment

创建 Deployment 后,Deployment 控制器将立即创建一个 ReplicaSet 的副本集,并由 ReplicaSet 创建所需的 Pod

下面的 yaml 文件中 (nginx-deployment.yaml) 定义了一个 Deployment 该 Deployment 将创建一个有 3 个 Nginx Pod 的副本的 ReplicaSet (副本集)

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

在这个例子中:

  • 将创建一个 nginx-deployment 的 Deployment,名称由metadata.name
    字段决定的

  • 该 Deployment 将创建 3 个 Pod 的副本,副本由.spec.replicas
    字段决定的

  • .spec.selector
    字段指定了 Deployment 如何找到由它管理的 Pod,此案例中,我们使用了 Pod Template 定义了一个标签 (apps:nginx),对于极少数的情况,这个字段可以定义更加复杂的规则

  • .template
    字段包含了如下字段:

    • .template.metadata.labels
      指定了 Pod 的标签
    • .template.spec.containers[].image
      指定了启动容器使用的镜像版本
    • .template.spec.containers[].name
      指定了启动容器的名字

执行下面步骤创建 Deployment

  1. 执行下面的命令创建Deployment

    kubectl apply -f nginx-deployment.yaml

    你可以为该命令增加一个--record
    参数选项,此时 kubectl 会将 kubectl apply -f nginx-deployment.yaml
    写入到 Deployment 的 annotation (注解) kubernetes.io/change-cause
    中,这样在将来就可以回顾一个 Deployment 的版本变化了

  2. 执行命令 kubectl get deployment
    查看 Deployment 的创建情况,输出如下结果

    # 正在创建中
    NAME READY UP-TO-DATE AVAILABLE AGE
    nginx-deployment 0/3 3 0 2s

    #
    创建完成
    NAME READY UP-TO-DATE AVAILABLE AGE
    nginx-deployment 3/3 3 3 43s

    字段含义:

    字段名称说明
    NAMEDeployment 名称
    READY当前正在运行的 Pod 个数/期望的 Pod 的副本集个数
    UP-TO-DATEDeployment 中,符合当前 Pod Template 的 Pod 数量
    AVAILABLE当前对用户可用的 Pod 数量
    AGEDeployment 部署到先的时长
  3. 查看 Deployment 的发布状态 (rollout status),执行命令kubectl rollout status deployment.v1.apps/<deploymentname>

    # 执行命令
    kubectl rollout status deployment.v1.apps/nginx-deployment

    #
    输出结果(如果已经创建完成不会出现第一句提示)
    Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    deployment.apps/nginx-deployment successfully rolled out

  4. 查看该 Deployment 创建的 ReplicaSet (缩写 rs)

    # 执行命令
    kubectl get rs

    #
    输出结果
    NAME DESIRED CURRENT READY AGE
    nginx-deployment-799c8f8f87 3 3 3 14m

  5. 查看创建 Pod 的标签

    # 执行命令
    kubectl get pods --show-labels

    #
    输出结果
    NAME READY STATUS RESTARTS AGE LABELS
    nginx-deployment-799c8f8f87-7kwlz 1/1 Running 0 15m apps=nginx,pod-template-hash=799c8f8f87
    nginx-deployment-799c8f8f87-dh6h9 1/1 Running 0 15m apps=nginx,pod-template-hash=799c8f8f87
    nginx-deployment-799c8f8f87-pqcmv 1/1 Running 0 15m apps=nginx,pod-template-hash=799c8f8f87

    Deployment 创建的 ReplicaSet 确保集群中有 3 个 nginx Pod

    你必须为 Deployment 中的.spec.selector
    .template.metadata.labels
    定义一个合适的标签(这里例子中的标签是 apps:nginx ),请不要使用与其他控制器(其他 Deployment 或者 ReplicaSet 等)相同的.spec.selector
    .template.metadata.labels
    ,否则可能会发生冲突


    pod-template-hash标签(一定不要修改这个标签)

    pod-template-hash 标签是 Deployment 创建 ReplicaSet 时添加到 ReplicaSet 上的,ReplicaSet 进而将此标签添加到 Pod 上,这个标签用于区分 Deployment 中那个 ReplicaSet 创建了那些 Pod ,该标签的值是.spec.template
    的 hash 值

更新 Deployment

更新 Deployment 中 Pod 定义 (例如,发布新版本的镜像),此时 Deployment 控制器为该 Deployment 创建新的 ReplicaSet (副本集),并逐步在新的 ReplicaSet 上创建新的 Pod,在旧的 ReplicaSet 中删除 Pod ,已达到滚动更新的效果

执行更新

当 Deployment 中的 Pod Template 中的.spec.template
字段内容发生变化时(例如: 修改标签,容器的名字,镜像版本) Deployment 的发布更新 (rollout) 才会被触发,Deployment 中的其他字段改变(例如: .spec.replicas
)将不会触发 Deployment 的发布更新 (rollout)

使用下面步骤更新Deployment

  1. 执行下面命令,将容器的镜像版本从 1.7.9 更新到 1.18.0

    # 执行下面命令
    kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.18.0

    #
    输出结果
    deployment.apps/nginx-deployment image updated

    或者你可以 edit
    这个 Deployment ,并将.spec.template.spec.containers[].image
    从 nginx:1.7.9 改为 nginx:1.18.0

    # 执行命令
    kubectl edit deployment.v1.apps/nginx-deployment

    #
    输出结果
    deployment.apps/nginx-deployment edited

    在或者你可以直接先编辑nginx-deployment.yaml
    文件,并将将.spec.template.spec.containers[].image
    从 nginx:1.7.9 改为 nginx:1.18.0,然后在执行kubectl apply -f nginx-deployment.yaml
    ,命令更新

  2. 查看发布更新 (rollout) 的状态

    # 执行命令
    kubectl rollout status deployment.v1.apps/nginx-deployment

    #
    输出结果(如果已经创建完成不会出现第一句提示)
    Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    deployment "nginx-deployment" successfully rolled out

查看更新后的 Deployment 详情

  • 查看更新成功后的结果

    # 执行命令
    kubectl get deployment

    #
    输出结果
    NAME READY UP-TO-DATE AVAILABLE AGE
    nginx-deployment 3/3 3 3 55m

  • 查看更新后的 ReplicaSet (Deployment 的更新是通过创建一个新的 3 个副本数的 ReplicaSet 并同时将旧的 Replicaset 的副本数缩容到 0 个副本 来达成的)

    # 执行命令
    kubectl get rs

    #
    输出结果
    NAME DESIRED CURRENT READY AGE
    nginx-deployment-5bdb998678 3 3 3 12m
    nginx-deployment-799c8f8f87 0 0 0 10m

  • 查看更新后的 Pod

    # 执行命令
    kubectl get pods

    #
    输出结果
    NAME READY STATUS RESTARTS AGE
    nginx-deployment-5bdb998678-7njtm 1/1 Running 0 7m39s
    nginx-deployment-5bdb998678-w8rqc 1/1 Running 0 7m38s
    nginx-deployment-5bdb998678-x9hkk 1/1 Running 0 7m37s

    例如,如果你仔细观察上述 Deployment 的更新过程,你将注意到 Deployment Controller 先创建一个新 Pod,然后删除一个旧 Pod,然后再创建新的,如此循环,直到全部更新,Deployment Controller 不会 kill 旧的 Pod,除非足够数量的新 Pod 已经就绪,Deployment Controller 也不会创新新 Pod 直到足够数量的旧 Pod 已经被 kill,这个过程将确保更新过程中,任意时刻,最少 2 个 最多 4 个 Pod 可用

    • 如果你想要修改这些新的 Pod ,只需要再次修改 Deployment 中的 Pod Template 即可
    • Deployment 将确保更新过程中,任意时刻只有一定数量的 Pod 被关闭,默认情况下 Deployment 确保至少 .spec.replicas
      的 75% 的 Pod 持续可用 (25% 不可用)
    • Deployment 将确保更新过程中,任意时刻只有一定数量的 Pod 被创建,默认情况下 Deployment 确保至少.spec.replicas
      的 25% 的 Pod 被创建
  • 查看 Deployment 的详情,执行如下命令

    kubectl describe deployment nginx-deployment

    输出结果如下

    Name:                   nginx-deployment
    Namespace: default
    CreationTimestamp: Tue, 19 May 2020 16:53:37 +0800
    Labels: apps=nginx
    Annotations: deployment.kubernetes.io/revision: 4
    kubectl.kubernetes.io/last-applied-configuration:
    {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"apps":"nginx"},"name":"nginx-deployment","namespace":"...
    kubernetes.io/change-cause:
    kubectl deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.18.0 --record=true
    Selector: apps=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: apps=nginx
    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-5bdb998678 (3/3 replicas created)
    Events:
    Type Reason Age From Message
    ---- ------ ---- ---- -------
    Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set nginx-deployment-5bdb998678 to 1
    Normal ScalingReplicaSet 23m deployment-controller Scaled down replica set nginx-deployment-799c8f8f87 to 2
    Normal ScalingReplicaSet 23m deployment-controller Scaled down replica set nginx-deployment-799c8f8f87 to 1
    Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set nginx-deployment-5bdb998678 to 3
    Normal ScalingReplicaSet 23m deployment-controller Scaled down replica set nginx-deployment-799c8f8f87 to 0
    Normal ScalingReplicaSet 21m deployment-controller Scaled up replica set nginx-deployment-799c8f8f87 to 1

    此时,在 Events
    中,你可以看到:

    • 你创建 Deployment 时,Deployment Controller 创建了一个 ReplicaSet (nginx-deployment-799c8f8f87) 并直接将其 scale up 到 3 个副本
    • 当您更新 Deployment 时,Deployment Controller 先创建一个新的 ReplicaSet (nginx-deployment-5bdb998678) 并将其 scale up 到 1 个副本,然后 scale down 旧的 ReplicaSet 到 2
    • Deployment Controller 继续 scale up 新的 ReplicaSet 并 scale down 旧的 ReplicaSet,直到最后,新旧两个 ReplicaSet,一个副本数为 3,另一个副本数为 0

覆盖更新 Rollover(更新过程中再更新)

每创建一个 Deployment ,Deployment Controller 都为其创建一个 ReplicaSet ,并设定其副本数为期望的 Pod 数(.spec.replicas
)字段的值,如果 Deployment 被更新,旧的 RepicaSet 被 Scale down ,新建的 ReplicaSet 将被 Scale up,直到最后新旧两个 ReplicaSet,一个副本数为 .spec.replicas
另一个副本数为0 ,这个过程叫 rollout

当 Deployment 的 rollout 正在进行中的时候,如果您再次更新 Deployment 的信息,此时 Deployment 将再创建一个新的 ReplicaSet 并开始将其 scale up,将先前正在 scale up 的 ReplicaSet 也作为一个旧的 ReplicaSet,并开始将其 scale down

例如:

  • 假设您创建了一个 Deployment 有 5 个 nginx:1.7.9 的副本
  • 您立刻更新该 Deployment 使得其 .spec.replicas
    为 5,容器镜像为 nginx:1.18.0
    ,而此时只有 3 个 nginx:1.7.9 的副本已创建
  • 此时,Deployment Controller 将立刻开始 kill 已经创建的 3 个 nginx:1.7.9 的 Pod,并开始创建 nginx:1.18.0 的 Pod。Deployment Controller 不会等到 5 个 nginx:1.7.9 的 Pod 都创建完之后在开始新的更新

回滚 Deployment

回滚到一个早期的 Deployment 版本

某些情况下,你可能要回滚(rollback)Deployment,例如: Deployment 不稳定(可能不断的崩溃),默认情况下 kubernetes 将保存 Deployment 的所有更新的历史,你可以设定 revision history limit
来确定保存的历史版本数量

只有当 Deployment 中的 .spec.template
字段更新了,例如: (更新容器的版本),kubernetes 才会为其创建一个 Deployment revision (版本),Deployment 的其他的更新,例如: (修改 .spec.replicas
字段),将不会创建Deployment revision (版本)

模拟更新错误

  • 假设你更新 Deployment 的时候,犯了一个拼写错误,将 nginx:1.18.0 写成了 nginx:1.180
  kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.180 --record=true

输出结果如下

  deployment.apps/nginx-deployment image updated

  • 该更新将被卡住,执行下面命令
  kubectl rollout status deployment.v1.apps/nginx-deployment

输出结果

  Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
# 卡住

  • 查看 ReplicaSet,执行下面命令
  kubectl get rs

输出结果

  NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5bdb998678 3 3 3 3m21s
nginx-deployment-cf96ccf4f 1 1 0 2m40s

可以看到有两个 ReplicaSet 一个新的 (nginx-deployment-cf96ccf4f) 和 一个旧的 (nginx-deployment-5bdb998678) 新的 ReplicaSet 的 DESIRED (期望的pod个数) 和 CURRENT(当前的 Pod 个数) 都为 1 说明没有更新成功

  • 查看 Pod ,执行下面命令
  kubectl get pods

输出结果

  NAME                                READY   STATUS             RESTARTS   AGE
nginx-deployment-5bdb998678-4m4qm 1/1 Running 0 8m54s
nginx-deployment-5bdb998678-hw4ct 1/1 Running 0 8m54s
nginx-deployment-5bdb998678-s2q5q 1/1 Running 0 8m54s
nginx-deployment-cf96ccf4f-k98dr 0/1 ImagePullBackOff 0 8m13s

你可以看到一个由新 ReplicaSet 创建的一个 Pod 卡在了 ImagePullBackOff (拉取镜像)的死循环中

Deployment Controller 将自动的停止有问题的更新,不会继续 scale up 新的 ReplicaSet

maxUnavailable 参数指定了最多会有几个 Pod 副本卡住,该参数的默认值是 25%

  • 查看 Deployment 的详情,执行下面的命令
  kubectl describe deployment nginx-deployment

输出结果如下

  Name:                   nginx-deployment
Namespace: default
CreationTimestamp: Wed, 20 May 2020 10:12:17 +0800
Labels: apps=nginx
Annotations: deployment.kubernetes.io/revision: 2
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"apps":"nginx"},"name":"nginx-deployment","namespace":"...
kubernetes.io/change-cause: kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.180 --record=true
Selector: apps=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: apps=nginx
Containers:
nginx:
Image: nginx:1.180
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing False ProgressDeadlineExceeded
OldReplicaSets: nginx-deployment-5bdb998678 (3/3 replicas created)
NewReplicaSet: nginx-deployment-cf96ccf4f (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 13m deployment-controller Scaled up replica set nginx-deployment-5bdb998678 to 3
Normal ScalingReplicaSet 12m deployment-controller Scaled up replica set nginx-deployment-cf96ccf4f to 1

为了修复这个问题,你需要将其回滚到之前的一个稳定的版本

检查 Deployment 的更新历史

  1. 执行下面命令查看 Deployment 的更新历史
 kubectl rollout history deployment.v1.apps/nginx-deployment

输出结果如下

 deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 --record=true
3 kubectl set image deployment nginx-deployment nginx=nginx:1.12.2 --record=true
4 kubectl set image deployment nginx-deployment nginx=nginx:1.180 --record=true

CHANGE-CAUSE 是该 revision(版本) 创建时从 Deployment 的 annotation kubernetes.io/change-cause
拷贝而来的

你可以通过如下方式定制 CHANGE-CAUSE信息

  • 为 Deployment 加上 annotation (注解),kubectl annotation deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="imgae update to 1.18.0"
  • 执行 kubectl apply
    命令时,增加 --record
    选项
  • 手动编辑 Deployment 的.metadata.annotation
    字段信息
  1. 查看 revision (版本的)详细信息
 kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2

输出的结果如下

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

回滚到前一个 revision (版本)

下面的步骤将 Deployment 从当前的版本回滚到前一个版本

  1. 执行下面命令回滚到前一个版本
 kubectl rollout undo deployment.v1.apps/nginx-deployment

或者,你可以使用--to-revision
选项回滚到指定的版本

 kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2

输出的结果

 deployment.apps/nginx-deployment rolled back

  1. 执行下面命令,查看是否回滚成功,并且有没有按照预期的数量运行
 kubectl get deployment nginx-deployment

输出结果

 NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment 3/3 3 3 21m

  1. 执行命令查看 Deployment 的详情
 kubectl describe deployment nginx-deployment

输出结果

 Name:                   nginx-deployment
Namespace: default
CreationTimestamp: Wed, 20 May 2020 10:31:23 +0800
Labels: apps=nginx
Annotations: deployment.kubernetes.io/revision: 5
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"apps":"nginx"},"name":"nginx-deployment","namespace":"...
kubernetes.io/change-cause: kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 --record=true
Selector: apps=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: apps=nginx
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-786bd55cb (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set nginx-deployment-5bdb998678 to 3
Normal ScalingReplicaSet 21m deployment-controller Scaled down replica set nginx-deployment-5bdb998678 to 2
Normal ScalingReplicaSet 20m deployment-controller Scaled down replica set nginx-deployment-5bdb998678 to 1
Normal ScalingReplicaSet 20m deployment-controller Scaled down replica set nginx-deployment-5bdb998678 to 0
Normal ScalingReplicaSet 19m deployment-controller Scaled up replica set nginx-deployment-7c5f94dbcf to 1
Normal ScalingReplicaSet 18m deployment-controller Scaled down replica set nginx-deployment-786bd55cb to 2
Normal ScalingReplicaSet 17m (x5 over 18m) deployment-controller (combined from similar events): Scaled up replica set nginx-deployment-cf96ccf4f to 1
Normal ScalingReplicaSet 3m21s (x2 over 21m) deployment-controller Scaled up replica set nginx-deployment-786bd55cb to 1
Normal ScalingReplicaSet 3m21s deployment-controller Scaled down replica set nginx-deployment-cf96ccf4f to 0
Normal ScalingReplicaSet 3m19s deployment-controller Scaled down replica set nginx-deployment-7c5f94dbcf to 2
Normal ScalingReplicaSet 3m19s (x2 over 21m) deployment-controller Scaled up replica set nginx-deployment-786bd55cb to 2
Normal ScalingReplicaSet 3m18s (x2 over 20m) deployment-controller Scaled up replica set nginx-deployment-786bd55cb to 3
Normal ScalingReplicaSet 3m18s deployment-controller Scaled down replica set nginx-deployment-7c5f94dbcf to 1
Normal ScalingReplicaSet 3m17s deployment-controller Scaled down replica set nginx-deployment-7c5f94dbcf to 0

伸缩 Deployment

伸缩 (scaling) Deployement,是指改变 Deployment 中的 Pod 副本数量,以应对实际业务的流量变化

执行伸缩

执行伸缩的方式如下:

  • 使用kubectl autoscale
    命令
  • 使用 kubectl edit
    直接更改 Deployment
  • 更改.yaml
    文件相应字段,执行kubectl apply -f <xxx.yaml>

执行命令操作如下

kubectl scale deployment.v1.apps/nginx-deployment --replicas=10

输出结果

deployment.apps/nginx-deployment scaled

查看 Pod

kubectl get pods

输出结果

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5bdb998678-82pzr 1/1 Running 0 59s
nginx-deployment-5bdb998678-c7868 1/1 Running 0 8s
nginx-deployment-5bdb998678-jdljl 1/1 Running 0 8s
nginx-deployment-5bdb998678-ljgh4 1/1 Running 0 8s
nginx-deployment-5bdb998678-n2hs6 1/1 Running 0 59s
nginx-deployment-5bdb998678-p4wml 1/1 Running 0 8s
nginx-deployment-5bdb998678-rgsjj 1/1 Running 0 8s
nginx-deployment-5bdb998678-sc4mx 1/1 Running 0 8s
nginx-deployment-5bdb998678-wq6sp 1/1 Running 0 59s
nginx-deployment-5bdb998678-ws95v 1/1 Running 0 8s

上面结果可以看出已经伸缩成功了

如果你的集群启用了自动伸缩 (HPA),执行下面的命令,你就可以基于 CPU 的利用率在一个最大和最小的区间自动伸缩你的 Deployment

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

输出结果如下

horizontalpodautoscaler.autoscaling/nginx-deployment autoscaled

按比例伸缩

滚动更新 (Rolling Update) Deployment 过程中同一时间点运行应用程序的多个版本,如果一个 Deployment 正在执行滚动更新 (Rolling Update) 的过程中(也可能暂停了滚动更新),你使用自动伸缩器(autoscale)对该 Deployment 执行伸缩操作,此时 Deployment Controller 会按照比例将新建的 Pod 分配到当前活动的 ReplicaSet (有 Pod 的 ReplicaSet) 中,以避免可能的风险,这种情况叫按比例伸缩

滚动更新 (Rolling Update) 是 Deployment 的另一个更新策略 其滚动更新策略使用的两个参数 maxUnavailable
maxSurge
的意思是

  • maxUnavailable
    表示在更新过程中能够进入不可用状态的 Pod 的最大值
  • maxSurge
    表示能够额外创建的 Pod 个数

例如:假设你已经运行了一个运行 10 个 Pod 的 Deployment 其 maxSurge=3, maxUnavailable=2

  • 执行下面命令确认 Deployment 中有 10 个 Pod 正在运行
  kubectl get deployment

输出结果

  NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment 10/10 10 10 97s

  • 执行下面命令,将容器的镜像更新到一个不存在的版本
  kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:sometag

输出结果

  deployment.apps/nginx-deployment image updated

  • 执行命令查看滚动更新的状态
  kubectl get rs

输出结果

NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5bdb998678 8 8 8 2m10s
nginx-deployment-5c4d867fd7 5 5 0 4s

更新镜像后,Deployment Controller 开始执行滚动更新(rolling update) 并创建一个新的 ReplicaSet nginx-deployment-5c4d867fd7
,但由于 maxUnavailable 的限制,该滚动更新将被阻止

  • 执行下面的命令将 Deployment 的 replicas 调整到 15 ,此时 Deployment Controller 需要决定如何分配新加上的 5 个 Pod 副本,根据 “按比例伸缩” 的原则

    • 更大比例的新 Pod 数被分配到副本数最多的 ReplicaSet
    • 更小比例的新 Pod 数被分配到副本数最少的 ReplicaSet
    • 如果还有剩余的新 Pod 数未分配,则将被增加到副本最多的 ReplicaSet
    • 副本数为 0 的 ReplicaSet ,scale up 后,副本数仍然是 0
  kubectl scale deployment.v1.apps/nginx-deployment --replicas=15

在本例中,3个新的副本被添加到旧的 ReplicaSet ,2个新的副本被添加到新的 ReplicaSet, 如果新的副本都达到了就绪状态,滚动更新过程最终会将所有的副本放到新的 ReplicaSet 中,执行命令 kubectl get deployment
查看 Deployment 的情况

# 执行命令
kubectl get deployment

#
结果
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 12/15 7 12 27m

执行命令 kubectl get rs
查看 ReplicaSet 的情况

# 执行命令
kubectl get rs

#
结果
NAME DESIRED CURRENT READY AGE
nginx-deployment-5bdb998678 12 12 12 29m
nginx-deployment-5c4d867fd7 7 7 0 26m

本篇文章文字太多了,公众号发送的时候总是无响应,只能分为两篇文章了

Deployment 第二篇文章请点击: kubernetes 控制器 - Deployment - v2

文章转载自小朱哥的技术人生,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论