《重识云原生系列》专题索引:

  1. 第一章——不谋全局不足以谋一域
  2. 第二章计算第1节——计算虚拟化技术总述
  3. 第二章计算第2节——主流虚拟化技术之VMare ESXi
  4. 第二章计算第3节——主流虚拟化技术之Xen
  5. 第二章计算第4节——主流虚拟化技术之KVM
  6. 第二章计算第5节——商用云主机方案
  7. 第二章计算第6节——裸金属方案
  8. 第三章云存储第1节——分布式云存储总述
  9. 第三章云存储第2节——SPDK方案综述
  10. 第三章云存储第3节——Ceph统一存储方案
  11. 第三章云存储第4节——OpenStack Swift 对象存储方案
  12. 第三章云存储第5节——商用分布式云存储方案
  13. 第四章云网络第一节——云网络技术发展简述
  14. 第四章云网络4.2节——相关基础知识准备
  15. 第四章云网络4.3节——重要网络协议
  16. 第四章云网络4.3.1节——路由技术简述
  17. 第四章云网络4.3.2节——VLAN技术
  18. 第四章云网络4.3.3节——RIP协议
  19. 第四章云网络4.3.4节——OSPF协议
  20. 第四章云网络4.3.5节——EIGRP协议
  21. 第四章云网络4.3.6节——IS-IS协议
  22. 第四章云网络4.3.7节——BGP协议
  23. 第四章云网络4.3.7.2节——BGP协议概述
  24. 第四章云网络4.3.7.3节——BGP协议实现原理
  25. 第四章云网络4.3.7.4节——高级特性
  26. 第四章云网络4.3.7.5节——实操
  27. 第四章云网络4.3.7.6节——MP-BGP协议
  28. 第四章云网络4.3.8节——策略路由
  29. 第四章云网络4.3.9节——Graceful Restart(平滑重启)技术
  30. 第四章云网络4.3.10节——VXLAN技术
  31. 第四章云网络4.3.10.2节——VXLAN Overlay网络方案设计
  32. 第四章云网络4.3.10.3节——VXLAN隧道机制
  33. 第四章云网络4.3.10.4节——VXLAN报文转发过程
  34. 第四章云网络4.3.10.5节——VXlan组网架构
  35. 第四章云网络4.3.10.6节——VXLAN应用部署方案
  36. 第四章云网络4.4节——Spine-Leaf网络架构
  37. 第四章云网络4.5节——大二层网络
  38. 第四章云网络4.6节——Underlay 和 Overlay概念
  39. 第四章云网络4.7.1节——网络虚拟化与卸载加速技术的演进简述
  40. 第四章云网络4.7.2节——virtio网络半虚拟化简介
  41. 第四章云网络4.7.3节——Vhost-net方案
  42. 第四章云网络4.7.4节vhost-user方案——virtio的DPDK卸载方案
  43. 第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现
  44. 第四章云网络4.7.6节——virtio-blk存储虚拟化方案
  45. 第四章云网络4.7.8节——SR-IOV方案
  46. 第四章云网络4.7.9节——NFV
  47. 第四章云网络4.8.1节——SDN总述
  48. 第四章云网络4.8.2.1节——OpenFlow概述
  49. 第四章云网络4.8.2.2节——OpenFlow协议详解
  50. 第四章云网络4.8.2.3节——OpenFlow运行机制
  51. 第四章云网络4.8.3.1节——Open vSwitch简介
  52. 第四章云网络4.8.3.2节——Open vSwitch工作原理详解
  53. 第四章云网络4.8.4节——OpenStack与SDN的集成
  54. 第四章云网络4.8.5节——OpenDayLight
  55. 第四章云网络4.8.6节——Dragonflow
  56.  第四章云网络4.9.1节——网络卸载加速技术综述

  57. 第四章云网络4.9.2节——传统网络卸载技术

  58. 第四章云网络4.9.3.1节——DPDK技术综述

  59. 第四章云网络4.9.3.2节——DPDK原理详解

  60. 第四章云网络4.9.4.1节——智能网卡SmartNIC方案综述

  61. 第四章云网络4.9.4.2节——智能网卡实现

  62. 第六章容器6.1.1节——容器综述

  63. 第六章容器6.1.2节——容器安装部署

  64. 第六章容器6.1.3节——Docker常用命令

  65. 第六章容器6.1.4节——Docker核心技术LXC

  66. 第六章容器6.1.5节——Docker核心技术Namespace

  67. 第六章容器6.1.6节—— Docker核心技术Chroot

  68. 第六章容器6.1.7.1节——Docker核心技术cgroups综述

  69. 第六章容器6.1.7.2节——cgroups原理剖析

  70. 第六章容器6.1.7.3节——cgroups数据结构剖析

  71. 第六章容器6.1.7.4节——cgroups使用

  72. 第六章容器6.1.8节——Docker核心技术UnionFS

  73. 第六章容器6.1.9节——Docker镜像技术剖析

  74. 第六章容器6.1.10节——DockerFile解析

  75. 第六章容器6.1.11节——docker-compose容器编排

  76. 第六章容器6.1.12节——Docker网络模型设计

  77. 第六章容器6.2.1节——Kubernetes概述

  78. 第六章容器6.2.2节——K8S架构剖析

  79. 第六章容器6.3.1节——K8S核心组件总述

  80. 第六章容器6.3.2节——API Server组件

  81. 第六章容器6.3.3节——Kube-Scheduler使用篇

  82. 第六章容器6.3.4节——etcd组件

  83. 第六章容器6.3.5节——Controller Manager概述

  84. 第六章容器6.3.6节——kubelet组件

  85. 第六章容器6.3.7节——命令行工具kubectl

  86. 第六章容器6.3.8节——kube-proxy

  87. 第六章容器6.4.1节——K8S资源对象总览

  88. 第六章容器6.4.2.1节——pod详解

  89. 第六章容器6.4.2.2节——Pod使用(上)

  90. 第六章容器6.4.2.3节——Pod使用(下)

  91. 第六章容器6.4.3节——ReplicationController

  92. 第六章容器6.4.4节——ReplicaSet组件

  93. 第六章容器基础6.4.5.1节——Deployment概述

  94. 第六章容器基础6.4.5.2节——Deployment配置详细说明

  95. 第六章容器基础6.4.5.3节——Deployment实现原理解析

  96. 第六章容器基础6.4.6节——Daemonset

  97. 第六章容器基础6.4.7节——Job

  98. 第六章容器基础6.4.8节——CronJob

