Kubernetes概念:工作负载:工作负载管理:1. Deployments

Deployments

官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/
API:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/workload-resources/deployment-v1/#Deployment

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

用例

以下是 Deployments 的典型用例(作用):

  • 创建 Deployment 以将 ReplicaSet 上线。ReplicaSet 在后台创建 Pod。 检查 ReplicaSet 的上线状态,查看其是否成功。
  • 通过更新 Deployment 的 PodTemplateSpec,声明 Pod 的新状态 。 新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新 Deployment 的修订版本。
  • 如果 Deployment 的当前状态不稳定,回滚到较早的 Deployment 版本。 每次回滚都会更新 Deployment 的修订版本。
  • 扩大 Deployment 规模以承担更多负载。
  • 暂停 Deployment 的上线 以应用对 PodTemplateSpec 所作的多项修改, 然后恢复其执行以启动新的上线版本。
  • 使用 Deployment 状态来判定上线过程是否出现停滞。
  • 清理较旧的不再需要的 ReplicaSet 。
    下面是一个 Deployment 示例。其中创建了一个 ReplicaSet,负责启动三个 nginx Pod:controllers/nginx-deployment.yaml
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。 该名称将成为后续创建 ReplicaSet 和 Pod 的命名基础。
  • 该 Deployment 创建一个 ReplicaSet,它创建三个(由 .spec.replicas 字段标明)Pod 副本。
  • .spec.selector 字段定义所创建的 ReplicaSet 如何查找要管理的 Pod。 在这里,你选择spec.selector.matchLabels在 Pod 模板中定义的标签(app: nginx)。 不过,更复杂的选择规则是也可能的,只要 Pod 模板本身满足所给规则即可。

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

  • template 字段包含以下子字段:
    • Pod 被使用 .metadata.labels 字段打上 app: nginx 标签。
    • Pod 模板规约(即 .template.spec 字段)指示 Pod 运行一个 nginx 容器, 该容器运行版本为 1.14.2 的 nginx Docker Hub 镜像。
    • 创建一个容器并使用 .spec.template.spec.containers[0].name 字段将其命名为 nginx

总结:共有三个app: nginx,分别作用是,定义Deployment 的 labels;第二个,给Deployment选择 app: nginx 标签的pod模板;给这个pod模板打上 app: nginx 标签。

按照以下步骤创建上述 Deployment :

  1. 通过运行以下命令创建 Deployment :
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
  1. 运行 kubectl get deployments 检查 Deployment 是否已创建。 如果仍在创建 Deployment,则输出类似于:
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   0/3     0            0           1s
  • 在检查集群中的 Deployment 时,所显示的字段有:
    • NAME 列出了名字空间中 Deployment 的名称。
    • READY 显示应用程序的可用的“副本”数。显示的模式是“就绪个数/期望个数”。
    • UP-TO-DATE 显示为了达到期望状态已经更新的副本数。
    • AVAILABLE 显示应用可供用户使用的副本数。
    • AGE 显示应用程序运行的时间。
      请注意期望副本数是根据 .spec.replicas 字段设置 3。
  1. 要查看 Deployment 上线状态,运行 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
  1. 几秒钟后再次运行 kubectl get deployments。输出类似于:
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           18s

注意 Deployment 已创建全部三个副本,并且所有副本都是最新的(它们包含最新的 Pod 模板) 并且可用。

  1. 要查看 Deployment 创建的 ReplicaSet(rs),运行 kubectl get rs。 输出类似于:
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-75675f5897   3         3         3       18s
  • ReplicaSet 输出中包含以下字段:
    • NAME 列出名字空间中 ReplicaSet 的名称;
    • DESIRED 显示应用的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态;
    • CURRENT 显示当前运行状态中的副本个数;
    • READY 显示应用中有多少副本可以为用户提供服务;
    • AGE 显示应用已经运行的时间长度。
      注意 ReplicaSet 的名称格式始终为 [Deployment 名称]-[哈希]。 该名称将成为所创建的 Pod 的命名基础。 其中的哈希字符串与 ReplicaSet 上的 pod-template-hash 标签一致。
  1. 要查看每个 Pod 自动生成的标签,运行 kubectl get pods --show-labels。 输出类似于:
