详解作业副本控制器 Deployment

2022-04-17 20:41:19   最后更新: 2022-04-17 20:41:19   访问数量:86




 

上一篇文章中,我们详细介绍了 Kubernetes 中的 Pod 的原理和配置:

 

详解 Kubernetes 中的 Pod

 

我们看到,Pod 仅仅是对若干容器进行的封装和加强,在实际的场景下,光是有 Pod 是不够的,我们还需要考虑 Pod 之间的相互关系,这个时候,我们就需要更高一层的抽象,这就是 Kubernetes 中的控制器思想,本文,我们就来详细介绍一下 Kubernetes 中最基本的控制器 -- Deployment。

 

 

在 Kubernetes 中,有着许多的控制器组件,他们都是由 kube-controller-manager 组件管理的,包括:

 

  1. deployment
  2. job
  3. cronjob
  4. podautoscaller
  5. cloud
  6. volume
  7. replication
  8. ...

 

控制器在配置时,我们会通过 spec 字段定义我们希望的期望状态。

 

控制器通过“控制编排模式”让集群最终达到期望状态。所谓的“控制编排模式”主要就是定时执行以下步骤:

 

  1. 统计当前实际状态;
  2. 对比实际状态与期望状态;
  3. 如果实际状态与期望状态不符,则对实际状态进行调整,以达期望状态。

 

 

下面就是一个典型的 Deployment 的配置:

 

 

 

  • 需要注意的是,Deployment 中的容器必须配置 restartPolicy=Always

 

 

从 PaaS 时代开始,水平扩展/收缩都是容器编排平台必须具备的功能。在 Kubernetes 中也自然是如此,但 Kubernetes 中,容器的水平扩展与收缩是通过 ReplicaSet 对象实现的。

 

ReplicaSet 具有两个基本属性:副本数与 Pod 模板,这是一个典型的 ReplicaSet 示例:

 

apiVersion: apps/v1 kind: ReplicaSet metadata: name: nginx-set labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9

 

 

而 Deployment 对集群的控制正是通过 ReplicaSet 实现的:

 

 

 

当用户修改副本数后,Deployment 就会与其控制的 ReplicaSet 交互,ReplicaSet 得到新的副本数后,通过对它所控制的 Pod 进行增减从而实现水平扩展或收缩。

 

 

当用户修改 Pod 模板,就会自动触发 Deployment 的滚动更新。

 

Deployment 的滚动更新是通过创建一个新的 ReplicaSet,并且周期性的在旧的 ReplicaSet 中删除 Pod 节点,在新的 ReplicaSet 中创建新的 Pod 节点实现的。

 

 

 

通过配置 Deployment 的 spec.strategy 中的 RollingUpdateStrategy 可以设置滚动更新的策略:

 

spec: minReadySeconds: 5 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 replicas: 2 revisionHistoryLimit: 10 template: ...

 

 

maxSurge 指定了除了用户期望创建的 Pod 外,在一次滚动更新中,Deployment 控制器最多可以创建的新 Pod 节点数;maxUnavailable 指的是一次滚动更新中 Deployment 最多可以删除的旧 Pod 节点数。我们可以配置百分比,例如 maxUnvailable: 50%,表示一次最多可以删除期望数量的 50%。

 

通过滚动更新,新版本的 ReplicaSet 中所有 Running 状态的节点数最终达到用户期望,而旧版本的 ReplicaSet 中的 Pod 节点则全部被删除后,滚动更新就这样完成了。

 

而最终,我们看到,一个应用的版本与 ReplicaSet 的版本是一一对应的。

 

 

通过 kubectl rollout undo 命令就可以实现滚动更新的反向操作 -- 回滚:

 

$ kubectl rollout undo deployment/nginx-deployment --to-version=2

 

可想而知,Deployment 必须保存相应的历史版本的 ReplicaSet 才能够实现对应版本的回滚,但保存所有历史版本往往是不现实的,Deployment 支持通过 spec.revisionHistoryLimit 字段指定保留的历史版本数,特殊的,如果它设置为 0,就相当于关闭了回滚功能。

 

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,只有全部原创,只有干货没有鸡汤

 

linux 使用及配置相关






kubernetes      deployment      replicaset      pod      容器化      云原生     


京ICP备2021035038号