1 Deployment 概念解析

1.1 Deployment 是什么?

        为了更好地解决服务编排的问题,k8s在V1.2版本开始,引入了deployment控制器,值得一提的是,这种控制器并不直接管理pod,而是通过管理replicaset来间接管理pod,即:deployment管理replicaset,replicaset管理pod。所以deployment比replicaset的功能更强大。

        Deployment在内部使用了ReplicaSet实现编排pod功能,当创建一个Deployment时,ReplicaSet资源会随之创建,ReplicaSet是新一代的ReplicationController,并推荐使用它替代ReplicationController来复制和管理Pod,在使用Deployment时,实际的Pod是由Deployment的ReplicaSet创建和管理的。

        deployment的主要功能有下面几个:

  • 支持replicaset的所有功能
  • 支持发布的停止、继续
  • 支持版本的滚动更新和版本回退

1.2 Deployment的使用场景

        Deployment的使用场景有以下几个:

1)创建一个Deployment对象来生成对应的ReplicaSet并完成Pod副本的创建

2)检查Deployment的状态来看部署动作是否完成(Pod副本数量是否达到了预期的值)

3)更新Deployment以创建新的Pod(比如镜像升级)

4)如果当前Deployment不稳定,可以回滚到一个早先的Deployment版本

5)暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后在恢复Deployment,进行新的发布

6)扩展Deployment以应对高负载

7)查看Deployment的状态,以此作为发布是否成功的标志

8)清理不在需要的旧版本ReplicaSet

1.3 deployment的资源清单文件

        主要字段说明:

 全量字段说明:

apiVersion: apps/v1 #版本号 
kind: Deployment #类型 
metadata: #元数据 
  name: #rs名称 
  namespace: #所属命名空间 
  labels: #标签 
    controller: deploy 