NAME                                READY     STATUS    RESTARTS   AGE       LABELS
nginx-deployment-75675f5897-7ci7o   1/1       Running   0          18s       app=nginx,pod-template-hash=75675f5897
nginx-deployment-75675f5897-kzszj   1/1       Running   0          18s       app=nginx,pod-template-hash=75675f5897
nginx-deployment-75675f5897-qqcnn   1/1       Running   0          18s       app=nginx,pod-template-hash=75675f5897

所创建的 ReplicaSet 确保总是存在三个 nginx Pod。

说明:
你必须在 Deployment 中指定适当的选择算符和 Pod 模板标签(在本例中为 app: nginx)。 标签或者选择算符不要与其他控制器(包括其他 Deployment 和 StatefulSet)重叠。 Kubernetes 不会阻止你这样做,但是如果多个控制器具有重叠的选择算符, 它们可能会发生冲突执行难以预料的操作。

Pod-template-hash 标签

注意:
不要更改此标签。
Deployment 控制器将 pod-template-hash 标签添加到 Deployment 所创建或收留的每个 ReplicaSet 。
此标签可确保 Deployment 的子 ReplicaSet 不重叠。 标签是通过对 ReplicaSet 的 PodTemplate 进行哈希处理。 所生成的哈希值被添加到 ReplicaSet 选择算符、Pod 模板标签,并存在于在 ReplicaSet 可能拥有的任何现有 Pod 中。

更新 Deployment

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

  1. 先来更新 nginx Pod 以使用 nginx:1.16.1 镜像,而不是 nginx:1.14.2 镜像。
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1
或者
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1

在这里,deployment/nginx-deployment 表明 Deployment 的名称,nginx 表明需要进行更新的容器, 而 nginx:1.16.1 则表示镜像的新版本以及它的标签。

  1. 或者,可以对 Deployment 执行 edit 操作并将 .spec.template.spec.containers[0].imagenginx:1.14.2 更改至 nginx:1.16.1
kubectl edit deployment/nginx-deployment
  1. 要查看上线状态
kubectl rollout status deployment/nginx-deployment

获取 Deployment 的更多信息:

  • 在上线成功后,可以通过运行 kubectl get deployments 来查看 Deployment。
  • 运行 kubectl get rs 以查看 Deployment 通过创建新的 ReplicaSet 并将其扩容到 3 个副本并将旧 ReplicaSet 缩容到 0 个副本完成了 Pod 的更新操作。
  • 现在运行 kubectl get pods 应仅显示新的 Pod。
  • kubectl describe deployments

回滚 Deployment

有时,你可能想要回滚 Deployment;例如,当 Deployment 不稳定时(例如进入反复崩溃状态)。 默认情况下,Deployment 的所有上线记录都保留在系统中,以便可以随时回滚 (你可以通过修改修订历史记录限制来更改这一约束)。

检查 Deployment 上线历史

首先,检查 Deployment 修订历史:kubectl rollout history deployment/nginx-deployment
要查看修订历史的详细信息,运行:kubectl rollout history deployment/nginx-deployment --revision=2

回滚到之前的修订版本

按照下面给出的步骤将 Deployment 从当前版本回滚到以前的版本(即版本 2)。
假定现在你已决定撤消当前上线并回滚到以前的修订版本:kubectl rollout undo deployment/nginx-deployment
或者,你也可以通过使用 --to-revision 来回滚到特定修订版本:kubectl rollout undo deployment/nginx-deployment --to-revision=2
检查回滚是否成功以及 Deployment 是否正在运行,运行:kubectl get deployment nginx-deployment
获取 Deployment 描述信息:kubectl describe deployment nginx-deployment

缩放 Deployment

你可以使用如下指令缩放 Deployment:kubectl scale deployment/nginx-deployment --replicas=10
假设集群启用了Pod 的水平自动缩放, 你可以为 Deployment 设置自动缩放器,并基于现有 Pod 的 CPU 利用率选择要运行的 Pod 个数下限和上限。kubectl autoscale deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80

