Switch language name 'zh' to 'zh-cn'

This is the first step to rename 'zh' to 'zh-cn'. There are several reasons why we rename the language name.

- The upstream docsy theme changed the language name, leading to many warnings during site build;
  The side-effect is that the i18n strings are no longer working.
- We believe renaming the language is the right thing to do, because this move can make room for other variants of Chinese language, such as 'zh-tw', 'zh-sg' etc.

There would be several follow-ups to this PR, such as fixing the intra-site links, adding redirects etc.

We will lock up changes to zh/zh-cn pages for the moment, until this one gets in.

This PR is based on commit cdad0a7342.
This commit is contained in:
Qiming Teng
2022-06-10 20:25:27 +08:00
parent 3d345b1816
commit c52818c03d
1347 changed files with 8 additions and 6 deletions
@@ -0,0 +1,4 @@
---
title: "工作负载资源"
weight: 20
---
@@ -0,0 +1,345 @@
---
title: CronJob
content_type: concept
weight: 80
---
<!--
title: CronJob
content_type: concept
weight: 80
-->
<!-- overview -->
{{< feature-state for_k8s_version="v1.21" state="stable" >}}
<!--
A _CronJob_ creates {{< glossary_tooltip term_id="job" text="Jobs" >}} on a repeating schedule.
One CronJob object is like one line of a _crontab_ (cron table) file. It runs a job periodically
on a given schedule, written in [Cron](https://en.wikipedia.org/wiki/Cron) format.
-->
_CronJob_ 创建基于时隔重复调度的 {{< glossary_tooltip term_id="job" text="Jobs" >}}。
一个 CronJob 对象就像 _crontab_ (cron table) 文件中的一行。
它用 [Cron](https://en.wikipedia.org/wiki/Cron) 格式进行编写,
并周期性地在给定的调度时间执行 Job。
<!--
All **CronJob** `schedule:` times are based on the timezone of the
If your control plane runs the kube-controller-manager in Pods or bare
containers, the timezone set for the kube-controller-manager container determines the timezone
that the cron job controller uses.
-->
{{< caution >}}
所有 **CronJob**`schedule:` 时间都是基于
{{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}.
的时区。
如果你的控制平面在 Pod 或是裸容器中运行了 kube-controller-manager
那么为该容器所设置的时区将会决定 Cron Job 的控制器所使用的时区。
{{< /caution >}}
<!--
The [v1 CronJob API](/docs/reference/kubernetes-api/workload-resources/cron-job-v1/)
does not officially support setting timezone as explained above.
Setting variables such as `CRON_TZ` or `TZ` is not officially supported by the Kubernetes project.
`CRON_TZ` or `TZ` is an implementation detail of the internal library being used
for parsing and calculating the next Job creation time. Any usage of it is not
recommended in a production cluster.
-->
{{< caution >}}
如 [v1 CronJob API](/zh/docs/reference/kubernetes-api/workload-resources/cron-job-v1/) 所述,官方并不支持设置时区。
Kubernetes 项目官方并不支持设置如 `CRON_TZ` 或者 `TZ` 等变量。
`CRON_TZ` 或者 `TZ` 是用于解析和计算下一个 Job 创建时间所使用的内部库中一个实现细节。
不建议在生产集群中使用它。
{{< /caution>}}
<!--
When creating the manifest for a CronJob resource, make sure the name you provide
is a valid [DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
The name must be no longer than 52 characters. This is because the CronJob controller will automatically
append 11 characters to the job name provided and there is a constraint that the
maximum length of a Job name is no more than 63 characters.
-->
为 CronJob 资源创建清单时,请确保所提供的名称是一个合法的
[DNS 子域名](/zh/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
名称不能超过 52 个字符。
这是因为 CronJob 控制器将自动在提供的 Job 名称后附加 11 个字符,并且存在一个限制,
即 Job 名称的最大长度不能超过 63 个字符。
<!-- body -->
<!--
## CronJob
CronJobs are meant for performing regular scheduled actions such as backups,
report generation, and so on. Each of those tasks should be configured to recur
indefinitely (for example: once a day / week / month); you can define the point
in time within that interval when the job should start.
-->
## CronJob
CronJob 用于执行周期性的动作,例如备份、报告生成等。
这些任务中的每一个都应该配置为周期性重复的(例如:每天/每周/每月一次);
你可以定义任务开始执行的时间间隔。
<!--
### Example
This example CronJob manifest prints the current time and a hello message every minute:
-->
### 示例
下面的 CronJob 示例清单会在每分钟打印出当前时间和问候消息:
{{< codenew file="application/job/cronjob.yaml" >}}
[使用 CronJob 运行自动化任务](/zh/docs/tasks/job/automated-tasks-with-cron-jobs/)
一文会为你详细讲解此例。
<!--
### Cron schedule syntax
-->
### Cron 时间表语法
```
# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 月的某天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 周的某天 (0 - 6)(周日到周一;在某些系统上,7 也是星期日)
# │ │ │ │ │ 或者是 sunmontuewebthufrisat
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
```
<!--
| Entry | Description | Equivalent to |
| ------------- | ------------- |------------- |
| @yearly (or @annually) | Run once a year at midnight of 1 January | 0 0 1 1 * |
| @monthly | Run once a month at midnight of the first day of the month | 0 0 1 * * |
| @weekly | Run once a week at midnight on Sunday morning | 0 0 * * 0 |
| @daily (or @midnight) | Run once a day at midnight | 0 0 * * * |
| @hourly | Run once an hour at the beginning of the hour | 0 * * * * |
-->
| 输入 | 描述 | 相当于 |
| ------------- | ------------- |------------- |
| @yearly (or @annually) | 每年 1 月 1 日的午夜运行一次 | 0 0 1 1 * |
| @monthly | 每月第一天的午夜运行一次 | 0 0 1 * * |
| @weekly | 每周的周日午夜运行一次 | 0 0 * * 0 |
| @daily (or @midnight) | 每天午夜运行一次 | 0 0 * * * |
| @hourly | 每小时的开始一次 | 0 * * * * |
<!--
For example, the line below states that the task must be started every Friday at midnight, as well as on the 13th of each month at midnight:
-->
例如,下面这行指出必须在每个星期五的午夜以及每个月 13 号的午夜开始任务:
`0 0 13 * 5`
<!--
To generate CronJob schedule expressions, you can also use web tools like [crontab.guru](https://crontab.guru/).
-->
要生成 CronJob 时间表表达式,你还可以使用 [crontab.guru](https://crontab.guru/) 之类的 Web 工具。
<!--
## Time zones
For CronJobs with no time zone specified, the kube-controller-manager interprets schedules relative to its local time zone.
{{< feature-state for_k8s_version="v1.24" state="alpha" >}}
If you enable the `CronJobTimeZone` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/),
you can specify a time zone for a CronJob (if you don't enable that feature gate, or if you are using a version of
Kubernetes that does not have experimental time zone support, all CronJobs in your cluster have an unspecified
timezone).
When you have the feature enabled, you can set `spec.timeZone` to the name of a valid [time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) name. For example, setting
`spec.timeZone: "Etc/UTC"` instructs Kubernetes to interpret the schedule relative to Coordinated Universal Time.
A time zone database from the Go standard library is included in the binaries and used as a fallback in case an external database is not available on the system.
-->
## 时区 {#time-zones}
对于没有指定时区的 CronJobkube-controller-manager 基于本地时区解释排期表(Schedule)。
{{< feature-state for_k8s_version="v1.24" state="alpha" >}}
如果启用了 `CronJobTimeZone` [特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)
你可以为 CronJob 指定一个时区(如果你没有启用该特性门控,或者你使用的是不支持试验性时区功能的
Kubernetes 版本,集群中所有 CronJob 的时区都是未指定的)。
启用该特性后,你可以将 `spec.timeZone`
设置为有效[时区](https://zh.wikipedia.org/zh-hant/%E6%97%B6%E5%8C%BA%E4%BF%A1%E6%81%AF%E6%95%B0%E6%8D%AE%E5%BA%93s)名称。
例如,设置 `spec.timeZone: "Etc/UTC"` 指示 Kubernetes 采用 UTC 来解释排期表。
Go 标准库中的时区数据库包含在二进制文件中,并用作备用数据库,以防系统上没有可用的外部数据库。
<!--
## Time zones
For CronJobs with no time zone specified, the kube-controller-manager interprets schedules relative to its local time zone.
-->
## 时区 {#time-zones}
对于没有指定时区的 CronJobkube-controller-manager 会根据其本地时区来解释其排期表(schedule)。
{{< feature-state for_k8s_version="v1.24" state="alpha" >}}
<!--
If you enable the `CronJobTimeZone` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/),
you can specify a time zone for a CronJob (if you don't enable that feature gate, or if you are using a version of
Kubernetes that does not have experimental time zone support, all CronJobs in your cluster have an unspecified
timezone).
-->
如果启用 `CronJobTimeZone` [特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)
你可以为 CronJob 指定时区(如果你不启用该特性门控,或者如果你使用的 Kubernetes 版本不支持实验中的时区特性,
则集群中的所有 CronJob 都属于未指定时区)。
<!--
When you have the feature enabled, you can set `spec.timeZone` to the name of a valid [time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) name. For example, setting
`spec.timeZone: "Etc/UTC"` instructs Kubernetes to interpret the schedule relative to Coordinated Universal Time.
A time zone database from the Go standard library is included in the binaries and used as a fallback in case an external database is not available on the system.
-->
当你启用该特性时,你可以将 `spec.timeZone` 设置为有效的[时区](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)名称。
例如,设置 `spec.timeZone: "Etc/UTC"` 表示 Kubernetes
使用协调世界时(Coordinated Universal Time)进行解释排期表。
Go 标准库中的时区数据库包含在二进制文件中,并用作备用数据库,以防系统上没有外部数据库可用。
<!--
## CronJob Limitations
A cron job creates a job object _about_ once per execution time of its schedule. We say "about" because there
are certain circumstances where two jobs might be created, or no job might be created. We attempt to make these rare,
but do not completely prevent them. Therefore, jobs should be _idempotent_.
-->
## CronJob 限制 {#cron-job-limitations}
CronJob 根据其计划编排,在每次该执行任务的时候大约会创建一个 Job。
我们之所以说 "大约",是因为在某些情况下,可能会创建两个 Job,或者不会创建任何 Job。
我们试图使这些情况尽量少发生,但不能完全杜绝。因此,Job 应该是 _幂等的_
<!--
If `startingDeadlineSeconds` is set to a large value or left unset (the default)
and if `concurrencyPolicy` is set to `Allow`, the jobs will always run
at least once.
-->
如果 `startingDeadlineSeconds` 设置为很大的数值或未设置(默认),并且
`concurrencyPolicy` 设置为 `Allow`,则作业将始终至少运行一次。
{{< caution >}}
<!--
If `startingDeadlineSeconds` is set to a value less than 10 seconds, the CronJob may not be scheduled. This is because the CronJob controller checks things every 10 seconds.
-->
如果 `startingDeadlineSeconds` 的设置值低于 10 秒钟,CronJob 可能无法被调度。
这是因为 CronJob 控制器每 10 秒钟执行一次检查。
{{< /caution >}}
<!--
For every CronJob, the CronJob {{< glossary_tooltip term_id="controller" >}} checks how many schedules it missed in the duration from its last scheduled time until now. If there are more than 100 missed schedules, then it does not start the job and logs the error
-->
对于每个 CronJobCronJob {{< glossary_tooltip term_text="控制器" term_id="controller" >}}
检查从上一次调度的时间点到现在所错过了调度次数。如果错过的调度次数超过 100 次,
那么它就不会启动这个任务,并记录这个错误:
````
Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.
````
<!--
It is important to note that if the `startingDeadlineSeconds` field is set (not `nil`), the controller counts how many missed jobs occurred from the value of `startingDeadlineSeconds` until now rather than from the last scheduled time until now. For example, if `startingDeadlineSeconds` is `200`, the controller counts how many missed jobs occurred in the last 200 seconds.
-->
需要注意的是,如果 `startingDeadlineSeconds` 字段非空,则控制器会统计从
`startingDeadlineSeconds` 设置的值到现在而不是从上一个计划时间到现在错过了多少次 Job。
例如,如果 `startingDeadlineSeconds` 是 `200`,则控制器会统计在过去 200 秒中错过了多少次 Job。
<!--
A CronJob is counted as missed if it has failed to be created at its scheduled time. For example, If `concurrencyPolicy` is set to `Forbid` and a CronJob was attempted to be scheduled when there was a previous schedule still running, then it would count as missed.
-->
如果未能在调度时间内创建 CronJob,则计为错过。
例如,如果 `concurrencyPolicy` 被设置为 `Forbid`,并且当前有一个调度仍在运行的情况下,
试图调度的 CronJob 将被计算为错过。
<!--
For example, suppose a CronJob is set to schedule a new Job every one minute beginning at `08:30:00`, and its
`startingDeadlineSeconds` field is not set. If the CronJob controller happens to
be down from `08:29:00` to `10:21:00`, the job will not start as the number of missed jobs which missed their schedule is greater than 100.
-->
例如,假设一个 CronJob 被设置为从 `08:30:00` 开始每隔一分钟创建一个新的 Job,
并且它的 `startingDeadlineSeconds` 字段未被设置。如果 CronJob 控制器从
`08:29:00` 到 `10:21:00` 终止运行,则该 Job 将不会启动,因为其错过的调度
次数超过了 100。
<!--
To illustrate this concept further, suppose a CronJob is set to schedule a new Job every one minute beginning at `08:30:00`, and its
`startingDeadlineSeconds` is set to 200 seconds. If the CronJob controller happens to
be down for the same period as the previous example (`08:29:00` to `10:21:00`,) the Job will still start at 10:22:00. This happens as the controller now checks how many missed schedules happened in the last 200 seconds (ie, 3 missed schedules), rather than from the last scheduled time until now.
-->
为了进一步阐述这个概念,假设将 CronJob 设置为从 `08:30:00` 开始每隔一分钟创建一个新的 Job,
并将其 `startingDeadlineSeconds` 字段设置为 200 秒。
如果 CronJob 控制器恰好在与上一个示例相同的时间段(`08:29:00` 到 `10:21:00`)终止运行,
则 Job 仍将从 `10:22:00` 开始。
造成这种情况的原因是控制器现在检查在最近 200 秒(即 3 个错过的调度)中发生了多少次错过的
Job 调度,而不是从现在为止的最后一个调度时间开始。
<!--
The CronJob is only responsible for creating Jobs that match its schedule, and
the Job in turn is responsible for the management of the Pods it represents.
-->
CronJob 仅负责创建与其调度时间相匹配的 Job,而 Job 又负责管理其代表的 Pod。
<!--
## Controller version {#new-controller}
Starting with Kubernetes v1.21 the second version of the CronJob controller
is the default implementation. To disable the default CronJob controller
and use the original CronJob controller instead, one pass the `CronJobControllerV2`
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
flag to the {{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}},
and set this flag to `false`. For example:
-->
## 控制器版本 {#new-controller}
从 Kubernetes v1.21 版本开始,CronJob 控制器的第二个版本被用作默认实现。
要禁用此默认 CronJob 控制器而使用原来的 CronJob 控制器,请在
{{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}
中设置[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)
`CronJobControllerV2`,将此标志设置为 `false`。例如:
```
--feature-gates="CronJobControllerV2=false"
```
## {{% heading "whatsnext" %}}
<!--
* Learn about [Pods](/docs/concepts/workloads/pods/) and
[Jobs](/docs/concepts/workloads/controllers/job/), two concepts
that CronJobs rely upon.
* Read about the [format](https://pkg.go.dev/github.com/robfig/cron/v3#hdr-CRON_Expression_Format)
of CronJob `.spec.schedule` fields.
* For instructions on creating and working with CronJobs, and for an example
of a CronJob manifest,
see [Running automated tasks with CronJobs](/docs/tasks/job/automated-tasks-with-cron-jobs/).
* For instructions to clean up failed or completed jobs automatically,
see [Clean up Jobs automatically](/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically)
* `CronJob` is part of the Kubernetes REST API.
Read the {{< api-reference page="workload-resources/cron-job-v1" >}}
object definition to understand the API for Kubernetes cron jobs.
-->
* 了解 CronJob 所依赖的 [Pods](/zh/docs/concepts/workloads/pods/) 与 [Job](/zh/docs/concepts/workloads/controllers/job/) 的概念。
* 阅读 CronJob `.spec.schedule` 字段的[格式](https://pkg.go.dev/github.com/robfig/cron/v3#hdr-CRON_Expression_Format)。
* 有关创建和使用 CronJob 的说明及示例规约文件,请参见
[使用 CronJob 运行自动化任务](/zh/docs/tasks/job/automated-tasks-with-cron-jobs/)。
* 有关自动清理失败或完成作业的说明,请参阅[自动清理作业](/zh/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically)
* `CronJob` 是 Kubernetes REST API 的一部分,
阅读 {{< api-reference page="workload-resources/cron-job-v1" >}}
对象定义以了解关于该资源的 API。
@@ -0,0 +1,478 @@
---
title: DaemonSet
content_type: concept
weight: 50
---
<!--
title: DaemonSet
content_type: concept
weight: 50
--->
<!-- overview -->
<!--
A _DaemonSet_ ensures that all (or some) Nodes run a copy of a Pod. As nodes are added to the
cluster, Pods are added to them. As nodes are removed from the cluster, those Pods are garbage
collected. Deleting a DaemonSet will clean up the Pods it created.
--->
_DaemonSet_ 确保全部(或者某些)节点上运行一个 Pod 的副本。
当有节点加入集群时, 也会为他们新增一个 Pod 。
当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
<!--
Some typical uses of a DaemonSet are:
- running a cluster storage daemon on every node
- running a logs collection daemon on every node
- running a node monitoring daemon on every node
-->
DaemonSet 的一些典型用法:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
<!--
In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon.
A more complex setup might use multiple DaemonSets for a single type of daemon, but with
different flags and/or different memory and cpu requests for different hardware types.
-->
一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。
一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志,
并且对不同硬件类型具有不同的内存、CPU 要求。
<!-- body -->
<!--
## Writing a DaemonSet Spec
### Create a DaemonSet
-->
## 编写 DaemonSet Spec {#writing-a-daemon-set-spec}
### 创建 DaemonSet {#create-a-daemon-set}
<!--
You can describe a DaemonSet in a YAML file. For example, the `daemonset.yaml` file below
describes a DaemonSet that runs the fluentd-elasticsearch Docker image:
-->
你可以在 YAML 文件中描述 DaemonSet。
例如,下面的 daemonset.yaml 文件描述了一个运行 fluentd-elasticsearch Docker 镜像的 DaemonSet
{{< codenew file="controllers/daemonset.yaml" >}}
<!--
Create a DaemonSet based on the YAML file:
-->
基于 YAML 文件创建 DaemonSet
```
kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml
```
<!--
### Required Fields
As with all other Kubernetes config, a DaemonSet needs `apiVersion`, `kind`, and `metadata` fields. For
general information about working with config files, see
[running stateless applications](/docs/tasks/run-application/run-stateless-application-deployment/)
and [object management using kubectl](/docs/concepts/overview/working-with-objects/object-management/).
The name of a DaemonSet object must be a valid
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
A DaemonSet also needs a
[`.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)
section.
-->
### 必需字段 {#required-fields}
和所有其他 Kubernetes 配置一样,DaemonSet 需要 `apiVersion``kind``metadata` 字段。
有关配置文件的基本信息,参见
[部署应用](/zh/docs/tasks/run-application/run-stateless-application-deployment/)、
[配置容器](/zh/docs/tasks/)和
[使用 kubectl 进行对象管理](/zh/docs/concepts/overview/working-with-objects/object-management/)
文档。
DaemonSet 对象的名称必须是一个合法的
[DNS 子域名](/zh/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)。
DaemonSet 也需要一个 [`.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) 配置段。
<!--
### Pod Template
The `.spec.template` is one of the required fields in `.spec`.
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/#pod-templates).
It has exactly the same schema as a {{< glossary_tooltip text="Pod" term_id="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 DaemonSet has to specify appropriate
labels (see [pod selector](#pod-selector)).
A Pod Template in a DaemonSet must have a [`RestartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy)
equal to `Always`, or be unspecified, which defaults to `Always`.
-->
### Pod 模板 {#pod-template}
`.spec` 中唯一必需的字段是 `.spec.template`
`.spec.template` 是一个 [Pod 模板](/zh/docs/concepts/workloads/pods/#pod-templates)。
除了它是嵌套的,因而不具有 `apiVersion``kind` 字段之外,它与
{{< glossary_tooltip text="Pod" term_id="pod" >}} 具有相同的 schema。
除了 Pod 必需字段外,在 DaemonSet 中的 Pod 模板必须指定合理的标签(查看 [Pod 选择算符](#pod-selector))。
在 DaemonSet 中的 Pod 模板必须具有一个值为 `Always`
[`RestartPolicy`](/zh/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy)。
当该值未指定时,默认是 `Always`
<!--
### Pod Selector
The `.spec.selector` field is a pod selector. It works the same as the `.spec.selector` of
a [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/).
You must specify a pod selector that matches the labels of the
`.spec.template`.
Also, once a DaemonSet is created,
its `.spec.selector` can not be mutated. Mutating the pod selector can lead to the
unintentional orphaning of Pods, and it was found to be confusing to users.
-->
### Pod 选择算符 {#pod-selector}
`.spec.selector` 字段表示 Pod 选择算符,它与
[Job](/zh/docs/concepts/workloads/controllers/job/) 的 `.spec.selector` 的作用是相同的。
你必须指定与 `.spec.template` 的标签匹配的 Pod 选择算符。
此外,一旦创建了 DaemonSet,它的 `.spec.selector` 就不能修改。
修改 Pod 选择算符可能导致 Pod 意外悬浮,并且这对用户来说是费解的。
<!--
The `.spec.selector` is an object consisting of two fields:
-->
`spec.selector` 是一个对象,如下两个字段组成:
<!--
* `matchLabels` - works the same as the `.spec.selector` of a
[ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/).
* `matchExpressions` - allows to build more sophisticated selectors by specifying key,
list of values and an operator that relates the key and values.
-->
* `matchLabels` - 与 [ReplicationController](/zh/docs/concepts/workloads/controllers/replicationcontroller/)
`.spec.selector` 的作用相同。
* `matchExpressions` - 允许构建更加复杂的选择器,可以通过指定 key、value
列表以及将 key 和 value 列表关联起来的 operator。
<!--
When the two are specified the result is ANDed.
-->
当上述两个字段都指定时,结果会按逻辑与(AND)操作处理。
<!--
The `.spec.selector` must match the `.spec.template.metadata.labels`.
Config with these two not matching will be rejected by the API.
-->
`.spec.selector` 必须与 `.spec.template.metadata.labels` 相匹配。
如果配置中这两个字段不匹配,则会被 API 拒绝。
<!--
### Running Pods on Only Some Nodes
If you specify a `.spec.template.spec.nodeSelector`, then the DaemonSet controller will
create Pods on nodes which match that [node selector](/docs/concepts/scheduling-eviction/assign-pod-node/).
Likewise if you specify a `.spec.template.spec.affinity`,
then DaemonSet controller will create Pods on nodes which match that
[node affinity](/docs/concepts/scheduling-eviction/assign-pod-node/).
If you do not specify either, then the DaemonSet controller will create Pods on all nodes.
-->
### 仅在某些节点上运行 Pod {#running-pods-on-only-some-nodes}
如果指定了 `.spec.template.spec.nodeSelector`DaemonSet 控制器将在能够与
[Node 选择算符](/zh/docs/concepts/scheduling-eviction/assign-pod-node/) 匹配的节点上创建 Pod。
类似这种情况,可以指定 `.spec.template.spec.affinity`,之后 DaemonSet 控制器
将在能够与[节点亲和性](/zh/docs/concepts/scheduling-eviction/assign-pod-node/)
匹配的节点上创建 Pod。
如果根本就没有指定,则 DaemonSet Controller 将在所有节点上创建 Pod。
<!--
## How Daemon Pods are Scheduled
### Scheduled by default scheduler
-->
## Daemon Pods 是如何被调度的 {#how-daemon-pods-are-scheduled}
### 通过默认调度器调度 {#scheduled-by-default-scheduler}
{{< feature-state for_k8s_version="1.17" state="stable" >}}
<!--
A DaemonSet ensures that all eligible nodes run a copy of a Pod. Normally, the
node that a Pod runs on is selected by the Kubernetes scheduler. However,
DaemonSet pods are created and scheduled by the DaemonSet controller instead.
That introduces the following issues:
* Inconsistent Pod behavior: Normal Pods waiting to be scheduled are created
and in `Pending` state, but DaemonSet pods are not created in `Pending`
state. This is confusing to the user.
* [Pod preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/)
is handled by default scheduler. When preemption is enabled, the DaemonSet controller
will make scheduling decisions without considering pod priority and preemption.
-->
DaemonSet 确保所有符合条件的节点都运行该 Pod 的一个副本。
通常,运行 Pod 的节点由 Kubernetes 调度器选择。
不过,DaemonSet Pods 由 DaemonSet 控制器创建和调度。这就带来了以下问题:
* Pod 行为的不一致性:正常 Pod 在被创建后等待调度时处于 `Pending` 状态,
DaemonSet Pods 创建后不会处于 `Pending` 状态下。这使用户感到困惑。
* [Pod 抢占](/zh/docs/concepts/configuration/pod-priority-preemption/)
由默认调度器处理。启用抢占后,DaemonSet 控制器将在不考虑 Pod 优先级和抢占
的情况下制定调度决策。
<!--
`ScheduleDaemonSetPods` allows you to schedule DaemonSets using the default
scheduler instead of the DaemonSet controller, by adding the `NodeAffinity` term
to the DaemonSet pods, instead of the `.spec.nodeName` term. The default
scheduler is then used to bind the pod to the target host. If node affinity of
the DaemonSet pod already exists, it is replaced (the original node affinity was
taken into account before selecting the target host). The DaemonSet controller only
performs these operations when creating or modifying DaemonSet pods, and no
changes are made to the `spec.template` of the DaemonSet.
-->
`ScheduleDaemonSetPods` 允许你使用默认调度器而不是 DaemonSet 控制器来调度 DaemonSets
方法是将 `NodeAffinity` 条件而不是 `.spec.nodeName` 条件添加到 DaemonSet Pods。
默认调度器接下来将 Pod 绑定到目标主机。
如果 DaemonSet Pod 的节点亲和性配置已存在,则被替换
(原始的节点亲和性配置在选择目标主机之前被考虑)。
DaemonSet 控制器仅在创建或修改 DaemonSet Pod 时执行这些操作,
并且不会更改 DaemonSet 的 `spec.template`
```yaml
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchFields:
- key: metadata.name
operator: In
values:
- target-host-name
```
<!--
In addition, `node.kubernetes.io/unschedulable:NoSchedule` toleration is added
automatically to DaemonSet Pods. The default scheduler ignores
`unschedulable` Nodes when scheduling DaemonSet Pods.
-->
此外,系统会自动添加 `node.kubernetes.io/unschedulableNoSchedule` 容忍度到
DaemonSet Pods。在调度 DaemonSet Pod 时,默认调度器会忽略 `unschedulable` 节点。
<!--
### Taints and Tolerations
Although Daemon Pods respect
[taints and tolerations](/docs/concepts/configuration/taint-and-toleration),
the following tolerations are added to DaemonSet Pods automatically according to
the related features.
-->
### 污点和容忍度 {#taint-and-toleration}
尽管 Daemon Pods 遵循[污点和容忍度](/zh/docs/concepts/scheduling-eviction/taint-and-toleration)
规则,根据相关特性,控制器会自动将以下容忍度添加到 DaemonSet Pod
| 容忍度键名 | 效果 | 版本 | 描述 |
| ---------------------------------------- | ---------- | ------- | ------------------------------------------------------------ |
| `node.kubernetes.io/not-ready` | NoExecute | 1.13+ | 当出现类似网络断开的情况导致节点问题时,DaemonSet Pod 不会被逐出。 |
| `node.kubernetes.io/unreachable` | NoExecute | 1.13+ | 当出现类似于网络断开的情况导致节点问题时,DaemonSet Pod 不会被逐出。 |
| `node.kubernetes.io/disk-pressure` | NoSchedule | 1.8+ | DaemonSet Pod 被默认调度器调度时能够容忍磁盘压力属性。 |
| `node.kubernetes.io/memory-pressure` | NoSchedule | 1.8+ | DaemonSet Pod 被默认调度器调度时能够容忍内存压力属性。 |
| `node.kubernetes.io/unschedulable` | NoSchedule | 1.12+ | DaemonSet Pod 能够容忍默认调度器所设置的 `unschedulable` 属性. |
| `node.kubernetes.io/network-unavailable` | NoSchedule | 1.12+ | DaemonSet 在使用宿主网络时,能够容忍默认调度器所设置的 `network-unavailable` 属性。 |
<!--
## Communicating with Daemon Pods
-->
<!--
Some possible patterns for communicating with Pods in a DaemonSet are:
- **Push**: Pods in the DaemonSet are configured to send updates to another service, such
as a stats database. They do not have clients.
- **NodeIP and Known Port**: Pods in the DaemonSet can use a `hostPort`, so that the pods
are reachable via the node IPs.
Clients know the list of node IPs somehow, and know the port by convention.
- **DNS**: Create a [headless service](/docs/concepts/services-networking/service/#headless-services)
with the same pod selector, and then discover DaemonSets using the `endpoints`
resource or retrieve multiple A records from DNS.
- **Service**: Create a service with the same Pod selector, and use the service to reach a
daemon on a random node. (No way to reach specific node.)
-->
## 与 Daemon Pods 通信 {#communicating-with-daemon-pods}
与 DaemonSet 中的 Pod 进行通信的几种可能模式如下:
- **推送(Push**:配置 DaemonSet 中的 Pod,将更新发送到另一个服务,例如统计数据库。
这些服务没有客户端。
- **NodeIP 和已知端口**DaemonSet 中的 Pod 可以使用 `hostPort`,从而可以通过节点 IP
访问到 Pod。客户端能通过某种方法获取节点 IP 列表,并且基于此也可以获取到相应的端口。
- **DNS**:创建具有相同 Pod 选择算符的
[无头服务](/zh/docs/concepts/services-networking/service/#headless-services)
通过使用 `endpoints` 资源或从 DNS 中检索到多个 A 记录来发现 DaemonSet。
- **Service**:创建具有相同 Pod 选择算符的服务,并使用该服务随机访问到某个节点上的
守护进程(没有办法访问到特定节点)。
<!--
## Updating a DaemonSet
If node labels are changed, the DaemonSet will promptly add Pods to newly matching nodes and delete
Pods from newly not-matching nodes.
You can modify the Pods that a DaemonSet creates. However, Pods do not allow all
fields to be updated. Also, the DaemonSet controller will use the original template the next
time a node (even with the same name) is created.
-->
## 更新 DaemonSet {#updating-a-daemon-set}
如果节点的标签被修改,DaemonSet 将立刻向新匹配上的节点添加 Pod,
同时删除不匹配的节点上的 Pod。
你可以修改 DaemonSet 创建的 Pod。不过并非 Pod 的所有字段都可更新。
下次当某节点(即使具有相同的名称)被创建时,DaemonSet 控制器还会使用最初的模板。
<!--
You can delete a DaemonSet. If you specify `--cascade=orphan` with `kubectl`, then the Pods
will be left on the nodes. If you subsequently create a new DaemonSet with the same selector,
the new DaemonSet adopts the existing Pods. If any Pods need replacing the DaemonSet replaces
them according to its `updateStrategy`.
You can [perform a rolling update](/docs/tasks/manage-daemon/update-daemon-set/) on a DaemonSet.
-->
你可以删除一个 DaemonSet。如果使用 `kubectl` 并指定 `--cascade=orphan` 选项,
则 Pod 将被保留在节点上。接下来如果创建使用相同选择算符的新 DaemonSet,
新的 DaemonSet 会收养已有的 Pod。
如果有 Pod 需要被替换,DaemonSet 会根据其 `updateStrategy` 来替换。
你可以对 DaemonSet [执行滚动更新](/zh/docs/tasks/manage-daemon/update-daemon-set/)操作。
<!--
## Alternatives to DaemonSet
### Init Scripts
-->
## DaemonSet 的替代方案 {#alternatives-to-daemon-set}
### init 脚本 {#init-scripts}
<!--
It is certainly possible to run daemon processes by directly starting them on a node (e.g. using
`init`, `upstartd`, or `systemd`). This is perfectly fine. However, there are several advantages to
running such processes via a DaemonSet:
- Ability to monitor and manage logs for daemons in the same way as applications.
- Same config language and tools (e.g. Pod templates, `kubectl`) for daemons and applications.
- Running daemons in containers with resource limits increases isolation between daemons from app
containers. However, this can also be accomplished by running the daemons in a container but not in a Pod
(e.g. start directly via Docker).
-->
直接在节点上启动守护进程(例如使用 `init``upstartd``systemd`)的做法当然是可行的。
不过,基于 DaemonSet 来运行这些进程有如下一些好处:
- 像所运行的其他应用一样,DaemonSet 具备为守护进程提供监控和日志管理的能力。
- 为守护进程和应用所使用的配置语言和工具(如 Pod 模板、`kubectl`)是相同的。
- 在资源受限的容器中运行守护进程能够增加守护进程和应用容器的隔离性。
然而,这一点也可以通过在容器中运行守护进程但却不在 Pod 中运行之来实现。
例如,直接基于 Docker 启动。
<!--
### Bare Pods
It is possible to create Pods directly which specify a particular node to run on. However,
a DaemonSet replaces Pods that are deleted or terminated for any reason, such as in the case of
node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, you should
use a DaemonSet rather than creating individual Pods.
-->
### 裸 Pod {#bare-pods}
直接创建 Pod并指定其运行在特定的节点上也是可以的。
然而,DaemonSet 能够替换由于任何原因(例如节点失败、例行节点维护、内核升级)
而被删除或终止的 Pod。
由于这个原因,你应该使用 DaemonSet 而不是单独创建 Pod。
<!--
### Static Pods
It is possible to create Pods by writing a file to a certain directory watched by Kubelet. These
are called [static pods](/docs/tasks/configure-pod-container/static-pod/).
Unlike DaemonSet, static Pods cannot be managed with kubectl
or other Kubernetes API clients. Static Pods do not depend on the apiserver, making them useful
in cluster bootstrapping cases. Also, static Pods may be deprecated in the future.
-->
### 静态 Pod {#static-pods}
通过在一个指定的、受 `kubelet` 监视的目录下编写文件来创建 Pod 也是可行的。
这类 Pod 被称为[静态 Pod](/zh/docs/tasks/configure-pod-container/static-pod/)。
不像 DaemonSet,静态 Pod 不受 `kubectl` 和其它 Kubernetes API 客户端管理。
静态 Pod 不依赖于 API 服务器,这使得它们在启动引导新集群的情况下非常有用。
此外,静态 Pod 在将来可能会被废弃。
<!--
### Deployments
DaemonSets are similar to [Deployments](/docs/concepts/workloads/controllers/deployment/) in that
they both create Pods, and those Pods have processes which are not expected to terminate (e.g. web servers,
storage servers).
Use a Deployment for stateless services, like frontends, where scaling up and down the
number of replicas and rolling out updates are more important than controlling exactly which host
the Pod runs on. Use a DaemonSet when it is important that a copy of a Pod always run on
all or certain hosts, if the DaemonSet provides node-level functionality that allows other Pods to run correctly on that particular node.
For example, [network plugins](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) often include a component that runs as a DaemonSet. The DaemonSet component makes sure that the node where it's running has working cluster networking.
-->
### Deployments
DaemonSet 与 [Deployments](/zh/docs/concepts/workloads/controllers/deployment/) 非常类似,
它们都能创建 Pod,并且 Pod 中的进程都不希望被终止(例如,Web 服务器、存储服务器)。
建议为无状态的服务使用 Deployments,比如前端服务。
对这些服务而言,对副本的数量进行扩缩容、平滑升级,比精确控制 Pod 运行在某个主机上要重要得多。
当需要 Pod 副本总是运行在全部或特定主机上,并且当该 DaemonSet 提供了节点级别的功能(允许其他 Pod 在该特定节点上正确运行)时,
应该使用 DaemonSet。
例如,[网络插件](/zh/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/)通常包含一个以 DaemonSet 运行的组件。
这个 DaemonSet 组件确保它所在的节点的集群网络正常工作。
## {{% heading "whatsnext" %}}
<!--
* Learn about [Pods](/docs/concepts/workloads/pods).
* Learn about [static Pods](#static-pods), which are useful for running Kubernetes
{{< glossary_tooltip text="control plane" term_id="control-plane" >}} components.
* Find out how to use DaemonSets
* [Perform a rolling update on a DaemonSet](/docs/tasks/manage-daemon/update-daemon-set/)
* [Perform a rollback on a DaemonSet](/docs/tasks/manage-daemon/rollback-daemon-set/)
(for example, if a roll out didn't work how you expected).
* Understand [how Kubernetes assigns Pods to Nodes](/docs/concepts/scheduling-eviction/assign-pod-node/).
* Learn about [device plugins](/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/) and
[add ons](/docs/concepts/cluster-administration/addons/), which often run as DaemonSets.
* `DaemonSet` is a top-level resource in the Kubernetes REST API.
Read the {{< api-reference page="workload-resources/daemon-set-v1" >}}
object definition to understand the API for daemon sets.
-->
* 了解 [Pods](/zh/docs/concepts/workloads/pods)。
* 了解[静态 Pod](#static-pods),这对运行 Kubernetes {{< glossary_tooltip text="控制面" term_id="control-plane" >}}组件有帮助。
* 了解如何使用 DaemonSet
* [对 DaemonSet 执行滚动更新](/zh/docs/tasks/manage-daemon/update-daemon-set/)
* [对 DaemonSet 执行回滚](/zh/docs/tasks/manage-daemon/rollback-daemon-set/)(例如:新的版本没有达到你的预期)
* 理解[Kubernetes 如何将 Pod 分配给节点](/zh/docs/concepts/scheduling-eviction/assign-pod-node/)。
* 了解[设备插件](/zh/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)和
[扩展(Addons](/zh/docs/concepts/cluster-administration/addons/),它们常以 DaemonSet 运行。
* `DaemonSet` 是 Kubernetes REST API 中的顶级资源。阅读 {{< api-reference page="workload-resources/daemon-set-v1" >}}
对象定义理解关于该资源的 API。
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,762 @@
---
title: ReplicaSet
content_type: concept
weight: 20
---
<!--
reviewers:
- Kashomon
- bprashanth
- madhusudancs
title: ReplicaSet
content_type: concept
weight: 20
-->
<!-- overview -->
<!--
A ReplicaSet's purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often
used to guarantee the availability of a specified number of identical Pods.
-->
ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。
因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。
<!-- body -->
<!--
## How a ReplicaSet works
A ReplicaSet is defined with fields, including a selector that specifies how to identify Pods it can acquire, a number
of replicas indicating how many Pods it should be maintaining, and a pod template specifying the data of new Pods
it should create to meet the number of replicas criteria. A ReplicaSet then fulfills its purpose by creating
and deleting Pods as needed to reach the desired number. When a ReplicaSet needs to create new Pods, it uses its Pod
template.
-->
## ReplicaSet 的工作原理 {#how-a-replicaset-works}
ReplicaSet 是通过一组字段来定义的,包括一个用来识别可获得的 Pod
的集合的选择算符、一个用来标明应该维护的副本个数的数值、一个用来指定应该创建新 Pod
以满足副本个数条件时要使用的 Pod 模板等等。
每个 ReplicaSet 都通过根据需要创建和 删除 Pod 以使得副本个数达到期望值,
进而实现其存在价值。当 ReplicaSet 需要创建新的 Pod 时,会使用所提供的 Pod 模板。
<!--
A ReplicaSet is linked to its Pods via the Pods' [metadata.ownerReferences](/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents)
field, which specifies what resource the current object is owned by. All Pods acquired by a ReplicaSet have their owning
ReplicaSet's identifying information within their ownerReferences field. It's through this link that the ReplicaSet
knows of the state of the Pods it is maintaining and plans accordingly.
-->
ReplicaSet 通过 Pod 上的
[metadata.ownerReferences](/zh/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents)
字段连接到附属 Pod,该字段给出当前对象的属主资源。
ReplicaSet 所获得的 Pod 都在其 ownerReferences 字段中包含了属主 ReplicaSet
的标识信息。正是通过这一连接,ReplicaSet 知道它所维护的 Pod 集合的状态,
并据此计划其操作行为。
<!--
A ReplicaSet identifies new Pods to acquire by using its selector. If there is a Pod that has no OwnerReference or the
OwnerReference is not a {{< glossary_tooltip term_id="controller" >}} and it matches a ReplicaSet's selector, it will be immediately acquired by said
ReplicaSet.
-->
ReplicaSet 使用其选择算符来辨识要获得的 Pod 集合。如果某个 Pod 没有
OwnerReference 或者其 OwnerReference 不是一个
{{< glossary_tooltip text="控制器" term_id="controller" >}},且其匹配到
某 ReplicaSet 的选择算符,则该 Pod 立即被此 ReplicaSet 获得。
<!--
## When to use a ReplicaSet
A ReplicaSet ensures that a specified number of pod replicas are running at any given
time. However, a Deployment is a higher-level concept that manages ReplicaSets and
provides declarative updates to Pods along with a lot of other useful features.
Therefore, we recommend using Deployments instead of directly using ReplicaSets, unless
you require custom update orchestration or don't require updates at all.
This actually means that you may never need to manipulate ReplicaSet objects:
use a Deployment instead, and define your application in the spec section.
-->
## 何时使用 ReplicaSet {#when-to-use-a-replicaset}
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。
然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod
提供声明式的更新以及许多其他有用的功能。
因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非
你需要自定义更新业务流程或根本不需要更新。
这实际上意味着,你可能永远不需要操作 ReplicaSet 对象:而是使用
Deployment,并在 spec 部分定义你的应用。
<!--
## Example
-->
## 示例 {#example}
{{< codenew file="controllers/frontend.yaml" >}}
<!--
Saving this manifest into `frontend.yaml` and submitting it to a Kubernetes cluster will
create the defined ReplicaSet and the Pods that it manages.
-->
将此清单保存到 `frontend.yaml` 中,并将其提交到 Kubernetes 集群,
就能创建 yaml 文件所定义的 ReplicaSet 及其管理的 Pod。
```shell
kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml
```
<!--
You can then get the current ReplicaSets deployed:
-->
你可以看到当前被部署的 ReplicaSet:
```shell
kubectl get rs
```
<!--
And see the frontend one you created:
-->
并看到你所创建的前端:
```
NAME DESIRED CURRENT READY AGE
frontend 3 3 3 6s
```
<!--
You can also check on the state of the ReplicaSet:
-->
你也可以查看 ReplicaSet 的状态:
```shell
kubectl describe rs/frontend
```
<!--
And you will see output similar to:
-->
你会看到类似如下的输出:
```
Name: frontend
Namespace: default
Selector: tier=frontend
Labels: app=guestbook
tier=frontend
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"labels":{"app":"guestbook","tier":"frontend"},"name":"frontend",...
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: tier=frontend
Containers:
php-redis:
Image: gcr.io/google_samples/gb-frontend:v3
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 117s replicaset-controller Created pod: frontend-wtsmm
Normal SuccessfulCreate 116s replicaset-controller Created pod: frontend-b2zdv
Normal SuccessfulCreate 116s replicaset-controller Created pod: frontend-vcmts
```
<!--
And lastly you can check for the Pods brought up:
-->
最后可以查看启动了的 Pods
```shell
kubectl get pods
```
<!--
You should see Pod information similar to:
-->
你会看到类似如下的 Pod 信息:
```
NAME READY STATUS RESTARTS AGE
frontend-b2zdv 1/1 Running 0 6m36s
frontend-vcmts 1/1 Running 0 6m36s
frontend-wtsmm 1/1 Running 0 6m36s
```
<!--
You can also verify that the owner reference of these pods is set to the frontend ReplicaSet.
To do this, get the yaml of one of the Pods running:
-->
你也可以查看 Pods 的属主引用被设置为前端的 ReplicaSet。
要实现这点,可取回运行中的 Pods 之一的 YAML:
```shell
kubectl get pods frontend-b2zdv -o yaml
```
<!--
The output will look similar to this, with the frontend ReplicaSet's info set in the metadata's ownerReferences field:
-->
输出将类似这样,frontend ReplicaSet 的信息被设置在 metadata 的
`ownerReferences` 字段中:
```yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-02-12T07:06:16Z"
generateName: frontend-
labels:
tier: frontend
name: frontend-b2zdv
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: frontend
uid: f391f6db-bb9b-4c09-ae74-6a1f77f3d5cf
...
```
<!--
## Non-Template Pod acquisitions
-->
## 非模板 Pod 的获得 {#non-template-pod-acquisitions}
<!--
While you can create bare Pods with no problems, it is strongly recommended to make sure that the bare Pods do not have
labels which match the selector of one of your ReplicaSets. The reason for this is because a ReplicaSet is not limited
to owning Pods specified by its template-- it can acquire other Pods in the manner specified in the previous sections.
Take the previous frontend ReplicaSet example, and the Pods specified in the following manifest:
-->
尽管你完全可以直接创建裸的 Pods,强烈建议你确保这些裸的 Pods 并不包含可能与你
的某个 ReplicaSet 的选择算符相匹配的标签。原因在于 ReplicaSet 并不仅限于拥有
在其模板中设置的 Pods,它还可以像前面小节中所描述的那样获得其他 Pods。
{{< codenew file="pods/pod-rs.yaml" >}}
<!--
As those Pods do not have a Controller (or any object) as their owner reference and match the selector of the frontend
ReplicaSet, they will immediately be acquired by it.
Suppose you create the Pods after the frontend ReplicaSet has been deployed and has set up its initial Pod replicas to
fulfill its replica count requirement:
-->
由于这些 Pod 没有控制器(Controller,或其他对象)作为其属主引用,并且
其标签与 frontend ReplicaSet 的选择算符匹配,它们会立即被该 ReplicaSet
获取。
假定你在 frontend ReplicaSet 已经被部署之后创建 Pods,并且你已经在 ReplicaSet
中设置了其初始的 Pod 副本数以满足其副本计数需要:
```shell
kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml
```
<!--
The new Pods will be acquired by the ReplicaSet, and then immediately terminated as the ReplicaSet would be over
its desired count.
Fetching the Pods:
-->
新的 Pods 会被该 ReplicaSet 获取,并立即被 ReplicaSet 终止,因为
它们的存在会使得 ReplicaSet 中 Pod 个数超出其期望值。
取回 Pods
```shell
kubectl get pods
```
<!--
The output shows that the new Pods are either already terminated, or in the process of being terminated:
-->
输出显示新的 Pods 或者已经被终止,或者处于终止过程中:
```
NAME READY STATUS RESTARTS AGE
frontend-b2zdv 1/1 Running 0 10m
frontend-vcmts 1/1 Running 0 10m
frontend-wtsmm 1/1 Running 0 10m
pod1 0/1 Terminating 0 1s
pod2 0/1 Terminating 0 1s
```
<!--
If you create the Pods first:
-->
如果你先行创建 Pods
```shell
kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml
```
<!--
And then create the ReplicaSet however:
-->
之后再创建 ReplicaSet
```shell
kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml
```
<!--
You shall see that the ReplicaSet has acquired the Pods and has only created new ones according to its spec until the
number of its new Pods and the original matches its desired count. As fetching the Pods:
-->
你会看到 ReplicaSet 已经获得了该 Pods,并仅根据其规约创建新的 Pods,直到
新的 Pods 和原来的 Pods 的总数达到其预期个数。
这时取回 Pods
```shell
kubectl get pods
```
<!--
Will reveal in its output:
-->
将会生成下面的输出:
```
NAME READY STATUS RESTARTS AGE
frontend-hmmj2 1/1 Running 0 9s
pod1 1/1 Running 0 36s
pod2 1/1 Running 0 36s
```
<!--
In this manner, a ReplicaSet can own a non-homogenous set of Pods
-->
采用这种方式,一个 ReplicaSet 中可以包含异质的 Pods 集合。
<!--
## Writing a ReplicaSet manifest
As with all other Kubernetes API objects, a ReplicaSet needs the `apiVersion`, `kind`, and `metadata` fields.
For ReplicaSets, the `kind` is always a ReplicaSet.
The name of a ReplicaSet object must be a valid
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
A ReplicaSet also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
-->
## 编写 ReplicaSet 的清单 {#writing-a-replicaset-manifest}
与所有其他 Kubernetes API 对象一样,ReplicaSet 也需要 `apiVersion``kind`、和 `metadata` 字段。
对于 ReplicaSets 而言,其 `kind` 始终是 ReplicaSet。
ReplicaSet 对象的名称必须是合法的
[DNS 子域名](/zh/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)。
ReplicaSet 也需要
[`.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)
部分。
<!--
### Pod Template
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/#pod-templates) which is also
required to have labels in place. In our `frontend.yaml` example we had one label: `tier: frontend`.
Be careful not to overlap with the selectors of other controllers, lest they try to adopt this Pod.
For the template's [restart policy](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) field,
`.spec.template.spec.restartPolicy`, the only allowed value is `Always`, which is the default.
-->
### Pod 模版 {#pod-template}
`.spec.template` 是一个 [Pod 模版](/zh/docs/concepts/workloads/pods/#pod-templates)
要求设置标签。在 `frontend.yaml` 示例中,我们指定了标签 `tier: frontend`
注意不要将标签与其他控制器的选择算符重叠,否则那些控制器会尝试收养此 Pod。
对于模板的[重启策略](/zh/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy)
字段,`.spec.template.spec.restartPolicy`,唯一允许的取值是 `Always`,这也是默认值.
<!--
### Pod Selector
The `.spec.selector` field is a [label selector](/docs/concepts/overview/working-with-objects/labels/). As discussed
[earlier](#how-a-replicaset-works) these are the labels used to identify potential Pods to acquire. In our
`frontend.yaml` example, the selector was:
```yaml
matchLabels:
tier: frontend
```
In the ReplicaSet, `.spec.template.metadata.labels` must match `spec.selector`, or it will
be rejected by the API.
-->
### Pod 选择算符 {#pod-selector}
`.spec.selector` 字段是一个[标签选择算符](/zh/docs/concepts/overview/working-with-objects/labels/)。
如前文中[所讨论的](#how-a-replicaset-works),这些是用来标识要被获取的 Pods
的标签。在签名的 `frontend.yaml` 示例中,选择算符为:
```yaml
matchLabels:
tier: frontend
```
在 ReplicaSet 中,`.spec.template.metadata.labels` 的值必须与 `spec.selector`
相匹配,否则该配置会被 API 拒绝。
{{< note >}}
<!--
For 2 ReplicaSets specifying the same `.spec.selector` but different `.spec.template.metadata.labels` and `.spec.template.spec` fields, each ReplicaSet ignores the Pods created by the other ReplicaSet.
-->
对于设置了相同的 `.spec.selector`,但
`.spec.template.metadata.labels``.spec.template.spec` 字段不同的
两个 ReplicaSet 而言,每个 ReplicaSet 都会忽略被另一个 ReplicaSet 所
创建的 Pods。
{{< /note >}}
<!--
### Replicas
You can specify how many Pods should run concurrently by setting `.spec.replicas`. The ReplicaSet will create/delete
its Pods to match this number.
If you do not specify `.spec.replicas`, then it defaults to 1.
-->
### Replicas
你可以通过设置 `.spec.replicas` 来指定要同时运行的 Pod 个数。
ReplicaSet 创建、删除 Pods 以与此值匹配。
如果你没有指定 `.spec.replicas`,那么默认值为 1。
<!--
## Working with ReplicaSets
### Deleting a ReplicaSet and its Pods
To delete a ReplicaSet and all of its Pods, use [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete). The [Garbage collector](/docs/concepts/workloads/controllers/garbage-collection/) automatically deletes all of the dependent Pods by default.
When using the REST API or the `client-go` library, you must set `propagationPolicy` to `Background` or `Foreground` in
the -d option.
For example:
-->
## 使用 ReplicaSets {#working-with-replicasets}
### 删除 ReplicaSet 和它的 Pod {#deleting-a-replicaset-and-its-pods}
要删除 ReplicaSet 和它的所有 Pod,使用
[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 命令。
默认情况下,[垃圾收集器](/zh/docs/concepts/workloads/controllers/garbage-collection/)
自动删除所有依赖的 Pod。
当使用 REST API 或 `client-go` 库时,你必须在 `-d` 选项中将 `propagationPolicy`
设置为 `Background``Foreground`。例如:
```shell
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
-H "Content-Type: application/json"
```
<!--
### Deleting just a ReplicaSet
You can delete a ReplicaSet without affecting any of its Pods using [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) with the `--cascade=orphan` option.
When using the REST API or the `client-go` library, you must set `propagationPolicy` to `Orphan`.
For example:
-->
### 只删除 ReplicaSet {#deleting-just-a-replicaset}
你可以只删除 ReplicaSet 而不影响它的 Pods,方法是使用
[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete)
命令并设置 `--cascade=orphan` 选项。
当使用 REST API 或 `client-go` 库时,你必须将 `propagationPolicy` 设置为 `Orphan`
例如:
```shell
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
-H "Content-Type: application/json"
```
<!--
Once the original is deleted, you can create a new ReplicaSet to replace it. As long
as the old and new `.spec.selector` are the same, then the new one will adopt the old Pods.
However, it will not make any effort to make existing Pods match a new, different pod template.
To update Pods to a new spec in a controlled way, use a
[Deployment](/docs/concepts/workloads/controllers/deployment/#creating-a-deployment), as ReplicaSets do not support a rolling update directly.
-->
一旦删除了原来的 ReplicaSet,就可以创建一个新的来替换它。
由于新旧 ReplicaSet 的 `.spec.selector` 是相同的,新的 ReplicaSet 将接管老的 Pod。
但是,它不会努力使现有的 Pod 与新的、不同的 Pod 模板匹配。
若想要以可控的方式更新 Pod 的规约,可以使用
[Deployment](/zh/docs/concepts/workloads/controllers/deployment/#creating-a-deployment)
资源,因为 ReplicaSet 并不直接支持滚动更新。
<!--
### Isolating Pods from a ReplicaSet
You can remove Pods from a ReplicaSet by changing their labels. This technique may be used to remove Pods
from service for debugging, data recovery, etc. Pods that are removed in this way will be replaced automatically (
assuming that the number of replicas is not also changed).
-->
### 将 Pod 从 ReplicaSet 中隔离 {#isolating-pods-from-a-replicaset}
可以通过改变标签来从 ReplicaSet 中移除 Pod。
这种技术可以用来从服务中去除 Pod,以便进行排错、数据恢复等。
以这种方式移除的 Pod 将被自动替换(假设副本的数量没有改变)。
<!--
### Scaling a ReplicaSet
A ReplicaSet can be easily scaled up or down by simply updating the `.spec.replicas` field. The ReplicaSet controller
ensures that a desired number of Pods with a matching label selector are available and operational.
-->
### 缩放 RepliaSet {#scaling-a-replicaset}
通过更新 `.spec.replicas` 字段,ReplicaSet 可以被轻松的进行缩放。ReplicaSet
控制器能确保匹配标签选择器的数量的 Pod 是可用的和可操作的。
<!--
When scaling down, the ReplicaSet controller chooses which pods to delete by sorting the available pods to
prioritize scaling down pods based on the following general algorithm:
-->
在降低集合规模时,ReplicaSet 控制器通过对可用的 Pods 进行排序来优先选择
要被删除的 Pods。其一般性算法如下:
<!--
1. Pending (and unschedulable) pods are scaled down first
2. If `controller.kubernetes.io/pod-deletion-cost` annotation is set, then
the pod with the lower value will come first.
3. Pods on nodes with more replicas come before pods on nodes with fewer replicas.
4. If the pods' creation times differ, the pod that was created more recently
comes before the older pod (the creation times are bucketed on an integer log scale
when the `LogarithmicScaleDown` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled)
-->
1. 首先选择剔除悬决(Pending,且不可调度)的 Pods
2. 如果设置了 `controller.kubernetes.io/pod-deletion-cost` 注解,则注解值
较小的优先被裁减掉
3. 所处节点上副本个数较多的 Pod 优先于所处节点上副本较少者
4. 如果 Pod 的创建时间不同,最近创建的 Pod 优先于早前创建的 Pod 被裁减。
(当 `LogarithmicScaleDown` 这一
[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)
被启用时,创建时间是按整数幂级来分组的)。
如果以上比较结果都相同,则随机选择。
<!--
### Pod deletion cost
-->
### Pod 删除开销 {#pod-deletion-cost}
{{< feature-state for_k8s_version="v1.22" state="beta" >}}
<!--
Using the [`controller.kubernetes.io/pod-deletion-cost`](/docs/reference/labels-annotations-taints/#pod-deletion-cost)
annotation, users can set a preference regarding which pods to remove first when downscaling a ReplicaSet.
-->
通过使用 [`controller.kubernetes.io/pod-deletion-cost`](/zh/docs/reference/labels-annotations-taints/#pod-deletion-cost)
注解,用户可以对 ReplicaSet 缩容时要先删除哪些 Pods 设置偏好。
<!--
The annotation should be set on the pod, the range is [-2147483647, 2147483647]. It represents the cost of
deleting a pod compared to other pods belonging to the same ReplicaSet. Pods with lower deletion
cost are preferred to be deleted before pods with higher deletion cost.
-->
此注解要设置到 Pod 上,取值范围为 [-2147483647, 2147483647]。
所代表的的是删除同一 ReplicaSet 中其他 Pod 相比较而言的开销。
删除开销较小的 Pods 比删除开销较高的 Pods 更容易被删除。
<!--
The implicit value for this annotation for pods that don't set it is 0; negative values are permitted.
Invalid values will be rejected by the API server.
-->
Pods 如果未设置此注解,则隐含的设置值为 0。负值也是可接受的。
如果注解值非法,API 服务器会拒绝对应的 Pod。
<!--
This feature is beta and enabled by default. You can disable it using the
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
`PodDeletionCost` in both kube-apiserver and kube-controller-manager.
-->
此功能特性处于 Beta 阶段,默认被禁用。你可以通过为 kube-apiserver 和
kube-controller-manager 设置
[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)
`PodDeletionCost` 来启用此功能。
{{< note >}}
<!--
- This is honored on a best-effort basis, so it does not offer any guarantees on pod deletion order.
- Users should avoid updating the annotation frequently, such as updating it based on a metric value,
because doing so will generate a significant number of pod updates on the apiserver.
-->
- 此机制实施时仅是尽力而为,并不能对 Pod 的删除顺序作出任何保证;
- 用户应避免频繁更新注解值,例如根据某观测度量值来更新此注解值是应该避免的。
这样做会在 API 服务器上产生大量的 Pod 更新操作。
{{< /note >}}
<!--
#### Example Use Case
The different pods of an application could have different utilization levels. On scale down, the application
may prefer to remove the pods with lower utilization. To avoid frequently updating the pods, the application
should update `controller.kubernetes.io/pod-deletion-cost` once before issuing a scale down (setting the
annotation to a value proportional to pod utilization level). This works if the application itself controls
the down scaling; for example, the driver pod of a Spark deployment.
-->
#### 使用场景示例 {#example-use-case}
同一应用的不同 Pods 可能其利用率是不同的。在对应用执行缩容操作时,可能
希望移除利用率较低的 Pods。为了避免频繁更新 Pods,应用应该在执行缩容
操作之前更新一次 `controller.kubernetes.io/pod-deletion-cost` 注解值
(将注解值设置为一个与其 Pod 利用率对应的值)。
如果应用自身控制器缩容操作时(例如 Spark 部署的驱动 Pod),这种机制
是可以起作用的。
<!--
### ReplicaSet as a Horizontal Pod Autoscaler Target
A ReplicaSet can also be a target for
[Horizontal Pod Autoscalers (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/). That is,
a ReplicaSet can be auto-scaled by an HPA. Here is an example HPA targeting
the ReplicaSet we created in the previous example.
-->
### ReplicaSet 作为水平的 Pod 自动缩放器目标 {#replicaset-as-a-horizontal-pod-autoscaler-target}
ReplicaSet 也可以作为
[水平的 Pod 缩放器 (HPA)](/zh/docs/tasks/run-application/horizontal-pod-autoscale/)
的目标。也就是说,ReplicaSet 可以被 HPA 自动缩放。
以下是 HPA 以我们在前一个示例中创建的副本集为目标的示例。
{{< codenew file="controllers/hpa-rs.yaml" >}}
<!--
Saving this manifest into `hpa-rs.yaml` and submitting it to a Kubernetes cluster should
create the defined HPA that autoscales the target ReplicaSet depending on the CPU usage
of the replicated Pods.
-->
将这个列表保存到 `hpa-rs.yaml` 并提交到 Kubernetes 集群,就能创建它所定义的
HPA,进而就能根据复制的 Pod 的 CPU 利用率对目标 ReplicaSet进行自动缩放。
```shell
kubectl apply -f https://k8s.io/examples/controllers/hpa-rs.yaml
```
<!--
Alternatively, you can use the `kubectl autoscale` command to accomplish the same
(and it's easier!)
-->
或者,可以使用 `kubectl autoscale` 命令完成相同的操作。(而且它更简单!)
```shell
kubectl autoscale rs frontend --max=10 --min=3 --cpu-percent=50
```
<!--
## Alternatives to ReplicaSet
### Deployment (recommended)
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is an object which can own ReplicaSets and update
them and their Pods via declarative, server-side rolling updates.
While ReplicaSets can be used independently, today they're mainly used by Deployments as a mechanism to orchestrate Pod
creation, deletion and updates. When you use Deployments you don't have to worry about managing the ReplicaSets that
they create. Deployments own and manage their ReplicaSets.
As such, it is recommended to use Deployments when you want ReplicaSets.
-->
## ReplicaSet 的替代方案 {#alternatives-to-replicaset}
### Deployment(推荐) {#deployment-recommended}
[`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) 是一个
可以拥有 ReplicaSet 并使用声明式方式在服务器端完成对 Pods 滚动更新的对象。
尽管 ReplicaSet 可以独立使用,目前它们的主要用途是提供给 Deployment 作为
编排 Pod 创建、删除和更新的一种机制。当使用 Deployment 时,你不必关心
如何管理它所创建的 ReplicaSetDeployment 拥有并管理其 ReplicaSet。
因此,建议你在需要 ReplicaSet 时使用 Deployment。
<!--
### Bare Pods
Unlike the case where a user directly created Pods, a ReplicaSet replaces Pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, we recommend that you use a ReplicaSet even if your application requires only a single Pod. Think of it similarly to a process supervisor, only it supervises multiple Pods across multiple nodes instead of individual processes on a single node. A ReplicaSet delegates local container restarts to some agent on the node (for example, Kubelet or Docker).
-->
### 裸 Pod {#bare-pods}
与用户直接创建 Pod 的情况不同,ReplicaSet 会替换那些由于某些原因被删除或被终止的
Pod,例如在节点故障或破坏性的节点维护(如内核升级)的情况下。
因为这个原因,我们建议你使用 ReplicaSet,即使应用程序只需要一个 Pod。
想像一下,ReplicaSet 类似于进程监视器,只不过它在多个节点上监视多个 Pod,
而不是在单个节点上监视单个进程。
ReplicaSet 将本地容器重启的任务委托给了节点上的某个代理(例如,Kubelet 或 Docker)去完成。
<!--
### Job
Use a [`Job`](/docs/concepts/workloads/controllers/job/) instead of a ReplicaSet for Pods that are expected to terminate on their own
(that is, batch jobs).
-->
### Job
使用[`Job`](/zh/docs/concepts/workloads/controllers/job/) 代替ReplicaSet
可以用于那些期望自行终止的 Pod。
<!--
### DaemonSet
Use a [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) instead of a ReplicaSet for Pods that provide a
machine-level function, such as machine monitoring or machine logging. These Pods have a lifetime that is tied
to a machine lifetime: the Pod needs to be running on the machine before other Pods start, and are
safe to terminate when the machine is otherwise ready to be rebooted/shutdown.
-->
### DaemonSet
对于管理那些提供主机级别功能(如主机监控和主机日志)的容器,
就要用 [`DaemonSet`](/zh/docs/concepts/workloads/controllers/daemonset/)
而不用 ReplicaSet。
这些 Pod 的寿命与主机寿命有关:这些 Pod 需要先于主机上的其他 Pod 运行,
并且在机器准备重新启动/关闭时安全地终止。
### ReplicationController
<!--
ReplicaSets are the successors to [_ReplicationControllers_](/docs/concepts/workloads/controllers/replicationcontroller/).
The two serve the same purpose, and behave similarly, except that a ReplicationController does not support set-based
selector requirements as described in the [labels user guide](/docs/concepts/overview/working-with-objects/labels/#label-selectors).
As such, ReplicaSets are preferred over ReplicationControllers
-->
ReplicaSet 是 [ReplicationController](/zh/docs/concepts/workloads/controllers/replicationcontroller/)
的后继者。二者目的相同且行为类似,只是 ReplicationController 不支持
[标签用户指南](/zh/docs/concepts/overview/working-with-objects/labels/#label-selectors)
中讨论的基于集合的选择算符需求。
因此,相比于 ReplicationController,应优先考虑 ReplicaSet。
## {{% heading "whatsnext" %}}
<!--
* Learn about [Pods](/docs/concepts/workloads/pods).
* Learn about [Deployments](/docs/concepts/workloads/controllers/deployment/).
* [Run a Stateless Application Using a Deployment](/docs/tasks/run-application/run-stateless-application-deployment/),
which relies on ReplicaSets to work.
* `ReplicaSet` is a top-level resource in the Kubernetes REST API.
Read the {{< api-reference page="workload-resources/replica-set-v1" >}}
object definition to understand the API for replica sets.
* Read about [PodDisruptionBudget](/docs/concepts/workloads/pods/disruptions/) and how
you can use it to manage application availability during disruptions.
-->
* 了解 [Pods](/zh/docs/concepts/workloads/pods)。
* 了解 [Deployments](/zh/docs/concepts/workloads/controllers/deployment/)。
* [使用 Deployment 运行一个无状态应用](/zh/docs/tasks/run-application/run-stateless-application-deployment/),它依赖于 ReplicaSet。
* `ReplicaSet` 是 Kubernetes REST API 中的顶级资源。阅读
{{< api-reference page="workload-resources/replica-set-v1" >}}
对象定义理解关于该资源的 API。
* 阅读 [Pod 干扰预算(Disruption Budget](/zh/docs/concepts/workloads/pods/disruptions/)
了解如何在干扰下运行高度可用的应用。
@@ -0,0 +1,612 @@
---
title: ReplicationController
feature:
title: 自我修复
anchor: ReplicationController 如何工作
description: >
重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器,并且在它们准备好服务之前不会将它们公布给客户端。
content_type: concept
weight: 90
---
<!--
reviewers:
- bprashanth
- janetkuo
title: ReplicationController
feature:
title: Self-healing
anchor: How a ReplicationController Works
description: >
Restarts containers that fail, replaces and reschedules containers when nodes die, kills containers that don't respond to your user-defined health check, and doesn't advertise them to clients until they are ready to serve.
content_type: concept
weight: 90
-->
<!-- overview -->
<!--
A [`Deployment`](/docs/concepts/workloads/controllers/deployment/) that configures a [`ReplicaSet`](/docs/concepts/workloads/controllers/replicaset/) is now the recommended way to set up replication.
-->
{{< note >}}
现在推荐使用配置 [`ReplicaSet`](/zh/docs/concepts/workloads/controllers/replicaset/) 的
[`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) 来建立副本管理机制。
{{< /note >}}
<!--
A _ReplicationController_ ensures that a specified number of pod replicas are running at any one
time. In other words, a ReplicationController makes sure that a pod or a homogeneous set of pods is
always up and available.
-->
_ReplicationController_ 确保在任何时候都有特定数量的 Pod 副本处于运行状态。
换句话说,ReplicationController 确保一个 Pod 或一组同类的 Pod 总是可用的。
<!-- body -->
<!--
## How a ReplicationController Works
If there are too many pods, the ReplicationController terminates the extra pods. If there are too few, the
ReplicationController starts more pods. Unlike manually created pods, the pods maintained by a
ReplicationController are automatically replaced if they fail, are deleted, or are terminated.
For example, your pods are re-created on a node after disruptive maintenance such as a kernel upgrade.
For this reason, you should use a ReplicationController even if your application requires
only a single pod. A ReplicationController is similar to a process supervisor,
but instead of supervising individual processes on a single node, the ReplicationController supervises multiple pods
across multiple nodes.
-->
## ReplicationController 如何工作
当 Pod 数量过多时,ReplicationController 会终止多余的 Pod。当 Pod 数量太少时,ReplicationController 将会启动新的 Pod。
与手动创建的 Pod 不同,由 ReplicationController 创建的 Pod 在失败、被删除或被终止时会被自动替换。
例如,在中断性维护(如内核升级)之后,你的 Pod 会在节点上重新创建。
因此,即使你的应用程序只需要一个 Pod,你也应该使用 ReplicationController 创建 Pod。
ReplicationController 类似于进程管理器,但是 ReplicationController 不是监控单个节点上的单个进程,而是监控跨多个节点的多个 Pod。
<!--
ReplicationController is often abbreviated to "rc" in discussion, and as a shortcut in
kubectl commands.
A simple case is to create one ReplicationController object to reliably run one instance of
a Pod indefinitely. A more complex use case is to run several identical replicas of a replicated
service, such as web servers.
-->
在讨论中,ReplicationController 通常缩写为 "rc",并作为 kubectl 命令的快捷方式。
一个简单的示例是创建一个 ReplicationController 对象来可靠地无限期地运行 Pod 的一个实例。
更复杂的用例是运行一个多副本服务(如 web 服务器)的若干相同副本。
<!--
## Running an example ReplicationController
This example ReplicationController config runs three copies of the nginx web server.
-->
## 运行一个示例 ReplicationController
这个示例 ReplicationController 配置运行 nginx Web 服务器的三个副本。
{{< codenew file="controllers/replication.yaml" >}}
<!--
Run the example job by downloading the example file and then running this command:
-->
通过下载示例文件并运行以下命令来运行示例任务:
```shell
kubectl apply -f https://k8s.io/examples/controllers/replication.yaml
```
<!--
The output is similar to this:
-->
输出类似于:
```
replicationcontroller/nginx created
```
<!--
Check on the status of the ReplicationController using this command:
-->
使用以下命令检查 ReplicationController 的状态:
```shell
kubectl describe replicationcontrollers/nginx
```
<!--
The output is similar to this:
-->
输出类似于:
```
Name: nginx
Namespace: default
Selector: app=nginx
Labels: app=nginx
Annotations: <none>
Replicas: 3 current / 3 desired
Pods Status: 0 Running / 3 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- ---- ------ -------
20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-qrm3m
20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-3ntk0
20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-4ok8v
```
<!--
Here, three pods are created, but none is running yet, perhaps because the image is being pulled.
A little later, the same command may show:
-->
在这里,创建了三个 Pod,但没有一个 Pod 正在运行,这可能是因为正在拉取镜像。
稍后,相同的命令可能会显示:
```
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
```
<!--
To list all the pods that belong to the ReplicationController in a machine readable form, you can use a command like this:
-->
要以机器可读的形式列出属于 ReplicationController 的所有 Pod,可以使用如下命令:
```shell
pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name})
echo $pods
```
<!--
The output is similar to this:
-->
输出类似于:
```
nginx-3ntk0 nginx-4ok8v nginx-qrm3m
```
<!--
Here, the selector is the same as the selector for the ReplicationController (seen in the
`kubectl describe` output), and in a different form in `replication.yaml`. The `--output=jsonpath` option
specifies an expression with the name from each pod in the returned list.
-->
这里,选择算符与 ReplicationController 的选择算符相同(参见 `kubectl describe` 输出),并以不同的形式出现在 `replication.yaml` 中。
`--output=jsonpath` 选项指定了一个表达式,仅从返回列表中的每个 Pod 中获取名称。
<!--
## Writing a ReplicationController Spec
As with all other Kubernetes config, a ReplicationController needs `apiVersion`, `kind`, and `metadata` fields.
For general information about working with configuration files, see [object management](/docs/concepts/overview/working-with-objects/object-management/).
A ReplicationController also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
-->
## 编写一个 ReplicationController 规约
与所有其它 Kubernetes 配置一样,ReplicationController 需要 `apiVersion`
`kind``metadata` 字段。
有关使用配置文件的常规信息,参考
[对象管理](/zh/docs/concepts/overview/working-with-objects/object-management/)。
ReplicationController 也需要一个 [`.spec` 部分](https://git.k8s.io/community/contributors/devel/sig-architecture/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`.
-->
### Pod 模板 {#pod-template}
`.spec.template``.spec` 的唯一必需字段。
`.spec.template` 是一个 [Pod 模板](/zh/docs/concepts/workloads/pods/#pod-templates)。
它的模式与 [Pod](/zh/docs/concepts/workloads/pods/) 完全相同,只是它是嵌套的,没有 `apiVersion``kind` 属性。
<!--
In addition to required fields for a Pod, a pod template in a ReplicationController must specify appropriate
labels and an appropriate restart policy. For labels, make sure not to overlap with other controllers. See [pod selector](#pod-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.
For local container restarts, ReplicationControllers delegate to an agent on the node,
for example the [Kubelet](/docs/admin/kubelet/) or Docker.
-->
除了 Pod 所需的字段外,ReplicationController 中的 Pod 模板必须指定适当的标签和适当的重新启动策略。
对于标签,请确保不与其他控制器重叠。参考 [Pod 选择算符](#pod-selector)。
只允许 [`.spec.template.spec.restartPolicy`](/zh/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) 等于 `Always`,如果没有指定,这是默认值。
对于本地容器重启,ReplicationController 委托给节点上的代理,
例如 [Kubelet](/zh/docs/reference/command-line-tools-reference/kubelet/) 或 Docker。
<!--
### Labels on the ReplicationController
The ReplicationController can itself have labels (`.metadata.labels`). Typically, you
would set these the same as the `.spec.template.metadata.labels`; if `.metadata.labels` is not specified
then it defaults to `.spec.template.metadata.labels`. However, they are allowed to be
different, and the `.metadata.labels` do not affect the behavior of the ReplicationController.
-->
### ReplicationController 上的标签
ReplicationController 本身可以有标签 `.metadata.labels`)。
通常,你可以将这些设置为 `.spec.template.metadata.labels`
如果没有指定 `.metadata.labels` 那么它默认为 `.spec.template.metadata.labels`
但是,Kubernetes 允许它们是不同的,`.metadata.labels` 不会影响 ReplicationController 的行为。
<!--
### Pod Selector
The `.spec.selector` field is a [label selector](/docs/concepts/overview/working-with-objects/labels/#label-selectors). A ReplicationController
manages all the pods with labels that match the selector. It does not distinguish
between pods that it created or deleted and pods that another person or process created or
deleted. This allows the ReplicationController to be replaced without affecting the running pods.
-->
### Pod 选择算符 {#pod-selector}
`.spec.selector` 字段是一个[标签选择算符](/zh/docs/concepts/overview/working-with-objects/labels/#label-selectors)。
ReplicationController 管理标签与选择算符匹配的所有 Pod。
它不区分它创建或删除的 Pod 和其他人或进程创建或删除的 Pod。
这允许在不影响正在运行的 Pod 的情况下替换 ReplicationController。
<!--
If specified, the `.spec.template.metadata.labels` must be equal to the `.spec.selector`, or it will
be rejected by the API. If `.spec.selector` is unspecified, it will be defaulted to
`.spec.template.metadata.labels`.
-->
如果指定了 `.spec.template.metadata.labels`,它必须和 `.spec.selector` 相同,否则它将被 API 拒绝。
如果没有指定 `.spec.selector`,它将默认为 `.spec.template.metadata.labels`
<!--
Also you should not normally create any pods whose labels match this selector, either directly, with
another ReplicationController, or with another controller such as Job. If you do so, the
ReplicationController thinks that it created the other pods. Kubernetes does not stop you
from doing this.
If you do end up with multiple controllers that have overlapping selectors, you
will have to manage the deletion yourself (see [below](#working-with-replicationcontrollers)).
-->
另外,通常不应直接使用另一个 ReplicationController 或另一个控制器(例如 Job)
来创建其标签与该选择算符匹配的任何 Pod。如果这样做,ReplicationController 会认为它创建了这些 Pod。
Kubernetes 并没有阻止你这样做。
如果你的确创建了多个控制器并且其选择算符之间存在重叠,那么你将不得不自己管理删除操作(参考[后文](#working-with-replicationcontrollers))。
<!--
### Multiple Replicas
You can specify how many pods should run concurrently by setting `.spec.replicas` to the number
of pods you would like to have running concurrently. The number running at any time may be higher
or lower, such as if the replicas were just increased or decreased, or if a pod is gracefully
shutdown, and a replacement starts early.
If you do not specify `.spec.replicas`, then it defaults to 1.
-->
### 多个副本
你可以通过设置 `.spec.replicas` 来指定应该同时运行多少个 Pod。
在任何时候,处于运行状态的 Pod 个数都可能高于或者低于设定值。例如,副本个数刚刚被增加或减少时,或者一个 Pod 处于优雅终止过程中而其替代副本已经提前开始创建时。
如果你没有指定 `.spec.replicas` ,那么它默认是 1。
<!--
## Working with ReplicationControllers
### Deleting a ReplicationController and its Pods
To delete a ReplicationController and all its pods, use [`kubectl
delete`](/docs/reference/generated/kubectl/kubectl-commands#delete). Kubectl will scale the ReplicationController to zero and wait
for it to delete each pod before deleting the ReplicationController itself. If this kubectl
command is interrupted, it can be restarted.
When using the REST API or [client library](/docs/reference/using-api/client-libraries), you need to do the steps explicitly (scale replicas to
0, wait for pod deletions, then delete the ReplicationController).
-->
## 使用 ReplicationController {#working-with-replicationcontrollers}
### 删除一个 ReplicationController 以及它的 Pod
要删除一个 ReplicationController 以及它的 Pod,使用
[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete)。
kubectl 将 ReplicationController 缩放为 0 并等待以便在删除 ReplicationController 本身之前删除每个 Pod。
如果这个 kubectl 命令被中断,可以重新启动它。
当使用 REST API 或[客户端库](/zh/docs/reference/using-api/client-libraries)时,你需要明确地执行这些步骤(缩放副本为 0、
等待 Pod 删除,之后删除 ReplicationController 资源)。
<!--
### Deleting only a ReplicationController
You can delete a ReplicationController without affecting any of its pods.
Using kubectl, specify the `--cascade=orphan` option to [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete).
When using the REST API or [client library](/docs/reference/using-api/client-libraries), you can delete the ReplicationController object.
-->
### 只删除 ReplicationController
你可以删除一个 ReplicationController 而不影响它的任何 Pod。
使用 kubectl,为 [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 指定 `--cascade=orphan` 选项。
当使用 REST API 或客户端库(/zh/docs/reference/using-api/client-libraries)时,只需删除 ReplicationController 对象。
<!--
Once the original is deleted, you can create a new ReplicationController to replace it. As long
as the old and new `.spec.selector` are the same, then the new one will adopt the old pods.
However, it will not make any effort to make existing pods match a new, different pod template.
To update pods to a new spec in a controlled way, use a [rolling update](#rolling-updates).
-->
一旦原始对象被删除,你可以创建一个新的 ReplicationController 来替换它。
只要新的和旧的 `.spec.selector` 相同,那么新的控制器将领养旧的 Pod。
但是,它不会做出任何努力使现有的 Pod 匹配新的、不同的 Pod 模板。
如果希望以受控方式更新 Pod 以使用新的 spec,请执行[滚动更新](#rolling-updates)操作。
<!--
### Isolating pods from a ReplicationController
Pods may be removed from a ReplicationController's target set by changing their labels. This technique may be used to remove pods from service for debugging and data recovery. Pods that are removed in this way will be replaced automatically (assuming that the number of replicas is not also changed).
-->
### 从 ReplicationController 中隔离 Pod
通过更改 Pod 的标签,可以从 ReplicationController 的目标中删除 Pod。
此技术可用于从服务中删除 Pod 以进行调试、数据恢复等。以这种方式删除的 Pod
将被自动替换(假设复制副本的数量也没有更改)。
<!--
## Common usage patterns
-->
## 常见的使用模式
<!--
### Rescheduling
As mentioned above, whether you have 1 pod you want to keep running, or 1000, a ReplicationController will ensure that the specified number of pods exists, even in the event of node failure or pod termination (for example, due to an action by another control agent).
-->
### 重新调度 {#rescheduling}
如上所述,无论你想要继续运行 1 个 Pod 还是 1000 个 Pod,一个 ReplicationController 都将确保存在指定数量的 Pod,即使在节点故障或 Pod 终止(例如,由于另一个控制代理的操作)的情况下也是如此。
<!--
### Scaling
The ReplicationController enables scaling the number of replicas up or down, either manually or by an auto-scaling control agent, by updating the `replicas` field.
-->
### 扩缩容 {#scaling}
通过设置 `replicas` 字段,ReplicationController 可以允许扩容或缩容副本的数量。
你可以手动或通过自动缩放控制代理来控制 ReplicationController 执行此操作。
<!--
### Rolling updates
The ReplicationController is designed to facilitate rolling updates to a service by replacing pods one-by-one.
As explained in [#1353](http://issue.k8s.io/1353), the recommended approach is to create a new ReplicationController with 1 replica, scale the new (+1) and old (-1) controllers one by one, and then delete the old controller after it reaches 0 replicas. This predictably updates the set of pods regardless of unexpected failures.
-->
### 滚动更新 {#rolling-updates}
ReplicationController 的设计目的是通过逐个替换 Pod 以方便滚动更新服务。
如 [#1353](https://issue.k8s.io/1353) PR 中所述,建议的方法是使用 1 个副本创建一个新的 ReplicationController
逐个扩容新的(+1)和缩容旧的(-1)控制器,然后在旧的控制器达到 0 个副本后将其删除。
这一方法能够实现可控的 Pod 集合更新,即使存在意外失效的状况。
<!--
Ideally, the rolling update controller would take application readiness into account, and would ensure that a sufficient number of pods were productively serving at any given time.
The two ReplicationControllers would need to create pods with at least one differentiating label, such as the image tag of the primary container of the pod, since it is typically image updates that motivate rolling updates.
Rolling update is implemented in the client tool
[`kubectl rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update). Visit [`kubectl rolling-update` task](/docs/tasks/run-application/rolling-update-replication-controller/) for more concrete examples.
-->
理想情况下,滚动更新控制器将考虑应用程序的就绪情况,并确保在任何给定时间都有足够数量的 Pod 有效地提供服务。
这两个 ReplicationController 将需要创建至少具有一个不同标签的 Pod,比如 Pod 主要容器的镜像标签,因为通常是镜像更新触发滚动更新。
滚动更新是在客户端工具 [`kubectl rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update)
中实现的。访问 [`kubectl rolling-update` 任务](/zh/docs/tasks/run-application/rolling-update-replication-controller/)以获得更多的具体示例。
<!--
### Multiple release tracks
In addition to running multiple releases of an application while a rolling update is in progress, it's common to run multiple releases for an extended period of time, or even continuously, using multiple release tracks. The tracks would be differentiated by labels.
For instance, a service might target all pods with `tier in (frontend), environment in (prod)`. Now say you have 10 replicated pods that make up this tier. But you want to be able to 'canary' a new version of this component. You could set up a ReplicationController with `replicas` set to 9 for the bulk of the replicas, with labels `tier=frontend, environment=prod, track=stable`, and another ReplicationController with `replicas` set to 1 for the canary, with labels `tier=frontend, environment=prod, track=canary`. Now the service is covering both the canary and non-canary pods. But you can mess with the ReplicationControllers separately to test things out, monitor the results, etc.
-->
### 多个版本跟踪
除了在滚动更新过程中运行应用程序的多个版本之外,通常还会使用多个版本跟踪来长时间,
甚至持续运行多个版本。这些跟踪将根据标签加以区分。
例如,一个服务可能把具有 `tier in (frontend), environment in (prod)` 的所有 Pod 作为目标。
现在假设你有 10 个副本的 Pod 组成了这个层。但是你希望能够 `canary` `金丝雀`)发布这个组件的新版本。
你可以为大部分副本设置一个 ReplicationController,其中 `replicas` 设置为 9
标签为 `tier=frontend, environment=prod, track=stable` 而为 `canary`
设置另一个 ReplicationController,其中 `replicas` 设置为 1
标签为 `tier=frontend, environment=prod, track=canary`
现在这个服务覆盖了 `canary` 和非 `canary` Pod。但你可以单独处理
ReplicationController,以测试、监控结果等。
<!--
### Using ReplicationControllers with Services
Multiple ReplicationControllers can sit behind a single service, so that, for example, some traffic
goes to the old version, and some goes to the new version.
A ReplicationController will never terminate on its own, but it isn't expected to be as long-lived as services. Services may be composed of pods controlled by multiple ReplicationControllers, and it is expected that many ReplicationControllers may be created and destroyed over the lifetime of a service (for instance, to perform an update of pods that run the service). Both services themselves and their clients should remain oblivious to the ReplicationControllers that maintain the pods of the services.
-->
### 和服务一起使用 ReplicationController
多个 ReplicationController 可以位于一个服务的后面,例如,一部分流量流向旧版本,
一部分流量流向新版本。
一个 ReplicationController 永远不会自行终止,但它不会像服务那样长时间存活。
服务可以由多个 ReplicationController 控制的 Pod 组成,并且在服务的生命周期内
(例如,为了执行 Pod 更新而运行服务),可以创建和销毁许多 ReplicationController。
服务本身和它们的客户端都应该忽略负责维护服务 Pod 的 ReplicationController 的存在。
<!--
## Writing programs for Replication
Pods created by a ReplicationController are intended to be fungible and semantically identical, though their configurations may become heterogeneous over time. This is an obvious fit for replicated stateless servers, but ReplicationControllers can also be used to maintain availability of master-elected, sharded, and worker-pool applications. Such applications should use dynamic work assignment mechanisms, such as the [RabbitMQ work queues](https://www.rabbitmq.com/tutorials/tutorial-two-python.html), as opposed to static/one-time customization of the configuration of each pod, which is considered an anti-pattern. Any pod customization performed, such as vertical auto-sizing of resources (for example, cpu or memory), should be performed by another online controller process, not unlike the ReplicationController itself.
-->
## 编写多副本的应用
由 ReplicationController 创建的 Pod 是可替换的,语义上是相同的,
尽管随着时间的推移,它们的配置可能会变得异构。
这显然适合于多副本的无状态服务器,但是 ReplicationController 也可以用于维护主选、
分片和工作池应用程序的可用性。
这样的应用程序应该使用动态的工作分配机制,例如
[RabbitMQ 工作队列](https://www.rabbitmq.com/tutorials/tutorial-two-python.html)
而不是静态的或者一次性定制每个 Pod 的配置,这被认为是一种反模式。
执行的任何 Pod 定制,例如资源的垂直自动调整大小(例如,CPU 或内存),
都应该由另一个在线控制器进程执行,这与 ReplicationController 本身没什么不同。
<!--
## Responsibilities of the ReplicationController
The ReplicationController ensures that the desired number of pods matches its label selector and are operational. Currently, only terminated pods are excluded from its count. In the future, [readiness](http://issue.k8s.io/620) and other information available from the system may be taken into account, we may add more controls over the replacement policy, and we plan to emit events that could be used by external clients to implement arbitrarily sophisticated replacement and/or scale-down policies.
-->
## ReplicationController 的职责
ReplicationController 仅确保所需的 Pod 数量与其标签选择算符匹配,并且是可操作的。
目前,它的计数中只排除终止的 Pod。
未来,可能会考虑系统提供的[就绪状态](https://issue.k8s.io/620)和其他信息,
我们可能会对替换策略添加更多控制,
我们计划发出事件,这些事件可以被外部客户端用来实现任意复杂的替换和/或缩减策略。
<!--
The ReplicationController is forever constrained to this narrow responsibility. It itself will not perform readiness nor liveness probes. Rather than performing auto-scaling, it is intended to be controlled by an external auto-scaler (as discussed in [#492](http://issue.k8s.io/492)), which would change its `replicas` field. We will not add scheduling policies (for example, [spreading](http://issue.k8s.io/367#issuecomment-48428019)) to the ReplicationController. Nor should it verify that the pods controlled match the currently specified template, as that would obstruct auto-sizing and other automated processes. Similarly, completion deadlines, ordering dependencies, configuration expansion, and other features belong elsewhere. We even plan to factor out the mechanism for bulk pod creation ([#170](http://issue.k8s.io/170)).
-->
ReplicationController 永远被限制在这个狭隘的职责范围内。
它本身既不执行就绪态探测,也不执行活跃性探测。
它不负责执行自动缩放,而是由外部自动缩放器控制(如
[#492](https://issue.k8s.io/492) 中所述),后者负责更改其 `replicas` 字段值。
我们不会向 ReplicationController 添加调度策略(例如,
[spreading](https://issue.k8s.io/367#issuecomment-48428019))。
它也不应该验证所控制的 Pod 是否与当前指定的模板匹配,因为这会阻碍自动调整大小和其他自动化过程。
类似地,完成期限、整理依赖关系、配置扩展和其他特性也属于其他地方。
我们甚至计划考虑批量创建 Pod 的机制(查阅 [#170](https://issue.k8s.io/170))。
<!--
The ReplicationController is intended to be a composable building-block primitive. We expect higher-level APIs and/or tools to be built on top of it and other complementary primitives for user convenience in the future. The "macro" operations currently supported by kubectl (run, scale, rolling-update) are proof-of-concept examples of this. For instance, we could imagine something like [Asgard](https://netflixtechblog.com/asgard-web-based-cloud-management-and-deployment-2c9fc4e4d3a1) managing ReplicationControllers, auto-scalers, services, scheduling policies, canaries, etc.
-->
ReplicationController 旨在成为可组合的构建基元。
我们希望在它和其他补充原语的基础上构建更高级别的 API 或者工具,以便于将来的用户使用。
kubectl 目前支持的 "macro" 操作(运行、缩放、滚动更新)就是这方面的概念示例。
例如,我们可以想象类似于 [Asgard](https://netflixtechblog.com/asgard-web-based-cloud-management-and-deployment-2c9fc4e4d3a1)
的东西管理 ReplicationController、自动定标器、服务、调度策略、金丝雀发布等。
<!--
## API Object
Replication controller is a top-level resource in the Kubernetes REST API. More details about the
API object can be found at:
[ReplicationController API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#replicationcontroller-v1-core).
-->
## API 对象
在 Kubernetes REST API 中 Replication controller 是顶级资源。
更多关于 API 对象的详细信息可以在
[ReplicationController API 对象](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#replicationcontroller-v1-core)找到。
<!--
## Alternatives to ReplicationController
### ReplicaSet
[`ReplicaSet`](/docs/concepts/workloads/controllers/replicaset/) is the next-generation ReplicationController that supports the new [set-based label selector](/docs/concepts/overview/working-with-objects/labels/#set-based-requirement).
Its mainly used by [Deployment](/docs/concepts/workloads/controllers/deployment/) as a mechanism to orchestrate Pod creation, deletion and updates.
Note that we recommend using Deployments instead of directly using Replica Sets, unless you require custom update orchestration or dont require updates at all.
-->
## ReplicationController 的替代方案
### ReplicaSet
[`ReplicaSet`](/zh/docs/concepts/workloads/controllers/replicaset/) 是下一代 ReplicationController
支持新的[基于集合的标签选择算符](/zh/docs/concepts/overview/working-with-objects/labels/#set-based-requirement)。
它主要被 [`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/)
用来作为一种编排 Pod 创建、删除及更新的机制。
请注意,我们推荐使用 Deployment 而不是直接使用 ReplicaSet,除非
你需要自定义更新编排或根本不需要更新。
<!--
### Deployment (Recommended)
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is a higher-level API object that updates its underlying Replica Sets and their Pods.
Deployments are recommended if you want the rolling update functionality,
because they are declarative, server-side, and have additional features.
-->
### Deployment (推荐)
[`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) 是一种更高级别的 API 对象,用于更新其底层 ReplicaSet 及其 Pod。
如果你想要这种滚动更新功能,那么推荐使用 Deployment,因为它们是声明式的、服务端的,并且具有其它特性。
<!--
### Bare Pods
Unlike in the case where a user directly created pods, a ReplicationController replaces pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, we recommend that you use a ReplicationController even if your application requires only a single pod. Think of it similarly to a process supervisor, only it supervises multiple pods across multiple nodes instead of individual processes on a single node. A ReplicationController delegates local container restarts to some agent on the node (for example, Kubelet or Docker).
-->
### 裸 Pod
与用户直接创建 Pod 的情况不同,ReplicationController 能够替换因某些原因
被删除或被终止的 Pod ,例如在节点故障或中断节点维护的情况下,例如内核升级。
因此,我们建议你使用 ReplicationController,即使你的应用程序只需要一个 Pod。
可以将其看作类似于进程管理器,它只管理跨多个节点的多个 Pod ,而不是单个节点上的单个进程。
ReplicationController 将本地容器重启委托给节点上的某个代理(例如,Kubelet 或 Docker)。
<!--
### Job
Use a [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) instead of a ReplicationController for Pods that are expected to terminate on their own
(that is, batch jobs).
-->
### Job
对于预期会自行终止的 Pod (即批处理任务),使用
[`Job`](/zh/docs/concepts/workloads/controllers/job/) 而不是 ReplicationController。
<!--
### DaemonSet
Use a [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) instead of a ReplicationController for pods that provide a
machine-level function, such as machine monitoring or machine logging. These pods have a lifetime that is tied
to a machine lifetime: the pod needs to be running on the machine before other pods start, and are
safe to terminate when the machine is otherwise ready to be rebooted/shutdown.
-->
### DaemonSet
对于提供机器级功能(例如机器监控或机器日志记录)的 Pod,
使用 [`DaemonSet`](/zh/docs/concepts/workloads/controllers/daemonset/) 而不是
ReplicationController。
这些 Pod 的生命期与机器的生命期绑定:它们需要在其他 Pod 启动之前在机器上运行,
并且在机器准备重新启动或者关闭时安全地终止。
<!--
## {{% heading "whatsnext" %}}
* Learn about [Pods](/docs/concepts/workloads/pods).
* Learn about [Deployment](/docs/concepts/workloads/controllers/deployment/), the replacement
for ReplicationController.
* `ReplicationController` is part of the Kubernetes REST API.
Read the {{< api-reference page="workload-resources/replication-controller-v1" >}}
object definition to understand the API for replication controllers.
-->
## {{% heading "whatsnext" %}}
- 了解 [Pods](/zh/docs/concepts/workloads/pods)。
- 了解 [Depolyment](/zh/docs/concepts/workloads/controllers/deployment/)ReplicationController 的替代品。
- `ReplicationController` 是 Kubernetes REST API 的一部分,阅读 {{< api-reference page="workload-resources/replication-controller-v1" >}}
对象定义以了解 replication controllers 的 API。
@@ -0,0 +1,793 @@
---
title: StatefulSets
content_type: concept
weight: 30
---
<!--
title: StatefulSets
content_type: concept
weight: 40
-->
<!-- overview -->
<!--
StatefulSet is the workload API object used to manage stateful applications.
-->
StatefulSet 是用来管理有状态应用的工作负载 API 对象。
{{< glossary_definition term_id="statefulset" length="all" >}}
<!-- body -->
<!--
## Using StatefulSets
StatefulSets are valuable for applications that require one or more of the
following.
-->
## 使用 StatefulSets
StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:
<!--
* Stable, unique network identifiers.
* Stable, persistent storage.
* Ordered, graceful deployment and scaling.
* Ordered, automated rolling updates.
-->
* 稳定的、唯一的网络标识符。
* 稳定的、持久的存储。
* 有序的、优雅的部署和缩放。
* 有序的、自动的滚动更新。
<!--
In the above, stable is synonymous with persistence across Pod (re)scheduling.
If an application doesn't require any stable identifiers or ordered deployment,
deletion, or scaling, you should deploy your application using a workload object
that provides a set of stateless replicas.
[Deployment](/docs/concepts/workloads/controllers/deployment/) or
[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) may be better suited to your stateless needs.
-->
在上面描述中,“稳定的”意味着 Pod 调度或重调度的整个过程是有持久性的。
如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用
由一组无状态的副本控制器提供的工作负载来部署应用程序,比如
[Deployment](/zh/docs/concepts/workloads/controllers/deployment/) 或者
[ReplicaSet](/zh/docs/concepts/workloads/controllers/replicaset/)
可能更适用于你的无状态应用部署需要。
<!--
## Limitations
-->
## 限制 {#limitations}
<!--
* The storage for a given Pod must either be provisioned by a [PersistentVolume Provisioner](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin.
* Deleting and/or scaling a StatefulSet down will *not* delete the volumes associated with the StatefulSet. This is done to ensure data safety, which is generally more valuable than an automatic purge of all related StatefulSet resources.
* StatefulSets currently require a [Headless Service](/docs/concepts/services-networking/service/#headless-services) to be responsible for the network identity of the Pods. You are responsible for creating this Service.
* StatefulSets do not provide any guarantees on the termination of pods when a StatefulSet is deleted. To achieve ordered and graceful termination of the pods in the StatefulSet, it is possible to scale the StatefulSet down to 0 prior to deletion.
* When using [Rolling Updates](#rolling-updates) with the default
[Pod Management Policy](#pod-management-policies) (`OrderedReady`),
it's possible to get into a broken state that requires
[manual intervention to repair](#forced-rollback).
-->
* 给定 Pod 的存储必须由
[PersistentVolume 驱动](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/README.md)
基于所请求的 `storage class` 来提供,或者由管理员预先提供。
* 删除或者收缩 StatefulSet 并*不会*删除它关联的存储卷。
这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
* StatefulSet 当前需要[无头服务](/zh/docs/concepts/services-networking/service/#headless-services)
来负责 Pod 的网络标识。你需要负责创建此服务。
* 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。
为了实现 StatefulSet 中的 Pod 可以有序地且体面地终止,可以在删除之前将 StatefulSet
缩放为 0。
* 在默认 [Pod 管理策略](#pod-management-policies)(`OrderedReady`) 时使用
[滚动更新](#rolling-updates),可能进入需要[人工干预](#forced-rollback)
才能修复的损坏状态。
<!--
## Components
The example below demonstrates the components of a StatefulSet.
-->
## 组件 {#components}
下面的示例演示了 StatefulSet 的组件。
```yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # 必须匹配 .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # 默认值是 1
minReadySeconds: 10 # 默认值是 0
template:
metadata:
labels:
app: nginx # 必须匹配 .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
```
<!--
In the above example:
* A Headless Service, named `nginx`, is used to control the network domain.
* The StatefulSet, named `web`, has a Spec that indicates that 3 replicas of the nginx container will be launched in unique Pods.
* The `volumeClaimTemplates` will provide stable storage using [PersistentVolumes](/docs/concepts/storage/persistent-volumes/) provisioned by a PersistentVolume Provisioner.
The name of a StatefulSet object must be a valid
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
-->
上述例子中:
* 名为 `nginx` 的 Headless Service 用来控制网络域名。
* 名为 `web` 的 StatefulSet 有一个 Spec,它表明将在独立的 3 个 Pod 副本中启动 nginx 容器。
* `volumeClaimTemplates` 将通过 PersistentVolumes 驱动提供的
[PersistentVolumes](/zh/docs/concepts/storage/persistent-volumes/) 来提供稳定的存储。
StatefulSet 的命名需要遵循[DNS 子域名](/zh/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)规范。
<!--
### Pod Selector
-->
### Pod 选择算符 {#pod-selector}
<!--
You must set the `.spec.selector` field of a StatefulSet to match the labels of its `.spec.template.metadata.labels`. Failing to specify a matching Pod Selector will result in a validation error during StatefulSet creation.
-->
你必须设置 StatefulSet 的 `.spec.selector` 字段,使之匹配其在
`.spec.template.metadata.labels` 中设置的标签。
未指定匹配的 Pod 选择器将在创建 StatefulSet 期间导致验证错误。
<!--
### Volume Claim Templates
You can set the `.spec.volumeClaimTemplates` which can provide stable storage using [PersistentVolumes](/docs/concepts/storage/persistent-volumes/) provisioned by a PersistentVolume Provisioner.
-->
### 卷申领模版 {#volume-claim-templates}
你可以设置 `.spec.volumeClaimTemplates`
它可以使用 PersistentVolume 制备程序所准备的
[PersistentVolumes](/zh/docs/concepts/storage/persistent-volumes/) 来提供稳定的存储。
<!-- ### Minimum ready seconds -->
### 最短就绪秒数 {#minimum-ready-seconds}
{{< feature-state for_k8s_version="v1.23" state="beta" >}}
<!--
`.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.
Please note that this feature is beta and enabled by default. Please opt out by unsetting the StatefulSetMinReadySeconds flag, if you don't
want this feature to be enabled. This field 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).
-->
`.spec.minReadySeconds` 是一个可选字段,
它指定新创建的 Pod 应该准备好且其任何容器不崩溃的最小秒数,以使其被视为可用。
请注意,此功能是测试版,默认启用。如果你不希望启用此功能,
请通过取消设置 StatefulSetMinReadySeconds 标志来选择退出。
该字段默认为 0(Pod 准备就绪后将被视为可用)。
要了解有关何时认为 Pod 准备就绪的更多信息,
请参阅[容器探针](/zh/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)。
<!--
## Pod Identity
StatefulSet Pods have a unique identity that is comprised of an ordinal, a
stable network identity, and stable storage. The identity sticks to the Pod,
regardless of which node it's (re)scheduled on.
-->
## Pod 标识 {#pod-identity}
StatefulSet Pod 具有唯一的标识,该标识包括顺序标识、稳定的网络标识和稳定的存储。
该标识和 Pod 是绑定的,不管它被调度在哪个节点上。
<!--
### Ordinal Index
For a StatefulSet with N replicas, each Pod in the StatefulSet will be
assigned an integer ordinal, from 0 up through N-1, that is unique over the Set.
-->
### 有序索引 {#ordinal-index}
对于具有 N 个副本的 StatefulSetStatefulSet 中的每个 Pod 将被分配一个整数序号,
从 0 到 N-1,该序号在 StatefulSet 上是唯一的。
<!--
### Stable Network ID
Each Pod in a StatefulSet derives its hostname from the name of the StatefulSet
and the ordinal of the Pod. The pattern for the constructed hostname
is `$(statefulset name)-$(ordinal)`. The example above will create three Pods
named `web-0,web-1,web-2`.
A StatefulSet can use a [Headless Service](/docs/concepts/services-networking/service/#headless-services)
to control the domain of its Pods. The domain managed by this Service takes the form:
`$(service name).$(namespace).svc.cluster.local`, where "cluster.local" is the
cluster domain.
As each Pod is created, it gets a matching DNS subdomain, taking the form:
`$(podname).$(governing service domain)`, where the governing service is defined
by the `serviceName` field on the StatefulSet.
-->
### 稳定的网络 ID {#stable-network-id}
StatefulSet 中的每个 Pod 根据 StatefulSet 的名称和 Pod 的序号派生出它的主机名。
组合主机名的格式为`$(StatefulSet 名称)-$(序号)`
上例将会创建三个名称分别为 `web-0、web-1、web-2` 的 Pod。
StatefulSet 可以使用 [无头服务](/zh/docs/concepts/services-networking/service/#headless-services)
控制它的 Pod 的网络域。管理域的这个服务的格式为:
`$(服务名称).$(命名空间).svc.cluster.local`,其中 `cluster.local` 是集群域。
一旦每个 Pod 创建成功,就会得到一个匹配的 DNS 子域,格式为:
`$(pod 名称).$(所属服务的 DNS 域名)`,其中所属服务由 StatefulSet 的 `serviceName` 域来设定。
<!--
Depending on how DNS is configured in your cluster, you may not be able to look up the DNS
name for a newly-run Pod immediately. This behavior can occur when other clients in the
cluster have already sent queries for the hostname of the Pod before it was created.
Negative caching (normal in DNS) means that the results of previous failed lookups are
remembered and reused, even after the Pod is running, for at least a few seconds.
If you need to discover Pods promptly after they are created, you have a few options:
- Query the Kubernetes API directly (for example, using a watch) rather than relying on DNS lookups.
- Decrease the time of caching in your Kubernetes DNS provider (typically this means editing the config map for CoreDNS, which currently caches for 30 seconds).
As mentioned in the [limitations](#limitations) section, you are responsible for
creating the [Headless Service](/docs/concepts/services-networking/service/#headless-services)
responsible for the network identity of the pods.
-->
取决于集群域内部 DNS 的配置,有可能无法查询一个刚刚启动的 Pod 的 DNS 命名。
当集群内其他客户端在 Pod 创建完成前发出 Pod 主机名查询时,就会发生这种情况。
负缓存 (在 DNS 中较为常见) 意味着之前失败的查询结果会被记录和重用至少若干秒钟,
即使 Pod 已经正常运行了也是如此。
如果需要在 Pod 被创建之后及时发现它们,有以下选项:
- 直接查询 Kubernetes API(比如,利用 watch 机制)而不是依赖于 DNS 查询
- 缩短 Kubernetes DNS 驱动的缓存时长(通常这意味着修改 CoreDNS 的 ConfigMap,目前缓存时长为 30 秒)
正如[限制](#limitations)中所述,你需要负责创建[无头服务](/zh/docs/concepts/services-networking/service/#headless-services)
以便为 Pod 提供网络标识。
<!--
Here are some examples of choices for Cluster Domain, Service name,
StatefulSet name, and how that affects the DNS names for the StatefulSet's Pods.
Cluster Domain | Service (ns/name) | StatefulSet (ns/name) | StatefulSet Domain | Pod DNS | Pod Hostname |
-------------- | ----------------- | ----------------- | -------------- | ------- | ------------ |
cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
-->
下面给出一些选择集群域、服务名、StatefulSet 名、及其怎样影响 StatefulSet 的 Pod 上的 DNS 名称的示例:
集群域名 | 服务(名字空间/名字)| StatefulSet(名字空间/名字) | StatefulSet 域名 | Pod DNS | Pod 主机名 |
-------------- | -------------------- | ---------------------------- | ---------------- | ------- | ------------ |
cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
<!--
Cluster Domain will be set to `cluster.local` unless
[otherwise configured](/docs/concepts/services-networking/dns-pod-service/#how-it-works).
-->
{{< note >}}
集群域会被设置为 `cluster.local`,除非有[其他配置](/zh/docs/concepts/services-networking/dns-pod-service/)。
{{< /note >}}
<!--
### Stable Storage
For each VolumeClaimTemplate entry defined in a StatefulSet, each Pod receives one PersistentVolumeClaim. In the nginx example above, each Pod receives a single PersistentVolume with a StorageClass of `my-storage-class` and 1 Gib of provisioned storage. If no StorageClass
is specified, then the default StorageClass will be used. When a Pod is (re)scheduled
onto a node, its `volumeMounts` mount the PersistentVolumes associated with its
PersistentVolume Claims. Note that, the PersistentVolumes associated with the
Pods' PersistentVolume Claims are not deleted when the Pods, or StatefulSet are deleted.
This must be done manually.
-->
### 稳定的存储 {#stable-storage}
对于 StatefulSet 中定义的每个 VolumeClaimTemplate,每个 Pod 接收到一个 PersistentVolumeClaim。在上面的 nginx 示例中,每个 Pod 将会得到基于 StorageClass `my-storage-class` 提供的
1 Gib 的 PersistentVolume。
如果没有声明 StorageClass,就会使用默认的 StorageClass。
当一个 Pod 被调度(重新调度)到节点上时,它的 `volumeMounts` 会挂载与其
PersistentVolumeClaims 相关联的 PersistentVolume。
请注意,当 Pod 或者 StatefulSet 被删除时,与 PersistentVolumeClaims 相关联的
PersistentVolume 并不会被删除。要删除它必须通过手动方式来完成。
<!--
### Pod Name Label
When the StatefulSet {{< glossary_tooltip term_id="controller" >}} creates a Pod,
it adds a label, `statefulset.kubernetes.io/pod-name`, that is set to the name of
the Pod. This label allows you to attach a Service to a specific Pod in
the StatefulSet.
-->
### Pod 名称标签 {#pod-name-label}
当 StatefulSet {{< glossary_tooltip term_id="controller" >}} 创建 Pod 时,
它会添加一个标签 `statefulset.kubernetes.io/pod-name`,该标签值设置为 Pod 名称。
这个标签允许你给 StatefulSet 中的特定 Pod 绑定一个 Service。
<!--
## Deployment and Scaling Guarantees
* For a StatefulSet with N replicas, when Pods are being deployed, they are created sequentially, in order from {0..N-1}.
* When Pods are being deleted, they are terminated in reverse order, from {N-1..0}.
* Before a scaling operation is applied to a Pod, all of its predecessors must be Running and Ready.
* Before a Pod is terminated, all of its successors must be completely shutdown.
-->
## 部署和扩缩保证 {#deployment-and-scaling-guarantees}
* 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为 `0..N-1`
* 当删除 Pod 时,它们是逆序终止的,顺序为 `N-1..0`
* 在将缩放操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
* 在 Pod 终止之前,所有的继任者必须完全关闭。
<!--
The StatefulSet should not specify a `pod.Spec.TerminationGracePeriodSeconds` of 0. This practice is unsafe and strongly discouraged. For further explanation, please refer to [force deleting StatefulSet Pods](/docs/tasks/run-application/force-delete-stateful-set-pod/).
-->
StatefulSet 不应将 `pod.Spec.TerminationGracePeriodSeconds` 设置为 0。
这种做法是不安全的,要强烈阻止。更多的解释请参考
[强制删除 StatefulSet Pod](/zh/docs/tasks/run-application/force-delete-stateful-set-pod/)。
<!--
When the nginx example above is created, three Pods will be deployed in the order
web-0, web-1, web-2. web-1 will not be deployed before web-0 is
[Running and Ready](/docs/user-guide/pod-states/), and web-2 will not be deployed until
web-1 is Running and Ready. If web-0 should fail, after web-1 is Running and Ready, but before
web-2 is launched, web-2 will not be launched until web-0 is successfully relaunched and
becomes Running and Ready.
-->
在上面的 nginx 示例被创建后,会按照 web-0、web-1、web-2 的顺序部署三个 Pod。
在 web-0 进入 [Running 和 Ready](/zh/docs/concepts/workloads/pods/pod-lifecycle/)
状态前不会部署 web-1。在 web-1 进入 Running 和 Ready 状态前不会部署 web-2。
如果 web-1 已经处于 Running 和 Ready 状态,而 web-2 尚未部署,在此期间发生了
web-0 运行失败,那么 web-2 将不会被部署,要等到 web-0 部署完成并进入 Running 和
Ready 状态后,才会部署 web-2。
<!--
If a user were to scale the deployed example by patching the StatefulSet such that
`replicas=1`, web-2 would be terminated first. web-1 would not be terminated until web-2
is fully shutdown and deleted. If web-0 were to fail after web-2 has been terminated and
is completely shutdown, but prior to web-1's termination, web-1 would not be terminated
until web-0 is Running and Ready.
-->
如果用户想将示例中的 StatefulSet 收缩为 `replicas=1`,首先被终止的是 web-2。
在 web-2 没有被完全停止和删除前,web-1 不会被终止。
当 web-2 已被终止和删除、web-1 尚未被终止,如果在此期间发生 web-0 运行失败,
那么就不会终止 web-1,必须等到 web-0 进入 Running 和 Ready 状态后才会终止 web-1。
<!--
### Pod Management Policies
StatefulSet allows you to relax its ordering guarantees while
preserving its uniqueness and identity guarantees via its `.spec.podManagementPolicy` field.
-->
### Pod 管理策略 {#pod-management-policies}
StatefulSet 允许你放宽其排序保证,
同时通过它的 `.spec.podManagementPolicy` 域保持其唯一性和身份保证。
<!--
#### OrderedReady Pod Management
`OrderedReady` pod management is the default for StatefulSets. It implements the behavior
described [above](#deployment-and-scaling-guarantees).
-->
#### OrderedReady Pod 管理
`OrderedReady` Pod 管理是 StatefulSet 的默认设置。它实现了
[上面](#deployment-and-scaling-guarantees)描述的功能。
<!--
#### Parallel Pod Management
`Parallel` pod management tells the StatefulSet controller to launch or
terminate all Pods in parallel, and to not wait for Pods to become Running
and Ready or completely terminated prior to launching or terminating another
Pod. This option only affects the behavior for scaling operations. Updates are not affected.
-->
#### 并行 Pod 管理 {#parallel-pod-management}
`Parallel` Pod 管理让 StatefulSet 控制器并行的启动或终止所有的 Pod,
启动或者终止其他 Pod 前,无需等待 Pod 进入 Running 和 ready 或者完全停止状态。
这个选项只会影响伸缩操作的行为,更新则不会被影响。
<!--
## Update Strategies
A StatefulSet's `.spec.updateStrategy` field allows you to configure
and disable automated rolling updates for containers, labels, resource request/limits, and
annotations for the Pods in a StatefulSet. There are two possible values:
-->
## 更新策略 {#update-strategies}
StatefulSet 的 `.spec.updateStrategy` 字段让
你可以配置和禁用掉自动滚动更新 Pod 的容器、标签、资源请求或限制、以及注解。
有两个允许的值:
<!--
`OnDelete`
: When a StatefulSet's `.spec.updateStrategy.type` is set to `OnDelete`,
the StatefulSet controller will not automatically update the Pods in a
StatefulSet. Users must manually delete Pods to cause the controller to
create new Pods that reflect modifications made to a StatefulSet's `.spec.template`.
`RollingUpdate`
: The `RollingUpdate` update strategy implements automated, rolling update for the Pods in a StatefulSet. This is the default update strategy.
-->
`OnDelete`
: 当 StatefulSet 的 `.spec.updateStrategy.type` 设置为 `OnDelete` 时,
它的控制器将不会自动更新 StatefulSet 中的 Pod。
用户必须手动删除 Pod 以便让控制器创建新的 Pod,以此来对 StatefulSet 的
`.spec.template` 的变动作出反应。
`RollingUpdate`
: `RollingUpdate` 更新策略对 StatefulSet 中的 Pod 执行自动的滚动更新。这是默认的更新策略。
<!--
## Rolling Updates
When a StatefulSet's `.spec.updateStrategy.type` is set to `RollingUpdate`, the
StatefulSet controller will delete and recreate each Pod in the StatefulSet. It will proceed
in the same order as Pod termination (from the largest ordinal to the smallest), updating
each Pod one at a time.
The Kubernetes control plane waits until an updated Pod is Running and Ready prior
to updating its predecessor. If you have set `.spec.minReadySeconds` (see
[Minimum Ready Seconds](#minimum-ready-seconds)), the control plane additionally waits that
amount of time after the Pod turns ready, before moving on.
-->
## 滚动更新 {#rolling-updates}
当 StatefulSet 的 `.spec.updateStrategy.type` 被设置为 `RollingUpdate` 时,
StatefulSet 控制器会删除和重建 StatefulSet 中的每个 Pod。
它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。
Kubernetes 控制面会等到被更新的 Pod 进入 Running 和 Ready 状态,然后再更新其前身。
如果你设置了 `.spec.minReadySeconds`(查看[最短就绪秒数](#minimum-ready-seconds)),控制面在 Pod 就绪后会额外等待一定的时间再执行下一步。
<!--
### Partitioned rolling updates {#partitions}
The `RollingUpdate` update strategy can be partitioned, by specifying a
`.spec.updateStrategy.rollingUpdate.partition`. If a partition is specified, all Pods with an
ordinal that is greater than or equal to the partition will be updated when the StatefulSet's
`.spec.template` is updated. All Pods with an ordinal that is less than the partition will not
be updated, and, even if they are deleted, they will be recreated at the previous version. If a
StatefulSet's `.spec.updateStrategy.rollingUpdate.partition` is greater than its `.spec.replicas`,
updates to its `.spec.template` will not be propagated to its Pods.
In most cases you will not need to use a partition, but they are useful if you want to stage an
update, roll out a canary, or perform a phased roll out.
-->
### 分区滚动更新 {#partitions}
通过声明 `.spec.updateStrategy.rollingUpdate.partition` 的方式,`RollingUpdate`
更新策略可以实现分区。
如果声明了一个分区,当 StatefulSet 的 `.spec.template` 被更新时,
所有序号大于等于该分区序号的 Pod 都会被更新。
所有序号小于该分区序号的 Pod 都不会被更新,并且,即使他们被删除也会依据之前的版本进行重建。
如果 StatefulSet 的 `.spec.updateStrategy.rollingUpdate.partition` 大于它的
`.spec.replicas`,对它的 `.spec.template` 的更新将不会传递到它的 Pod。
在大多数情况下,你不需要使用分区,但如果你希望进行阶段更新、执行金丝雀或执行
分阶段上线,则这些分区会非常有用。
<!--
### Maximum unavailable Pods
-->
### 最大不可用 Pod
{{< feature-state for_k8s_version="v1.24" state="alpha" >}}
<!--
You can control the maximum number of Pods that can be unavailable during an update
by specifying the `.spec.updateStrategy.rollingUpdate.maxUnavailable` field.
The value can be an absolute number (for example, `5`) or a percentage of desired
Pods (for example, `10%`). Absolute number is calculated from the percentage value
by rounding it up. This field cannot be 0. The default setting is 1.
-->
你可以通过指定 `.spec.updateStrategy.rollingUpdate.maxUnavailable`
字段来控制更新期间不可用的 Pod 的最大数量。
该值可以是绝对值(例如,“5”)或者是期望 Pod 个数的百分比(例如,`10%`)。
绝对值是根据百分比值四舍五入计算的。
该字段不能为 0。默认设置为 1。
<!--
This field applies to all Pods in the range `0` to `replicas - 1`. If there is any
unavailable Pod in the range `0` to `replicas - 1`, it will be counted towards
`maxUnavailable`.
-->
该字段适用于 `0``replicas - 1` 范围内的所有 Pod。
如果在 `0``replicas - 1` 范围内存在不可用 Pod,这类 Pod 将被计入 `maxUnavailable` 值。
<!--
{{< note >}}
The `maxUnavailable` field is in Alpha stage and it is honored only by API servers
that are running with the `MaxUnavailableStatefulSet`
[feature gate](/docs/reference/commmand-line-tools-reference/feature-gates/)
enabled.
{{< /note >}}
-->
{{< note >}}
`maxUnavailable` 字段处于 Alpha 阶段,仅当 API 服务器启用了 `MaxUnavailableStatefulSet`
[特性门控](/zh/docs/reference/commmand-line-tools-reference/feature-gates/)时才起作用。
{{< /note >}}
<!--
### Forced Rollback
When using [Rolling Updates](#rolling-updates) with the default
[Pod Management Policy](#pod-management-policies) (`OrderedReady`),
it's possible to get into a broken state that requires manual intervention to repair.
If you update the Pod template to a configuration that never becomes Running and
Ready (for example, due to a bad binary or application-level configuration error),
StatefulSet will stop the rollout and wait.
-->
### 强制回滚 {#forced-rollback}
在默认 [Pod 管理策略](#pod-management-policies)(`OrderedReady`) 下使用
[滚动更新](#rolling-updates) ,可能进入需要人工干预才能修复的损坏状态。
如果更新后 Pod 模板配置进入无法运行或就绪的状态(例如,由于错误的二进制文件
或应用程序级配置错误),StatefulSet 将停止回滚并等待。
<!--
In this state, it's not enough to revert the Pod template to a good configuration.
Due to a [known issue](https://github.com/kubernetes/kubernetes/issues/67250),
StatefulSet will continue to wait for the broken Pod to become Ready
(which never happens) before it will attempt to revert it back to the working
configuration.
After reverting the template, you must also delete any Pods that StatefulSet had
already attempted to run with the bad configuration.
StatefulSet will then begin to recreate the Pods using the reverted template.
-->
在这种状态下,仅将 Pod 模板还原为正确的配置是不够的。由于
[已知问题](https://github.com/kubernetes/kubernetes/issues/67250)StatefulSet
将继续等待损坏状态的 Pod 准备就绪(永远不会发生),然后再尝试将其恢复为正常工作配置。
恢复模板后,还必须删除 StatefulSet 尝试使用错误的配置来运行的 Pod。这样,
StatefulSet 才会开始使用被还原的模板来重新创建 Pod。
<!-- ## PersistentVolumeClaim retention -->
## PersistentVolumeClaim 保留 {#persistentvolumeclaim-retention}
{{< feature-state for_k8s_version="v1.23" state="alpha" >}}
<!--
The optional `.spec.persistentVolumeClaimRetentionPolicy` field controls if
and how PVCs are deleted during the lifecycle of a StatefulSet. You must enable the
`StatefulSetAutoDeletePVC` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
to use this field. Once enabled, there are two policies you can configure for each
StatefulSet:
-->
在 StatefulSet 的生命周期中,可选字段
`.spec.persistentVolumeClaimRetentionPolicy` 控制是否删除以及如何删除 PVC。
使用该字段,你必须启用 `StatefulSetAutoDeletePVC`
[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。
启用后,你可以为每个 StatefulSet 配置两个策略:
<!--
`whenDeleted`
: configures the volume retention behavior that applies when the StatefulSet is deleted
`whenScaled`
: configures the volume retention behavior that applies when the replica count of
the StatefulSet is reduced; for example, when scaling down the set.
For each policy that you can configure, you can set the value to either `Delete` or `Retain`.
-->
`whenDeleted`
: 配置删除 StatefulSet 时应用的卷保留行为
`whenScaled`
: 配置当 StatefulSet 的副本数减少时应用的卷保留行为;例如,缩小集合时。
对于你可以配置的每个策略,你可以将值设置为 `Delete``Retain`
<!--
`Delete`
: The PVCs created from the StatefulSet `volumeClaimTemplate` are deleted for each Pod
affected by the policy. With the `whenDeleted` policy all PVCs from the
`volumeClaimTemplate` are deleted after their Pods have been deleted. With the
`whenScaled` policy, only PVCs corresponding to Pod replicas being scaled down are
deleted, after their Pods have been deleted.
-->
`Delete`
: 对于受策略影响的每个 Pod,基于 StatefulSet 的 `volumeClaimTemplate` 字段创建的 PVC 都会被删除。
使用 `whenDeleted` 策略,所有来自 `volumeClaimTemplate` 的 PVC 在其 Pod 被删除后都会被删除。
使用 `whenScaled` 策略,只有与被缩减的 Pod 副本对应的 PVC 在其 Pod 被删除后才会被删除。
<!--
`Retain` (default)
: PVCs from the `volumeClaimTemplate` are not affected when their Pod is
deleted. This is the behavior before this new feature.
-->
`Retain`(默认)
: 来自 `volumeClaimTemplate` 的 PVC 在 Pod 被删除时不受影响。这是此新功能之前的行为。
<!--
Bear in mind that these policies **only** apply when Pods are being removed due to the
StatefulSet being deleted or scaled down. For example, if a Pod associated with a StatefulSet
fails due to node failure, and the control plane creates a replacement Pod, the StatefulSet
retains the existing PVC. The existing volume is unaffected, and the cluster will attach it to
the node where the new Pod is about to launch.
The default for policies is `Retain`, matching the StatefulSet behavior before this new feature.
Here is an example policy.
-->
请记住,这些策略**仅**适用于由于 StatefulSet 被删除或被缩小而被删除的 Pod。
例如,如果与 StatefulSet 关联的 Pod 由于节点故障而失败,
并且控制平面创建了替换 Pod,则 StatefulSet 保留现有的 PVC。
现有卷不受影响,集群会将其附加到新 Pod 即将启动的节点上。
策略的默认值为 `Retain`,与此新功能之前的 StatefulSet 行为相匹配。
这是一个示例策略。
```yaml
apiVersion: apps/v1
kind: StatefulSet
...
spec:
persistentVolumeClaimRetentionPolicy:
whenDeleted: Retain
whenScaled: Delete
...
```
<!--
The StatefulSet {{<glossary_tooltip text="controller" term_id="controller">}} adds [owner
references](/docs/concepts/overview/working-with-objects/owners-dependents/#owner-references-in-object-specifications)
to its PVCs, which are then deleted by the {{<glossary_tooltip text="garbage collector"
term_id="garbage-collection">}} after the Pod is terminated. This enables the Pod to
cleanly unmount all volumes before the PVCs are deleted (and before the backing PV and
volume are deleted, depending on the retain policy). When you set the `whenDeleted`
policy to `Delete`, an owner reference to the StatefulSet instance is placed on all PVCs
associated with that StatefulSet.
-->
StatefulSet {{<glossary_tooltip text="控制器" term_id="controller">}}为其 PVC 添加了
[属主引用](/zh/docs/concepts/overview/working-with-objects/owners-dependents/#owner-references-in-object-specifications)
这些 PVC 在 Pod 终止后被{{<glossary_tooltip text="垃圾回收器" term_id="garbage-collection">}}删除。
这使 Pod 能够在删除 PVC 之前(以及在删除后备 PV 和卷之前,取决于保留策略)干净地卸载所有卷。
当你设置 `whenDeleted` 删除策略,对 StatefulSet 实例的属主引用放置在与该 StatefulSet 关联的所有 PVC 上。
<!--
The `whenScaled` policy must delete PVCs only when a Pod is scaled down, and not when a
Pod is deleted for another reason. When reconciling, the StatefulSet controller compares
its desired replica count to the actual Pods present on the cluster. Any StatefulSet Pod
whose id greater than the replica count is condemned and marked for deletion. If the
`whenScaled` policy is `Delete`, the condemned Pods are first set as owners to the
associated StatefulSet template PVCs, before the Pod is deleted. This causes the PVCs
to be garbage collected after only the condemned Pods have terminated.
-->
`whenScaled` 策略必须仅在 Pod 缩减时删除 PVC,而不是在 Pod 因其他原因被删除时删除。
执行协调操作时,StatefulSet 控制器将其所需的副本数与集群上实际存在的 Pod 进行比较。
对于 StatefulSet 中的所有 Pod 而言,如果其 ID 大于副本数,则将被废弃并标记为需要删除。
如果 `whenScaled` 策略是 `Delete`,则在删除 Pod 之前,
首先将已销毁的 Pod 设置为与 StatefulSet 模板 对应的 PVC 的属主。
这会导致 PVC 仅在已废弃的 Pod 终止后被垃圾收集。
<!--
This means that if the controller crashes and restarts, no Pod will be deleted before its
owner reference has been updated appropriate to the policy. If a condemned Pod is
force-deleted while the controller is down, the owner reference may or may not have been
set up, depending on when the controller crashed. It may take several reconcile loops to
update the owner references, so some condemned Pods may have set up owner references and
other may not. For this reason we recommend waiting for the controller to come back up,
which will verify owner references before terminating Pods. If that is not possible, the
operator should verify the owner references on PVCs to ensure the expected objects are
deleted when Pods are force-deleted.
-->
这意味着如果控制器崩溃并重新启动,在其属主引用更新到适合策略的 Pod 之前,不会删除任何 Pod。
如果在控制器关闭时强制删除了已废弃的 Pod,则属主引用可能已被设置,也可能未被设置,具体取决于控制器何时崩溃。
更新属主引用可能需要几个协调循环,因此一些已废弃的 Pod 可能已经被设置了属主引用,而其他可能没有。
出于这个原因,我们建议等待控制器恢复,控制器将在终止 Pod 之前验证属主引用。
如果这不可行,则操作员应验证 PVC 上的属主引用,以确保在强制删除 Pod 时删除预期的对象。
<!--
### Replicas
`.spec.replicas` is an optional field that specifies the number of desired Pods. It defaults to 1.
Should you manually scale a deployment, example via `kubectl scale
statefulset statefulset --replicas=X`, and then you update that StatefulSet
based on a manifest (for example: by running `kubectl apply -f
statefulset.yaml`), then applying that manifest overwrites the manual scaling
that you previously did.
-->
### 副本数 {#replicas}
`.spec.replicas` 是一个可选字段,用于指定所需 Pod 的数量。它的默认值为 1。
如果你手动扩缩已部署的负载,例如通过 `kubectl scale statefulset statefulset --replicas=X`
然后根据清单更新 StatefulSet(例如:通过运行 `kubectl apply -f statefulset.yaml`),
那么应用该清单的操作会覆盖你之前所做的手动缩放。
<!--
If a [HorizontalPodAutoscaler](/docs/tasks/run-application/horizontal-pod-autoscale/)
(or any similar API for horizontal scaling) is managing scaling for a
Statefulset, don't set `.spec.replicas`. Instead, allow the Kubernetes
{{<glossary_tooltip text="control plane" term_id="control-plane" >}} to manage
the `.spec.replicas` field automatically.
-->
如果 [HorizontalPodAutoscaler](/zh/docs/tasks/run-application/horizontal-pod-autoscale/)
(或任何类似的水平缩放 API)正在管理 Statefulset 的缩放,
请不要设置 `.spec.replicas`
相反,允许 Kubernetes 控制平面自动管理 `.spec.replicas` 字段。
## {{% heading "whatsnext" %}}
<!--
* Learn about [Pods](/docs/concepts/workloads/pods).
* Find out how to use StatefulSets
* Follow an example of [deploying a stateful application](/docs/tutorials/stateful-application/basic-stateful-set/).
* Follow an example of [deploying Cassandra with Stateful Sets](/docs/tutorials/stateful-application/cassandra/).
* Follow an example of [running a replicated stateful application](/docs/tasks/run-application/run-replicated-stateful-application/).
* Learn how to [scale a StatefulSet](/docs/tasks/run-application/scale-stateful-set/).
* Learn what's involved when you [delete a StatefulSet](/docs/tasks/run-application/delete-stateful-set/).
* Learn how to [configure a Pod to use a volume for storage](/docs/tasks/configure-pod-container/configure-volume-storage/).
* Learn how to [configure a Pod to use a PersistentVolume for storage](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/).
* `StatefulSet` is a top-level resource in the Kubernetes REST API.
Read the {{< api-reference page="workload-resources/stateful-set-v1" >}}
object definition to understand the API for stateful sets.
* Read about [PodDisruptionBudget](/docs/concepts/workloads/pods/disruptions/) and how
you can use it to manage application availability during disruptions.
-->
* 了解 [Pod](/zh/docs/concepts/workloads/pods)。
* 了解如何使用 StatefulSet
* 跟随示例[部署有状态应用](/zh/docs/tutorials/stateful-application/basic-stateful-set/)。
* 跟随示例[使用 StatefulSet 部署 Cassandra](/zh/docs/tutorials/stateful-application/cassandra/)。
* 跟随示例[运行多副本的有状态应用程序](/zh/docs/tasks/run-application/run-replicated-stateful-application/)。
* 了解如何[扩缩 StatefulSet](/zh/docs/tasks/run-application/scale-stateful-set/)。
* 了解[删除 StatefulSet](/zh/docs/tasks/run-application/delete-stateful-set/)涉及到的操作。
* 了解如何[配置 Pod 以使用卷进行存储](/zh/docs/tasks/configure-pod-container/configure-volume-storage/)。
* 了解如何[配置 Pod 以使用 PersistentVolume 作为存储](/zh/docs/tasks/configure-pod-container/configure-persistent-volume-storage/)。
* `StatefulSet` 是 Kubernetes REST API 中的顶级资源。阅读 {{< api-reference page="workload-resources/stateful-set-v1" >}}
对象定义理解关于该资源的 API。
* 阅读 [Pod 干扰预算(Disruption Budget](/zh/docs/concepts/workloads/pods/disruptions/),了解如何在干扰下运行高度可用的应用。
@@ -0,0 +1,128 @@
---
title: 已完成 Job 的自动清理
content_type: concept
weight: 70
---
<!--
title: Automatic Clean-up for Finished Jobs
content_type: concept
weight: 70
-->
<!-- overview -->
{{< feature-state for_k8s_version="v1.23" state="stable" >}}
<!--
TTL-after-finished {{<glossary_tooltip text="controller" term_id="controller">}} provides a
TTL (time to live) mechanism to limit the lifetime of resource objects that
have finished execution. TTL controller only handles
{{< glossary_tooltip text="Jobs" term_id="job" >}}.
-->
TTL-after-finished {{<glossary_tooltip text="控制器" term_id="controller">}} 提供了一种 TTL 机制来限制已完成执行的资源对象的生命周期。
TTL 控制器目前只处理 {{< glossary_tooltip text="Job" term_id="job" >}}。
<!-- body -->
<!--
## TTL-after-finished Controller
The TTL-after-finished controller is only supported for Jobs. A cluster operator can use this feature to clean
up finished Jobs (either `Complete` or `Failed`) automatically by specifying the
`.spec.ttlSecondsAfterFinished` field of a Job, as in this
[example](/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically).
-->
## TTL-after-finished 控制器
TTL-after-finished 控制器只支持 Job。集群操作员可以通过指定 Job 的 `.spec.ttlSecondsAfterFinished`
字段来自动清理已结束的作业(`Complete``Failed`),如
[示例](/zh/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically)
所示。
<!--
The TTL-after-finished controller will assume that a job is eligible to be cleaned up
TTL seconds after the job has finished, in other words, when the TTL has expired. When the
TTL-after-finished controller cleans up a job, it will delete it cascadingly, that is to say it will delete
its dependent objects together with it. Note that when the job is deleted,
its lifecycle guarantees, such as finalizers, will be honored.
-->
TTL-after-finished 控制器假设作业能在执行完成后的 TTL 秒内被清理,也就是当 TTL 过期后。
当 TTL 控制器清理作业时,它将做级联删除操作,即删除资源对象的同时也删除其依赖对象。
注意,当资源被删除时,由该资源的生命周期保证其终结器(Finalizers)等被执行。
<!--
The TTL seconds can be set at any time. Here are some examples for setting the
`.spec.ttlSecondsAfterFinished` field of a Job:
-->
可以随时设置 TTL 秒。以下是设置 Job 的 `.spec.ttlSecondsAfterFinished` 字段的一些示例:
<!--
* Specify this field in the job manifest, so that a Job can be cleaned up
automatically some time after it finishes.
* Set this field of existing, already finished jobs, to adopt this new feature.
* Use a
[mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
to set this field dynamically at job creation time. Cluster administrators can
use this to enforce a TTL policy for finished jobs.
* Use a
[mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
to set this field dynamically after the job has finished, and choose
different TTL values based on job status, labels, etc.
-->
* 在作业清单(manifest)中指定此字段,以便 Job 在完成后的某个时间被自动清除。
* 将此字段设置为现有的、已完成的作业,以采用此新功能。
* 在创建作业时使用 [mutating admission webhook](/zh/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
动态设置该字段。集群管理员可以使用它对完成的作业强制执行 TTL 策略。
* 使用 [mutating admission webhook](/zh/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
在作业完成后动态设置该字段,并根据作业状态、标签等选择不同的 TTL 值。
<!--
## Caveat
### Updating TTL Seconds
Note that the TTL period, e.g. `.spec.ttlSecondsAfterFinished` field of Jobs,
can be modified after the job is created or has finished. However, once the
Job becomes eligible to be deleted (when the TTL has expired), the system won't
guarantee that the Jobs will be kept, even if an update to extend the TTL
returns a successful API response.
-->
## 警告
### 更新 TTL 秒数
请注意,在创建 Job 或已经执行结束后,仍可以修改其 TTL 周期,例如 Job 的
`.spec.ttlSecondsAfterFinished` 字段。
但是一旦 Job 变为可被删除状态(当其 TTL 已过期时),即使你通过 API 增加其 TTL
时长得到了成功的响应,系统也不保证 Job 将被保留。
<!--
### Time Skew
Because TTL-after-finished controller uses timestamps stored in the Kubernetes resources to
determine whether the TTL has expired or not, this feature is sensitive to time
skew in the cluster, which may cause TTL-after-finished controller to clean up resource objects
at the wrong time.
-->
### 时间偏差 {#time-skew}
由于 TTL-after-finished 控制器使用存储在 Kubernetes 资源中的时间戳来确定 TTL 是否已过期,
因此该功能对集群中的时间偏差很敏感,这可能导致 TTL-after-finished 控制器在错误的时间清理资源对象。
<!--
Clocks aren't always correct, but the difference should be
very small. Please be aware of this risk when setting a non-zero TTL.
-->
时钟并不总是如此正确,但差异应该很小。
设置非零 TTL 时请注意避免这种风险。
## {{% heading "whatsnext" %}}
<!--
* [Clean up Jobs automatically](/docs/concepts/workloads/controllers/jobs-run-to-completion/#clean-up-finished-jobs-automatically)
* [Design doc](https://github.com/kubernetes/enhancements/blob/master/keps/sig-apps/592-ttl-after-finish/README.md)
-->
* [自动清理 Job](/zh/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically)
* [设计文档](https://github.com/kubernetes/enhancements/blob/master/keps/sig-apps/592-ttl-after-finish/README.md)