spec: #详情描述 
  replicas: #副本数量 
  revisionHistoryLimit: #保留历史版本,默认是10 
  paused: #暂停部署,默认是false 
  progressDeadlineSeconds: #部署超时时间(s),默认是600 
  strategy: #策略 
    type: RollingUpdates #滚动更新策略 
    rollingUpdate: #滚动更新 
      maxSurge: #最大额外可以存在的副本数,可以为百分比,也可以为整数 
      maxUnavaliable: #最大不可用状态的pod的最大值,可以为百分比,也可以为整数 
  selector: #选择器,通过它指定该控制器管理哪些pod 
    matchLabels: #Labels匹配规则 
      app: nginx-pod 
    matchExpressions: #Expression匹配规则 
      - {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

1.4 资源对象信息

1.4.1 Deployment信息

[root@localhost ~]# kubectl get deploy -n kube-system 
NAME             DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 
st-ui-wnunzeyg     1       1         1         1       1d 
st-ui-x3w4xumy     1       1         1         1       1d
  • DESIRED:pod副本数量的期望值(Deployment中定义的Replica数)
  • CURRENT:当前Replica值(Deployment实际创建的ReplicaSet中Replica值),该值会一直增加到DESIRED值为止才算整个应用实例创建完毕,部署才算完成。
  • UP-TO-DATE:最新版本的pod副本数量,用于指示在滚动升级过程中,有多少pod副本已成功升级。(Deployment滚动升级过程中ReplicaSet的Replica成功数)
  • AVAILABLE:当前集群中可用pod副本数。(Deployment创建的ReplicaSet中Replica存活数)
  • AGE:表示距离最后一次操作的时长。

1.4.2 ReplicaSet信息

[root@localhost ~]# kubectl get rs -n kube-system 
NAME                       DESIRED CURRENT READY  AGE 
st-ui-wnunzeyg-391614280      1       1      1     1d 
st-ui-x3w4xumy-1656786196     1       1      1     1d

  我们可以看到ReplicaSet的命名和Deployment是相关的,ReplicaSet命名是以Deployment名为前缀,在Deployment名字基础上又加了一串随机数。

1.4.3 Pods信息

[root@localhost ~]# kubectl get pods -n kube-system 
NAME                             READY STATUS     RESTARTS AGE 
st-ui-wnunzeyg-391614280-3brk8    1/1   Running     0       1d 
st-ui-x3w4xumy-1656786196-f4w8z   1/1   Running     0       1d

  pod名称以Deployment中的ReplicaSet名称为前缀,在此基础上又加了随机字符串。

2 Deployment使用

2.1 Deployment基本命令

  假设Deployment的服务名称为test-tomcat-deploy,yaml模板文件名为test-tomcat.yaml。使用命令时,deploy等价于deployment等价于deployments。若需要指定命名空间ns_name时,需要加上-n ns_name。

  • 创建deployment
    • 基于模板创建
$ kubectl create -f test-tomcat.yaml
  • 删除deployment
    • 基于模板删除
$ kubectl delete -f test-tomcat.yaml
  • 基于名称删除

$ kubectl delete deployment test-tomcat-deploy
  • 更新deployment
    • 基于模板更新
$ kubectl apply -f test-tomcat.yaml
    • 基于名称更新
$ kubectl edit deploy/test-tomcat-deploy
  • 查看deployment
    • 基于模板查看
$ kubectl get deploy test-tomcat-deploy -o yaml
    • 基于名称查看
$ kubectl describe deployments test-tomcat-deploy
  • 查看列表
$ kubectl get deploy

2.2 Deployment使用场景说明

2.2.1 创建 Deployment

        下面是一个 Deployment 示例,它创建了一个 Replica Set 来启动 3 个 nginx pod。

        下载示例文件并执行命令:

$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record 
deployment "nginx-deployment" created

        将 kubectl 的 —record 的 flag 设置为 true 可以在 annotation 中记录当前命令创建或者升级了该资源。这在未来会很有用,例如,查看在每个 Deployment revision 中执行了哪些命令。

        然后立即执行 get 将获得如下结果:

$ kubectl get deployments 
NAME             DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 
nginx-deployment    3       0        0         0       1s

        输出结果表明我们希望的 repalica 数是 3(根据 deployment 中的 .spec.replicas 配置)当前 replica 数( .status.replicas)是 0, 最新的 replica 数(.status.updatedReplicas)是 0,可用的 replica 数(.status.availableReplicas)是 0。

        过几秒后再执行 get 命令,将获得如下输出:

$ kubectl get deployments 
NAME             DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 
nginx-deployment    3       3        3         3       18s

        我们可以看到 Deployment 已经创建了 3 个 replica,所有的 replica 都已经是最新的了(包含最新的 pod template),可用的(根据 Deployment 中的 .spec.minReadySeconds 声明,处于已就绪状态的 pod 的最少个数)。执行 kubectl get rs 和 kubectl get pods 会显示 Replica Set(RS)和 Pod 已创建。

$ kubectl get rs 
NAME                         DESIRED CURRENT READY AGE 
nginx-deployment-2035384211     3       3      0    18s

        你可能会注意到 Replica Set 的名字总是 -。

$ kubectl get pods --show-labels 
NAME                              READY STATUS  RESTARTS AGE     LABELS 
nginx-deployment-2035384211-7ci7o  1/1  Running    0      18s app=nginx,pod-template-hash=2035384211 
nginx-deployment-2035384211-kzszj  1/1  Running    0      18s app=nginx,pod-template-hash=2035384211 
nginx-deployment-2035384211-qqcnn  1/1  Running    0      18s app=nginx,pod-template-hash=2035384211

        刚创建的 Replica Set 将保证总是有 3 个 nginx 的 pod 存在。

注意:你必须在 Deployment 中的 selector 指定正确 pod template label(在该示例中是 app = nginx),不要跟其他的 controller 搞混了(包括 Deployment、Replica Set、Replication Controller 等)。Kubernetes 本身不会阻止你这么做 ,如果你真的这么做了,这些 controller 之间会相互打架,并可能导致不正确的行为。

2.2.2 更新 Deployment

注意:Deployment 的 rollout 当且仅当 Deployment 的 pod template(例如 .spec.template)中的 label 更新或者镜像更改时被触发。其他更新,例如扩容 Deployment 不会触发 rollout。

2.2.2.1 更新Deployment演示

        假如我们现在想要让 nginx pod 使用 nginx:1.9.1 的镜像来代替原来的 nginx:1.7.9 的镜像。

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 
deployment "nginx-deployment" image updated

        我们可以使用 edit 命令来编辑 Deployment,修改 .spec.template.spec.containers[0].image ,将 nginx:1.7.9 改写成 nginx:1.9.1。

$ kubectl edit deployment/nginx-deployment 
deployment "nginx-deployment" edited

        查看 rollout 的状态,只要执行:

$ kubectl rollout status deployment/nginx-deployment 
Waiting for rollout to finish: 2 out of 3 new replicas have been updated... 
deployment "nginx-deployment" successfully rolled out

        Rollout 成功后,get Deployment:

$ kubectl get deployments 
NAME             DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 
nginx-deployment    3       3        3         3      36s

        UP-TO-DATE 的 replica 的数目已经达到了配置中要求的数目。

        CURRENT 的 replica 数表示 Deployment 管理的 replica 数量,AVAILABLE 的 replica 数是当前可用的 replica 数量。

        我们通过执行 kubectl get rs 可以看到 Deployment 更新了 Pod,通过创建一个新的 Replica Set 并扩容了 3 个 replica,同时将原来的 Replica Set 缩容到了 0 个 replica。

$ kubectl get rs 
NAME                         DESIRED CURRENT READY AGE 
nginx-deployment-1564180365     3       3      0    6s 
nginx-deployment-2035384211     0       0      0    36s

        执行 get pods 只会看到当前的新的 pod:

$ kubectl get pods 
NAME                              READY STATUS  RESTARTS AGE 
nginx-deployment-1564180365-khku8  1/1  Running    0     14s 
nginx-deployment-1564180365-nacti  1/1  Running    0     14s 
nginx-deployment-1564180365-z9gth  1/1  Running    0     14s

        下次更新这些 pod 的时候,只需要更新 Deployment 中的 pod 的 template 即可。

        Deployment 可以保证在升级时只有一定数量的 Pod 是 down 的。默认的,它会确保至少有比期望的 Pod 数量少一个的 Pod 是 up 状态(最多一个不可用)。

        Deployment 同时也可以确保只创建出超过期望数量的一定数量的 Pod。默认的,它会确保最多比期望的 Pod 数量多一个的 Pod 是 up 的(最多 1 个 surge)。

        在未来的 Kubernetes 版本中,将从 1-1 变成 25%-25%)

        例如,如果你自己看下上面的 Deployment,你会发现,开始创建一个新的 Pod,然后删除一些旧的 Pod 再创建一个新的。当新的 Pod 创建出来之前不会杀掉旧的 Pod。这样能够确保可用的 Pod 数量至少有 2 个,Pod 的总数最多 4 个。