比例缩放

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

暂停、恢复 Deployment 的上线过程

在你更新一个 Deployment 的时候,或者计划更新它的时候, 你可以在触发一个或多个更新之前暂停 Deployment 的上线过程。 当你准备应用这些变更时,你可以重新恢复 Deployment 上线过程。 这样做使得你能够在暂停和恢复执行之间应用多个修补程序,而不会触发不必要的上线操作。
使用如下指令暂停上线:kubectl rollout pause deployment/nginx-deployment
接下来更新 Deployment 镜像:kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
注意没有新的上线被触发:kubectl rollout history deployment/nginx-deployment
获取上线状态验证现有的 ReplicaSet 没有被更改:kubectl get rs
你可以根据需要执行很多更新操作,例如,可以要使用的资源:kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
最终,恢复 Deployment 上线并观察新的 ReplicaSet 的创建过程,其中包含了所应用的所有更新:kubectl rollout resume deployment/nginx-deployment
观察上线的状态,直到完成。kubectl get rs -w

编写 Deployment 规约

同其他 Kubernetes 配置一样, Deployment 需要 .apiVersion.kind.metadata 字段。 有关配置文件的其他信息,请参考部署 Deployment、 配置容器和使用 kubectl 管理资源等相关文档。
当控制面为 Deployment 创建新的 Pod 时,Deployment 的 .metadata.name 是命名这些 Pod 的部分基础。 Deployment 的名称必须是一个合法的 DNS 子域值, 但这会对 Pod 的主机名产生意外的结果。为获得最佳兼容性,名称应遵循更严格的 DNS 标签规则。
Deployment 还需要 .spec 部分。

Pod 模板

.spec 中只有 .spec.template.spec.selector 是必需的字段。
.spec.template 是一个 Pod 模板。 它和 Pod 的语法规则完全相同。 只是这里它是嵌套的,因此不需要 apiVersionkind
除了 Pod 的必填字段外,Deployment 中的 Pod 模板必须指定适当的标签和适当的重新启动策略。 对于标签,请确保不要与其他控制器重叠。请参考选择算符。
只有 .spec.template.spec.restartPolicy 等于 Always 才是被允许的,这也是在没有指定时的默认设置。

副本

.spec.replicas 是指定所需 Pod 的可选字段。它的默认值是1。
如果你对某个 Deployment 执行了手动扩缩操作(例如,通过 kubectl scale deployment deployment --replicas=X), 之后基于清单对 Deployment 执行了更新操作(例如通过运行 kubectl apply -f deployment.yaml),那么通过应用清单而完成的更新会覆盖之前手动扩缩所作的变更。
如果一个 HorizontalPodAutoscaler (或者其他执行水平扩缩操作的类似 API)在管理 Deployment 的扩缩, 则不要设置 .spec.replicas
恰恰相反,应该允许 Kubernetes 控制面来自动管理 .spec.replicas 字段。

选择算符

.spec.selector 是指定本 Deployment 的 Pod 标签选择算符的必需字段。
.spec.selector 必须匹配 .spec.template.metadata.labels,否则请求会被 API 拒绝。
在 API apps/v1版本中,.spec.selector.metadata.labels 如果没有设置的话, 不会被默认设置为 .spec.template.metadata.labels,所以需要明确进行设置。 同时在 apps/v1版本中,Deployment 创建后 .spec.selector 是不可变的。
当 Pod 的标签和选择算符匹配,但其模板和 .spec.template 不同时,或者此类 Pod 的总数超过 .spec.replicas 的设置时,Deployment 会终结之。 如果 Pod 总数未达到期望值,Deployment 会基于 .spec.template 创建新的 Pod。

你不应直接创建与此选择算符匹配的 Pod,也不应通过创建另一个 Deployment 或者类似于 ReplicaSet 或 ReplicationController 这类控制器来创建标签与此选择算符匹配的 Pod。 如果这样做,第一个 Deployment 会认为它创建了这些 Pod。 Kubernetes 不会阻止你这么做。

