Update localization guidelines (#10485)
* Update localization guidelines for language labels
Continuing work
Continuing work
Continuing work
More work in progress
Add local OWNERS folders
Add an OWNERS file to Chinese
Remove shortcode for repos
Add Japanese
Alphabetize languages, change weights accordingly
More updates
Add Korean in Korean
Add English to languageName
Feedback from gochist
Move Chinese content from cn/ to zh/
Move OWNERS from cn/ to zh/
Resolve merge conflicts by updating from master
Add files back in to prep for resolution
After rebase on upstream/master, remove files
Review and update localization guidelines
Feedback from gochist, tnir, cstoku
Add a trailing newline to content/ja/OWNERS
Add a trailing newline to content/zh/OWNERS
Drop requirement for GH repo project
Clarify language about forks/branches
Edits and typos
Remove a shortcode specific to a multi-repo language setup
Update aliases and owners
Add explicit OWNERS for content/en
Migrate content from Chinese repo, update regex in config.toml
Remove untranslated strings
Add trailing newline to content/en/OWNERS
Add trailing newlines to OWNERS files
add Jaguar project description (#10433)
* add Jaguar project description
[Jaguar](https://gitlab.com/sdnlab/jaguar) is an open source solution for Kubernetes's network based on OpenDaylight.
Jaguar provides overlay network using vxlan and Jaguar CNIPlugin provides one IP address per pod.
* Minor newline tweak
blog post for azure vmss (#10538)
Add microk8s to pick-right-solution.md (#10542)
* Add microk8s to pick-right-solution.md
Microk8s is a single-command installation of upstream Kubernetes on any Linux and should be included in the list of local-machine solutions.
* capitalized Istio
Add microk8s to foundational.md (#10543)
* Add microk8s to foundational.md
Adding microk8s as credible and stable alternative to get started with Kubernetes on a local machine. This is especially attractive for those not wanting to incur the overhead of running a VM for a local cluster.
* Update foundational.md
Thank you for your suggestions! LMK if this works now?
* Rewrote first paragraph
And included a bullet list of features of microk8s
* Copyedit
fix typo (#10545)
Fix the kubectl subcommands links. (#10550)
Signed-off-by: William Zhang <warmchang@outlook.com>
Fix command issue (#10515)
Signed-off-by: mooncake <xcoder@tenxcloud.com>
remove imported community files per issue 10184 (#10501)
networking.md: Markdown fix (#10498)
Fix front matter, federation command-line tools (#10500)
Clean up glossary entry (#10399)
update slack link (#10536)
typo in StatefulSet docs (#10558)
fix discription about horizontal pod autoscale (#10557)
Remove redundant symbols (#10556)
Fix issue #10520 (#10554)
Signed-off-by: William Zhang <warmchang@outlook.com>
Update api-concepts.md (#10534)
Revert "Fix command issue (#10515)"
This reverts commit c02a7fb9f9.
Update memory-constraint-namespace.md (#10530)
update memory request to 100MiB corresponding the yaml content
Blog: Introducing Volume Snapshot Alpha for Kubernetes (#10562)
* blog post for azure vmss
* snapshot blog post
Resolve merge conflicts in OWNERS*
Minor typo fix (#10567)
Not sure what's supposed to be here, proposing removing it.
* Feedback from gochist
Tweaks to feedback
* Feedback from ClaudiaJKang
This commit is contained in:
committed by
k8s-ci-robot
parent
753f57f0e6
commit
abcee2dccd
@@ -0,0 +1,212 @@
|
||||
---
|
||||
approvers:
|
||||
- erictune
|
||||
- soltysh
|
||||
- janetkuo
|
||||
title: Cron Job
|
||||
redirect_from:
|
||||
- "/docs/concepts/jobs/cron-jobs/"
|
||||
- "/docs/concepts/jobs/cron-jobs.html"
|
||||
- "/docs/user-guide/cron-jobs/"
|
||||
- "/docs/user-guide/cron-jobs.html"
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
|
||||
|
||||
## Cron Job 是什么?
|
||||
|
||||
_Cron Job_ 管理基于时间的 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/),即:
|
||||
|
||||
* 在给定时间点只运行一次
|
||||
* 在给定时间点周期性地运行
|
||||
|
||||
一个 CronJob 对象类似于 _crontab_ (cron table)文件中的一行。它根据指定的预定计划周期性地运行一个 Job,格式可以参考 [Cron](https://en.wikipedia.org/wiki/Cron) 。
|
||||
|
||||
|
||||
|
||||
**注意:** 在预定计划中,问号(`?`)和星号(`*`)的意义是相同的,表示给定字段的取值是任意可用值。
|
||||
|
||||
**注意:** 在 Kubernetes 1.4 版本引入了 ScheduledJob 资源,但从 1.5 版本开始改成了 CronJob。
|
||||
|
||||
典型的用法如下所示:
|
||||
|
||||
|
||||
|
||||
* 在给定的时间点调度 Job 运行
|
||||
* 创建周期性运行的 Job,例如:数据库备份、发送邮件。
|
||||
|
||||
### 前提条件
|
||||
|
||||
|
||||
|
||||
当使用的 Kubernetes 集群,版本 >= 1.4(对 ScheduledJob),>= 1.5(对 CronJob),当启动 API Server(参考 [为集群开启或关闭 API 版本](/docs/admin/cluster-management/#turn-on-or-off-an-api-version-for-your-cluster) 获取更多信息)时,通过传递选项 `--runtime-config=batch/v2alpha1=true` 可以开启 batch/v2alpha1 API。
|
||||
|
||||
## 创建 Cron Job
|
||||
|
||||
下面是一个 Cron Job 的例子。它会每分钟运行一个 Job,打印出当前时间并输出问候语 hello。
|
||||
|
||||
% include code.html language="yaml" file="cronjob.yaml" ghlink="/docs/concepts/workloads/controllers/cronjob.yaml" %}
|
||||
|
||||
下载并运行该示例 Cron Job,然后执行如下命令:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f ./cronjob.yaml
|
||||
cronjob "hello" created
|
||||
```
|
||||
|
||||
|
||||
|
||||
可选地,使用 `kubectl run` 创建一个 Cron Job,不需要写完整的配置:
|
||||
|
||||
```shell
|
||||
$ kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
|
||||
cronjob "hello" created
|
||||
```
|
||||
|
||||
|
||||
|
||||
创建该 Cron Job 之后,通过如下命令获取它的状态信息:
|
||||
|
||||
```shell
|
||||
$ kubectl get cronjob hello
|
||||
NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
|
||||
hello */1 * * * * False 0 <none>
|
||||
```
|
||||
|
||||
|
||||
|
||||
如上所示,既没有 active 的 Job,也没有被调度的 Job。
|
||||
|
||||
等待并观察创建的 Job,大约一分钟时间:
|
||||
|
||||
```shell
|
||||
$ kubectl get jobs --watch
|
||||
NAME DESIRED SUCCESSFUL AGE
|
||||
hello-4111706356 1 1 2s
|
||||
```
|
||||
|
||||
|
||||
|
||||
现在能看到一个名称为 hello 的 Job 在运行。我们可以停止观察,并再次获取该 Job 的状态信息:
|
||||
|
||||
```shell
|
||||
$ kubectl get cronjob hello
|
||||
NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
|
||||
hello */1 * * * * False 0 Mon, 29 Aug 2016 14:34:00 -0700
|
||||
```
|
||||
|
||||
|
||||
应该能够看到名称为 “hello” 的 Job 在 `LAST-SCHEDULE` 指定的时间点被调度了。当前存在 0 个活跃(Active)的 Job,说明该 Job 已经被调度运行完成或失败。
|
||||
|
||||
现在,找到最近一次被调度的 Job 创建的 Pod,能够看到其中一个 Pod 的标准输出。注意,Job 名称和 Pod 名称是不一样的。
|
||||
|
||||
```shell
|
||||
# Replace "hello-4111706356" with the job name in your system
|
||||
$ pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items..metadata.name})
|
||||
|
||||
$ echo $pods
|
||||
hello-4111706356-o9qcm
|
||||
|
||||
$ kubectl logs $pods
|
||||
Mon Aug 29 21:34:09 UTC 2016
|
||||
Hello from the Kubernetes cluster
|
||||
```
|
||||
|
||||
|
||||
## 删除 Cron Job
|
||||
|
||||
一旦不再需要 Cron Job,简单地可以使用 `kubectl` 命令删除它:
|
||||
|
||||
```shell
|
||||
$ kubectl delete cronjob hello
|
||||
cronjob "hello" deleted
|
||||
```
|
||||
|
||||
|
||||
|
||||
这将会终止正在创建的 Job。然而,运行中的 Job 将不会被终止,不会删除 Job 或 它们的 Pod。为了清理那些 Job 和 Pod,需要列出该 Cron Job 创建的全部 Job,然后删除它们:
|
||||
|
||||
```shell
|
||||
$ kubectl get jobs
|
||||
NAME DESIRED SUCCESSFUL AGE
|
||||
hello-1201907962 1 1 11m
|
||||
hello-1202039034 1 1 8m
|
||||
...
|
||||
|
||||
$ kubectl delete jobs hello-1201907962 hello-1202039034 ...
|
||||
job "hello-1201907962" deleted
|
||||
job "hello-1202039034" deleted
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
|
||||
一旦 Job 被删除,由 Job 创建的 Pod 也会被删除。注意,所有由名称为 “hello” 的 Cron Job 创建的 Job 会以前缀字符串 “hello-” 进行命名。如果想要删除当前 Namespace 中的所有 Job,可以通过命令 `kubectl delete jobs --all` 立刻删除它们。
|
||||
|
||||
|
||||
|
||||
## Cron Job 限制
|
||||
|
||||
Cron Job 在每次调度运行时间内 _大概_ 会创建一个 Job 对象。我们之所以说 _大概_ ,是因为在特定的环境下可能会创建两个 Job,或者一个 Job 都没创建。我们尝试少发生这种情况,但却不能完全避免。因此,创建 Job 操作应该是 _幂等的_。
|
||||
|
||||
Job 根据它所创建的 Pod 的并行度,负责重试创建 Pod,并就决定这一组 Pod 的成功或失败。Cron Job 根本不会去检查 Pod。
|
||||
|
||||
|
||||
|
||||
## 编写 Cron Job 规约
|
||||
|
||||
和其它 Kubernetes 配置一样,Cron Job 需要 `apiVersion`、 `kind`、和 `metadata` 这三个字段。
|
||||
关于如何实现一个配置文件的更新信息,参考文档 [部署应用](/docs/user-guide/deploying-applications)、
|
||||
[配置容器](/docs/user-guide/configuring-containers) 和
|
||||
[使用 kubectl 管理资源](/docs/user-guide/working-with-resources)。
|
||||
|
||||
Cron Job 也需要 [`.spec` 段](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status)。
|
||||
|
||||
**注意:** 对一个 Cron Job 的所有修改,尤其是对其 `.spec` 的修改,仅会在下一次运行的时候生效。
|
||||
|
||||
|
||||
### 调度
|
||||
|
||||
`.spec.schedule` 是 `.spec` 中必需的字段,它的值是 [Cron](https://en.wikipedia.org/wiki/Cron) 格式字的符串,例如:`0 * * * *`,或者 `@hourly`,根据指定的调度时间 Job 会被创建和执行。
|
||||
|
||||
|
||||
|
||||
### Job 模板
|
||||
|
||||
`.spec.jobTemplate` 是另一个 `.spec` 中必需的字段。它是 Job 的模板。
|
||||
除了它可以是嵌套的,并且不具有 `apiVersion` 或 `kind` 字段之外,它和 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) 一样具有完全相同的模式(schema)。
|
||||
参考 [编写 Job 规格](/docs/concepts/jobs/run-to-completion-finite-workloads/#writing-a-job-spec)。
|
||||
|
||||
|
||||
|
||||
### 启动 Job 的期限(秒级别)
|
||||
|
||||
`.spec.startingDeadlineSeconds` 字段是可选的。它表示启动 Job 的期限(秒级别),如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限。
|
||||
|
||||
|
||||
|
||||
### 并发策略
|
||||
|
||||
`.spec.concurrencyPolicy` 字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:
|
||||
|
||||
* `Allow`(默认):允许并发运行 Job
|
||||
* `Forbid`:禁止并发运行,如果前一个还没有完成,则直接跳过下一个
|
||||
* `Replace`:取消当前正在运行的 Job,用一个新的来替换
|
||||
|
||||
注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。
|
||||
|
||||
|
||||
|
||||
### 挂起
|
||||
|
||||
`.spec.suspend` 字段也是可选的。如果设置为 `true`,后续所有执行都将被挂起。它对已经开始执行的 Job 不起作用。默认值为 `false`。
|
||||
|
||||
|
||||
|
||||
### Job 历史限制
|
||||
|
||||
`.spec.successfulJobsHistoryLimit` 和 `.spec.failedJobsHistoryLimit` 这两个字段是可选的。它们指定了可以保留完成和失败 Job 数量的限制。
|
||||
|
||||
默认没有限制,所有成功和失败的 Job 都会被保留。然而,当运行一个 Cron Job 时,很快就会堆积很多 Job,推荐设置这两个字段的值。设置限制值为 `0`,相关类型的 Job 完成后将不会被保留。
|
||||
@@ -0,0 +1,163 @@
|
||||
---
|
||||
approvers:
|
||||
- erictune
|
||||
title: DaemonSet
|
||||
redirect_from:
|
||||
- "/docs/admin/daemons/"
|
||||
- "/docs/admin/daemons.html"
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
|
||||
|
||||
## 什么是 DaemonSet?
|
||||
|
||||
_DaemonSet_ 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时,也会为他们新增一个 Pod 。
|
||||
当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
|
||||
|
||||
|
||||
|
||||
使用 DaemonSet 的一些典型用法:
|
||||
|
||||
- 运行集群存储 daemon,例如在每个节点上运行 `glusterd`、`ceph`。
|
||||
- 在每个节点上运行日志收集 daemon,例如`fluentd`、`logstash`。
|
||||
- 在每个节点上运行监控 daemon,例如 [Prometheus Node Exporter](https://github.com/prometheus/node_exporter)、`collectd`、Datadog 代理、New Relic 代理,或 Ganglia `gmond`。
|
||||
|
||||
一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种类型的 daemon 使用。
|
||||
一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志,和/或对不同硬件类型具有不同的内存、CPU要求。
|
||||
|
||||
|
||||
|
||||
## 编写 DaemonSet 规约
|
||||
|
||||
### 必需字段
|
||||
|
||||
|
||||
|
||||
和其它所有 Kubernetes 配置一样,DaemonSet 需要 `apiVersion`、`kind` 和 `metadata` 字段。
|
||||
有关配置文件的基本信息,详见文档 [deploying applications](/docs/user-guide/deploying-applications/)、[配置容器](/docs/user-guide/configuring-containers/) 和 [资源管理](/docs/concepts/tools/kubectl/object-management-overview/) 。
|
||||
|
||||
DaemonSet 也需要一个 [`.spec`](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) 配置段。
|
||||
|
||||
|
||||
|
||||
### Pod 模板
|
||||
|
||||
`.spec` 唯一必需的字段是 `.spec.template`。
|
||||
|
||||
|
||||
|
||||
`.spec.template` 是一个 [Pod 模板](/docs/user-guide/replication-controller/#pod-template)。
|
||||
它与 [Pod](/docs/user-guide/pods) 具有相同的 schema,除了它是嵌套的,而且不具有 `apiVersion` 或 `kind` 字段。
|
||||
|
||||
除了 Pod 必需字段外,在 DaemonSet 中的 Pod 模板必须指定合理的标签(查看 [Pod Selector](#pod-selector))。
|
||||
|
||||
在 DaemonSet 中的 Pod 模板必须具有一个值为 `Always` 的 [`RestartPolicy`](/docs/user-guide/pod-states),或者未指定它的值,默认是 `Always`。
|
||||
|
||||
|
||||
|
||||
### Pod Selector
|
||||
|
||||
`.spec.selector` 字段表示 Pod Selector,它与 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) 或其它资源的 `.spec.selector` 的作用是相同的。
|
||||
|
||||
`spec.selector` 表示一个对象,它由如下两个字段组成:
|
||||
|
||||
* `matchLabels` - 与 [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/) 的 `.spec.selector` 的作用相同。
|
||||
* `matchExpressions` - 允许构建更加复杂的 Selector,可以通过指定 key、value 列表,以及与 key 和 value 列表相关的操作符。
|
||||
|
||||
|
||||
|
||||
当上述两个字段都指定时,结果表示的是 AND 关系。
|
||||
|
||||
如果指定了 `.spec.selector`,必须与 `.spec.template.metadata.labels` 相匹配。如果没有指定,它们默认是等价的。如果与它们配置的不匹配,则会被 API 拒绝。
|
||||
|
||||
如果 Pod 的 label 与 selector 匹配,或者直接基于其它的 DaemonSet、或者 Controller(例如 ReplicationController),也不可以创建任何 Pod。
|
||||
否则 DaemonSet Controller 将认为那些 Pod 是它创建的。Kubernetes 不会阻止这样做。一个场景是,可能希望在一个具有不同值的、用来测试用的节点上手动创建 Pod。
|
||||
|
||||
|
||||
|
||||
### 仅在某些节点上运行 Pod
|
||||
|
||||
如果指定了 `.spec.template.spec.nodeSelector`,DaemonSet Controller 将在能够与 [Node Selector](/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。
|
||||
类似这种情况,可以指定 `.spec.template.spec.affinity`,然后 DaemonSet Controller 将在能够与 [Node Affinity](/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。
|
||||
如果根本就没有指定,则 DaemonSet Controller 将在所有节点上创建 Pod。
|
||||
|
||||
|
||||
|
||||
## 如何调度 Daemon Pod
|
||||
|
||||
正常情况下,Pod 运行在哪个机器上是由 Kubernetes 调度器来选择的。然而,由 Daemon Controller 创建的 Pod 已经确定了在哪个机器上(Pod 创建时指定了 `.spec.nodeName`),因此:
|
||||
|
||||
- DaemonSet Controller 并不关心一个节点的 [`unschedulable`](/docs/admin/node/#manual-node-administration) 字段。
|
||||
- DaemonSet Controller 可以创建 Pod,即使调度器还没有启动,这对集群启动是非常有帮助的。
|
||||
|
||||
|
||||
|
||||
Daemon Pod 关心 [Taint 和 Toleration](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature),它们会为没有指定 `tolerationSeconds` 的 `node.kubernetes.io/not-ready` 和 `node.alpha.kubernetes.io/unreachable` 的 Taint,创建具有 `NoExecute` 的 Toleration。这确保了当 alpha 特性的 `TaintBasedEvictions` 被启用时,发生节点故障,比如网络分区,这时它们将不会被清除掉(当 `TaintBasedEvictions` 特性没有启用,在这些场景下也不会被清除,但会因为 NodeController 的硬编码行为而被清除,而不会因为 Toleration 导致被清除)。
|
||||
|
||||
|
||||
|
||||
## 与 Daemon Pod 通信
|
||||
|
||||
与 DaemonSet 中的 Pod 进行通信,几种可能的模式如下:
|
||||
|
||||
- **Push**:配置 DaemonSet 中的 Pod 向其它 Service 发送更新,例如统计数据库。它们没有客户端。
|
||||
- **NodeIP 和已知端口**:DaemonSet 中的 Pod 可以使用 `hostPort`,从而可以通过节点 IP 访问到 Pod。客户端能通过某种方法知道节点 IP 列表,并且基于此也可以知道端口。
|
||||
- **DNS**:创建具有相同 Pod Selector 的 [Headless Service](/docs/user-guide/services/#headless-services),然后通过使用 `endpoints` 资源或从 DNS 检索到多个 A 记录来发现 DaemonSet。
|
||||
- **Service**:创建具有相同 Pod Selector 的 Service,并使用该 Service 随机访问到某个节点上的 daemon(没有办法访问到特定节点)。
|
||||
|
||||
|
||||
|
||||
## 更新 DaemonSet
|
||||
|
||||
如果修改了节点标签(Label),DaemonSet 将立刻向新匹配上的节点添加 Pod,同时删除新近不能够匹配的节点上的 Pod。
|
||||
|
||||
我们可以修改 DaemonSet 创建的 Pod。然而,不允许对 Pod 的所有字段进行更新。当下次节点(即使具有相同的名称)被创建时,DaemonSet Controller 还会使用最初的模板。
|
||||
|
||||
|
||||
|
||||
可以删除一个 DaemonSet。如果使用 `kubectl` 并指定 `--cascade=false` 选项,则 Pod 将被保留在节点上。然后可以创建具有不同模板的新 DaemonSet。具有不同模板的新 DaemonSet 将能够通过标签匹配并识别所有已经存在的 Pod。它不会修改或删除它们,即使是错误匹配了 Pod 模板。通过删除 Pod 或者删除节点,可以强制创建新的 Pod。
|
||||
|
||||
在 Kubernetes 1.6 或以后版本,可以在 DaemonSet 上 [执行滚动升级](/docs/tasks/manage-daemon/update-daemon-set/)。
|
||||
|
||||
未来的 Kubernetes 版本将支持节点的可控更新。
|
||||
|
||||
|
||||
|
||||
## DaemonSet 的可替代选择
|
||||
|
||||
### init 脚本
|
||||
|
||||
我们很可能希望直接在一个节点上启动 daemon 进程(例如,使用 `init`、`upstartd`、或 `systemd`)。这非常好,但基于 DaemonSet 来运行这些进程有如下一些好处:
|
||||
|
||||
|
||||
|
||||
- 像对待应用程序一样,具备为 daemon 提供监控和管理日志的能力。
|
||||
- 为 daemon 和应用程序使用相同的配置语言和工具(如 Pod 模板、`kubectl`)。
|
||||
- Kubernetes 未来版本可能会支持对 DaemonSet 创建 Pod 与节点升级工作流进行集成。
|
||||
- 在资源受限的容器中运行 daemon,能够增加 daemon 和应用容器的隔离性。然而,这也实现了在容器中运行 daemon,但却不能在 Pod 中运行(例如,直接基于 Docker 启动)。
|
||||
|
||||
|
||||
|
||||
### 裸 Pod
|
||||
|
||||
可能要直接创建 Pod,同时指定其运行在特定的节点上。
|
||||
然而,DaemonSet 替换了由于任何原因被删除或终止的 Pod,例如节点失败、例行节点维护、内核升级。由于这个原因,我们应该使用 DaemonSet 而不是单独创建 Pod。
|
||||
|
||||
|
||||
|
||||
### 静态 Pod
|
||||
|
||||
可能需要通过在一个指定目录下编写文件来创建 Pod,该目录受 Kubelet 所监视。这些 Pod 被称为 [静态 Pod](/docs/concepts/cluster-administration/static-pod/)。
|
||||
不像 DaemonSet,静态 Pod 不受 kubectl 和其它 Kubernetes API 客户端管理。静态 Pod 不依赖于 apiserver,这使得它们在集群启动的情况下非常有用。
|
||||
而且,未来静态 Pod 可能会被废弃掉。
|
||||
|
||||
|
||||
|
||||
### Replication Controller
|
||||
|
||||
DaemonSet 与 [Replication Controller](/docs/user-guide/replication-controller) 非常类似,它们都能创建 Pod,这些 Pod 对应的进程都不希望被终止掉(例如,Web 服务器、存储服务器)。
|
||||
为无状态的 Service 使用 Replication Controller,比如前端(Frontend)服务,实现对副本的数量进行扩缩容、平滑升级,比之于精确控制 Pod 运行在某个主机上要重要得多。
|
||||
需要 Pod 副本总是运行在全部或特定主机上,并需要先于其他 Pod 启动,当这被认为非常重要时,应该使用 Daemon Controller。
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: fluentd-elasticsearch
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: fluentd-logging
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: fluentd-elasticsearch
|
||||
spec:
|
||||
containers:
|
||||
- name: fluentd-elasticsearch
|
||||
image: k8s.gcr.io/fluentd-elasticsearch:1.20
|
||||
resources:
|
||||
limits:
|
||||
memory: 200Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 200Mi
|
||||
volumeMounts:
|
||||
- name: varlog
|
||||
mountPath: /var/log
|
||||
- name: varlibdockercontainers
|
||||
mountPath: /var/lib/docker/containers
|
||||
readOnly: true
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: varlog
|
||||
hostPath:
|
||||
path: /var/log
|
||||
- name: varlibdockercontainers
|
||||
hostPath:
|
||||
path: /var/lib/docker/containers
|
||||
@@ -0,0 +1,947 @@
|
||||
---
|
||||
approvers:
|
||||
- bgrant0607
|
||||
- janetkuo
|
||||
title: Deployments
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
A _Deployment_ controller provides declarative updates for [Pods](/docs/concepts/workloads/pods/pod/) and
|
||||
[ReplicaSets](/docs/concepts/workloads/controllers/replicaset/).
|
||||
|
||||
You describe a _desired state_ in a Deployment object, and the Deployment controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments.
|
||||
|
||||
{{< note >}}
|
||||
**Note:** You should not manage ReplicaSets owned by a Deployment. All the use cases should be covered by manipulating the Deployment object. Consider opening an issue in the main Kubernetes repository if your use case is not covered below.
|
||||
{{< /note >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Use Case
|
||||
|
||||
The following are typical use cases for Deployments:
|
||||
|
||||
* [Create a Deployment to rollout a ReplicaSet](#creating-a-deployment). The ReplicaSet creates Pods in the background. Check the status of the rollout to see if it succeeds or not.
|
||||
* [Declare the new state of the Pods](#updating-a-deployment) by updating the PodTemplateSpec of the Deployment. A new ReplicaSet is created and the Deployment manages moving the Pods from the old ReplicaSet to the new one at a controlled rate. Each new ReplicaSet updates the revision of the Deployment.
|
||||
* [Rollback to an earlier Deployment revision](#rolling-back-a-deployment) if the current state of the Deployment is not stable. Each rollback updates the revision of the Deployment.
|
||||
* [Scale up the Deployment to facilitate more load.](#scaling-a-deployment)
|
||||
* [Pause the Deployment](#pausing-and-resuming-a-deployment) to apply multiple fixes to its PodTemplateSpec and then resume it to start a new rollout.
|
||||
* [Use the status of the Deployment](#deployment-status) as an indicator that a rollout has stuck
|
||||
* [Clean up older ReplicaSets](#clean-up-policy) that you don't need anymore
|
||||
|
||||
|
||||
## Creating a Deployment
|
||||
|
||||
Here is an example Deployment. It creates a ReplicaSet to bring up three nginx Pods.
|
||||
|
||||
{{< code file="nginx-deployment.yaml" >}}
|
||||
|
||||
Run the example by downloading the example file and then running this command:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record
|
||||
deployment "nginx-deployment" created
|
||||
```
|
||||
|
||||
Setting the kubectl flag `--record` to `true` allows you to record current command in the annotations of
|
||||
the resources being created or updated. It is useful for future introspection: for example, to see the
|
||||
commands executed in each Deployment revision.
|
||||
|
||||
Then running `get` immediately will give:
|
||||
|
||||
```shell
|
||||
$ kubectl get deployments
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3 0 0 0 1s
|
||||
```
|
||||
|
||||
This indicates that the Deployment's number of desired replicas is 3 (according to deployment's `.spec.replicas`),
|
||||
the number of current replicas (`.status.replicas`) is 0, the number of up-to-date replicas (`.status.updatedReplicas`)
|
||||
is 0, and the number of available replicas (`.status.availableReplicas`) is also 0.
|
||||
|
||||
To see the Deployment rollout status, run:
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
Running the `get` again a few seconds later should give:
|
||||
|
||||
```shell
|
||||
$ kubectl get deployments
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3 3 3 3 18s
|
||||
```
|
||||
|
||||
This indicates that the Deployment has created all three replicas, and all replicas are up-to-date (contains the
|
||||
latest pod template) and available (pod status is ready for at least Deployment's `.spec.minReadySeconds`). Running
|
||||
`kubectl get rs` and `kubectl get pods` will show the ReplicaSet (RS) and Pods created.
|
||||
|
||||
```shell
|
||||
$ kubectl get rs
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-2035384211 3 3 3 18s
|
||||
```
|
||||
|
||||
You may notice that the name of the ReplicaSet is always `<the name of the Deployment>-<hash value of the pod template>`.
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
The created ReplicaSet ensures that there are three nginx Pods at all times.
|
||||
|
||||
{{< note >}}
|
||||
**Note:** You must specify an appropriate selector and pod template labels in a Deployment (in this case,
|
||||
`app = nginx`). That is, don't overlap with other controllers (including other Deployments, ReplicaSets,
|
||||
StatefulSets, etc.). Kubernetes doesn't stop you from overlapping, and if multiple
|
||||
controllers have overlapping selectors, those controllers may fight with each other and won't behave
|
||||
correctly.
|
||||
{{< /note >}}
|
||||
|
||||
### Pod-template-hash label
|
||||
|
||||
{{< note >}}
|
||||
**Note:** Do not change this label.
|
||||
{{< /note >}}
|
||||
|
||||
Note the pod-template-hash label in the example output in the pod labels above. This label is added by the
|
||||
Deployment controller to every ReplicaSet that a Deployment creates or adopts. Its purpose is to make sure that child
|
||||
ReplicaSets of a Deployment do not overlap. It is computed by hashing the PodTemplate of the ReplicaSet
|
||||
and using the resulting hash as the label value that will be added in the ReplicaSet selector, pod template labels,
|
||||
and in any existing Pods that the ReplicaSet may have.
|
||||
|
||||
## Updating a Deployment
|
||||
|
||||
{{< note >}}
|
||||
**Note:** A Deployment's rollout is triggered if and only if the Deployment's pod template (that is, `.spec.template`)
|
||||
is changed, for example if the labels or container images of the template are updated. Other updates, such as scaling the Deployment, do not trigger a rollout.
|
||||
{{< /note >}}
|
||||
|
||||
Suppose that we now want to update the nginx Pods to use the `nginx:1.9.1` image
|
||||
instead of the `nginx:1.7.9` image.
|
||||
|
||||
```shell
|
||||
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
|
||||
deployment "nginx-deployment" image updated
|
||||
```
|
||||
|
||||
Alternatively, we can `edit` the Deployment and change `.spec.template.spec.containers[0].image` from `nginx:1.7.9` to `nginx:1.9.1`:
|
||||
|
||||
```shell
|
||||
$ kubectl edit deployment/nginx-deployment
|
||||
deployment "nginx-deployment" edited
|
||||
```
|
||||
|
||||
To see the rollout status, run:
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
After the rollout succeeds, you may want to `get` the Deployment:
|
||||
|
||||
```shell
|
||||
$ kubectl get deployments
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3 3 3 3 36s
|
||||
```
|
||||
|
||||
The number of up-to-date replicas indicates that the Deployment has updated the replicas to the latest configuration.
|
||||
The current replicas indicates the total replicas this Deployment manages, and the available replicas indicates the
|
||||
number of current replicas that are available.
|
||||
|
||||
We can run `kubectl get rs` to see that the Deployment updated the Pods by creating a new ReplicaSet and scaling it
|
||||
up to 3 replicas, as well as scaling down the old ReplicaSet to 0 replicas.
|
||||
|
||||
```shell
|
||||
$ kubectl get rs
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-1564180365 3 3 3 6s
|
||||
nginx-deployment-2035384211 0 0 0 36s
|
||||
```
|
||||
|
||||
Running `get pods` should now show only the new Pods:
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
Next time we want to update these Pods, we only need to update the Deployment's pod template again.
|
||||
|
||||
Deployment can ensure that only a certain number of Pods may be down while they are being updated. By
|
||||
default, it ensures that at least 1 less than the desired number of Pods are up (1 max unavailable).
|
||||
|
||||
Deployment can also ensure that only a certain number of Pods may be created above the desired number of
|
||||
Pods. By default, it ensures that at most 1 more than the desired number of Pods are up (1 max surge).
|
||||
|
||||
In a future version of Kubernetes, the defaults will change from 1-1 to 25%-25%.
|
||||
|
||||
For example, if you look at the above Deployment closely, you will see that it first created a new Pod,
|
||||
then deleted some old Pods and created new ones. It does not kill old Pods until a sufficient number of
|
||||
new Pods have come up, and does not create new Pods until a sufficient number of old Pods have been killed.
|
||||
It makes sure that number of available Pods is at least 2 and the number of total Pods is at most 4.
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
Here we see that when we first created the Deployment, it created a ReplicaSet (nginx-deployment-2035384211)
|
||||
and scaled it up to 3 replicas directly. When we updated the Deployment, it created a new ReplicaSet
|
||||
(nginx-deployment-1564180365) and scaled it up to 1 and then scaled down the old ReplicaSet to 2, so that at
|
||||
least 2 Pods were available and at most 4 Pods were created at all times. It then continued scaling up and down
|
||||
the new and the old ReplicaSet, with the same rolling update strategy. Finally, we'll have 3 available replicas
|
||||
in the new ReplicaSet, and the old ReplicaSet is scaled down to 0.
|
||||
|
||||
### Rollover (aka multiple updates in-flight)
|
||||
|
||||
Each time a new deployment object is observed by the deployment controller, a ReplicaSet is created to bring up
|
||||
the desired Pods if there is no existing ReplicaSet doing so. Existing ReplicaSet controlling Pods whose labels
|
||||
match `.spec.selector` but whose template does not match `.spec.template` are scaled down. Eventually, the new
|
||||
ReplicaSet will be scaled to `.spec.replicas` and all old ReplicaSets will be scaled to 0.
|
||||
|
||||
If you update a Deployment while an existing rollout is in progress, the Deployment will create a new ReplicaSet
|
||||
as per the update and start scaling that up, and will roll over the ReplicaSet that it was scaling up previously
|
||||
-- it will add it to its list of old ReplicaSets and will start scaling it down.
|
||||
|
||||
For example, suppose you create a Deployment to create 5 replicas of `nginx:1.7.9`,
|
||||
but then updates the Deployment to create 5 replicas of `nginx:1.9.1`, when only 3
|
||||
replicas of `nginx:1.7.9` had been created. In that case, Deployment will immediately start
|
||||
killing the 3 `nginx:1.7.9` Pods that it had created, and will start creating
|
||||
`nginx:1.9.1` Pods. It will not wait for 5 replicas of `nginx:1.7.9` to be created
|
||||
before changing course.
|
||||
|
||||
### Label selector updates
|
||||
|
||||
It is generally discouraged to make label selector updates and it is suggested to plan your selectors up front.
|
||||
In any case, if you need to perform a label selector update, exercise great caution and make sure you have grasped
|
||||
all of the implications.
|
||||
|
||||
* Selector additions require the pod template labels in the Deployment spec to be updated with the new label too,
|
||||
otherwise a validation error is returned. This change is a non-overlapping one, meaning that the new selector does
|
||||
not select ReplicaSets and Pods created with the old selector, resulting in orphaning all old ReplicaSets and
|
||||
creating a new ReplicaSet.
|
||||
* Selector updates -- that is, changing the existing value in a selector key -- result in the same behavior as additions.
|
||||
* Selector removals -- that is, removing an existing key from the Deployment selector -- do not require any changes in the
|
||||
pod template labels. No existing ReplicaSet is orphaned, and a new ReplicaSet is not created, but note that the
|
||||
removed label still exists in any existing Pods and ReplicaSets.
|
||||
|
||||
## Rolling Back a Deployment
|
||||
|
||||
Sometimes you may want to rollback a Deployment; for example, when the Deployment is not stable, such as crash looping.
|
||||
By default, all of the Deployment's rollout history is kept in the system so that you can rollback anytime you want
|
||||
(you can change that by modifying revision history limit).
|
||||
|
||||
{{< note >}}
|
||||
**Note:** A Deployment's revision is created when a Deployment's rollout is triggered. This means that the
|
||||
new revision is created if and only if the Deployment's pod template (`.spec.template`) is changed,
|
||||
for example if you update the labels or container images of the template. Other updates, such as scaling the Deployment,
|
||||
do not create a Deployment revision, so that we can facilitate simultaneous manual- or auto-scaling.
|
||||
This means that when you roll back to an earlier revision, only the Deployment's pod template part is
|
||||
rolled back.
|
||||
{{< /note >}}
|
||||
|
||||
Suppose that we made a typo while updating the Deployment, by putting the image name as `nginx:1.91` instead of `nginx:1.9.1`:
|
||||
|
||||
```shell
|
||||
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91
|
||||
deployment "nginx-deployment" image updated
|
||||
```
|
||||
|
||||
The rollout will be stuck.
|
||||
|
||||
```shell
|
||||
$ kubectl rollout status deployments nginx-deployment
|
||||
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
|
||||
```
|
||||
|
||||
Press Ctrl-C to stop the above rollout status watch. For more information on stuck rollouts,
|
||||
[read more here](#deployment-status).
|
||||
|
||||
You will also see that both the number of old replicas (nginx-deployment-1564180365 and
|
||||
nginx-deployment-2035384211) and new replicas (nginx-deployment-3066724191) are 2.
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
Looking at the Pods created, you will see that the 2 Pods created by new ReplicaSet are stuck in an image pull loop.
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
**Note:** The Deployment controller will stop the bad rollout automatically, and will stop scaling up the new
|
||||
ReplicaSet. This depends on the rollingUpdate parameters (`maxUnavailable` specifically) that you have specified.
|
||||
Kubernetes by default sets the value to 1 and spec.replicas to 1 so if you haven't cared about setting those
|
||||
parameters, your Deployment can have 100% unavailability by default! This will be fixed in Kubernetes in a future
|
||||
version.
|
||||
{{< /note >}}
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
To fix this, we need to rollback to a previous revision of Deployment that is stable.
|
||||
|
||||
### Checking Rollout History of a Deployment
|
||||
|
||||
First, check the revisions of this deployment:
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
Because we recorded the command while creating this Deployment using `--record`, we can easily see
|
||||
the changes we made in each revision.
|
||||
|
||||
To further see the details of each revision, run:
|
||||
|
||||
```shell
|
||||
$ 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.
|
||||
```
|
||||
|
||||
### Rolling Back to a Previous Revision
|
||||
|
||||
Now we've decided to undo the current rollout and rollback to the previous revision:
|
||||
|
||||
```shell
|
||||
$ kubectl rollout undo deployment/nginx-deployment
|
||||
deployment "nginx-deployment" rolled back
|
||||
```
|
||||
|
||||
Alternatively, you can rollback to a specific revision by specify that in `--to-revision`:
|
||||
|
||||
```shell
|
||||
$ kubectl rollout undo deployment/nginx-deployment --to-revision=2
|
||||
deployment "nginx-deployment" rolled back
|
||||
```
|
||||
|
||||
For more details about rollout related commands, read [`kubectl rollout`](/docs/user-guide/kubectl/{{< param "version" >}}/#rollout).
|
||||
|
||||
The Deployment is now rolled back to a previous stable revision. As you can see, a `DeploymentRollback` event
|
||||
for rolling back to revision 2 is generated from Deployment controller.
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
## Scaling a Deployment
|
||||
|
||||
You can scale a Deployment by using the following command:
|
||||
|
||||
```shell
|
||||
$ kubectl scale deployment nginx-deployment --replicas=10
|
||||
deployment "nginx-deployment" scaled
|
||||
```
|
||||
|
||||
Assuming [horizontal pod autoscaling](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/) is enabled
|
||||
in your cluster, you can setup an autoscaler for your Deployment and choose the minimum and maximum number of
|
||||
Pods you want to run based on the CPU utilization of your existing Pods.
|
||||
|
||||
```shell
|
||||
$ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
|
||||
deployment "nginx-deployment" autoscaled
|
||||
```
|
||||
|
||||
### Proportional scaling
|
||||
|
||||
RollingUpdate Deployments support running multiple versions of an application at the same time. When you
|
||||
or an autoscaler scales a RollingUpdate Deployment that is in the middle of a rollout (either in progress
|
||||
or paused), then the Deployment controller will balance the additional replicas in the existing active
|
||||
ReplicaSets (ReplicaSets with Pods) in order to mitigate risk. This is called *proportional scaling*.
|
||||
|
||||
For example, you are running a Deployment with 10 replicas, [maxSurge](#max-surge)=3, and [maxUnavailable](#max-unavailable)=2.
|
||||
|
||||
```shell
|
||||
$ kubectl get deploy
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 10 10 10 10 50s
|
||||
```
|
||||
|
||||
You update to a new image which happens to be unresolvable from inside the cluster.
|
||||
|
||||
```shell
|
||||
$ kubectl set image deploy/nginx-deployment nginx=nginx:sometag
|
||||
deployment "nginx-deployment" image updated
|
||||
```
|
||||
|
||||
The image update starts a new rollout with ReplicaSet nginx-deployment-1989198191, but it's blocked due to the
|
||||
maxUnavailable requirement that we mentioned above.
|
||||
|
||||
```shell
|
||||
$ kubectl get rs
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-1989198191 5 5 0 9s
|
||||
nginx-deployment-618515232 8 8 8 1m
|
||||
```
|
||||
|
||||
Then a new scaling request for the Deployment comes along. The autoscaler increments the Deployment replicas
|
||||
to 15. The Deployment controller needs to decide where to add these new 5 replicas. If we weren't using
|
||||
proportional scaling, all 5 of them would be added in the new ReplicaSet. With proportional scaling, we
|
||||
spread the additional replicas across all ReplicaSets. Bigger proportions go to the ReplicaSets with the
|
||||
most replicas and lower proportions go to ReplicaSets with less replicas. Any leftovers are added to the
|
||||
ReplicaSet with the most replicas. ReplicaSets with zero replicas are not scaled up.
|
||||
|
||||
In our example above, 3 replicas will be added to the old ReplicaSet and 2 replicas will be added to the
|
||||
new ReplicaSet. The rollout process should eventually move all replicas to the new ReplicaSet, assuming
|
||||
the new replicas become healthy.
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
## Pausing and Resuming a Deployment
|
||||
|
||||
You can pause a Deployment before triggering one or more updates and then resume it. This will allow you to
|
||||
apply multiple fixes in between pausing and resuming without triggering unnecessary rollouts.
|
||||
|
||||
For example, with a Deployment that was just created:
|
||||
|
||||
```shell
|
||||
$ kubectl get deploy
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx 3 3 3 3 1m
|
||||
$ kubectl get rs
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-2142116321 3 3 3 1m
|
||||
```
|
||||
|
||||
Pause by running the following command:
|
||||
|
||||
```shell
|
||||
$ kubectl rollout pause deployment/nginx-deployment
|
||||
deployment "nginx-deployment" paused
|
||||
```
|
||||
|
||||
Then update the image of the Deployment:
|
||||
|
||||
```shell
|
||||
$ kubectl set image deploy/nginx-deployment nginx=nginx:1.9.1
|
||||
deployment "nginx-deployment" image updated
|
||||
```
|
||||
|
||||
Notice that no new rollout started:
|
||||
|
||||
```shell
|
||||
$ kubectl rollout history deploy/nginx-deployment
|
||||
deployments "nginx"
|
||||
REVISION CHANGE-CAUSE
|
||||
1 <none>
|
||||
|
||||
$ kubectl get rs
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-2142116321 3 3 3 2m
|
||||
```
|
||||
|
||||
You can make as many updates as you wish, for example, update the resources that will be used:
|
||||
|
||||
```shell
|
||||
$ kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
|
||||
deployment "nginx" resource requirements updated
|
||||
```
|
||||
|
||||
The initial state of the Deployment prior to pausing it will continue its function, but new updates to
|
||||
the Deployment will not have any effect as long as the Deployment is paused.
|
||||
|
||||
Eventually, resume the Deployment and observe a new ReplicaSet coming up with all the new updates:
|
||||
|
||||
```shell
|
||||
$ kubectl rollout resume deploy/nginx-deployment
|
||||
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
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
**Note:** You cannot rollback a paused Deployment until you resume it.
|
||||
{{< /note >}}
|
||||
|
||||
## Deployment status
|
||||
|
||||
A Deployment enters various states during its lifecycle. It can be [progressing](#progressing-deployment) while
|
||||
rolling out a new ReplicaSet, it can be [complete](#complete-deployment), or it can [fail to progress](#failed-deployment).
|
||||
|
||||
### Progressing Deployment
|
||||
|
||||
Kubernetes marks a Deployment as _progressing_ when one of the following tasks is performed:
|
||||
|
||||
* The Deployment creates a new ReplicaSet.
|
||||
* The Deployment is scaling up its newest ReplicaSet.
|
||||
* The Deployment is scaling down its older ReplicaSet(s).
|
||||
* New Pods become ready or available (ready for at least [MinReadySeconds](#min-ready-seconds)).
|
||||
|
||||
You can monitor the progress for a Deployment by using `kubectl rollout status`.
|
||||
|
||||
### Complete Deployment
|
||||
|
||||
Kubernetes marks a Deployment as _complete_ when it has the following characteristics:
|
||||
|
||||
* All of the replicas associated with the Deployment have been updated to the latest version you've specified, meaning any
|
||||
updates you've requested have been completed.
|
||||
* All of the replicas associated with the Deployment are available.
|
||||
* No old replicas for the Deployment are running.
|
||||
|
||||
You can check if a Deployment has completed by using `kubectl rollout status`. If the rollout completed
|
||||
successfully, `kubectl rollout status` returns a zero exit code.
|
||||
|
||||
```shell
|
||||
$ kubectl rollout status deploy/nginx-deployment
|
||||
Waiting for rollout to finish: 2 of 3 updated replicas are available...
|
||||
deployment "nginx" successfully rolled out
|
||||
$ echo $?
|
||||
0
|
||||
```
|
||||
|
||||
### Failed Deployment
|
||||
|
||||
Your Deployment may get stuck trying to deploy its newest ReplicaSet without ever completing. This can occur
|
||||
due to some of the following factors:
|
||||
|
||||
* Insufficient quota
|
||||
* Readiness probe failures
|
||||
* Image pull errors
|
||||
* Insufficient permissions
|
||||
* Limit ranges
|
||||
* Application runtime misconfiguration
|
||||
|
||||
One way you can detect this condition is to specify a deadline parameter in your Deployment spec:
|
||||
([`spec.progressDeadlineSeconds`](#progress-deadline-seconds)). `spec.progressDeadlineSeconds` denotes the
|
||||
number of seconds the Deployment controller waits before indicating (in the Deployment status) that the
|
||||
Deployment progress has stalled.
|
||||
|
||||
The following `kubectl` command sets the spec with `progressDeadlineSeconds` to make the controller report
|
||||
lack of progress for a Deployment after 10 minutes:
|
||||
|
||||
```shell
|
||||
$ kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
|
||||
"nginx-deployment" patched
|
||||
```
|
||||
Once the deadline has been exceeded, the Deployment controller adds a DeploymentCondition with the following
|
||||
attributes to the Deployment's `status.conditions`:
|
||||
|
||||
* Type=Progressing
|
||||
* Status=False
|
||||
* Reason=ProgressDeadlineExceeded
|
||||
|
||||
See the [Kubernetes API conventions](https://git.k8s.io/community/contributors/devel/api-conventions.md#typical-status-properties) for more information on status conditions.
|
||||
|
||||
{{< note >}}
|
||||
**Note:** Kubernetes will take no action on a stalled Deployment other than to report a status condition with
|
||||
`Reason=ProgressDeadlineExceeded`. Higher level orchestrators can take advantage of it and act accordingly, for
|
||||
example, rollback the Deployment to its previous version.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
**Note:** If you pause a Deployment, Kubernetes does not check progress against your specified deadline. You can
|
||||
safely pause a Deployment in the middle of a rollout and resume without triggering the condition for exceeding the
|
||||
deadline.
|
||||
{{< /note >}}
|
||||
|
||||
You may experience transient errors with your Deployments, either due to a low timeout that you have set or
|
||||
due to any other kind of error that can be treated as transient. For example, let's suppose you have
|
||||
insufficient quota. If you describe the Deployment you will notice the following section:
|
||||
|
||||
```shell
|
||||
$ kubectl describe deployment nginx-deployment
|
||||
<...>
|
||||
Conditions:
|
||||
Type Status Reason
|
||||
---- ------ ------
|
||||
Available True MinimumReplicasAvailable
|
||||
Progressing True ReplicaSetUpdated
|
||||
ReplicaFailure True FailedCreate
|
||||
<...>
|
||||
```
|
||||
|
||||
If you run `kubectl get deployment nginx-deployment -o yaml`, the Deployment status might look like this:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
Eventually, once the Deployment progress deadline is exceeded, Kubernetes updates the status and the
|
||||
reason for the Progressing condition:
|
||||
|
||||
```
|
||||
Conditions:
|
||||
Type Status Reason
|
||||
---- ------ ------
|
||||
Available True MinimumReplicasAvailable
|
||||
Progressing False ProgressDeadlineExceeded
|
||||
ReplicaFailure True FailedCreate
|
||||
```
|
||||
|
||||
You can address an issue of insufficient quota by scaling down your Deployment, by scaling down other
|
||||
controllers you may be running, or by increasing quota in your namespace. If you satisfy the quota
|
||||
conditions and the Deployment controller then completes the Deployment rollout, you'll see the
|
||||
Deployment's status update with a successful condition (`Status=True` and `Reason=NewReplicaSetAvailable`).
|
||||
|
||||
```
|
||||
Conditions:
|
||||
Type Status Reason
|
||||
---- ------ ------
|
||||
Available True MinimumReplicasAvailable
|
||||
Progressing True NewReplicaSetAvailable
|
||||
```
|
||||
|
||||
`Type=Available` with `Status=True` means that your Deployment has minimum availability. Minimum availability is dictated
|
||||
by the parameters specified in the deployment strategy. `Type=Progressing` with `Status=True` means that your Deployment
|
||||
is either in the middle of a rollout and it is progressing or that it has successfully completed its progress and the minimum
|
||||
required new replicas are available (see the Reason of the condition for the particulars - in our case
|
||||
`Reason=NewReplicaSetAvailable` means that the Deployment is complete).
|
||||
|
||||
You can check if a Deployment has failed to progress by using `kubectl rollout status`. `kubectl rollout status`
|
||||
returns a non-zero exit code if the Deployment has exceeded the progression deadline.
|
||||
|
||||
```shell
|
||||
$ kubectl rollout status deploy/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
|
||||
```
|
||||
|
||||
### Operating on a failed deployment
|
||||
|
||||
All actions that apply to a complete Deployment also apply to a failed Deployment. You can scale it up/down, roll back
|
||||
to a previous revision, or even pause it if you need to apply multiple tweaks in the Deployment pod template.
|
||||
|
||||
## Clean up Policy
|
||||
|
||||
You can set `.spec.revisionHistoryLimit` field in a Deployment to specify how many old ReplicaSets for
|
||||
this Deployment you want to retain. The rest will be garbage-collected in the background. By default,
|
||||
all revision history will be kept. In a future version, it will default to switch to 2.
|
||||
|
||||
{{< note >}}
|
||||
**Note:** Explicitly setting this field to 0, will result in cleaning up all the history of your Deployment
|
||||
thus that Deployment will not be able to roll back.
|
||||
{{< /note >}}
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Canary Deployment
|
||||
|
||||
If you want to roll out releases to a subset of users or servers using the Deployment, you
|
||||
can create multiple Deployments, one for each release, following the canary pattern described in
|
||||
[managing resources](/docs/concepts/cluster-administration/manage-deployment/#canary-deployments).
|
||||
|
||||
## Writing a Deployment Spec
|
||||
|
||||
As with all other Kubernetes configs, a Deployment needs `apiVersion`, `kind`, and `metadata` fields.
|
||||
For general information about working with config files, see [deploying applications](/docs/tutorials/stateless-application/run-stateless-application-deployment/),
|
||||
configuring containers, and [using kubectl to manage resources](/docs/tutorials/object-management-kubectl/object-management/) documents.
|
||||
|
||||
A Deployment also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status).
|
||||
|
||||
### Pod Template
|
||||
|
||||
The `.spec.template` is the only required field of the `.spec`.
|
||||
|
||||
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [Pod](/docs/concepts/workloads/pods/pod/), except it is nested and does not have an
|
||||
`apiVersion` or `kind`.
|
||||
|
||||
In addition to required fields for a Pod, a pod template in a Deployment must specify appropriate
|
||||
labels and an appropriate restart policy. For labels, make sure not to overlap with other controllers. See [selector](#selector)).
|
||||
|
||||
Only a [`.spec.template.spec.restartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) equal to `Always` is
|
||||
allowed, which is the default if not specified.
|
||||
|
||||
### Replicas
|
||||
|
||||
`.spec.replicas` is an optional field that specifies the number of desired Pods. It defaults to 1.
|
||||
|
||||
### Selector
|
||||
|
||||
`.spec.selector` is an optional field that specifies a [label selector](/docs/concepts/overview/working-with-objects/labels/)
|
||||
for the Pods targeted by this deployment.
|
||||
|
||||
If specified, `.spec.selector` must match `.spec.template.metadata.labels`, or it will be rejected by
|
||||
the API. If `.spec.selector` is unspecified, `.spec.selector.matchLabels` defaults to
|
||||
`.spec.template.metadata.labels`.
|
||||
|
||||
A Deployment may terminate Pods whose labels match the selector if their template is different
|
||||
from `.spec.template` or if the total number of such Pods exceeds `.spec.replicas`. It brings up new
|
||||
Pods with `.spec.template` if the number of Pods is less than the desired number.
|
||||
|
||||
{{< note >}}
|
||||
**Note:** You should not create other pods whose labels match this selector, either directly, by creating
|
||||
another Deployment, or by creating another controller such as a ReplicaSet or a ReplicationController. If you
|
||||
do so, the first Deployment thinks that it created these other pods. Kubernetes does not stop you from doing this.
|
||||
{{< /note >}}
|
||||
|
||||
If you have multiple controllers that have overlapping selectors, the controllers will fight with each
|
||||
other and won't behave correctly.
|
||||
|
||||
### Strategy
|
||||
|
||||
`.spec.strategy` specifies the strategy used to replace old Pods by new ones.
|
||||
`.spec.strategy.type` can be "Recreate" or "RollingUpdate". "RollingUpdate" is
|
||||
the default value.
|
||||
|
||||
#### Recreate Deployment
|
||||
|
||||
All existing Pods are killed before new ones are created when `.spec.strategy.type==Recreate`.
|
||||
|
||||
#### Rolling Update Deployment
|
||||
|
||||
The Deployment updates Pods in a [rolling update](/docs/tasks/run-application/rolling-update-replication-controller/)
|
||||
fashion when `.spec.strategy.type==RollingUpdate`. You can specify `maxUnavailable` and `maxSurge` to control
|
||||
the rolling update process.
|
||||
|
||||
##### Max Unavailable
|
||||
|
||||
`.spec.strategy.rollingUpdate.maxUnavailable` is an optional field that specifies the maximum number
|
||||
of Pods that can be unavailable during the update process. The value can be an absolute number (for example, 5)
|
||||
or a percentage of desired Pods (for example, 10%). The absolute number is calculated from percentage by
|
||||
rounding down. The value cannot be 0 if `.spec.strategy.rollingUpdate.maxSurge` is 0. The default value is 25%.
|
||||
|
||||
For example, when this value is set to 30%, the old ReplicaSet can be scaled down to 70% of desired
|
||||
Pods immediately when the rolling update starts. Once new Pods are ready, old ReplicaSet can be scaled
|
||||
down further, followed by scaling up the new ReplicaSet, ensuring that the total number of Pods available
|
||||
at all times during the update is at least 70% of the desired Pods.
|
||||
|
||||
##### Max Surge
|
||||
|
||||
`.spec.strategy.rollingUpdate.maxSurge` is an optional field that specifies the maximum number of Pods
|
||||
that can be created over the desired number of Pods. The value can be an absolute number (for example, 5) or a
|
||||
percentage of desired Pods (for example, 10%). The value cannot be 0 if `MaxUnavailable` is 0. The absolute number
|
||||
is calculated from the percentage by rounding up. The default value is 25%.
|
||||
|
||||
For example, when this value is set to 30%, the new ReplicaSet can be scaled up immediately when the
|
||||
rolling update starts, such that the total number of old and new Pods does not exceed 130% of desired
|
||||
Pods. Once old Pods have been killed, the new ReplicaSet can be scaled up further, ensuring that the
|
||||
total number of Pods running at any time during the update is at most 130% of desired Pods.
|
||||
|
||||
### Progress Deadline Seconds
|
||||
|
||||
`.spec.progressDeadlineSeconds` is an optional field that specifies the number of seconds you want
|
||||
to wait for your Deployment to progress before the system reports back that the Deployment has
|
||||
[failed progressing](#failed-deployment) - surfaced as a condition with `Type=Progressing`, `Status=False`.
|
||||
and `Reason=ProgressDeadlineExceeded` in the status of the resource. The deployment controller will keep
|
||||
retrying the Deployment. In the future, once automatic rollback will be implemented, the deployment
|
||||
controller will roll back a Deployment as soon as it observes such a condition.
|
||||
|
||||
If specified, this field needs to be greater than `.spec.minReadySeconds`.
|
||||
|
||||
### Min Ready Seconds
|
||||
|
||||
`.spec.minReadySeconds` is an optional field that specifies the minimum number of seconds for which a newly
|
||||
created Pod should be ready without any of its containers crashing, for it to be considered available.
|
||||
This defaults to 0 (the Pod will be considered available as soon as it is ready). To learn more about when
|
||||
a Pod is considered ready, see [Container Probes](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes).
|
||||
|
||||
### Rollback To
|
||||
|
||||
`.spec.rollbackTo` is an optional field with the configuration the Deployment
|
||||
should roll back to. Setting this field triggers a rollback, and this field will
|
||||
be cleared by the server after a rollback is done.
|
||||
|
||||
Because this field will be cleared by the server, it should not be used
|
||||
declaratively. For example, you should not perform `kubectl apply` with a
|
||||
manifest with `.spec.rollbackTo` field set.
|
||||
|
||||
#### Revision
|
||||
|
||||
`.spec.rollbackTo.revision` is an optional field specifying the revision to roll
|
||||
back to. Setting to 0 means rolling back to the last revision in history;
|
||||
otherwise, means rolling back to the specified revision. This defaults to 0 when
|
||||
[`spec.rollbackTo`](#rollback-to) is set.
|
||||
|
||||
### Revision History Limit
|
||||
|
||||
A Deployment's revision history is stored in the replica sets it controls.
|
||||
|
||||
`.spec.revisionHistoryLimit` is an optional field that specifies the number of old ReplicaSets to retain
|
||||
to allow rollback. Its ideal value depends on the frequency and stability of new Deployments. All old
|
||||
ReplicaSets will be kept by default, consuming resources in `etcd` and crowding the output of `kubectl get rs`,
|
||||
if this field is not set. The configuration of each Deployment revision is stored in its ReplicaSets;
|
||||
therefore, once an old ReplicaSet is deleted, you lose the ability to rollback to that revision of Deployment.
|
||||
|
||||
More specifically, setting this field to zero means that all old ReplicaSets with 0 replica will be cleaned up.
|
||||
In this case, a new Deployment rollout cannot be undone, since its revision history is cleaned up.
|
||||
|
||||
### Paused
|
||||
|
||||
`.spec.paused` is an optional boolean field for pausing and resuming a Deployment. The only difference between
|
||||
a paused Deployment and one that is not paused, is that any changes into the PodTemplateSpec of the paused
|
||||
Deployment will not trigger new rollouts as long as it is paused. A Deployment is not paused by default when
|
||||
it is created.
|
||||
|
||||
## Alternative to Deployments
|
||||
|
||||
### kubectl rolling update
|
||||
|
||||
[Kubectl rolling update](/docs/user-guide/kubectl/{{< param "version" >}}/#rolling-update) updates Pods and ReplicationControllers
|
||||
in a similar fashion. But Deployments are recommended, since they are declarative, server side, and have
|
||||
additional features, such as rolling back to any previous revision even after the rolling update is done.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: ReplicaSet
|
||||
metadata:
|
||||
name: frontend
|
||||
# these labels can be applied automatically
|
||||
# from the labels in the pod template if not set
|
||||
# labels:
|
||||
# app: guestbook
|
||||
# tier: frontend
|
||||
spec:
|
||||
# this replicas value is default
|
||||
# modify it according to your case
|
||||
replicas: 3
|
||||
# selector can be applied automatically
|
||||
# from the labels in the pod template if not set,
|
||||
# but we are specifying the selector here to
|
||||
# demonstrate its usage.
|
||||
selector:
|
||||
matchLabels:
|
||||
tier: frontend
|
||||
matchExpressions:
|
||||
- {key: tier, operator: In, values: [frontend]}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: php-redis
|
||||
image: gcr.io/google_samples/gb-frontend:v3
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
env:
|
||||
- name: GET_HOSTS_FROM
|
||||
value: dns
|
||||
# If your cluster config does not include a dns service, then to
|
||||
# instead access environment variables to find service host
|
||||
# info, comment out the 'value: dns' line above, and uncomment the
|
||||
# line below.
|
||||
# value: env
|
||||
ports:
|
||||
- containerPort: 80
|
||||
@@ -0,0 +1,181 @@
|
||||
---
|
||||
title: 垃圾收集
|
||||
redirect_from:
|
||||
- "/docs/concepts/abstractions/controllers/garbage-collection/"
|
||||
- "/docs/concepts/abstractions/controllers/garbage-collection.html"
|
||||
- "/docs/user-guide/garbage-collection/"
|
||||
- "/docs/user-guide/garbage-collection.html"
|
||||
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
|
||||
|
||||
Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。
|
||||
|
||||
**注意**:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
|
||||
## Owner 和 Dependent
|
||||
|
||||
某些 Kubernetes 对象是其它一些对象的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。
|
||||
具有 Owner 的对象被称为是 Owner 的 *Dependent*。
|
||||
每个 Dependent 对象具有一个指向其所属对象的 `metadata.ownerReferences` 字段。
|
||||
|
||||
有时,Kubernetes 会自动设置 `ownerReference` 的值。
|
||||
例如,当创建一个 ReplicaSet 时,Kubernetes 自动设置 ReplicaSet 中每个 Pod 的 `ownerReference` 字段值。
|
||||
在 1.6 版本,Kubernetes 会自动为某些对象设置 `ownerReference` 的值,这些对象是由 ReplicationController、ReplicaSet、StatefulSet、DaemonSet 和 Deployment 所创建或管理。
|
||||
|
||||
|
||||
|
||||
也可以通过手动设置 `ownerReference` 的值,来指定 Owner 和 Dependent 之间的关系。
|
||||
|
||||
这里有一个配置文件,表示一个具有 3 个 Pod 的 ReplicaSet:
|
||||
|
||||
{{< code file="my-repset.yaml" >}}
|
||||
|
||||
|
||||
|
||||
如果创建该 ReplicaSet,然后查看 Pod 的 metadata 字段,能够看到 OwnerReferences 字段:
|
||||
|
||||
```shell
|
||||
kubectl create -f https://k8s.io/docs/concepts/controllers/my-repset.yaml
|
||||
kubectl get pods --output=yaml
|
||||
```
|
||||
|
||||
|
||||
|
||||
输出显示了 Pod 的 Owner 是名为 my-repset 的 ReplicaSet:
|
||||
|
||||
```shell
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
...
|
||||
ownerReferences:
|
||||
- apiVersion: extensions/v1beta1
|
||||
controller: true
|
||||
blockOwnerDeletion: true
|
||||
kind: ReplicaSet
|
||||
name: my-repset
|
||||
uid: d9607e19-f88f-11e6-a518-42010a800195
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
## 控制垃圾收集器删除 Dependent
|
||||
|
||||
当删除对象时,可以指定是否该对象的 Dependent 也自动删除掉。
|
||||
自动删除 Dependent 也称为 *级联删除*。
|
||||
Kubernetes 中有两种 *级联删除* 的模式:*background* 模式和 *foreground* 模式。
|
||||
|
||||
如果删除对象时,不自动删除它的 Dependent,这些 Dependent 被称作是原对象的 *孤儿*。
|
||||
|
||||
|
||||
|
||||
### Background 级联删除
|
||||
|
||||
在 *background 级联删除* 模式下,Kubernetes 会立即删除 Owner 对象,然后垃圾收集器会在后台删除这些 Dependent。
|
||||
|
||||
|
||||
|
||||
### Foreground 级联删除
|
||||
|
||||
在 *foreground 级联删除* 模式下,根对象首先进入 “删除中” 状态。在 “删除中” 状态会有如下的情况:
|
||||
|
||||
* 对象仍然可以通过 REST API 可见。
|
||||
* 会设置对象的 `deletionTimestamp` 字段。
|
||||
* 对象的 `metadata.finalizers` 字段包含了值 "foregroundDeletion"。
|
||||
|
||||
一旦对象被设置为 “删除中” 状态,垃圾收集器会删除对象的所有 Dependent。
|
||||
垃圾收集器在删除了所有 “Blocking” 状态的 Dependent(对象的 `ownerReference.blockOwnerDeletion=true`)之后,它会删除 Owner 对象。
|
||||
|
||||
|
||||
|
||||
注意,在 “foreground 删除” 模式下,只有设置了 `ownerReference.blockOwnerDeletion` 值得 Dependent 才能阻止删除 Owner 对象。
|
||||
在 Kubernetes 1.7 版本中将增加许可控制器(Admission Controller),基于 Owner 对象上的删除权限来控制用户去设置 `blockOwnerDeletion` 的值为 true,所以未授权的 Dependent 不能够延迟 Owner 对象的删除。
|
||||
|
||||
如果一个对象的 `ownerReferences` 字段被一个 Controller(例如 Deployment 或 ReplicaSet)设置,`blockOwnerDeletion` 会被自动设置,不需要手动修改这个字段。
|
||||
|
||||
|
||||
|
||||
### 设置级联删除策略
|
||||
|
||||
通过为 Owner 对象设置 `deleteOptions.propagationPolicy` 字段,可以控制级联删除策略。
|
||||
可能的取值包括:“orphan”、“Foreground” 或 “Background”。
|
||||
|
||||
对很多 Controller 资源,包括 ReplicationController、ReplicaSet、StatefulSet、DaemonSet 和 Deployment,默认的垃圾收集策略是 `orphan`。
|
||||
因此,除非指定其它的垃圾收集策略,否则所有 Dependent 对象使用的都是 `orphan` 策略。
|
||||
|
||||
下面是一个在后台删除 Dependent 对象的例子:
|
||||
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"}' \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
|
||||
|
||||
下面是一个在前台删除 Dependent 对象的例子:
|
||||
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
|
||||
下面是一个孤儿 Dependent 的例子:
|
||||
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
|
||||
|
||||
kubectl 也支持级联删除。
|
||||
通过设置 `--cascade` 为 true,可以使用 kubectl 自动删除 Dependent 对象。
|
||||
设置 `--cascade` 为 false,会使 Dependent 对象成为孤儿 Dependent 对象。
|
||||
`--cascade` 的默认值是 true。
|
||||
|
||||
下面是一个例子,使一个 ReplicaSet 的 Dependent 对象成为孤儿 Dependent:
|
||||
|
||||
|
||||
```shell
|
||||
kubectl delete replicaset my-repset --cascade=false
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 已知的问题
|
||||
* 1.7 版本,垃圾收集不支持 [自定义资源](/docs/concepts/api-extension/custom-resources/),比如那些通过 CustomResourceDefinition 新增,或者通过 API server 聚集而成的资源对象。
|
||||
|
||||
[其它已知的问题](https://github.com/kubernetes/kubernetes/issues/26120)
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
|
||||
|
||||
[设计文档 1](https://git.k8s.io/community/contributors/design-proposals/garbage-collection.md)
|
||||
[设计文档 2](https://git.k8s.io/community/contributors/design-proposals/synchronous-garbage-collection.md)
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
apiVersion: autoscaling/v1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: frontend-scaler
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
kind: ReplicaSet
|
||||
name: frontend
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 50
|
||||
@@ -0,0 +1,15 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: pi
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: ReplicaSet
|
||||
metadata:
|
||||
name: my-repset
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
pod-is-for: garbage-collection-example
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
pod-is-for: garbage-collection-example
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.7.9
|
||||
ports:
|
||||
- containerPort: 80
|
||||
@@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
@@ -0,0 +1,331 @@
|
||||
---
|
||||
approvers:
|
||||
- erictune
|
||||
title: Init 容器
|
||||
redirect_from:
|
||||
- "/docs/concepts/abstractions/init-containers/"
|
||||
- "/docs/concepts/abstractions/init-containers.html"
|
||||
- "/docs/user-guide/pods/init-container/"
|
||||
- "/docs/user-guide/pods/init-container.html"
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
本页提供了 Init 容器的概览,它是一种专用的容器,在应用容器启动之前运行,并包括一些应用镜像中不存在的实用工具和安装脚本。
|
||||
{{% /capture %}}
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
|
||||
这个特性在 1.6 版本已经退出 beta 版本。Init 容器可以在 PodSpec 中同应用的 `containers` 数组一起来指定。
|
||||
beta 注解的值将仍然需要保留,并覆盖 PodSpec 字段值。
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
|
||||
## 理解 Init 容器
|
||||
|
||||
|
||||
|
||||
[Pod](/docs/concepts/abstractions/pod/) 能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的 Init 容器。
|
||||
|
||||
Init 容器与普通的容器非常像,除了如下两点:
|
||||
|
||||
|
||||
|
||||
* 它们总是运行到完成。
|
||||
* 每个都必须在下一个启动之前成功完成。
|
||||
|
||||
|
||||
|
||||
如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 `restartPolicy` 值为 Never,它不会重新启动。
|
||||
|
||||
指定容器为 Init 容器,需要在 PodSpec 中添加 `initContainers` 字段,以 [v1.Container](/docs/api-reference/v1.6/#container-v1-core) 类型对象的 JSON 数组的形式,还有 app 的 `containers` 数组。
|
||||
Init 容器的状态在 `status.initContainerStatuses` 字段中以容器状态数组的格式返回(类似 `status.containerStatuses` 字段)。
|
||||
|
||||
|
||||
|
||||
### 与普通容器的不同之处
|
||||
|
||||
Init 容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。
|
||||
然而,Init 容器对资源请求和限制的处理稍有不同,在下面 [资源](#resources) 处有说明。
|
||||
而且 Init 容器不支持 Readiness Probe,因为它们必须在 Pod 就绪之前运行完成。
|
||||
|
||||
如果为一个 Pod 指定了多个 Init 容器,那些容器会按顺序一次运行一个。
|
||||
每个 Init 容器必须运行成功,下一个才能够运行。
|
||||
当所有的 Init 容器运行完成时,Kubernetes 初始化 Pod 并像平常一样运行应用容器。
|
||||
|
||||
|
||||
|
||||
## Init 容器能做什么?
|
||||
|
||||
因为 Init 容器具有与应用容器分离的单独镜像,它们的启动相关代码具有如下优势:
|
||||
|
||||
* 它们可以包含并运行实用工具,处于安全考虑,是不建议在应用容器镜像中包含这些实用工具的。
|
||||
* 它们可以包含使用工具和定制化代码来安装,但是不能出现在应用镜像中。例如,创建镜像没必要 `FROM` 另一个镜像,只需要在安装过程中使用类似 `sed`、 `awk`、 `python` 或 `dig` 这样的工具。
|
||||
* 应用镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。
|
||||
* 它们使用 Linux Namespace,所以对应用容器具有不同的文件系统视图。因此,它们能够具有访问 Secret 的权限,而应用容器不能够访问。
|
||||
* 它们在应用容器启动之前运行完成,然而应用容器并行运行,所以 Init 容器提供了一种简单的方式来阻塞或延迟应用容器的启动,直到满足了一组先决条件。
|
||||
|
||||
|
||||
|
||||
### 示例
|
||||
|
||||
下面是一些如何使用 Init 容器的想法:
|
||||
|
||||
* 等待一个 Service 完成创建,通过类似如下 shell 命令:
|
||||
|
||||
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1
|
||||
|
||||
* 注册这个 Pod 到远程服务器,通过在命令中调用 API,类似如下:
|
||||
|
||||
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
|
||||
|
||||
* 在启动应用容器之前等一段时间,使用类似 `sleep 60` 的命令。
|
||||
* 克隆 Git 仓库到数据卷。
|
||||
* 将配置值放到配置文件中,运行模板工具为主应用容器动态地生成配置文件。例如,在配置文件中存放 POD_IP 值,并使用 Jinja 生成主应用配置文件。
|
||||
|
||||
更多详细用法示例,可以在 [StatefulSet 文档](/docs/concepts/abstractions/controllers/statefulsets/) 和 [Pod 初始化](/docs/tasks/configure-pod-container/configure-pod-initialization) 中找到。
|
||||
|
||||
|
||||
|
||||
### 使用 Init 容器
|
||||
|
||||
下面是 Kubernetes 1.5 版本 yaml 文件,展示了一个具有 2 个 Init 容器的简单 Pod。
|
||||
第一个等待 `myservice` 启动,第二个等待 `mydb` 启动。
|
||||
一旦这两个 Service 都启动完成,Pod 将开始启动。
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
annotations:
|
||||
pod.beta.kubernetes.io/init-containers: '[
|
||||
{
|
||||
"name": "init-myservice",
|
||||
"image": "busybox",
|
||||
"command": ["sh", "-c", "until nslookup myservice; do echo waiting for myservice; sleep 2; done;"]
|
||||
},
|
||||
{
|
||||
"name": "init-mydb",
|
||||
"image": "busybox",
|
||||
"command": ["sh", "-c", "until nslookup mydb; do echo waiting for mydb; sleep 2; done;"]
|
||||
}
|
||||
]'
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
image: busybox
|
||||
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
|
||||
```
|
||||
|
||||
|
||||
|
||||
这是 Kubernetes 1.6 版本的新语法,尽管老的 annotation 语法仍然可以使用。我们已经把 Init 容器的声明移到 `spec` 中:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
image: busybox
|
||||
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
|
||||
initContainers:
|
||||
- name: init-myservice
|
||||
image: busybox
|
||||
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
|
||||
- name: init-mydb
|
||||
image: busybox
|
||||
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
|
||||
```
|
||||
|
||||
|
||||
|
||||
1.5 版本的语法在 1.6 版本仍然可以使用,但是我们推荐使用 1.6 版本的新语法。
|
||||
在 Kubernetes 1.6 版本中,Init 容器在 API 中新建了一个字段。
|
||||
虽然期望使用 beta 版本的 annotation,但在未来发行版将会被废弃掉。
|
||||
|
||||
下面的 yaml 文件展示了 `mydb` 和 `myservice` 两个 Service:
|
||||
|
||||
```
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: myservice
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 9376
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mydb
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 9377
|
||||
```
|
||||
|
||||
|
||||
|
||||
这个 Pod 可以使用下面的命令进行启动和调试:
|
||||
|
||||
```
|
||||
$ kubectl create -f myapp.yaml
|
||||
pod "myapp-pod" created
|
||||
$ kubectl get -f myapp.yaml
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
myapp-pod 0/1 Init:0/2 0 6m
|
||||
$ kubectl describe -f myapp.yaml
|
||||
Name: myapp-pod
|
||||
Namespace: default
|
||||
[...]
|
||||
Labels: app=myapp
|
||||
Status: Pending
|
||||
[...]
|
||||
Init Containers:
|
||||
init-myservice:
|
||||
[...]
|
||||
State: Running
|
||||
[...]
|
||||
init-mydb:
|
||||
[...]
|
||||
State: Waiting
|
||||
Reason: PodInitializing
|
||||
Ready: False
|
||||
[...]
|
||||
Containers:
|
||||
myapp-container:
|
||||
[...]
|
||||
State: Waiting
|
||||
Reason: PodInitializing
|
||||
Ready: False
|
||||
[...]
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.201
|
||||
16s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image "busybox"
|
||||
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox"
|
||||
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined]
|
||||
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634
|
||||
$ kubectl logs myapp-pod -c init-myservice # Inspect the first init container
|
||||
$ kubectl logs myapp-pod -c init-mydb # Inspect the second init container
|
||||
```
|
||||
|
||||
|
||||
|
||||
一旦我们启动了 `mydb` 和 `myservice` 这两个 Service,我们能够看到 Init 容器完成,并且 `myapp-pod` 被创建:
|
||||
|
||||
```
|
||||
$ kubectl create -f services.yaml
|
||||
service "myservice" created
|
||||
service "mydb" created
|
||||
$ kubectl get -f myapp.yaml
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
myapp-pod 1/1 Running 0 9m
|
||||
```
|
||||
|
||||
|
||||
|
||||
这个例子非常简单,但是应该能够为创建自己的 Init 容器提供一些启发。
|
||||
|
||||
|
||||
|
||||
## 具体行为
|
||||
|
||||
在 Pod 启动过程中,Init 容器会按顺序在网络和数据卷初始化之后启动。
|
||||
每个容器必须在下一个容器启动之前成功退出。
|
||||
如果由于运行时或失败退出,导致容器启动失败,它会根据 Pod 的 `restartPolicy` 指定的策略进行重试。
|
||||
然而,如果 Pod 的 `restartPolicy` 设置为 Always,Init 容器失败时会使用 `RestartPolicy` 策略。
|
||||
|
||||
|
||||
|
||||
在所有的 Init 容器没有成功之前,Pod 将不会变成 `Ready` 状态。
|
||||
Init 容器的端口将不会在 Service 中进行聚集。
|
||||
正在初始化中的 Pod 处于 `Pending` 状态,但应该会将条件 `Initializing` 设置为 true。
|
||||
|
||||
如果 Pod [重启](#pod-restart-reasons),所有 Init 容器必须重新执行。
|
||||
|
||||
对 Init 容器 spec 的修改,被限制在容器 image 字段中。
|
||||
更改 Init 容器的 image 字段,等价于重启该 Pod。
|
||||
|
||||
|
||||
|
||||
因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的。
|
||||
特别地,被写到 `EmptyDirs` 中文件的代码,应该对输出文件可能已经存在做好准备。
|
||||
|
||||
Init 容器具有应用容器的所有字段。
|
||||
然而 Kubernetes 禁止使用 `readinessProbe`,因为 Init 容器不能够定义不同于完成(completion)的就绪(readiness)。
|
||||
这会在验证过程中强制执行。
|
||||
|
||||
|
||||
|
||||
在 Pod 上使用 `activeDeadlineSeconds`,在容器上使用 `livenessProbe`,这样能够避免 Init 容器一直失败。
|
||||
这就为 Init 容器活跃设置了一个期限。
|
||||
|
||||
在 Pod 中的每个 app 和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误。
|
||||
|
||||
|
||||
|
||||
### 资源
|
||||
|
||||
为 Init 容器指定顺序和执行逻辑,下面对资源使用的规则将被应用:
|
||||
|
||||
|
||||
|
||||
* 在所有 Init 容器上定义的,任何特殊资源请求或限制的最大值,是 *有效初始请求/限制*
|
||||
* Pod 对资源的 *有效请求/限制* 要高于:
|
||||
* 所有应用容器对某个资源的请求/限制之和
|
||||
* 对某个资源的有效初始请求/限制
|
||||
* 基于有效请求/限制完成调度,这意味着 Init 容器能够为初始化预留资源,这些资源在 Pod 生命周期过程中并没有被使用。
|
||||
* Pod 的 *有效 QoS 层*,是 Init 容器和应用容器相同的 QoS 层。
|
||||
|
||||
|
||||
|
||||
基于有效 Pod 请求和限制来应用配额和限制。
|
||||
Pod 级别的 cgroups 是基于有效 Pod 请求和限制,和调度器相同。
|
||||
|
||||
|
||||
|
||||
### Pod 重启的原因
|
||||
|
||||
Pod 能够重启,会导致 Init 容器重新执行,主要有如下几个原因:
|
||||
|
||||
* 用户更新 PodSpec 导致 Init 容器镜像发生改变。应用容器镜像的变更只会重启应用容器。
|
||||
* Pod 基础设施容器被重启。这不多见,但某些具有 root 权限可访问 Node 的人可能会这样做。
|
||||
* 当 `restartPolicy` 设置为 Always,Pod 中所有容器会终止,强制重启,由于垃圾收集导致 Init 容器完成的记录丢失。
|
||||
|
||||
|
||||
|
||||
## 支持与兼容性
|
||||
|
||||
Apiserver 版本为 1.6 或更高版本的集群,通过使用 `spec.initContainers` 字段来支持 Init 容器。
|
||||
之前的版本可以使用 alpha 和 beta 注解支持 Init 容器。
|
||||
`spec.initContainers` 字段也被加入到 alpha 和 beta 注解中,所以 Kubernetes 1.3.0 版本或更高版本可以执行 Init 容器,并且 1.6 版本的 apiserver 能够安全的回退到 1.5.x 版本,而不会使存在的已创建 Pod 失去 Init 容器的功能。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
|
||||
|
||||
* [创建具有 Init 容器的 Pod](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container)
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
---
|
||||
title: Pod 的生命周期
|
||||
redirect_from:
|
||||
- "/docs/user-guide/pod-states/"
|
||||
- "/docs/user-guide/pod-states.html"
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< comment >}}Updated: 4/14/2015{{< /comment >}}
|
||||
{{< comment >}}Edited and moved to Concepts section: 2/2/17{{< /comment >}}
|
||||
|
||||
该页面将描述 Pod 的生命周期。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Pod phase
|
||||
|
||||
Pod 的 `status` 定义在 [PodStatus](/docs/resources-reference/v1.7/#podstatus-v1-core) 对象中,其中有一个 `phase` 字段。
|
||||
|
||||
Pod 的运行阶段(phase)是 Pod 在其生命周期中的简单宏观概述。该阶段并不是对容器或 Pod 的综合汇总,也不是为了做为综合状态机。
|
||||
|
||||
Pod 相位的数量和含义是严格指定的。除了本文档中列举的内容外,不应该再假定 Pod 有其他的 `phase` 值。
|
||||
|
||||
下面是 `phase` 可能的值:
|
||||
|
||||
- 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
|
||||
- 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
|
||||
- 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
|
||||
- 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
|
||||
- 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
|
||||
|
||||
## Pod 状态
|
||||
|
||||
Pod 有一个 PodStatus 对象,其中包含一个 [PodCondition](/docs/resources-reference/v1.7/#podcondition-v1-core) 数组。 PodCondition 数组的每个元素都有一个 `type` 字段和一个 `status` 字段。`type` 字段是字符串,可能的值有 PodScheduled、Ready、Initialized 和 Unschedulable。`status` 字段是一个字符串,可能的值有 True、False 和 Unknown。
|
||||
|
||||
## 容器探针
|
||||
|
||||
[探针](/docs/resources-reference/v1.7/#probe-v1-core) 是由 [kubelet](/docs/admin/kubelet/) 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的 [Handler](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#Handler)。有三种类型的处理程序:
|
||||
|
||||
- [ExecAction](/docs/resources-reference/v1.7/#execaction-v1-core):在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
|
||||
- [TCPSocketAction](/docs/resources-reference/v1.7/#tcpsocketaction-v1-core):对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
|
||||
- [HTTPGetAction](/docs/resources-reference/v1.7/#httpgetaction-v1-core):对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
|
||||
|
||||
每次探测都将获得以下三种结果之一:
|
||||
|
||||
- 成功:容器通过了诊断。
|
||||
- 失败:容器未通过诊断。
|
||||
- 未知:诊断失败,因此不会采取任何行动。
|
||||
|
||||
Kubelet 可以选择是否执行在容器上运行的两种探针执行和做出反应:
|
||||
|
||||
- `livenessProbe`:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 [重启策略](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) 的影响。如果容器不提供存活探针,则默认状态为 `Success`。
|
||||
- `readinessProbe`:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 `Failure`。如果容器不提供就绪探针,则默认状态为 `Success`。
|
||||
|
||||
### 该什么时候使用存活(liveness)和就绪(readiness)探针?
|
||||
|
||||
如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活探针; kubelet 将根据 Pod 的`restartPolicy` 自动执行正确的操作。
|
||||
|
||||
如果您希望容器在探测失败时被杀死并重新启动,那么请指定一个存活探针,并指定`restartPolicy` 为 Always 或 OnFailure。
|
||||
|
||||
如果要仅在探测成功时才开始向 Pod 发送流量,请指定就绪探针。在这种情况下,就绪探针可能与存活探针相同,但是 spec 中的就绪探针的存在意味着 Pod 将在没有接收到任何流量的情况下启动,并且只有在探针探测成功后才开始接收流量。
|
||||
|
||||
如果您希望容器能够自行维护,您可以指定一个就绪探针,该探针检查与存活探针不同的端点。
|
||||
|
||||
请注意,如果您只想在 Pod 被删除时能够排除请求,则不一定需要使用就绪探针;在删除 Pod 时,Pod 会自动将自身置于未完成状态,无论就绪探针是否存在。当等待 Pod 中的容器停止时,Pod 仍处于未完成状态。
|
||||
|
||||
## Pod 和容器状态
|
||||
|
||||
有关 Pod 容器状态的详细信息,请参阅 [PodStatus](/docs/resources-reference/v1.7/#podstatus-v1-core) 和 [ContainerStatus](/docs/resources-reference/v1.7/#containerstatus-v1-core)。请注意,报告的 Pod 状态信息取决于当前的 [ContainerState](/docs/resources-reference/v1.7/#containerstatus-v1-core)。
|
||||
|
||||
## 重启策略
|
||||
|
||||
PodSpec 中有一个 `restartPolicy` 字段,可能的值为 Always、OnFailure 和 Never。默认为 Always。 `restartPolicy` 适用于 Pod 中的所有容器。`restartPolicy` 仅指通过同一节点上的 kubelet 重新启动容器。失败的容器由 kubelet 以五分钟为上限的指数退避延迟(10秒,20秒,40秒...)重新启动,并在成功执行十分钟后重置。如 [Pod 文档](/docs/user-guide/pods/#durability-of-pods-or-lack-thereof) 中所述,一旦绑定到一个节点,Pod 将永远不会重新绑定到另一个节点。
|
||||
|
||||
## Pod 的生命
|
||||
|
||||
一般来说,Pod 不会消失,直到人为销毁他们。这可能是一个人或控制器。这个规则的唯一例外是成功或失败的 `phase` 超过一段时间(由 master 确定)的Pod将过期并被自动销毁。
|
||||
|
||||
有三种可用的控制器:
|
||||
|
||||
- 使用 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) 运行预期会终止的 Pod,例如批量计算。Job 仅适用于重启策略为 `OnFailure` 或 `Never` 的 Pod。
|
||||
|
||||
|
||||
- 对预期不会终止的 Pod 使用 [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/)、[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) 和 [Deployment](/docs/concepts/workloads/controllers/deployment/) ,例如 Web 服务器。 ReplicationController 仅适用于具有 `restartPolicy` 为 Always 的 Pod。
|
||||
- 提供特定于机器的系统服务,使用 [DaemonSet](/docs/concepts/workloads/controllers/daemonset/) 为每台机器运行一个 Pod 。
|
||||
|
||||
所有这三种类型的控制器都包含一个 PodTemplate。建议创建适当的控制器,让它们来创建 Pod,而不是直接自己创建 Pod。这是因为单独的 Pod 在机器故障的情况下没有办法自动复原,而控制器却可以。
|
||||
|
||||
如果节点死亡或与集群的其余部分断开连接,则 Kubernetes 将应用一个策略将丢失节点上的所有 Pod 的 `phase` 设置为 Failed。
|
||||
|
||||
## 示例
|
||||
|
||||
### 高级 liveness 探针示例
|
||||
|
||||
存活探针由 kubelet 来执行,因此所有的请求都在 kubelet 的网络命名空间中进行。
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
test: liveness
|
||||
name: liveness-http
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- /server
|
||||
image: k8s.gcr.io/liveness
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
# when "host" is not defined, "PodIP" will be used
|
||||
# host: my-host
|
||||
# when "scheme" is not defined, "HTTP" scheme will be used. Only "HTTP" and "HTTPS" are allowed
|
||||
# scheme: HTTPS
|
||||
path: /healthz
|
||||
port: 8080
|
||||
httpHeaders:
|
||||
- name: X-Custom-Header
|
||||
value: Awesome
|
||||
initialDelaySeconds: 15
|
||||
timeoutSeconds: 1
|
||||
name: liveness
|
||||
```
|
||||
|
||||
### 状态示例
|
||||
|
||||
- Pod 中只有一个容器并且正在运行。容器成功退出。
|
||||
- 记录完成事件。
|
||||
- 如果 `restartPolicy` 为:
|
||||
- Always:重启容器;Pod `phase` 仍为 Running。
|
||||
- OnFailure:Pod `phase` 变成 Succeeded。
|
||||
- Never:Pod `phase` 变成 Succeeded。
|
||||
- Pod 中只有一个容器并且正在运行。容器退出失败。
|
||||
- 记录失败事件。
|
||||
- 如果 `restartPolicy` 为:
|
||||
- Always:重启容器;Pod `phase` 仍为 Running。
|
||||
- OnFailure:重启容器;Pod `phase` 仍为 Running。
|
||||
- Never:Pod `phase` 变成 Failed。
|
||||
- Pod 中有两个容器并且正在运行。有一个容器退出失败。
|
||||
- 记录失败事件。
|
||||
- 如果 restartPolicy 为:
|
||||
- Always:重启容器;Pod `phase` 仍为 Running。
|
||||
- OnFailure:重启容器;Pod `phase` 仍为 Running。
|
||||
- Never:不重启容器;Pod `phase` 仍为 Running。
|
||||
- 如果有一个容器没有处于运行状态,并且两个容器退出:
|
||||
- 记录失败事件。
|
||||
- 如果 `restartPolicy` 为:
|
||||
- Always:重启容器;Pod `phase` 仍为 Running。
|
||||
- OnFailure:重启容器;Pod `phase` 仍为 Running。
|
||||
- Never:Pod `phase` 变成 Failed。
|
||||
- Pod 中只有一个容器并处于运行状态。容器运行时内存超出限制:
|
||||
- 容器以失败状态终止。
|
||||
- 记录 OOM 事件。
|
||||
- 如果 `restartPolicy` 为:
|
||||
- Always:重启容器;Pod `phase` 仍为 Running。
|
||||
- OnFailure:重启容器;Pod `phase` 仍为 Running。
|
||||
- Never: 记录失败事件;Pod `phase` 仍为 Failed。
|
||||
- Pod 正在运行,磁盘故障:
|
||||
- 杀掉所有容器。
|
||||
- 记录适当事件。
|
||||
- Pod `phase` 变成 Failed。
|
||||
- 如果使用控制器来运行,Pod 将在别处重建。
|
||||
- Pod 正在运行,其节点被分段。
|
||||
- 节点控制器等待直到超时。
|
||||
- 节点控制器将 Pod `phase` 设置为 Failed。
|
||||
- 如果是用控制器来运行,Pod 将在别处重建。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
approvers:
|
||||
- jessfraz
|
||||
title: Pod Preset
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
本文提供了 PodPreset 的概述。 在 pod 创建时,用户可以使用 `podpreset` 对象将特定信息注入
|
||||
pod 中,这些信息可以包括 secret、 卷、卷挂载和环境变量。
|
||||
{{% /capture %}}
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
{{% capture body %}}
|
||||
## 理解 Pod Preset
|
||||
|
||||
`Pod Preset` 是一种 API 资源,在 pod 创建时,用户可以用它将额外的运行时需求信息注入 pod。
|
||||
使用[标签选择器(label selector)](/docs/concepts/overview/working-with-objects/labels/#label-selectors)来指定 Pod Preset 所适用的 pod。
|
||||
|
||||
使用 Pod Preset 使得 pod 模板编写者不必显式地为每个 pod 设置信息。
|
||||
这样,使用特定服务的 pod 模板编写者不需要了解该服务的所有细节。
|
||||
|
||||
了解更多的相关背景信息,请参考 [ PodPreset 设计提案](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md)。
|
||||
|
||||
## PodPreset 如何工作
|
||||
|
||||
Kubernetes 提供了准入控制器 (`PodPreset`),该控制器被启用时,会将 Pod Preset
|
||||
应用于接收到的 pod 创建请求中。
|
||||
当出现 pod 创建请求时,系统会执行以下操作:
|
||||
|
||||
1. 检索所有可用 `PodPresets` 。
|
||||
1. 检查 `PodPreset` 的标签选择器与要创建的 pod 的标签是否匹配。
|
||||
1. 尝试合并 `PodPreset` 中定义的各种资源,并注入要创建的 pod。
|
||||
1. 发生错误时抛出事件,该事件记录了 pod 信息合并错误,同时在 _不注入_ `PodPreset` 信息的情况下创建 pod。
|
||||
1. 为改动的 pod spec 添加注解,来表明它被 `PodPreset` 所修改。 注解形如:
|
||||
`podpreset.admission.kubernetes.io/podpreset-<pod-preset name>": "<resource version>"`。
|
||||
|
||||
一个 Pod 可能不与任何 Pod Preset 匹配,也可能匹配多个 Pod Preset。 同时,一个 `PodPreset`
|
||||
可能不应用于任何 Pod,也可能应用于多个 Pod。 当 `PodPreset` 应用于一个或多个 Pod 时,Kubernetes
|
||||
修改 pod spec。 对于 `Env`、 `EnvFrom` 和 `VolumeMounts` 的改动, Kubernetes 修改 pod
|
||||
中所有容器的规格,对于卷的改动,Kubernetes 修改 Pod spec。
|
||||
|
||||
{{< note >}}
|
||||
**注意:** Pod Preset 能够在适当的时候修改 Pod spec 的 `spec.containers` 字段,
|
||||
但是不会应用于 `initContainers` 字段。
|
||||
{{< /note >}}
|
||||
|
||||
### 为特定 Pod 禁用 Pod Preset
|
||||
|
||||
在一些情况下,用户不希望 pod 被 pod preset 所改动,这时,用户可以在 pod spec 中添加形如
|
||||
`podpreset.admission.kubernetes.io/exclude: "true"` 的注解。
|
||||
|
||||
## 启用 Pod Preset
|
||||
|
||||
为了在集群中使用 Pod Preset,必须确保以下几点:
|
||||
|
||||
1. 已启用 api 类型 `settings.k8s.io/v1alpha1/podpreset`。 这可以通过在 API 服务器的
|
||||
`--runtime-config` 配置项中包含 `settings.k8s.io/v1alpha1=true` 来实现。
|
||||
1. 已启用准入控制器 `PodPreset`。 启用的一种方式是在 API 服务器的 `--admission-control`
|
||||
配置项中包含 `PodPreset` 。
|
||||
1. 已经通过在相应的名字空间中创建 `PodPreset` 对象,定义了 Pod preset。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
* [使用 PodPreset 将信息注入 Pods](/docs/tasks/inject-data-application/podpreset/)
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user