$ kubectl describe deployments 
Name: nginx-deployment 
Namespace: default 
CreationTimestamp: Tue, 15 Mar 2016 12:01:06 -0700 
Labels: app=nginx 
Selector: app=nginx 
Replicas: 3 updated | 3 total | 3 available | 0 unavailable 
StrategyType: RollingUpdate 
MinReadySeconds: 0 
RollingUpdateStrategy: 1 max unavailable, 1 max surge 
OldReplicaSets: <none> 
NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created) 
Events:
 FirstSeen LastSeen Count From                    SubobjectPath   Type    Reason            Message 
---------  -------- ----- ----                    ------------- --------  ------            -------
 36s         36s      1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3 
 23s         23s      1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1 
 23s         23s      1   {deployment-controller}                Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2 
 23s         23s      1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2 
 21s         21s      1   {deployment-controller}                Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
 21s         21s      1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3

        我们可以看到当我们刚开始创建这个 Deployment 的时候,创建了一个 Replica Set(nginx-deployment-2035384211),并直接扩容到了 3 个 replica。

        当我们更新这个 Deployment 的时候,它会创建一个新的 Replica Set(nginx-deployment-1564180365),将它扩容到 1 个 replica,然后缩容原先的 Replica Set 到 2 个 replica,此时满足至少 2 个 Pod 是可用状态,同一时刻最多有 4 个 Pod 处于创建的状态。

        接着继续使用相同的 rolling update 策略扩容新的 Replica Set 和缩容旧的 Replica Set。最终,将会在新的 Replica Set 中有 3 个可用的 replica,旧的 Replica Set 的 replica 数目变成 0。

