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:
Zach Corleissen
2018-10-12 14:25:01 -07:00
committed by k8s-ci-robot
parent 753f57f0e6
commit abcee2dccd
316 changed files with 9227 additions and 169 deletions
@@ -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