如果有多个控制器的选择算符发生重叠,则控制器之间会因冲突而无法正常工作。

策略

.spec.strategy 策略指定用于用新 Pod 替换旧 Pod 的策略。 .spec.strategy.type 可以是 “Recreate” 或 “RollingUpdate”。“RollingUpdate” 是默认值

重新创建 Deployment

如果 .spec.strategy.type==Recreate,在创建新 Pod 之前,所有现有的 Pod 会被杀死。

说明:
这只会确保为了升级而创建新 Pod 之前其他 Pod 都已终止。如果你升级一个 Deployment, 所有旧版本的 Pod 都会立即被终止。控制器等待这些 Pod 被成功移除之后, 才会创建新版本的 Pod。如果你手动删除一个 Pod,其生命周期是由 ReplicaSet 来控制的, 后者会立即创建一个替换 Pod(即使旧的 Pod 仍然处于 Terminating 状态)。 如果你需要一种“最多 n 个”的 Pod 个数保证,你需要考虑使用 StatefulSet。

滚动更新 Deployment

Deployment 会在 .spec.strategy.type==RollingUpdate时,采取 滚动更新的方式更新 Pod。你可以指定 maxUnavailablemaxSurge 来控制滚动更新过程。

最大不可用

.spec.strategy.rollingUpdate.maxUnavailable 是一个可选字段, 用来指定更新过程中不可用的 Pod 的个数上限。该值可以是绝对数字(例如,5),也可以是所需 Pod 的百分比(例如,10%)。百分比值会转换成绝对数并去除小数部分。 如果 .spec.strategy.rollingUpdate.maxSurge 为 0,则此值不能为 0。 默认值为 25%。
例如,当此值设置为 30% 时,滚动更新开始时会立即将旧 ReplicaSet 缩容到期望 Pod 个数的70%。 新 Pod 准备就绪后,可以继续缩容旧有的 ReplicaSet,然后对新的 ReplicaSet 扩容, 确保在更新期间可用的 Pod 总数在任何时候都至少为所需的 Pod 个数的 70%。

最大峰值

.spec.strategy.rollingUpdate.maxSurge 是一个可选字段,用来指定可以创建的超出期望 Pod 个数的 Pod 数量。此值可以是绝对数(例如,5)或所需 Pod 的百分比(例如,10%)。 如果 MaxUnavailable 为 0,则此值不能为 0。百分比值会通过向上取整转换为绝对数。 此字段的默认值为 25%。
例如,当此值为 30% 时,启动滚动更新后,会立即对新的 ReplicaSet 扩容,同时保证新旧 Pod 的总数不超过所需 Pod 总数的 130%。一旦旧 Pod 被杀死,新的 ReplicaSet 可以进一步扩容, 同时确保更新期间的任何时候运行中的 Pod 总数最多为所需 Pod 总数的 130%。

以下是一些使用 maxUnavailable 和 maxSurge 的滚动更新 Deployment 的示例:

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
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1

等等

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-27 21:08:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-27 21:08:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-27 21:08:02       82 阅读
  4. Python语言-面向对象

    2024-03-27 21:08:02       91 阅读

热门阅读

  1. ASR工业化语音模型总结

    2024-03-27 21:08:02       38 阅读
  2. 一些关于网络的笔记

    2024-03-27 21:08:02       32 阅读
  3. C#实现简单同步Echo服务端和客户端

    2024-03-27 21:08:02       41 阅读
  4. day5-QT

    day5-QT

    2024-03-27 21:08:02      30 阅读
  5. reactive和ref的异同、toRef和toRefs的使用

    2024-03-27 21:08:02       35 阅读
  6. Unity运行中加载特效AB包并且对象池管理

    2024-03-27 21:08:02       36 阅读
  7. 自动化测试理论基础(超详细)

    2024-03-27 21:08:02       40 阅读
  8. 态势感知平台简单介绍

    2024-03-27 21:08:02       43 阅读