2.2.2.2 Rollover(多个 rollout 并行)

        每当 Deployment controller 观测到有新的 deployment 被创建时,如果没有已存在的 Replica Set 来创建期望个数的 Pod 的话,就会创建出一个新的 Replica Set 来做这件事。已存在的 Replica Set 控制 label 匹配 .spec.selector 但是 template 跟 .spec.template 不匹配的 Pod 缩容。最终,新的 Replica Set 将会扩容出 .spec.replicas 指定数目的 Pod,旧的 Replica Set 会缩容到 0。

        如果你更新了一个的已存在并正在进行中的 Deployment,每次更新 Deployment 都会创建一个新的 Replica Set 并扩容它,同时回滚之前扩容的 Replica Set——将它添加到旧的 Replica Set 列表,开始缩容。

        例如,假如你创建了一个有 5 个 niginx:1.7.9 replica 的 Deployment,但是当还只有 3 个 nginx:1.7.9 的 replica 创建出来的时候你就开始更新含有 5 个 nginx:1.9.1 replica 的 Deployment。在这种情况下,Deployment 会立即杀掉已创建的 3 个 nginx:1.7.9 的 Pod,并开始创建 nginx:1.9.1 的 Pod。它不会等到所有的 5 个 nginx:1.7.9 的 Pod 都创建完成后才开始执行滚动更新。

2.2.3 回退 Deployment

2.2.3.1 回退 Deployment操作演示

        有时候你可能想回退一个 Deployment,例如,当 Deployment 不稳定时,比如一直 crash looping。

        默认情况下,kubernetes 会在系统中保存所有的 Deployment 的 rollout 历史记录,以便你可以随时回退(你可以修改 revision history limit 来更改保存的 revision 数)。

