* zh-trans update content/zh/docs/concepts/workloads/controllers/deployment.md * zh-trans update content\zh\docs\concepts\workloads\controllers\deployment.md
81 KiB
reviewers, title, feature, content_template, weight
| reviewers | title | feature | content_template | weight | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
Deployments |
|
templates/concept | 30 |
{{% capture overview %}}
一个 Deployment 控制器为 Pods和 ReplicaSets提供描述性的更新方式。
描述 Deployment 中的 desired state,并且 Deployment 控制器以受控速率更改实际状态,以达到期望状态。可以定义 Deployments 以创建新的 ReplicaSets ,或删除现有 Deployments ,并通过新的 Deployments 使用其所有资源。
{{< note >}}
不要管理 Deployment 拥有的 ReplicaSets 。如果存在下面未介绍的用例,请考虑在主 Kubernetes 仓库中提出 issue。
{{< /note >}}
{{% /capture %}}
{{% capture body %}}
用例
以下是典型的 Deployments 用例:
- 创建 Deployment 以展开 ReplicaSet 。 ReplicaSet 在后台创建 Pods。检查 ReplicaSet 展开的状态,查看其是否成功。
- 声明 Pod 的新状态 通过更新 Deployment 的 PodTemplateSpec。将创建新的 ReplicaSet ,并且 Deployment 管理器以受控速率将 Pod 从旧 ReplicaSet 移动到新 ReplicaSet 。每个新的 ReplicaSet 都会更新 Deployment 的修改历史。
- 回滚到较早的 Deployment 版本,如果 Deployment 的当前状态不稳定。每次回滚都会更新 Deployment 的修改。
- 暂停 Deployment 对其 PodTemplateSpec 进行修改,然后恢复它以启动新的展开。
- 使用 Deployment 状态 作为卡住展开的指示器。
- 清理较旧的 ReplicaSets ,那些不在需要的。
创建 Deployment
下面是 Deployment 示例。创建一个 ReplicaSet 展开三个 nginx Pods:
{{< codenew file="controllers/nginx-deployment.yaml" >}}
在该例中:
- 将创建名为
nginx-deployment的 Deployment ,由.metadata.name字段指示。
- Deployment 创建三个复制的 Pods,由
replicas字段指示。
selector字段定义 Deployment 如何查找要管理的 Pods。 在这种情况下,只需选择在 Pod 模板(app: nginx)中定义的标签。但是,更复杂的选择规则是可能的,只要 Pod 模板本身满足规则。 {{< note >}}template字段包含以下子字段:- Pod 模板规范或
.template.spec字段指示 Pods 运行一个容器,nginx,运行nginxDocker Hub版本1.7.9的镜像 。
- 创建一个容器并使用
name字段将其命名为nginx。
按照以下步骤创建上述 Deployment :
开始之前,请确保的 Kubernetes 集群已启动并运行。
-
通过运行以下命令创建 Deployment :
{{< note >}}
例如,查看在每个 Deployment 修改中执行的命令。 {{< /note >}}```shell kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml ```- 运行
kubectl get deployments以检查 Deployment 是否已创建。如果仍在创建 Deployment ,则输出以下内容:shell NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 0 0 0 1s检查集群中的 Deployments 时,将显示以下字段:- 要查看 Deployment 展开状态,运行
kubectl rollout status deployment.v1.apps/nginx-deployment。输出:shell Waiting for rollout to finish: 2 out of 3 new replicas have been updated... deployment.apps/nginx-deployment successfully rolled out
- 几秒钟后再次运行
kubectl get deployments。输出:shell NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 18s请注意, Deployment 已创建所有三个副本,并且所有副本都是最新的(它们包含最新的 Pod 模板)并且可用。
- 要查看 Deployment 创建的 ReplicaSet (
rs),运行kubectl get rs。输出:shell NAME DESIRED CURRENT READY AGE nginx-deployment-75675f5897 3 3 3 18s请注意, ReplicaSet 的名称始终被格式化为[DEPLOYMENT-NAME]-[RANDOM-STRING]。随机字符串是随机生成并使用 pod-template-hash 作为种子。
- 要查看每个 Pod 自动生成的标签,运行
kubectl get pods --show-labels。返回以下输出:shell NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453创建的复制集可确保有三个nginxPods。
{{< note >}}
必须在 Deployment 中指定适当的选择器和 Pod 模板标签(在本例中为
app: nginx)。不要与其他控制器(包括其他 Deployments 和状态设置)重叠标签或选择器。Kubernetes 不会阻止重叠,如果多个控制器具有重叠的选择器,这些控制器可能会冲突并运行意外。 {{< /note >}}Pod-template-hash 标签
{{< note >}}
不要更改此标签。 {{< /note >}}
Deployment 控制器将
pod-template-hash标签添加到 Deployment 创建或使用的每个 ReplicaSet 。此标签可确保 Deployment 的子 ReplicaSets 不重叠。它通过对 ReplicaSet 的
PodTemplate进行哈希处理,并使用生成的哈希值添加到 ReplicaSet 选择器、Pod 模板标签,并在 ReplicaSet 可能具有的任何现有 Pod 中。更新 Deployment
{{< note >}}
仅当 Deployment Pod 模板(即
.spec.template)时,才会触发 Deployment 展开,例如,如果模板的标签或容器镜像已更新,其他更新(如扩展 Deployment )不会触发展开。 {{< /note >}}按照以下步骤更新 Deployment :
-
让我们更新 nginx Pods,以使用
nginx:1.9.1镜像 ,而不是nginx:1.7.9镜像 。kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1-
要查看展开状态,运行:
或者kubectl rollout status deployment.v1.apps/nginx-deploymentdeployment.apps/nginx-deployment successfully rolled out在更新后的 Deployment 上获取更多信息
- 在展开成功后,可以通过运行
kubectl get deployments来查看 Deployment 。 输出:NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 36s
-
运行
kubectl get rs以查看 Deployment 通过创建新的 ReplicaSet 并缩放它更新了 Pods 最多 3 个副本,以及将旧 ReplicaSet 缩放到 0 个副本。kubectl get rs-
运行
get pods现在应仅显示新的 Pods:kubectl get pods- 获取 Deployment 的更多信息
kubectl describe deployments输出:
deployment.apps/nginx-deployment scaled假设启用水平自动缩放 Pod在集群中,可以为 Deployment 设置自动缩放器,并选择最小和最大 要基于现有 Pods 的 CPU 利用率运行的 Pods。
kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80输出:
deployment.apps/nginx-deployment scaled比例缩放
滚动更新 Deployments 支持同时运行应用程序的多个版本。当自动缩放器缩放处于展开中间的滚动更新 Deployment (仍在进行中或暂停)时, Deployment 控制器平衡现有活动中的其他 ReplicaSets (带 Pods 的 ReplicaSets ),以降低风险。这称为比例缩放。
例如,运行一个10个副本的 Deployment ,最大增加=3, 最大不可用=2.
- 确保这10个副本都在运行。
kubectl get deploy-
更新到新镜像,该镜像恰好无法从集群内部解析。
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:sometag- 镜像更新使用 ReplicaSet nginx-deployment-1989198191 启动新的展开,但由于上面提到的最大不可用要求。检查展开状态:
kubectl get rs<!--
The output is similar to this: --> 输出:
NAME DESIRED CURRENT READY AGE nginx-deployment-1989198191 5 5 0 9s nginx-deployment-618515232 8 8 8 1m- 然后,出现了新的 Deployment 扩展请求。自动缩放器增加 Deployment 副本到15。 Deployment 控制器需要决定在何处添加这些新 5 个副本。如果未使用比例缩放,所有 5 个都将添加到新的 ReplicaSet 中。使用比例缩放,可以将其他副本分布到所有 ReplicaSets 。更大的比例转到 ReplicaSets 与大多数副本和较低的比例都转到副本较少的 ReplicaSets 。任何剩余部分都添加到具有最多副本的 ReplicaSet 。具有零副本的 ReplicaSets 不会放大。
在上面的示例中,3 个副本添加到旧 ReplicaSet 中,2 个副本添加到新 ReplicaSet 。展开过程最终应将所有副本移动到新的 ReplicaSet ,假定新的副本变得正常。要确认这一点,请运行:
kubectl get deploy输出:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 15 18 7 8 7m展开状态确认副本如何添加到每个 ReplicaSet 。
kubectl get rs输出:
NAME DESIRED CURRENT READY AGE nginx-deployment-1989198191 7 7 0 7m nginx-deployment-618515232 11 11 11 7m暂停、恢复 Deployment
可以在触发一个或多个更新之前暂停 Deployment ,然后继续它。这允许在暂停和恢复之间应用多个修补程序,而不会触发不必要的 Deployment 。
- 例如,对于一个刚刚创建的 Deployment :
获取 Deployment 信息:
kubectl get deploy获取 Deployment 状态:
kubectl get rs输出:
NAME DESIRED CURRENT READY AGE nginx-2142116321 3 3 3 1m使用如下指令中断运行:
shell kubectl rollout pause deployment.v1.apps/nginx-deployment<!--The output is similar to this: --> 输出:
deployment.apps/nginx-deployment paused-
然后更新 Deployment 镜像:
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1-
注意没有新的展开:
kubectl rollout history deployment.v1.apps/nginx-deployment-
获取展开状态确保 Deployment 更新已经成功:
kubectl get rs-
更新是很容易的,例如,可以这样更新使用到的资源:
kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi-
最后,恢复 Deployment 并观察新的 ReplicaSet ,并更新所有新的更新:
kubectl rollout resume deployment.v1.apps/nginx-deployment-
观察展开的状态,直到完成。
kubectl get rs -w-
获取最近展开的状态:
kubectl get rs暂停的 Deployment 不可以回滚,除非恢复它以后。 {{< /note >}}
Deployment 状态
一个 Deployment 的生命周期中会有许多状态。当正在生产新的 ReplicaSet 时可能是正在运行,可能是已完成,也可能是 Deployment 失败。
正在 Deployment
Kubernetes 使用 运行中 来标记一个 Deployment ,当下面的任务被执行时:
- 创建新的 ReplicaSet 。
- 正在向上扩展最新的 ReplicaSet 。
- Deployment 向下扩展旧的 ReplicaSet(s) 。
- 新的 Pods 已经就绪或者可用(在最小就绪时间内就绪)。
可以使用
kubectl rollout status监视 Deployment 的进度。完成 Deployment
Kubernetes 将 Deployment 标记为 完成,当它具有以下特征时:
- 与 Deployment 关联的所有副本都已更新到指定的最新版本,这意味着请求的任何更新都已完成。
- 与 Deployment 关联的所有副本都可用。
- 未运行 Deployment 的旧副本。
可以使用
kubectl rollout status检查 Deployment 是否已完成。如果展开成功完成,kubectl rollout status返回退出代码 0。kubectl rollout status deployment.v1.apps/nginx-deployment输出:
Waiting for rollout to finish: 2 of 3 updated replicas are available... deployment.apps/nginx-deployment successfully rolled out $ echo $? 0Deployment 失败
的 Deployment 可能会在未完成的情况下尝试 Deployment 其最新的 ReplicaSet 时遇到问题。可能发生此情况由于以下一些因素:
- 配额不足
- 就绪探测失败
- 镜像拉取错误
- 权限不足
- 限制范围
- 应用程序运行时配置错误
检测此条件的一种方法是在 Deployment 规范中指定截止时间参数:([
.spec.progressDeadlineSeconds](#progress-deadline-seconds))。.spec.progressDeadlineSeconds进度截止时间秒表示 Deployment 控制器在指示(处于 Deployment 状态)之前等待的秒数 Deployment 进度已停止。以下
kubectl命令设置具有进度的规范,使控制器报告 10 分钟后 Deployment 进度不足:kubectl patch deployment.v1.apps/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'输出:
deployment.apps/nginx-deployment patched超过截止时间后, Deployment 控制器将添加具有以下属性到 Deployment 的
.status.conditions:- Type=Progressing
- Status=False
- Reason=ProgressDeadlineExceeded
参考 Kubernetes API 约定 获取更多状态条件相关信息。
{{< note >}}
Kubernetes 对已停止的 Deployment 不执行任何操作,只需使用
Reason=ProgressDeadlineExceeded。更高级别的编排器可以利用它并相应地采取行动,例如,将 Deployment 回滚到其以前的版本。 {{< /note >}}{{< note >}}
如果暂停 Deployment ,Kubernetes 不会根据指定的截止时间检查进度。可以在展开栏中间安全地暂停 Deployment ,并在不触发超过最后期限时恢复。 {{< /note >}}
Deployments 可能会出现短暂的错误,既不是因为设置的超时时间过短,也不是因为任何真正的暂时性错误。例如配额不足。如果描述 Deployment ,将注意到以下部分:
kubectl describe deployment nginx-deployment输出:
<...> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True ReplicaSetUpdated ReplicaFailure True FailedCreate <...>如果运行
kubectl get deployment nginx-deployment -o yaml, Deployment 状态输出:status: availableReplicas: 2 conditions: - lastTransitionTime: 2016-10-04T12:25:39Z lastUpdateTime: 2016-10-04T12:25:39Z message: Replica set "nginx-deployment-4262182780" is progressing. reason: ReplicaSetUpdated status: "True" type: Progressing - lastTransitionTime: 2016-10-04T12:25:42Z lastUpdateTime: 2016-10-04T12:25:42Z message: Deployment has minimum availability. reason: MinimumReplicasAvailable status: "True" type: Available - lastTransitionTime: 2016-10-04T12:25:39Z lastUpdateTime: 2016-10-04T12:25:39Z message: 'Error creating: pods "nginx-deployment-4262182780-" is forbidden: exceeded quota: object-counts, requested: pods=1, used: pods=3, limited: pods=2' reason: FailedCreate status: "True" type: ReplicaFailure observedGeneration: 3 replicas: 2 unavailableReplicas: 2最终,一旦超过 Deployment 进度截止时间,Kubernetes 将更新状态和进度状态:
Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing False ProgressDeadlineExceeded ReplicaFailure True FailedCreate可以通过缩减 Deployment 来解决配额不足的问题,或者直接在命名空间中增加配额。如果配额条件满足, Deployment 控制器完成了 Deployment 展开, Deployment 状态会更新为成功(
Status=TrueandReason=NewReplicaSetAvailable)。Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailableType=Available和Status=True表示 Deployment 具有最低可用性。最低可用性由 Deployment 策略中的参数指定。Type=Progressing和Status=True表示 Deployment 处于展开中间,并且正在运行,或者已成功完成进度,最小所需新的副本处于可用(请参阅此种状态原因的相关细节,在我们的案例中Reason=NewReplicaSetAvailable表示 Deployment 已完成)。可以使用
kubectl rollout status检查 Deployment 是否未能取得进展。kubectl rollout status如果 Deployment 已超过进度截止时间,则返回非零退出代码。kubectl rollout status deployment.v1.apps/nginx-deployment输出:
Waiting for rollout to finish: 2 out of 3 new replicas have been updated... error: deployment "nginx" exceeded its progress deadline $ echo $? 1对失败 Deployment 的操作
应用于完整 Deployment 的所有操作也适用于失败的 Deployment 。可以向上/向下扩展,回滚到以前的修改版,或者如果需要在 Deployment Pod 模板中应用多个调整,甚至将其暂停。
清理策略
可以在 Deployment 中设置
.spec.revisionHistoryLimit,以指定保留多少此 Deployment 的 ReplicaSets。其余的将在后台进行垃圾回收。默认情况下,是10。{{< note >}}
显式将此字段设置为 0 将导致清理 Deployment 的所有历史记录,因此 Deployment 将无法回滚。 {{< /note >}}
金丝雀 Deployment
如果要使用 Deployment 向用户或服务器子集展开版本,则可以创建多个 Deployments ,每个版本一个,遵循资源管理。
编写 Deployment 脚本
同其他 Kubernetes 配置, Deployment 需要
apiVersion,kind, 和metadata字段。有关配置文件的其他信息,参考 应用 Deployment ,配置容器,和 使用 kubectl 管理资源 相关文档。Deployment 还需要
.spec部分。Pod 示例
.spec仅需要.spec.template和.spec.selector。.spec.template是一个 Pod 示例。它和 Pod的约束完全相同,除了它是嵌套的,而且没有apiVersion或kind。除了 Pod 的必填字段外, Deployment 中的 Pod 模板必须指定适当的标签和适当的重新启动策略。对于标签,请确保不要与其他控制器重叠。请参考选择器)。
只有
.spec.template.spec.restartPolicy等于Always被允许,这是在没有指定时的默认设置。副本
.spec.replicas是指定所需 Pod 的可选字段。它的默认值是1。选择器
.spec.selector是指定本次 Deployment Pods 标签选择器的必要字段。.spec.selector必须匹配.spec.template.metadata.labels,否则请求会被 API 拒绝。在 API
apps/v1版本中,.spec.selector和.metadata.labels不会被默认设置为.spec.template.metadata.labels,如果没有设置的话。所以需要明确进行设置。同时在apps/v1版本中, Deployment 创建后.spec.selector是可变的。当 Pods 的标签和选择器匹配时,此类 Pods 的模板和
.spec.template不同,或者此类 Pods 的总数超过.spec.replicas, Deployment 会终结这些 Pods。如果 Pods 总数达不到期望值,会用.spec.template创建新的 Pods。{{< note >}}
不应创建其标签与此选择器匹配的 Pods,或者直接创建另一个 Deployment ,或通过创建其他控制器(如 ReplicaSet 或复制控制器)。如果这样做,第一个 Deployment 认为它创建了这些其他 Pods。Kubernetes 不会阻止你这么做。 {{< /note >}}
如果有多个具有重叠选择器的控制器,则控制器之间会因冲突而故障。
策略
.spec.strategy策略指定用于用新 Pods 替换旧 Pods 的策略。.spec.strategy.type可以是“Recreate”或“RollingUpdate”。“RollingUpdate”是默认值。重新创建 Deployment
当
.spec.strategy.type==Recreate,所有现有的 Pods 在创建新 Pods 之前被杀死。滚动更新 Deployment
Deployment 会在
.spec.strategy.type==RollingUpdate时,采取 滚动更新的方式更新Pods。可以指定maxUnavailable和maxSurge来控制滚动更新操作。最大不可用
.spec.strategy.rollingUpdate.maxUnavailable是指定最大数量的可选字段,表示在更新过程中不可用的 Pods。该值可以是绝对数字(例如,5)或所需 Pods 的百分比(例如,10%)。绝对数按百分比计算,四舍五入下来。如果.spec.strategy.rollingUpdate.maxSurge为 0,则该值不能为 0。默认值为 25%。例如,当此值设置为 30% 时,滚动更新开始时会立即将旧 ReplicaSet 向下扩展到期望 Pods 的70%。新 Pods 准备就绪后,可以缩放旧 ReplicaSet 进一步向下,然后向上扩展新的 ReplicaSet ,确保可用的 Pods 总数在更新期间,任何时候都至少为 70% 所需的 Pods。
最大增量
.spec.strategy.rollingUpdate.maxSurge是指定最大 Pods 数的可选字段可在所需的 Pods 数上创建。该值可以是绝对数(例如,5)或所需 Pods 的百分比(例如,10%)。如果MaxUnavailable0,则值不能为 0。绝对数通过舍入从百分比计算。默认值为 25%。例如,当此值设置为 30 时,启动滚动更新后,会立即展开新的 ReplicaSet ,以便新旧 Pod 的总数不超过所需的 130%。一旦旧 Pods 被杀死,新的 ReplicaSet 可以进一步扩展,确保更新期间任何时间运行的 Pods 总数最多为所需 Pods 总数的130%。
Deployment 失败等待时间
.spec.progressDeadlineSeconds是一个可选字段,用于指定等待的秒数而后在系统报告中返回 Deployment 失败,同时在资源状态中Type=Progressing、Status=False、Reason=ProgressDeadlineExceeded。 Deployment 控制器将保留正在重试 Deployment 。将来,一旦实现自动回滚, Deployment 控制器将回滚 Deployment ,只要它探测到这样的条件。如果指定,则此字段需要大于
.spec.minReadySeconds。最小就绪时间
.spec.minReadySeconds是一个可选字段,用于指定新创建的 Pod 在没有任意容器崩溃情况下的最小就绪时间,以便将其视为可用。默认值为 0(Pod 在准备就绪后立即将被视为可用)。了解有关何时Pod 被视为已准备就绪,参考容器探针。回滚
.spec.rollbackTo字段已经在 API 版本extensions/v1beta1和apps/v1beta1中废弃了,并且从apps/v1beta2版本开始不在支持。相应的,会开始使用已经引入回滚到上一个版本中的kubectl rollout undo。修改历史限制
Deployment 修改历史记录存储在它所控制的 ReplicaSets 中。
.spec.revisionHistoryLimit修改历史记录限制是一个可选字段,用于指定要保留的旧 ReplicaSets 的数量以允许回滚。这些旧 ReplicaSets 消耗 etcd 中的资源,并占用kubectl get rs的输出。每个 Deployment 修改版的配置都存储在其 ReplicaSets 中;因此,一旦删除了旧的 ReplicaSet ,将失去回滚到 Deployment 版本的能力。默认情况下,将保留 10 个旧 ReplicaSets ,但其理想值取决于新 Deployment 的频率和稳定性。更具体地说,将此字段设置为 0 意味着将清理所有具有 0 个副本的旧 ReplicaSets 。在这种情况下,无法撤消新的 Deployment 展开,因为它的修改历史被清除了。
暂停
.spec.paused是用于暂停和恢复 Deployment 的可选布尔字段。暂停的 Deployment 和未暂停的 Deployment 唯一的区别,只要暂停 Deployment 处于暂停状态, PodTemplateSpec 的任意修改都不会触发新的展开。默认 Deployment 在创建时是不会被暂停的。Deployments 的替代方案
kubectl滚动更新
kubectl rolling update更新 Pods 和副本控制器的方式类似。但是,建议采取 Deployments 的方式来更新,因为它们是声明性的,在服务器端,并且具有其他功能,例如,即使在滚动更新完成后,也会回滚到以前的任何修改版本。{{% /capture %}}
-
-
-
-
-
-
-
- 镜像更新使用 ReplicaSet nginx-deployment-1989198191 启动新的展开,但由于上面提到的最大不可用要求。检查展开状态:
-
- 确保这10个副本都在运行。
- 获取 Deployment 的更多信息
-
- 在展开成功后,可以通过运行
-
- 要查看 Deployment 展开状态,运行
- 运行
- Pod 模板规范或