注意:只要 Deployment 的 rollout 被触发就会创建一个 revision。也就是说当且仅当 Deployment 的 Pod template(如.spec.template)被更改,例如更新 template 中的 label 和容器镜像时,就会创建出一个新的 revision。

        其他的更新,比如扩容 Deployment 不会创建 revision——因此我们可以很方便的手动或者自动扩容。这意味着当你回退到历史 revision 时,只有 Deployment 中的 Pod template 部分才会回退。

        假设我们在更新 Deployment 的时候犯了一个拼写错误,将镜像的名字写成了 nginx:1.91,而正确的名字应该是 nginx:1.9.1:

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91 
deployment "nginx-deployment" image updated

        Rollout 将会卡住。

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

        按住 Ctrl-C 停止上面的 rollout 状态监控。

        你会看到旧的 replicas(nginx-deployment-1564180365 和 nginx-deployment-2035384211)和新的 replicas (nginx-deployment-3066724191)数目都是 2 个。

$ kubectl get rs 
NAME                         DESIRED CURRENT READY  AGE 
nginx-deployment-1564180365     2       2      0    25s
nginx-deployment-2035384211     0       0      0    36s 
nginx-deployment-3066724191     2       2      2    6s

        看下创建 Pod,你会看到有两个新的 Replica Set 创建的 Pod 处于 ImagePullBackOff 状态,循环拉取镜像。

$ kubectl get pods 
NAME                              READY STATUS           RESTARTS AGE 
nginx-deployment-1564180365-70iae  1/1  Running             0     25s 
nginx-deployment-1564180365-jbqqo  1/1  Running             0     25s 
nginx-deployment-3066724191-08mng  0/1  ImagePullBackOff    0     6s 
nginx-deployment-3066724191-eocby  0/1  ImagePullBackOff    0     6s

        注意,Deployment controller 会自动停止坏的 rollout,并停止扩容新的 Replica Set。

$ kubectl describe deployment 
Name: nginx-deployment 
Namespace: default 
CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700 
Labels: app=nginx 
Selector: app=nginx 
Replicas: 2 updated | 3 total | 2 available | 2 unavailable 
StrategyType: RollingUpdate 
MinReadySeconds: 0 
RollingUpdateStrategy: 1 max unavailable, 1 max surge 
OldReplicaSets: nginx-deployment-1564180365 (2/2 replicas created) 
NewReplicaSet: nginx-deployment-3066724191 (2/2 replicas created) 
Events:
 FirstSeen LastSeen Count From                     SubobjectPath Type     Reason            Message
 --------- -------- ----- ----                     ------------- -------- ------            -------
     1m       1m      1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3 
     22s      22s     1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1 
     22s      22s     1   {deployment-controller}                Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2 
     22s      22s     1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2 
     21s      21s     1   {deployment-controller}                Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0 
     21s      21s     1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3 
     13s      13s     1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1 
     13s      13s     1   {deployment-controller}                Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2 
     13s      13s     1   {deployment-controller}                Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2

        为了修复这个问题,我们需要回退到稳定的 Deployment revision。

2.2.3.2 检查 Deployment 升级的历史记录

        首先,检查下 Deployment 的 revision:

$ kubectl rollout history deployment/nginx-deployment 
deployments "nginx-deployment": 
REVISION CHANGE-CAUSE 
1        kubectl create -f docs/user-guide/nginx-deployment.yaml --record 
2        kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 
3        kubectl set image deployment/nginx-deployment nginx=nginx:1.91

        因为我们创建 Deployment 的时候使用了 —recored 参数可以记录命令,我们可以很方便的查看每次 revison 的变化。

        查看单个 revision 的详细信息:

$ kubectl rollout history deployment/nginx-deployment --revision=2 
deployments "nginx-deployment" revision 2 
 Labels: app=nginx 
         pod-template-hash=1159050644
 Annotations: kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 
 Containers:
  nginx:
    Image: nginx:1.9.1
    Port: 80/TCP 
    QoS Tier:
      cpu: BestEffort
      memory: BestEffort
    Environment Variables: <none> 
 No volumes.

2.2.3.3 回退到历史版本

        现在,我们可以决定回退当前的 rollout 到之前的版本:

$ kubectl rollout undo deployment/nginx-deployment 
deployment "nginx-deployment" rolled back

        也可以使用 --to-revision 参数指定某个历史版本:

$ kubectl rollout undo deployment/nginx-deployment --to-revision=2 
deployment "nginx-deployment" rolled back

        与 rollout 相关的命令详细文档见 kubectl rollout

        该 Deployment 现在已经回退到了先前的稳定版本。如你所见,Deployment controller 产生了一个回退到 revison 2 的 DeploymentRollback 的 event。

$ kubectl get deployment 
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 
nginx-deployment 3 3 3 3 30m 

$ kubectl describe deployment 
Name: nginx-deployment 
Namespace: default 
CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700 
Labels: app=nginx 
Selector: app=nginx 
Replicas: 3 updated | 3 total | 3 available | 0 unavailable 
StrategyType: RollingUpdate 
MinReadySeconds: 0 
RollingUpdateStrategy: 1 max unavailable, 1 max surge 
OldReplicaSets: <none> 
NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created) 
Events:
 FirstSeen LastSeen Count From                    SubobjectPath Type     Reason            Message
 --------- -------- ----- ----                    ------------- -------- ------            -------
    30m      30m      1   {deployment-controller}               Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
    29m      29m      1   {deployment-controller}               Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1 
    29m      29m      1   {deployment-controller}               Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2 
    29m      29m      1   {deployment-controller}               Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2 
    29m      29m      1   {deployment-controller}               Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0 
    29m      29m      1   {deployment-controller}               Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2 
    29m      29m      1   {deployment-controller}               Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1 
    29m      29m      1   {deployment-controller}               Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2 
    2m       2m       1   {deployment-controller}               Normal   ScalingReplicaSet Scaled down replica set nginx-deployment-3066724191 to 0 
    2m       2m       1   {deployment-controller}               Normal   DeploymentRollback Rolled back deployment "nginx-deployment" to revision 2 
    29m      2m       2   {deployment-controller}               Normal   ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3

2.2.3.4 清理 Policy

        你可以通过设置 .spec.revisonHistoryLimit 项来指定 deployment 最多保留多少 revison 历史记录。默认的会保留所有的 revision;如果将该项设置为 0,Deployment 就不允许回退了。

2.2.4 Deployment 扩容

        你可以使用以下命令扩容 Deployment:

$ kubectl scale deployment nginx-deployment --replicas 10 
deployment "nginx-deployment" scaled

        假设你的集群中启用了 horizontal pod autoscaling (HPA),你可以给 Deployment 设置一个 autoscaler,基于当前 Pod 的 CPU 利用率选择最少和最多的 Pod 数。

$ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80 
deployment "nginx-deployment" autoscaled

2.2.5 比例扩容

        RollingUpdate Deployment 支持同时运行一个应用的多个版本。当你或者 autoscaler 扩容一个正在 rollout 中(进行中或者已经暂停)的 RollingUpdate Deployment 的时候,为了降低风险,Deployment controller 将会平衡已存在的 active 的 ReplicaSets(有 Pod 的 ReplicaSets)和新加入的 replicas。这被称为比例扩容。

        例如,你正在运行中含有 10 个 replica 的 Deployment。maxSurge=3,maxUnavailable=2。

$ kubectl get deploy 
NAME             DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 
nginx-deployment    10     10       10         10     50s

        你更新了一个镜像,而在集群内部无法解析。

$ kubectl set image deploy/nginx-deployment nginx=nginx:sometag 
deployment "nginx-deployment" image updated

        镜像更新启动了一个包含 ReplicaSet nginx-deployment-1989198191 的新的 rollout,但是它被阻塞了,因为我们上面提到的 maxUnavailable。

$ kubectl get rs 
NAME                         DESIRED CURRENT READY AGE 
nginx-deployment-1989198191     5       5      0    9s 
nginx-deployment-618515232      8       8      8    1m

        然后发起了一个新的 Deployment 扩容请求。autoscaler 将 Deployment 的 replica 数目增加到了 15 个。Deployment controller 需要判断在哪里增加这 5 个新的 replica。如果我们没有使用比例扩容,所有的 5 个 replica 都会加到一个新的 ReplicaSet 中。如果使用比例扩容,新添加的 replica 将传播到所有的 ReplicaSet 中。大的部分加入 replica 数最多的 ReplicaSet 中,小的部分加入到 replica 数少的 ReplciaSet 中。0 个 replica 的 ReplicaSet 不会被扩容。

        在我们上面的例子中,3 个 replica 将添加到旧的 ReplicaSet 中,2 个 replica 将添加到新的 ReplicaSet 中。rollout 进程最终会将所有的 replica 移动到新的 ReplicaSet 中,假设新的 replica 成为健康状态。

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

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

2.2.6 暂停和恢复 Deployment

        你可以在触发一次或多次更新前暂停一个 Deployment,然后再恢复它。这样你就能多次暂停和恢复 Deployment,在此期间进行一些修复工作,而不会触发不必要的 rollout。

        例如使用刚刚创建 Deployment:

$ kubectl get deploy 
NAME  DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 
nginx    3       3        3          3     1m 

[mkargaki@dhcp129-211 kubernetes]$ kubectl get rs 
NAME             DESIRED CURRENT READY AGE 
nginx-2142116321    3       3      3    1m

        使用以下命令暂停 Deployment:

$ kubectl rollout pause deployment/nginx-deployment 
deployment "nginx-deployment" paused

        然后更新 Deployment 中的镜像:

$ kubectl set image deploy/nginx nginx=nginx:1.9.1 
deployment "nginx-deployment" image updated

        注意没有启动新的 rollout:

$ kubectl rollout history deploy/nginx 
deployments "nginx" 
REVISION CHANGE-CAUSE 
    1       <none> 

$ kubectl get rs 
NAME             DESIRED CURRENT READY AGE 
nginx-2142116321    3       3      3    2m

        你可以进行任意多次更新,例如更新使用的资源:

$ kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi 
deployment "nginx" resource requirements updated

        Deployment 暂停前的初始状态将继续它的功能,而不会对 Deployment 的更新产生任何影响,只要 Deployment 是暂停的。

        最后,恢复这个 Deployment,观察完成更新的 ReplicaSet 已经创建出来了:

$ kubectl rollout resume deploy nginx 
deployment "nginx" resumed 

$ KUBECTL get rs -w 
NAME             DESIRED CURRENT READY AGE 
nginx-2142116321    2       2      2    2m 
nginx-3926361531    2       2      0    6s 
nginx-3926361531    2       2      1    18s 
nginx-2142116321    1       2      2    2m 
nginx-2142116321    1       2      2    2m 
nginx-3926361531    3       2      1    18s 
nginx-3926361531    3       2      1    18s 
nginx-2142116321    1       1      1    2m 
nginx-3926361531    3       3      1    18s 
nginx-3926361531    3       3      2    19s 
nginx-2142116321    0       1      1    2m 
nginx-2142116321    0       1      1    2m 
nginx-2142116321    0       0      0    2m 
nginx-3926361531    3       3      3    20s 
^C 

$ KUBECTL get rs 
NAME             DESIRED CURRENT READY AGE 
nginx-2142116321    0       0      0    2m 
nginx-3926361531    3       3      3    28s

注意:在恢复 Deployment 之前你无法回退一个暂停了的 Deployment。

参考链接 

Deployment · Kubernetes指南

k8s中的deployment_遂言的博客-CSDN博客_k8s中的deployment

k8s之deployment详解 - 王叫兽 - 博客园

k8s之Deployment 资源详解 - 知乎

k8s之Deployment详解_Jeremy_Lee123的博客-CSDN博客_deployment k8s

k8s deployment

k8s之deployment 

k8s之deployment - 路过的柚子厨 - 博客园

K8S-pod之Deployment - 简书

每天5分钟|轻松掌握开发工作必会的k8s-deployment与rs

kubernetes-Deployment部署无状态服务的原理详解(二十五) - Andya_net - 博客园

详解 Kubernetes Deployment 的实现原理 - 面向信仰编程

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