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,234 @@
---
title: API 概述
weight: 10
no_list: true
card:
name: reference
weight: 50
---
<!-- overview -->
<!--
This section provides reference information for the Kubernetes API.
-->
本文提供了 Kubernetes API 的参考信息。
<!--
The REST API is the fundamental fabric of Kubernetes. All operations and
communications between components, and external user commands are REST API
calls that the API Server handles. Consequently, everything in the Kubernetes
platform is treated as an API object and has a corresponding entry in the
[API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/).
-->
REST API 是 Kubernetes 的基本结构。
所有操作和组件之间的通信及外部用户命令都是调用 API 服务器处理的 REST API。
因此,Kubernetes 平台视一切皆为 API 对象,
且它们在 [API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) 中有相应的定义。
<!--
The [Kubernetes API reference](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)
lists the API for Kubernetes version {{< param "version" >}}.
-->
[Kubernetes API 参考](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)列
出了 Kubernetes {{< param "version" >}} 版本的 API。
<!--
For general background information, read
[The Kubernetes API](/docs/concepts/overview/kubernetes-api/).
[Controlling Access to the Kubernetes API](/docs/concepts/security/controlling-access/)
describes how clients can authenticate to the Kubernetes API server, and how their
requests are authorized.
-->
如需了解一般背景信息,请查阅 [Kubernetes API](/zh/docs/concepts/overview/kubernetes-api/)。
[Kubernetes API 控制访问](/zh/docs/concepts/security/controlling-access/)描述了客户端如何
向 Kubernetes API 服务器进行身份认证以及他们的请求如何被鉴权。
<!--
## API versioning
-->
## API 版本控制
<!--
The JSON and Protobuf serialization schemas follow the same guidelines for
schema changes. The following descriptions cover both formats.
-->
JSON 和 Protobuf 序列化模式遵循相同的模式更改原则。
以下描述涵盖了这两种格式。
<!--
The API versioning and software versioning are indirectly related.
The [API and release versioning proposal](https://git.k8s.io/community/contributors/design-proposals/release/versioning.md)
describes the relationship between API versioning and software versioning.
-->
API 版本控制和软件版本控制是间接相关的。
[API 和发布版本控制提案](https://git.k8s.io/community/contributors/design-proposals/release/versioning.md)
描述了 API 版本控制和软件版本控制间的关系。
<!--
Different API versions indicate different levels of stability and support. You
can find more information about the criteria for each level in the
[API Changes documentation](https://git.k8s.io/community/contributors/devel/sig-architecture/api_changes.md#alpha-beta-and-stable-versions).
-->
不同的 API 版本代表着不同的稳定性和支持级别。
你可以在 [API 变更文档](https://git.k8s.io/community/contributors/devel/sig-architecture/api_changes.md#alpha-beta-and-stable-versions)
中查看到更多的不同级别的判定标准。
<!--
Here's a summary of each level:
-->
下面是每个级别的摘要:
<!--
- Alpha:
- The version names contain `alpha` (for example, `v1alpha1`).
- The software may contain bugs. Enabling a feature may expose bugs. A
feature may be disabled by default.
- The support for a feature may be dropped at any time without notice.
- The API may change in incompatible ways in a later software release without notice.
- The software is recommended for use only in short-lived testing clusters,
due to increased risk of bugs and lack of long-term support.
-->
- Alpha:
- 版本名称包含 `alpha`(例如,`v1alpha1`)。
- 软件可能会有 Bug。启用某个特性可能会暴露出 Bug。
某些特性可能默认禁用。
- 对某个特性的支持可能会随时被删除,恕不另行通知。
- API 可能在以后的软件版本中以不兼容的方式更改,恕不另行通知。
- 由于缺陷风险增加和缺乏长期支持,建议该软件仅用于短期测试集群。
<!--
- Beta:
- The version names contain `beta` (for example, `v2beta3`).
- The software is well tested. Enabling a feature is considered safe.
Features are enabled by default.
- The support for a feature will not be dropped, though the details may change.
-->
- Beta:
- 版本名称包含 `beta` (例如, `v2beta3`)。
- 软件被很好的测试过。启用某个特性被认为是安全的。
特性默认开启。
- 尽管一些特性会发生细节上的变化,但它们将会被长期支持。
<!--
- The schema and/or semantics of objects may change in incompatible ways in
a subsequent beta or stable release. When this happens, migration
instructions are provided. Schema changes may require deleting, editing, and
re-creating API objects. The editing process may not be straightforward.
The migration may require downtime for applications that rely on the feature.
- The software is not recommended for production uses. Subsequent releases
may introduce incompatible changes. If you have multiple clusters which
can be upgraded independently, you may be able to relax this restriction.
-->
- 在随后的 Beta 版或稳定版中,对象的模式和(或)语义可能以不兼容的方式改变。
当这种情况发生时,将提供迁移说明。
模式更改可能需要删除、编辑和重建 API 对象。
编辑过程可能并不简单。
对于依赖此功能的应用程序,可能需要停机迁移。
- 该版本的软件不建议生产使用。
后续发布版本可能会有不兼容的变动。
如果你有多个集群可以独立升级,可以放宽这一限制。
<!--
Please try beta features and provide feedback. After the features exit beta, it
may not be practical to make more changes.
-->
{{< note >}}
请试用测试版特性时并提供反馈。特性完成 Beta 阶段测试后,
就可能不会有太多的变更了。
{{< /note >}}
<!--
- Stable:
- The version name is `vX` where `X` is an integer.
- The stable versions of features appear in released software for many subsequent versions.
-->
- Stable:
- 版本名称如 `vX`,其中 `X` 为整数。
- 特性的稳定版本会出现在后续很多版本的发布软件中。
<!--## API groups-->
## API 组
<!--
[API groups](https://git.k8s.io/community/contributors/design-proposals/api-machinery/api-group.md)
make it easier to extend the Kubernetes API.
The API group is specified in a REST path and in the `apiVersion` field of a
serialized object.
-->
[API 组](https://git.k8s.io/community/contributors/design-proposals/api-machinery/api-group.md)
能够简化对 Kubernetes API 的扩展。
API 组信息出现在REST 路径中,也出现在序列化对象的 `apiVersion` 字段中。
<!--
There are several API groups in Kubernetes:
* The *core* (also called *legacy*) group is found at REST path `/api/v1`.
The core group is not specified as part of the `apiVersion` field, for
example, `apiVersion: v1`.
* The named groups are at REST path `/apis/$GROUP_NAME/$VERSION` and use
`apiVersion: $GROUP_NAME/$VERSION` (for example, `apiVersion: batch/v1`).
You can find the full list of supported API groups in
[Kubernetes API reference](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#-strong-api-groups-strong-).
-->
以下是 Kubernetes 中的几个组:
* *核心*(也叫 *legacy*)组的 REST 路径为 `/api/v1`
核心组并不作为 `apiVersion` 字段的一部分,例如, `apiVersion: v1`
* 指定的组位于 REST 路径 `/apis/$GROUP_NAME/$VERSION`
并且使用 `apiVersion: $GROUP_NAME/$VERSION` (例如, `apiVersion: batch/v1`)。
你可以在 [Kubernetes API 参考文档](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#-strong-api-groups-strong-)
中查看全部的 API 组。
<!--
## Enabling or disabling API groups {#enabling-or-disabling}
Certain resources and API groups are enabled by default. You can enable or
disable them by setting `--runtime-config` on the API server. The
`--runtime-config` flag accepts comma separated `<key>[=<value>]` pairs
describing the runtime configuration of the API server. If the `=<value>`
part is omitted, it is treated as if `=true` is specified. For example:
- to disable `batch/v1`, set `--runtime-config=batch/v1=false`
- to enable `batch/v2alpha1`, set `--runtime-config=batch/v2alpha1`
- to enable a specific version of an API, such as `storage.k8s.io/v1beta1/csistoragecapacities`, set `--runtime-config=storage.k8s.io/v1beta1/csistoragecapacities`
-->
## 启用或禁用 API 组 {#enabling-or-disabling}
资源和 API 组是在默认情况下被启用的。
你可以通过在 API 服务器上设置 `--runtime-config` 参数来启用或禁用它们。
`--runtime-config` 参数接受逗号分隔的 `<key>[=<value>]` 对,
来描述 API 服务器的运行时配置。如果省略了 `=<value>` 部分,那么视其指定为 `=true`
例如:
- 禁用 `batch/v1` 对应参数设置 `--runtime-config=batch/v1=false`
- 启用 `batch/v2alpha1` 对应参数设置 `--runtime-config=batch/v2alpha1`
- 要启用特定版本的 API,如 `storage.k8s.io/v1beta1/csistoragecapacities`,可以设置
`--runtime-config=storage.k8s.io/v1beta1/csistoragecapacities`
<!--
When you enable or disable groups or resources, you need to restart the API
server and controller manager to pick up the `--runtime-config` changes.
-->
{{< note >}}
启用或禁用组或资源时,
你需要重启 API 服务器和控制器管理器来使 `--runtime-config` 生效。
{{< /note >}}
<!--
## Persistence
-->
## 持久化
<!--
Kubernetes stores its serialized state in terms of the API resources by writing them into
-->
Kubernetes 通过 API 资源来将序列化的状态写到 {{< glossary_tooltip term_id="etcd" >}} 中存储。
## {{% heading "whatsnext" %}}
<!--
- Learn more about [API conventions](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#api-conventions)
- Read the design documentation for
[aggregator](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md)
-->
- 进一步了解 [API 惯例](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#api-conventions)
- 阅读 [聚合器](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,159 @@
---
title: 客户端库
content_type: concept
weight: 30
---
<!--
title: Client Libraries
reviewers:
- ahmetb
content_type: concept
weight: 30
-->
<!-- overview -->
<!--
This page contains an overview of the client libraries for using the Kubernetes
API from various programming languages.
-->
本页面包含基于各种编程语言使用 Kubernetes API 的客户端库概述。
<!-- body -->
<!--
To write applications using the [Kubernetes REST API](/docs/reference/using-api/),
you do not need to implement the API calls and request/response types yourself.
You can use a client library for the programming language you are using.
-->
在使用 [Kubernetes REST API](/zh/docs/reference/using-api/) 编写应用程序时,
你并不需要自己实现 API 调用和 “请求/响应” 类型。
你可以根据自己的编程语言需要选择使用合适的客户端库。
<!--
Client libraries often handle common tasks such as authentication for you.
Most client libraries can discover and use the Kubernetes Service Account to
authenticate if the API client is running inside the Kubernetes cluster, or can
understand the [kubeconfig file](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
format to read the credentials and the API Server address.
-->
客户端库通常为你处理诸如身份验证之类的常见任务。
如果 API 客户端在 Kubernetes 集群中运行,大多数客户端库可以发现并使用 Kubernetes 服务帐户进行身份验证,
或者能够理解 [kubeconfig 文件](/zh/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
格式来读取凭据和 API 服务器地址。
<!--
## Officially-supported Kubernetes client libraries
-->
## 官方支持的 Kubernetes 客户端库 {#officially-supported-kubernetes-client-libraries}
<!--
The following client libraries are officially maintained by
[Kubernetes SIG API Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery).
-->
以下客户端库由 [Kubernetes SIG API Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery) 正式维护。
<!--
| Language | Client Library | Sample Programs |
|----------|----------------|-----------------|
| dotnet | [github.com/kubernetes-client/csharp](https://github.com/kubernetes-client/csharp) | [browse](https://github.com/kubernetes-client/csharp/tree/master/examples/simple)
| Go | [github.com/kubernetes/client-go/](https://github.com/kubernetes/client-go/) | [browse](https://github.com/kubernetes/client-go/tree/master/examples)
| Haskell | [github.com/kubernetes-client/haskell](https://github.com/kubernetes-client/haskell) | [browse](https://github.com/kubernetes-client/haskell/tree/master/kubernetes-client/example)
| Java | [github.com/kubernetes-client/java](https://github.com/kubernetes-client/java/) | [browse](https://github.com/kubernetes-client/java#installation)
| JavaScript | [github.com/kubernetes-client/javascript](https://github.com/kubernetes-client/javascript) | [browse](https://github.com/kubernetes-client/javascript/tree/master/examples)
| Python | [github.com/kubernetes-client/python/](https://github.com/kubernetes-client/python/) | [browse](https://github.com/kubernetes-client/python/tree/master/examples)
-->
| 语言 | 客户端库 | 样例程序 |
|---------|-----------------|-----------------|
| dotnet | [github.com/kubernetes-client/csharp](https://github.com/kubernetes-client/csharp) | [浏览](https://github.com/kubernetes-client/csharp/tree/master/examples/simple)
| Go | [github.com/kubernetes/client-go/](https://github.com/kubernetes/client-go/) | [浏览](https://github.com/kubernetes/client-go/tree/master/examples)
| Haskell | [github.com/kubernetes-client/haskell](https://github.com/kubernetes-client/haskell) | [浏览](https://github.com/kubernetes-client/haskell/tree/master/kubernetes-client/example)
| Java | [github.com/kubernetes-client/java](https://github.com/kubernetes-client/java/) | [浏览](https://github.com/kubernetes-client/java#installation)
| JavaScript | [github.com/kubernetes-client/javascript](https://github.com/kubernetes-client/javascript) | [浏览](https://github.com/kubernetes-client/javascript/tree/master/examples)
| Python | [github.com/kubernetes-client/python/](https://github.com/kubernetes-client/python/) | [浏览](https://github.com/kubernetes-client/python/tree/master/examples)
<!--
## Community-maintained client libraries
-->
## 社区维护的客户端库 {#community-maintained-client-libraries}
{{% thirdparty-content %}}
<!--
The following Kubernetes API client libraries are provided and maintained by
their authors, not the Kubernetes team.
-->
以下 Kubernetes API 客户端库是由社区,而非 Kubernetes 团队支持、维护的。
<!--
| Language | Client Library |
| -------------------- | ---------------------------------------- |
| Clojure | [github.com/yanatan16/clj-kubernetes-api](https://github.com/yanatan16/clj-kubernetes-api) |
| DotNet | [github.com/tonnyeremin/kubernetes_gen](https://github.com/tonnyeremin/kubernetes_gen) |
| DotNet (RestSharp) | [github.com/masroorhasan/Kubernetes.DotNet](https://github.com/masroorhasan/Kubernetes.DotNet) |
| Elixir | [github.com/obmarg/kazan](https://github.com/obmarg/kazan/) |
| Elixir | [github.com/coryodaniel/k8s](https://github.com/coryodaniel/k8s) |
| Go | [github.com/ericchiang/k8s](https://github.com/ericchiang/k8s) |
| Java (OSGi) | [bitbucket.org/amdatulabs/amdatu-kubernetes](https://bitbucket.org/amdatulabs/amdatu-kubernetes) |
| Java (Fabric8, OSGi) | [github.com/fabric8io/kubernetes-client](https://github.com/fabric8io/kubernetes-client) |
| Java | [github.com/manusa/yakc](https://github.com/manusa/yakc) |
| Lisp | [github.com/brendandburns/cl-k8s](https://github.com/brendandburns/cl-k8s) |
| Lisp | [github.com/xh4/cube](https://github.com/xh4/cube) |
| Node.js (TypeScript) | [github.com/Goyoo/node-k8s-client](https://github.com/Goyoo/node-k8s-client) |
| Node.js | [github.com/ajpauwels/easy-k8s](https://github.com/ajpauwels/easy-k8s)
| Node.js | [github.com/godaddy/kubernetes-client](https://github.com/godaddy/kubernetes-client) |
| Node.js | [github.com/tenxcloud/node-kubernetes-client](https://github.com/tenxcloud/node-kubernetes-client) |
| Perl | [metacpan.org/pod/Net::Kubernetes](https://metacpan.org/pod/Net::Kubernetes) |
| PHP | [github.com/allansun/kubernetes-php-client](https://github.com/allansun/kubernetes-php-client) |
| PHP | [github.com/maclof/kubernetes-client](https://github.com/maclof/kubernetes-client) |
| PHP | [github.com/travisghansen/kubernetes-client-php](https://github.com/travisghansen/kubernetes-client-php) |
| PHP | [github.com/renoki-co/php-k8s](https://github.com/renoki-co/php-k8s) |
| Python | [github.com/fiaas/k8s](https://github.com/fiaas/k8s) |
| Python | [github.com/gtsystem/lightkube](https://github.com/gtsystem/lightkube) |
| Python | [github.com/mnubo/kubernetes-py](https://github.com/mnubo/kubernetes-py) |
| Python | [github.com/tomplus/kubernetes_asyncio](https://github.com/tomplus/kubernetes_asyncio) |
| Python | [github.com/Frankkkkk/pykorm](https://github.com/Frankkkkk/pykorm) |
| Ruby | [github.com/abonas/kubeclient](https://github.com/abonas/kubeclient) |
| Ruby | [github.com/k8s-ruby/k8s-ruby](https://github.com/k8s-ruby/k8s-ruby) |
| Ruby | [github.com/kontena/k8s-client](https://github.com/kontena/k8s-client) |
| Rust | [github.com/clux/kube-rs](https://github.com/clux/kube-rs) |
| Rust | [github.com/ynqa/kubernetes-rust](https://github.com/ynqa/kubernetes-rust) |
| Scala | [github.com/hagay3/skuber](https://github.com/hagay3/skuber) |
| Scala | [github.com/joan38/kubernetes-client](https://github.com/joan38/kubernetes-client) |
-->
| 语言 | 客户端库 |
|----------------------| ---------------------------------------- |
| Clojure | [github.com/yanatan16/clj-kubernetes-api](https://github.com/yanatan16/clj-kubernetes-api) |
| DotNet | [github.com/tonnyeremin/kubernetes_gen](https://github.com/tonnyeremin/kubernetes_gen) |
| DotNet (RestSharp) | [github.com/masroorhasan/Kubernetes.DotNet](https://github.com/masroorhasan/Kubernetes.DotNet) |
| Elixir | [github.com/obmarg/kazan](https://github.com/obmarg/kazan/) |
| Elixir | [github.com/coryodaniel/k8s](https://github.com/coryodaniel/k8s) |
| Go | [github.com/ericchiang/k8s](https://github.com/ericchiang/k8s) |
| Java (OSGi) | [bitbucket.org/amdatulabs/amdatu-kubernetes](https://bitbucket.org/amdatulabs/amdatu-kubernetes) |
| Java (Fabric8, OSGi) | [github.com/fabric8io/kubernetes-client](https://github.com/fabric8io/kubernetes-client) |
| Java | [github.com/manusa/yakc](https://github.com/manusa/yakc) |
| Lisp | [github.com/brendandburns/cl-k8s](https://github.com/brendandburns/cl-k8s) |
| Lisp | [github.com/xh4/cube](https://github.com/xh4/cube) |
| Node.js (TypeScript) | [github.com/Goyoo/node-k8s-client](https://github.com/Goyoo/node-k8s-client) |
| Node.js | [github.com/ajpauwels/easy-k8s](https://github.com/ajpauwels/easy-k8s)
| Node.js | [github.com/godaddy/kubernetes-client](https://github.com/godaddy/kubernetes-client) |
| Node.js | [github.com/tenxcloud/node-kubernetes-client](https://github.com/tenxcloud/node-kubernetes-client) |
| Perl | [metacpan.org/pod/Net::Kubernetes](https://metacpan.org/pod/Net::Kubernetes) |
| PHP | [github.com/allansun/kubernetes-php-client](https://github.com/allansun/kubernetes-php-client) |
| PHP | [github.com/maclof/kubernetes-client](https://github.com/maclof/kubernetes-client) |
| PHP | [github.com/travisghansen/kubernetes-client-php](https://github.com/travisghansen/kubernetes-client-php) |
| PHP | [github.com/renoki-co/php-k8s](https://github.com/renoki-co/php-k8s) |
| Python | [github.com/fiaas/k8s](https://github.com/fiaas/k8s) |
| Python | [github.com/gtsystem/lightkube](https://github.com/gtsystem/lightkube) |
| Python | [github.com/mnubo/kubernetes-py](https://github.com/mnubo/kubernetes-py) |
| Python | [github.com/tomplus/kubernetes_asyncio](https://github.com/tomplus/kubernetes_asyncio) |
| Python | [github.com/Frankkkkk/pykorm](https://github.com/Frankkkkk/pykorm) |
| Ruby | [github.com/abonas/kubeclient](https://github.com/abonas/kubeclient) |
| Ruby | [github.com/k8s-ruby/k8s-ruby](https://github.com/k8s-ruby/k8s-ruby) |
| Ruby | [github.com/kontena/k8s-client](https://github.com/kontena/k8s-client) |
| Rust | [github.com/clux/kube-rs](https://github.com/clux/kube-rs) |
| Rust | [github.com/ynqa/kubernetes-rust](https://github.com/ynqa/kubernetes-rust) |
| Scala | [github.com/hagay3/skuber](https://github.com/hagay3/skuber) |
| Scala | [github.com/joan38/kubernetes-client](https://github.com/joan38/kubernetes-client) |
| Swift | [github.com/swiftkube/client](https://github.com/swiftkube/client) |
@@ -0,0 +1,764 @@
---
title: 已弃用 API 的迁移指南
weight: 45
content_type: reference
---
<!--
reviewers:
- liggitt
- lavalamp
- thockin
- smarterclayton
title: "Deprecated API Migration Guide"
weight: 45
content_type: reference
-->
<!-- overview -->
<!--
As the Kubernetes API evolves, APIs are periodically reorganized or upgraded.
When APIs evolve, the old API is deprecated and eventually removed.
This page contains information you need to know when migrating from
deprecated API versions to newer and more stable API versions.
-->
随着 Kubernetes API 的演化,APIs 会周期性地被重组或升级。
当 APIs 演化时,老的 API 会被弃用并被最终删除。
本页面包含你在将已弃用 API 版本迁移到新的更稳定的 API 版本时需要了解的知识。
<!-- body -->
<!--
## Removed APIs by release
-->
## 各发行版本中移除的 API {#removed-apis-by-release}
### v1.27
<!--
The **v1.27** release will stop serving the following deprecated API versions:
-->
**v1.27** 发行版本中将去除以下已弃用的 API 版本:
#### CSIStorageCapacity {#csistoragecapacity-v127}
<!--
The **storage.k8s.io/v1beta1** API version of CSIStorageCapacity will no longer be served in v1.27.
* Migrate manifests and API clients to use the **storage.k8s.io/v1** API version, available since v1.24.
* All existing persisted objects are accessible via the new API
* No notable changes
-->
**storage.k8s.io/v1beta1** API版本的 CSIStorageCapacity 将不再在 v1.27 提供。
* 自 v1.24 版本起,迁移清单和 API 客户端使用 **storage.k8s.io/v1** API 版本
* 所有现有的持久化对象都可以通过新的 API 访问
* 没有需要额外注意的变更
### v1.26
<!--
The **v1.26** release will stop serving the following deprecated API versions:
-->
**v1.26** 发行版本中将去除以下已弃用的 API 版本:
<!--
#### Flow control resources {#flowcontrol-resources-v126}
-->
#### 流控制资源 {#flowcontrol-resources-v126}
<!--
The **flowcontrol.apiserver.k8s.io/v1beta1** API version of FlowSchema and PriorityLevelConfiguration will no longer be served in v1.26.
* Migrate manifests and API clients to use the **flowcontrol.apiserver.k8s.io/v1beta2** API version, available since v1.23.
* All existing persisted objects are accessible via the new API
* No notable changes
-->
**flowcontrol.apiserver.k8s.io/v1beta1** API 版本的 FlowSchema
和 PriorityLevelConfiguration 将不会在 v1.26 中提供。
* 迁移清单和 API 客户端使用 **flowcontrol.apiserver.k8s.io/v1beta2** API 版本,
此 API 从 v1.23 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
#### HorizontalPodAutoscaler {#horizontalpodautoscaler-v126}
<!--
The **autoscaling/v2beta2** API version of HorizontalPodAutoscaler will no longer be served in v1.26.
* Migrate manifests and API clients to use the **autoscaling/v2** API version, available since v1.23.
* All existing persisted objects are accessible via the new API
-->
**autoscaling/v2beta2** API 版本的 HorizontalPodAutoscaler 将不会在
v1.26 版本中提供。
* 迁移清单和 API 客户端使用 **autoscaling/v2** API 版本,
此 API 从 v1.23 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
### v1.25
<!--
The **v1.25** release will stop serving the following deprecated API versions:
-->
**v1.25** 发行版本将停止提供以下已废弃 API 版本:
#### CronJob {#cronjob-v125}
<!--
The **batch/v1beta1** API version of CronJob will no longer be served in v1.25.
* Migrate manifests and API clients to use the **batch/v1** API version, available since v1.21.
* All existing persisted objects are accessible via the new API
* No notable changes
-->
**batch/v1beta1** API 版本的 CronJob 将不会在 v1.25 版本中继续提供。
* 迁移清单和 API 客户端使用 **batch/v1** API 版本,此 API 从 v1.21 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
#### EndpointSlice {#endpointslice-v125}
<!--
The **discovery.k8s.io/v1beta1** API version of EndpointSlice will no longer be served in v1.25.
* Migrate manifests and API clients to use the **discovery.k8s.io/v1** API version, available since v1.21.
* All existing persisted objects are accessible via the new API
* Notable changes in **discovery.k8s.io/v1**:
* use per Endpoint `nodeName` field instead of deprecated `topology["kubernetes.io/hostname"]` field
* use per Endpoint `zone` field instead of deprecated `topology["topology.kubernetes.io/zone"]` field
* `topology` is replaced with the `deprecatedTopology` field which is not writable in v1
-->
**discovery.k8s.io/v1beta1** API 版本的 EndpointSlice 将不会在 v1.25 版本中继续提供。
* 迁移清单和 API 客户端使用 **discovery.k8s.io/v1** API 版本,此 API 从 v1.21 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* **discovery.k8s.io/v1** 中值得注意的变更有:
* 使用每个 Endpoint 的 `nodeName` 字段而不是已被弃用的
`topology["kubernetes.io/hostname"]` 字段;
* 使用每个 Endpoint 的 `zone` 字段而不是已被弃用的
`topology["kubernetes.io/zone"]` 字段;
* `topology` 字段被替换为 `deprecatedTopology`,并且在 v1 版本中不可写入。
#### Event {#event-v125}
<!--
The **events.k8s.io/v1beta1** API version of Event will no longer be served in v1.25.
* Migrate manifests and API clients to use the **events.k8s.io/v1** API version, available since v1.19.
* All existing persisted objects are accessible via the new API
-->
**events.k8s.io/v1beta1** API 版本的 Event 将不会在 v1.25 版本中继续提供。
* 迁移清单和 API 客户端使用 **events.k8s.io/v1** API 版本,此 API 从 v1.19 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes in **events.k8s.io/v1**:
* `type` is limited to `Normal` and `Warning`
* `involvedObject` is renamed to `regarding`
* `action`, `reason`, `reportingController`, and `reportingInstance` are required when creating new **events.k8s.io/v1** Events
* use `eventTime` instead of the deprecated `firstTimestamp` field (which is renamed to `deprecatedFirstTimestamp` and not permitted in new **events.k8s.io/v1** Events)
* use `series.lastObservedTime` instead of the deprecated `lastTimestamp` field (which is renamed to `deprecatedLastTimestamp` and not permitted in new **events.k8s.io/v1** Events)
* use `series.count` instead of the deprecated `count` field (which is renamed to `deprecatedCount` and not permitted in new **events.k8s.io/v1** Events)
* use `reportingController` instead of the deprecated `source.component` field (which is renamed to `deprecatedSource.component` and not permitted in new **events.k8s.io/v1** Events)
* use `reportingInstance` instead of the deprecated `source.host` field (which is renamed to `deprecatedSource.host` and not permitted in new **events.k8s.io/v1** Events)
-->
* **events.k8s.io/v1** 中值得注意的变更有:
* `type` 字段只能设置为 `Normal``Warning` 之一;
* `involvedObject` 字段被更名为 `regarding`
* `action``reason``reportingController``reportingInstance` 字段
在创建新的 **events.k8s.io/v1** 版本 Event 时都是必需的字段;
* 使用 `eventTime` 而不是已被弃用的 `firstTimestamp` 字段
(该字段已被更名为 `deprecatedFirstTimestamp`,且不允许出现在新的 **events.k8s.io/v1** Event 对象中);
* 使用 `series.lastObservedTime` 而不是已被弃用的 `lastTimestamp` 字段
(该字段已被更名为 `deprecatedLastTimestamp`,且不允许出现在新的 **events.k8s.io/v1** Event 对象中);
* 使用 `series.count` 而不是已被弃用的 `count` 字段
(该字段已被更名为 `deprecatedCount`,且不允许出现在新的 **events.k8s.io/v1** Event 对象中);
* 使用 `reportingController` 而不是已被弃用的 `source.component` 字段
(该字段已被更名为 `deprecatedSource.component`,且不允许出现在新的 **events.k8s.io/v1** Event 对象中);
* 使用 `reportingInstance` 而不是已被弃用的 `source.host` 字段
(该字段已被更名为 `deprecatedSource.host`,且不允许出现在新的 **events.k8s.io/v1** Event 对象中)。
#### HorizontalPodAutoscaler {#horizontalpodautoscaler-v125}
<!--
The **autoscaling/v2beta1** API version of HorizontalPodAutoscaler will no longer be served in v1.25.
* Migrate manifests and API clients to use the **autoscaling/v2** API version, available since v1.23.
* All existing persisted objects are accessible via the new API
-->
**autoscaling/v2beta1** API 版本的 HorizontalPodAutoscaler 将不会在 v1.25 版本中继续提供。
* 迁移清单和 API 客户端使用 **autoscaling/v2** API 版本,此 API 从 v1.23 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
#### PodDisruptionBudget {#poddisruptionbudget-v125}
<!--
The **policy/v1beta1** API version of PodDisruptionBudget will no longer be served in v1.25.
* Migrate manifests and API clients to use the **policy/v1** API version, available since v1.21.
* All existing persisted objects are accessible via the new API
* Notable changes in **policy/v1**:
* an empty `spec.selector` (`{}`) written to a `policy/v1` PodDisruptionBudget selects all pods in the namespace (in `policy/v1beta1` an empty `spec.selector` selected no pods). An unset `spec.selector` selects no pods in either API version.
-->
**policy/v1beta1** API 版本的 PodDisruptionBudget 将不会在 v1.25 版本中继续提供。
* 迁移清单和 API 客户端使用 **policy/v1** API 版本,此 API 从 v1.21 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* **policy/v1** 中需要额外注意的变更有:
*`policy/v1` 版本的 PodDisruptionBudget 中将 `spec.selector`
设置为空(`{}`)时会选择名字空间中的所有 Pods(在 `policy/v1beta1`
版本中,空的 `spec.selector` 不会选择任何 Pods)。如果 `spec.selector`
未设置,则在两个 API 版本下都不会选择任何 Pods。
#### PodSecurityPolicy {#psp-v125}
<!--
PodSecurityPolicy in the **policy/v1beta1** API version will no longer be served in v1.25, and the PodSecurityPolicy admission controller will be removed.
PodSecurityPolicy replacements are still under discussion, but current use can be migrated to
[3rd-party admission webhooks](/docs/reference/access-authn-authz/extensible-admission-controllers/) now.
-->
**policy/v1beta1** API 版本中的 PodSecurityPolicy 将不会在 v1.25 中提供,
并且 PodSecurityPolicy 准入控制器也会被删除。
PodSecurityPolicy 的替换方案仍在讨论过程中,不过当前的用法可以迁移到
[第三方准入性质的 Webhook](/zh/docs/reference/access-authn-authz/extensible-admission-controllers/)。
#### RuntimeClass {#runtimeclass-v125}
<!--
RuntimeClass in the **node.k8s.io/v1beta1** API version will no longer be served in v1.25.
* Migrate manifests and API clients to use the **node.k8s.io/v1** API version, available since v1.20.
* All existing persisted objects are accessible via the new API
* No notable changes
-->
**node.k8s.io/v1beta1** API 版本中的 RuntimeClass 将不会在 v1.25 中提供。
* 迁移清单和 API 客户端使用 **node.k8s.io/v1** API 版本,此 API 从 v1.20 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
### v1.22
<!--
The **v1.22** release stopped serving the following deprecated API versions:
-->
**v1.22** 发行版本停止提供以下已废弃 API 版本:
<!--
#### Webhook resources {#webhook-resources-v122}
-->
#### Webhook 资源 {#webhook-resources-v122}
<!--
The **admissionregistration.k8s.io/v1beta1** API version of MutatingWebhookConfiguration and ValidatingWebhookConfiguration is no longer served as of v1.22.
-->
**admissionregistration.k8s.io/v1beta1** API 版本的 MutatingWebhookConfiguration
和 ValidatingWebhookConfiguration 不在 v1.22 版本中继续提供。
<!--
* Migrate manifests and API clients to use the **admissionregistration.k8s.io/v1** API version, available since v1.16.
* All existing persisted objects are accessible via the new APIs
-->
* 迁移清单和 API 客户端使用 **admissionregistration.k8s.io/v1** API 版本,
此 API 从 v1.16 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes:
* `webhooks[*].failurePolicy` default changed from `Ignore` to `Fail` for v1
* `webhooks[*].matchPolicy` default changed from `Exact` to `Equivalent` for v1
* `webhooks[*].timeoutSeconds` default changed from `30s` to `10s` for v1
* `webhooks[*].sideEffects` default value is removed, and the field made required, and only `None` and `NoneOnDryRun` are permitted for v1
* `webhooks[*].admissionReviewVersions` default value is removed and the field made required for v1 (supported versions for AdmissionReview are `v1` and `v1beta1`)
* `webhooks[*].name` must be unique in the list for objects created via `admissionregistration.k8s.io/v1`
-->
* 值得注意的变更:
* `webhooks[*].failurePolicy` 在 v1 版本中默认值从 `Ignore` 改为 `Fail`
* `webhooks[*].matchPolicy` 在 v1 版本中默认值从 `Exact` 改为 `Equivalent`
* `webhooks[*].timeoutSeconds` 在 v1 版本中默认值从 `30s` 改为 `10s`
* `webhooks[*].sideEffects` 的默认值被删除,并且该字段变为必须指定;
在 v1 版本中可选的值只能是 `None``NoneOnDryRun` 之一
* `webhooks[*].admissionReviewVersions` 的默认值被删除,在 v1
版本中此字段变为必须指定(AdmissionReview 的被支持版本包括 `v1``v1beta1`
* `webhooks[*].name` 必须在通过 `admissionregistration.k8s.io/v1`
创建的对象列表中唯一
#### CustomResourceDefinition {#customresourcedefinition-v122}
<!--
The **apiextensions.k8s.io/v1beta1** API version of CustomResourceDefinition is no longer served as of v1.22.
* Migrate manifests and API clients to use the **apiextensions.k8s.io/v1** API version, available since v1.16.
* All existing persisted objects are accessible via the new API
-->
**apiextensions.k8s.io/v1beta1** API 版本的 CustomResourceDefinition
不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **apiextensions/v1** API 版本,此 API 从 v1.16 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes:
* `spec.scope` is no longer defaulted to `Namespaced` and must be explicitly specified
* `spec.version` is removed in v1; use `spec.versions` instead
* `spec.validation` is removed in v1; use `spec.versions[*].schema` instead
* `spec.subresources` is removed in v1; use `spec.versions[*].subresources` instead
* `spec.additionalPrinterColumns` is removed in v1; use `spec.versions[*].additionalPrinterColumns` instead
* `spec.conversion.webhookClientConfig` is moved to `spec.conversion.webhook.clientConfig` in v1
-->
* 值得注意的变更:
* `spec.scope` 的默认值不再是 `Namespaced`,该字段必须显式指定
* `spec.version` 在 v1 版本中被删除;应改用 `spec.versions`
* `spec.validation` 在 v1 版本中被删除;应改用 `spec.versions[*].schema`
* `spec.subresources` 在 v1 版本中被删除;应改用 `spec.versions[*].subresources`
* `spec.additionalPrinterColumns` 在 v1 版本中被删除;应改用
`spec.versions[*].additionalPrinterColumns`
* `spec.conversion.webhookClientConfig` 在 v1 版本中被移动到
`spec.conversion.webhook.clientConfig`
<!--
* `spec.conversion.conversionReviewVersions` is moved to `spec.conversion.webhook.conversionReviewVersions` in v1
* `spec.versions[*].schema.openAPIV3Schema` is now required when creating v1 CustomResourceDefinition objects, and must be a [structural schema](/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema)
* `spec.preserveUnknownFields: true` is disallowed when creating v1 CustomResourceDefinition objects; it must be specified within schema definitions as `x-kubernetes-preserve-unknown-fields: true`
* In `additionalPrinterColumns` items, the `JSONPath` field was renamed to `jsonPath` in v1 (fixes [#66531](https://github.com/kubernetes/kubernetes/issues/66531))
-->
* `spec.conversion.conversionReviewVersions` 在 v1 版本中被移动到
`spec.conversion.webhook.conversionReviewVersions`
* `spec.versions[*].schema.openAPIV3Schema` 在创建 v1 版本的
CustomResourceDefinition 对象时变成必需字段,并且其取值必须是一个
[结构化的 Schema](/zh/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema)
* `spec.preserveUnknownFields: true` 在创建 v1 版本的 CustomResourceDefinition
对象时不允许指定;该配置必须在 Schema 定义中使用
`x-kubernetes-preserve-unknown-fields: true` 来设置
* 在 v1 版本中,`additionalPrinterColumns` 的条目中的 `JSONPath` 字段被更名为
`jsonPath`(补丁 [#66531](https://github.com/kubernetes/kubernetes/issues/66531)
#### APIService {#apiservice-v122}
<!--
The **apiregistration.k8s.io/v1beta1** API version of APIService is no longer served as of v1.22.
* Migrate manifests and API clients to use the **apiregistration.k8s.io/v1** API version, available since v1.10.
* All existing persisted objects are accessible via the new API
* No notable changes
-->
**apiregistration/v1beta1** API 版本的 APIService 不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **apiregistration.k8s.io/v1** API 版本,此 API 从
v1.10 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
#### TokenReview {#tokenreview-v122}
<!--
The **authentication.k8s.io/v1beta1** API version of TokenReview is no longer served as of v1.22.
* Migrate manifests and API clients to use the **authentication.k8s.io/v1** API version, available since v1.6.
* No notable changes
-->
**authentication.k8s.io/v1beta1** API 版本的 TokenReview 不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **authentication.k8s.io/v1** API 版本,此 API 从
v1.6 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
#### SubjectAccessReview resources {#subjectaccessreview-resources-v122}
<!--
The **authorization.k8s.io/v1beta1** API version of LocalSubjectAccessReview, SelfSubjectAccessReview, SubjectAccessReview, and SelfSubjectRulesReview is no longer served as of v1.22.
* Migrate manifests and API clients to use the **authorization.k8s.io/v1** API version, available since v1.6.
* Notable changes:
* `spec.group` was renamed to `spec.groups` in v1 (fixes [#32709](https://github.com/kubernetes/kubernetes/issues/32709))
-->
**authorization.k8s.io/v1beta1** API 版本的 LocalSubjectAccessReview、
SelfSubjectAccessReview、SubjectAccessReview、SelfSubjectRulesReview 不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **authorization.k8s.io/v1** API 版本,此 API 从
v1.6 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 需要额外注意的变更:
* `spec.group` 在 v1 版本中被更名为 `spec.groups`
(补丁 [#32709](https://github.com/kubernetes/kubernetes/issues/32709)
#### CertificateSigningRequest {#certificatesigningrequest-v122}
<!--
The **certificates.k8s.io/v1beta1** API version of CertificateSigningRequest is no longer served as of v1.22.
* Migrate manifests and API clients to use the **certificates.k8s.io/v1** API version, available since v1.19.
* All existing persisted objects are accessible via the new API
-->
**certificates.k8s.io/v1beta1** API 版本的 CertificateSigningRequest 不在
v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **certificates.k8s.io/v1** API 版本,此 API 从
v1.19 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes in `certificates.k8s.io/v1`:
* For API clients requesting certificates:
* `spec.signerName` is now required (see [known Kubernetes signers](/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers)), and requests for `kubernetes.io/legacy-unknown` are not allowed to be created via the `certificates.k8s.io/v1` API
* `spec.usages` is now required, may not contain duplicate values, and must only contain known usages
* For API clients approving or signing certificates:
* `status.conditions` may not contain duplicate types
* `status.conditions[*].status` is now required
* `status.certificate` must be PEM-encoded, and contain only `CERTIFICATE` blocks
-->
* `certificates.k8s.io/v1` 中需要额外注意的变更:
* 对于请求证书的 API 客户端而言:
* `spec.signerName` 现在变成必需字段(参阅
[已知的 Kubernetes 签署者](/zh/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers)),
并且通过 `certificates.k8s.io/v1` API 不可以创建签署者为
`kubernetes.io/legacy-unknown` 的请求
* `spec.usages` 现在变成必需字段,其中不可以包含重复的字符串值,
并且只能包含已知的用法字符串
* 对于要批准或者签署证书的 API 客户端而言:
* `status.conditions` 中不可以包含重复的类型
* `status.conditions[*].status` 字段现在变为必需字段
* `status.certificate` 必须是 PEM 编码的,而且其中只能包含 `CERTIFICATE`
数据块
#### Lease {#lease-v122}
<!--
The **coordination.k8s.io/v1beta1** API version of Lease is no longer served as of v1.22.
* Migrate manifests and API clients to use the **coordination.k8s.io/v1** API version, available since v1.14.
* All existing persisted objects are accessible via the new API
* No notable changes
-->
**coordination.k8s.io/v1beta1** API 版本的 Lease 不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **coordination.k8s.io/v1** API 版本,此 API 从
v1.14 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
#### Ingress {#ingress-v122}
<!--
The **extensions/v1beta1** and **networking.k8s.io/v1beta1** API versions of Ingress is no longer served as of v1.22.
* Migrate manifests and API clients to use the **networking.k8s.io/v1** API version, available since v1.19.
* All existing persisted objects are accessible via the new API
-->
**extensions/v1beta1****networking.k8s.io/v1beta1** API 版本的 Ingress
不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **networking.k8s.io/v1** API 版本,此 API 从
v1.19 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes:
* `spec.backend` is renamed to `spec.defaultBackend`
* The backend `serviceName` field is renamed to `service.name`
* Numeric backend `servicePort` fields are renamed to `service.port.number`
* String backend `servicePort` fields are renamed to `service.port.name`
* `pathType` is now required for each specified path. Options are `Prefix`, `Exact`, and `ImplementationSpecific`. To match the undefined `v1beta1` behavior, use `ImplementationSpecific`.
-->
* 值得注意的变更:
* `spec.backend` 字段被更名为 `spec.defaultBackend`
* 后端的 `serviceName` 字段被更名为 `service.name`
* 数值表示的后端 `servicePort` 字段被更名为 `service.port.number`
* 字符串表示的后端 `servicePort` 字段被更名为 `service.port.name`
* 对所有要指定的路径,`pathType` 都成为必需字段。
可选项为 `Prefix``Exact``ImplementationSpecific`
要匹配 `v1beta1` 版本中未定义路径类型时的行为,可使用 `ImplementationSpecific`
#### IngressClass {#ingressclass-v122}
<!--
The **networking.k8s.io/v1beta1** API version of IngressClass is no longer served as of v1.22.
* Migrate manifests and API clients to use the **networking.k8s.io/v1** API version, available since v1.19.
* All existing persisted objects are accessible via the new API
* No notable changes
-->
**networking.k8s.io/v1beta1** API 版本的 IngressClass 不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **networking.k8s.io/v1** API 版本,此 API 从
v1.19 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
<!--
#### RBAC resources {#rbac-resources-v122}
The **rbac.authorization.k8s.io/v1beta1** API version of ClusterRole, ClusterRoleBinding, Role, and RoleBinding is no longer served as of v1.22.
* Migrate manifests and API clients to use the **rbac.authorization.k8s.io/v1** API version, available since v1.8.
* All existing persisted objects are accessible via the new APIs
* No notable changes
-->
#### RBAC 资源 {#rbac-resources-v122}
**rbac.authorization.k8s.io/v1beta1** API 版本的 ClusterRole、ClusterRoleBinding、
Role 和 RoleBinding 不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **rbac.authorization.k8s.io/v1** API 版本,此 API 从
v1.8 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
#### PriorityClass {#priorityclass-v122}
<!--
The **scheduling.k8s.io/v1beta1** API version of PriorityClass is no longer served as of v1.22.
* Migrate manifests and API clients to use the **scheduling.k8s.io/v1** API version, available since v1.14.
* All existing persisted objects are accessible via the new API
* No notable changes
-->
**scheduling.k8s.io/v1beta1** API 版本的 PriorityClass 不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **scheduling.k8s.io/v1** API 版本,此 API 从
v1.14 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
<!--
#### Storage resources {#storage-resources-v122}
-->
#### 存储资源 {#storage-resources-v122}
<!--
The **storage.k8s.io/v1beta1** API version of CSIDriver, CSINode, StorageClass, and VolumeAttachment is no longer served as of v1.22.
* Migrate manifests and API clients to use the **storage.k8s.io/v1** API version
* CSIDriver is available in **storage.k8s.io/v1** since v1.19.
* CSINode is available in **storage.k8s.io/v1** since v1.17
* StorageClass is available in **storage.k8s.io/v1** since v1.6
* VolumeAttachment is available in **storage.k8s.io/v1** v1.13
* All existing persisted objects are accessible via the new APIs
* No notable changes
-->
**storage.k8s.io/v1beta1** API 版本的 CSIDriver、CSINode、StorageClass
和 VolumeAttachment 不在 v1.22 版本中继续提供。
* 迁移清单和 API 客户端使用 **storage.k8s.io/v1** API 版本
* CSIDriver 从 v1.19 版本开始在 **storage.k8s.io/v1** 中提供;
* CSINode 从 v1.17 版本开始在 **storage.k8s.io/v1** 中提供;
* StorageClass 从 v1.6 版本开始在 **storage.k8s.io/v1** 中提供;
* VolumeAttachment 从 v1.13 版本开始在 **storage.k8s.io/v1** 中提供;
* 所有的已保存的对象都可以通过新的 API 来访问;
* 没有需要额外注意的变更
### v1.16
<!--
The **v1.16** release stopped serving the following deprecated API versions:
-->
**v1.16** 发行版本停止提供以下已废弃 API 版本:
#### NetworkPolicy {#networkpolicy-v116}
<!--
The **extensions/v1beta1** API version of NetworkPolicy is no longer served as of v1.16.
* Migrate manifests and API clients to use the **networking.k8s.io/v1** API version, available since v1.8.
* All existing persisted objects are accessible via the new API
-->
**extensions/v1beta1** API 版本的 NetworkPolicy 不在 v1.16 版本中继续提供。
* 迁移清单和 API 客户端使用 **networking.k8s.io/v1** API 版本,此 API 从
v1.8 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
#### DaemonSet {#daemonset-v116}
<!--
The **extensions/v1beta1** and **apps/v1beta2** API versions of DaemonSet are no longer served as of v1.16.
* Migrate manifests and API clients to use the **apps/v1** API version, available since v1.9.
* All existing persisted objects are accessible via the new API
-->
**extensions/v1beta1****apps/v1beta2** API 版本的 DaemonSet 在
v1.16 版本中不再继续提供。
* 迁移清单和 API 客户端使用 **apps/v1** API 版本,此 API 从 v1.9 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes:
* `spec.templateGeneration` is removed
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
* `spec.updateStrategy.type` now defaults to `RollingUpdate` (the default in `extensions/v1beta1` was `OnDelete`)
-->
* 值得注意的变更:
* `spec.templateGeneration` 字段被删除
* `spec.selector` 现在变成必需字段,并且在对象创建之后不可变更;
可以将现有模板的标签作为选择算符以实现无缝迁移。
* `spec.updateStrategy.type` 的默认值变为 `RollingUpdate`
`extensions/v1beta1` API 版本中的默认值是 `OnDelete`)。
#### Deployment {#deployment-v116}
<!--
The **extensions/v1beta1**, **apps/v1beta1**, and **apps/v1beta2** API versions of Deployment are no longer served as of v1.16.
* Migrate manifests and API clients to use the **apps/v1** API version, available since v1.9.
* All existing persisted objects are accessible via the new API
-->
**extensions/v1beta1**、**apps/v1beta1** 和 **apps/v1beta2** API 版本的
Deployment 在 v1.16 版本中不再继续提供。
* 迁移清单和 API 客户端使用 **apps/v1** API 版本,此 API 从 v1.9 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes:
* `spec.rollbackTo` is removed
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
* `spec.progressDeadlineSeconds` now defaults to `600` seconds (the default in `extensions/v1beta1` was no deadline)
* `spec.revisionHistoryLimit` now defaults to `10` (the default in `apps/v1beta1` was `2`, the default in `extensions/v1beta1` was to retain all)
* `maxSurge` and `maxUnavailable` now default to `25%` (the default in `extensions/v1beta1` was `1`)
-->
* 值得注意的变更:
* `spec.rollbackTo` 字段被删除
* `spec.selector` 字段现在变为必需字段,并且在 Deployment 创建之后不可变更;
可以使用现有的模板的标签作为选择算符以实现无缝迁移。
* `spec.progressDeadlineSeconds` 的默认值变为 `600`
`extensions/v1beta1` 中的默认值是没有期限)
* `spec.revisionHistoryLimit` 的默认值变为 `10`
`apps/v1beta1` API 版本中此字段默认值为 `2`,在`extensions/v1beta1` API
版本中的默认行为是保留所有历史记录)。
* `maxSurge``maxUnavailable` 的默认值变为 `25%`
(在 `extensions/v1beta1` API 版本中,这些字段的默认值是 `1`)。
#### StatefulSet {#statefulset-v116}
<!--
The **apps/v1beta1** and **apps/v1beta2** API versions of StatefulSet are no longer served as of v1.16.
* Migrate manifests and API clients to use the **apps/v1** API version, available since v1.9.
* All existing persisted objects are accessible via the new API
-->
**apps/v1beta1****apps/v1beta2** API 版本的 StatefulSet 在 v1.16 版本中不再继续提供。
* 迁移清单和 API 客户端使用 **apps/v1** API 版本,此 API 从 v1.9 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes:
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
* `spec.updateStrategy.type` now defaults to `RollingUpdate` (the default in `apps/v1beta1` was `OnDelete`)
-->
* 值得注意的变更:
* `spec.selector` 字段现在变为必需字段,并且在 StatefulSet 创建之后不可变更;
可以使用现有的模板的标签作为选择算符以实现无缝迁移。
* `spec.updateStrategy.type` 的默认值变为 `RollingUpdate`
`apps/v1beta1` API 版本中的默认值是 `OnDelete`)。
#### ReplicaSet {#replicaset-v116}
<!--
The **extensions/v1beta1**, **apps/v1beta1**, and **apps/v1beta2** API versions of ReplicaSet are no longer served as of v1.16.
* Migrate manifests and API clients to use the **apps/v1** API version, available since v1.9.
* All existing persisted objects are accessible via the new API
-->
**extensions/v1beta1**、**apps/v1beta1** 和 **apps/v1beta2** API 版本的
ReplicaSet 在 v1.16 版本中不再继续提供。
* 迁移清单和 API 客户端使用 **apps/v1** API 版本,此 API 从 v1.9 版本开始可用;
* 所有的已保存的对象都可以通过新的 API 来访问;
<!--
* Notable changes:
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
-->
* 值得注意的变更:
* `spec.selector` 现在变成必需字段,并且在对象创建之后不可变更;
可以将现有模板的标签作为选择算符以实现无缝迁移。
#### PodSecurityPolicy {#psp-v116}
<!--
The **extensions/v1beta1** API version of PodSecurityPolicy is no longer served as of v1.16.
* Migrate manifests and API client to use the **policy/v1beta1** API version, available since v1.10.
* Note that the **policy/v1beta1** API version of PodSecurityPolicy will be removed in v1.25.
-->
**extensions/v1beta1** API 版本的 PodSecurityPolicy 在 v1.16 版本中不再继续提供。
* 迁移清单和 API 客户端使用 **policy/v1beta1** API 版本,此 API 从 v1.10 版本开始可用;
* 注意 **policy/v1beta1** API 版本的 PodSecurityPolicy 会在 v1.25 版本中移除。
<!--
## What to do
### Test with deprecated APIs disabled
-->
## 需要做什么 {#what-to-do}
### 在禁用已启用 API 的情况下执行测试
<!--
You can test your clusters by starting an API server with specific API versions disabled
to simulate upcoming removals. Add the following flag to the API server startup arguments:
-->
你可以通过在启动 API 服务器时禁用特定的 API 版本来模拟即将发生的
API 移除,从而完成测试。在 API 服务器启动参数中添加如下标志:
`--runtime-config=<group>/<version>=false`
<!--
For example:
-->
例如:
`--runtime-config=admissionregistration.k8s.io/v1beta1=false,apiextensions.k8s.io/v1beta1,...`
<!--
### Locate use of deprecated APIs
Use [client warnings, metrics, and audit information available in 1.19+](https://kubernetes.io/blog/2020/09/03/warnings/#deprecation-warnings)
to locate use of deprecated APIs.
-->
### 定位何处使用了已弃用的 API
使用 [client warnings, metrics, and audit information available in 1.19+](https://kubernetes.io/blog/2020/09/03/warnings/#deprecation-warnings)
来定位在何处使用了已启用的 API。
<!--
### Migrate to non-deprecated APIs
-->
### 迁移到未被弃用的 API
<!--
* Update custom integrations and controllers to call the non-deprecated APIs
* Change YAML files to reference the non-deprecated APIs
-->
* 更新自定义的集成组件和控制器,调用未被弃用的 API
* 更改 YAML 文件引用未被弃用的 API
<!--
You can use the `kubectl-convert` command (`kubectl convert` prior to v1.20)
to automatically convert an existing object:
-->
你可以用 `kubectl-convert` 命令(在 v1.20 之前是 `kubectl convert`
来自动转换现有对象:
`kubectl-convert -f <file> --output-version <group>/<version>`.
<!--
For example, to convert an older Deployment to `apps/v1`, you can run:
-->
例如,要将较老的 Deployment 转换为 `apps/v1` 版本,你可以运行
`kubectl-convert -f ./my-deployment.yaml --output-version apps/v1`
<!--
Note that this may use non-ideal default values. To learn more about a specific
resource, check the Kubernetes [API reference](/docs/reference/kubernetes-api/).
-->
注意这种操作生成的结果中可能使用的默认值并不理想。
要进一步了解某个特定资源,可查阅 Kubernetes [API 参考](/zh/docs/reference/kubernetes-api/)。
@@ -0,0 +1,810 @@
---
title: Kubernetes 弃用策略
content_type: concept
weight: 40
---
<!--
reviewers:
- bgrant0607
- lavalamp
- thockin
title: Kubernetes Deprecation Policy
content_type: concept
weight: 40
-->
<!-- overview -->
<!--
This document details the deprecation policy for various facets of the system.
-->
本文档详细解释系统中各个层面的弃用策略(Deprecation Policy)。
<!-- body -->
<!--
Kubernetes is a large system with many components and many contributors. As
with any such software, the feature set naturally evolves over time, and
sometimes a feature may need to be removed. This could include an API, a flag,
or even an entire feature. To avoid breaking existing users, Kubernetes follows
a deprecation policy for aspects of the system that are slated to be removed.
-->
Kubernetes 是一个组件众多、贡献者人数众多的大系统。
就像很多类似的软件,所提供的功能特性集合会随着时间推移而自然发生变化,
而且有时候某个功能特性可能需要被去除。被去除的可能是一个 API、一个参数标志或者
甚至某整个功能特性。为了避免影响到现有用户,Kubernetes 对于其中渐次移除
的各个方面规定了一种弃用策略并遵从此策略。
<!--
## Deprecating parts of the API
Since Kubernetes is an API-driven system, the API has evolved over time to
reflect the evolving understanding of the problem space. The Kubernetes API is
actually a set of APIs, called "API groups", and each API group is
independently versioned. [API versions](/docs/reference/using-api/#api-versioning) fall
into 3 main tracks, each of which has different policies for deprecation:
-->
## 弃用 API 的一部分 {#deprecating-parts-of-the-api}
由于 Kubernetes 是一个 API 驱动的系统,API 会随着时间推移而演化,以反映
人们对问题空间的认识的变化。Kubernetes API 实际上是一个 API 集合,其中每个
成员称作“API 组(API Group)”,并且每个 API 组都是独立管理版本的。
[API 版本](/zh/docs/reference/using-api/#api-versioning)会有
三类,每类有不同的废弃策略:
<!--
| Example | Track |
|----------|----------------------------------|
| v1 | GA (generally available, stable) |
| v1beta1 | Beta (pre-release) |
| v1alpha1 | Alpha (experimental) |
-->
| 示例 | 分类 |
|----------|----------------------------------|
| v1 | 正式发布(Generally availableGA,稳定版本) |
| v1beta1 | Beta (预发布)|
| v1alpha1 | Alpha (试验性) |
<!--
A given release of Kubernetes can support any number of API groups and any
number of versions of each.
The following rules govern the deprecation of elements of the API. This
includes:
-->
给定的 Kubernetes 发布版本中可以支持任意数量的 API 组,且每组可以包含
任意个数的版本。
下面的规则负责指导 API 元素的弃用,具体元素包括:
<!--
* REST resources (aka API objects)
* Fields of REST resources
* Annotations on REST resources, including "beta" annotations but not
including "alpha" annotations.
* Enumerated or constant values
* Component config structures
-->
* REST 资源(也即 API 对象)
* REST 资源的字段
* REST 资源的注解,包含“beta”类注解但不包含“alpha”类注解
* 枚举值或者常数值
* 组件配置结构
<!--
These rules are enforced between official releases, not between
arbitrary commits to master or release branches.
**Rule #1: API elements may only be removed by incrementing the version of the
API group.**
Once an API element has been added to an API group at a particular version, it
can not be removed from that version or have its behavior significantly
changed, regardless of track.
-->
以下是跨正式发布版本时要实施的规则,不适用于对 master 或发布分支上
不同提交之间的变化。
**规则 #1:只能在增加 API 组版本号时删除 API 元素。**
一旦在某个特定 API 组版本中添加了 API 元素,则该元素不可从该版本中删除,
且其行为也不能大幅度地变化,无论属于哪一类(GA、Alpha 或 Beta)。
<!--
For historical reasons, there are 2 "monolithic" API groups - "core" (no
group name) and "extensions". Resources will incrementally be moved from these
legacy API groups into more domain-specific API groups.
-->
{{< note >}}
由于历史原因,Kubernetes 中存在两个“单体式(Monolithic)”API 组 -
“core”(无组名)和“extensions”。这两个遗留 API 组中的资源会被逐渐迁移到
更为特定领域的 API 组中。
{{< /note >}}
<!--
**Rule #2: API objects must be able to round-trip between API versions in a given
release without information loss, with the exception of whole REST resources
that do not exist in some versions.**
-->
**规则 #2:在给定的发布版本中,API 对象必须能够在不同的 API 版本之间来回
转换且不造成信息丢失,除非整个 REST 资源在某些版本中完全不存在。**
<!--
For example, an object can be written as v1 and then read back as v2 and
converted to v1, and the resulting v1 resource will be identical to the
original. The representation in v2 might be different from v1, but the system
knows how to convert between them in both directions. Additionally, any new
field added in v2 must be able to round-trip to v1 and back, which means v1
might have to add an equivalent field or represent it as an annotation.
-->
例如,一个对象可被用 v1 来写入之后用 v2 来读出并转换为 v1,所得到的 v1 必须
与原来的 v1 对象完全相同。v2 中的表现形式可能与 v1 不同,但系统知道如何
在两个版本之间执行双向转换。
此外,v2 中添加的所有新字段都必须能够转换为 v1 再转换回来。这意味着 v1 必须
添加一个新的等效字段或者将其表现为一个注解。
<!--
**Rule #3: An API version in a given track may not be deprecated in favor of a less stable API version.**
* GA API versions can replace beta and alpha API versions.
* Beta API versions can replace earlier beta and alpha API versions, but *may not* replace GA API versions.
* Alpha API versions can replace earlier alpha API versions, but *may not* replace GA or beta API versions.
-->
**规则 #3:给定类别的 API 版本不可被弃用以支持稳定性更差的 API 版本。**
* 一个正式发布的(GA)API 版本可替换 beta 或 alpha API 版本。
* Beta API 版本可以替换早期的 beta 和 alpha API 版本,但 **不可以** 替换正式的 API 版本。
* Alpha API 版本可以替换早期的 alpha API 版本,但 **不可以** 替换正式的或 beta API 版本。
<!--
**Rule #4a: minimum API lifetime is determined by the API stability level**
* **GA API versions may be marked as deprecated, but must not be removed within a major version of Kubernetes**
* **Beta API versions must be supported for 9 months or 3 releases (whichever is longer) after deprecation**
* **Alpha API versions may be removed in any release without prior deprecation notice**
This ensures beta API support covers the [maximum supported version skew of 2 releases](/releases/version-skew-policy/).
-->
**规则 #4a:最短 API 生命周期由 API 稳定性级别决定**
* **GA API 版本可以被标记为已弃用,但不得在 Kubernetes 的主要版本中删除**
* **Beta API 版本必须支持 9 个月或弃用后的 3 个版本(以较长者为准)**
* **Alpha API 版本可能会在任何版本中被删除,不另行通知**
这确保了 beta API 支持涵盖了[最多 2 个版本的支持版本偏差](/zh/releases/version-skew-policy/)。
{{< note >}}
<!--
There are no current plans for a major version revision of Kubernetes that removes GA APIs.
-->
目前没有删除正式版本 API 的 Kubernetes 主要版本修订计划。
{{< /note >}}
<!--
Until [#52185](https://github.com/kubernetes/kubernetes/issues/52185) is
resolved, no API versions that have been persisted to storage may be removed.
Serving REST endpoints for those versions may be disabled (subject to the
deprecation timelines in this document), but the API server must remain capable
of decoding/converting previously persisted data from storage.
-->
{{< note >}}
在 [#52185](https://github.com/kubernetes/kubernetes/issues/52185) 被解决之前,
已经被保存到持久性存储中的 API 版本都不可以被去除。
你可以禁止这些版本所对应的 REST 末端(在符合本文中弃用时间线的前提下),
但是 API 服务器必须仍能解析和转换存储中以前写入的数据。
{{< /note >}}
<!--
**Rule #4b: The "preferred" API version and the "storage version" for a given
group may not advance until after a release has been made that supports both the
new version and the previous version**
-->
**规则 #4b:标记为“preferred(优选的)” API 版本和给定 API 组的
“storage version(存储版本)”在既支持老版本也支持新版本的 Kubernetes 发布
版本出来以前不可以提升其版本号。**
<!--
Users must be able to upgrade to a new release of Kubernetes and then roll back
to a previous release, without converting anything to the new API version or
suffering breakages (unless they explicitly used features only available in the
newer version). This is particularly evident in the stored representation of
objects.
All of this is best illustrated by examples. Imagine a Kubernetes release,
version X, which introduces a new API group. A new Kubernetes release is made
every approximately 4 months (3 per year). The following table describes which
API versions are supported in a series of subsequent releases.
-->
用户必须能够升级到 Kubernetes 新的发行版本,之后再回滚到前一个发行版本,且
整个过程中无需针对新的 API 版本做任何转换,也不允许出现功能损坏的情况,
除非用户显式地使用了仅在较新版本中才存在的功能特性。
就对象的存储表示而言,这一点尤其是不言自明的。
以上所有规则最好通过例子来说明。假定现有 Kubernetes 发行版本为 X,其中引入了
新的 API 组。大约每隔 4 个月会有一个新的 Kubernetes 版本被发布(每年 3 个版本)。
下面的表格描述了在一系列后续的发布版本中哪些 API 版本是受支持的。
<table>
<thead>
<tr>
<!-- th>Release</th>
<th>API Versions</th>
<th>Preferred/Storage Version</th>
<th>Notes</th -->
<th>发布版本</th>
<th>API 版本</th>
<th>优选/存储版本</th>
<th>注释</th>
</tr>
</thead>
<tbody>
<tr>
<td>X</td>
<td>v1alpha1</td>
<td>v1alpha1</td>
<td></td>
</tr>
<tr>
<td>X+1</td>
<td>v1alpha2</td>
<td>v1alpha2</td>
<td>
<ul>
<!-- li>v1alpha1 is removed, "action required" relnote</li -->
<li>v1alpha1 被去除,发布说明中会包含 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+2</td>
<td>v1beta1</td>
<td>v1beta1</td>
<td>
<ul>
<!-- li>v1alpha2 is removed, "action required" relnote</li -->
<li>v1alpha2 被去除,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+3</td>
<!-- td>v1beta2, v1beta1 (deprecated)</td -->
<td>v1beta2、v1beta1(已弃用)</td>
<td>v1beta1</td>
<td>
<ul>
<!-- li>v1beta1 is deprecated, "action required" relnote</li -->
<li>v1beta1 被弃用,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+4</td>
<!-- td>v1beta2, v1beta1 (deprecated)</td -->
<td>v1beta2、v1beta1(已弃用)</td>
<td>v1beta2</td>
<td></td>
</tr>
<tr>
<td>X+5</td>
<!-- td>v1, v1beta1 (deprecated), v1beta2 (deprecated)</td -->
<td>v1、v1beta1(已弃用)、v1beta2(已弃用)</td>
<td>v1beta2</td>
<td>
<ul>
<!-- li>v1beta2 is deprecated, "action required" relnote</li -->
<li>v1beta2 被弃用,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+6</td>
<!-- td>v1, v1beta2 (deprecated)</td -->
<td>v1、v1beta2(已弃用)</td>
<td>v1</td>
<td>
<ul>
<!-- li>v1beta1 is removed, "action required" relnote</li -->
<li>v1beta1 被去除,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+7</td>
<!-- td>v1, v1beta2 (deprecated)</td -->
<td>v1、v1beta2(已弃用)</td>
<td>v1</td>
<td></td>
</tr>
<tr>
<td>X+8</td>
<td>v2alpha1、v1</td>
<td>v1</td>
<td>
<ul>
<!-- li>v1beta2 is removed, "action required" relnote</li -->
<li>v1beta2 被去除,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+9</td>
<td>v2alpha2、v1</td>
<td>v1</td>
<td>
<ul>
<!-- li>v2alpha1 is removed, "action required" relnote</li -->
<li>v2alpha1 被删除,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+10</td>
<td>v2beta1、v1</td>
<td>v1</td>
<td>
<ul>
<!-- li>v2alpha2 is removed, "action required" relnote</li -->
<li>v2alpha2 被删除,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+11</td>
<!-- td>v2beta2, v2beta1 (deprecated), v1</td -->
<td>v2beta2、v2beta1(已弃用)、v1</td>
<td>v1</td>
<td>
<ul>
<!-- li>v2beta1 is deprecated, "action required" relnote</li -->
<li>v2beta1 被弃用,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+12</td>
<!-- td>v2, v2beta2 (deprecated), v2beta1 (deprecated), v1 (deprecated)</td -->
<td>v2、v2beta2(已弃用)、v2beta1(已弃用)、v1(已弃用)</td>
<td>v1</td>
<td>
<ul>
<!-- li>v2beta2 is deprecated, "action required" relnote</li>
<li>v1 is deprecated in favor of v2, but will not be removed</li -->
<li>v2beta2 已被弃用,发布说明中包含对应的 "action required(采取行动)" 说明</li>
<li>v1 已被弃用,取而代之的是 v2,但不会被删除</li>
</ul>
</td>
</tr>
<tr>
<td>X+13</td>
<!-- td>v2, v2beta1 (deprecated), v2beta2 (deprecated), v1 (deprecated)</td -->
<td>v2、v2beta1(已弃用)、v2beta2(已弃用)、v1(已弃用)</td>
<td>v2</td>
<td></td>
</tr>
<tr>
<td>X+14</td>
<!-- td>v2, v2beta2 (deprecated), v1 (deprecated)</td -->
<td>v2、v2beta2(已弃用)、v1(已弃用)</td>
<td>v2</td>
<td>
<ul>
<!-- li>v2beta1 is removed, "action required" relnote</li -->
<li>v2beta1 被删除,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
<tr>
<td>X+15</td>
<!-- td>v2, v1 (deprecated)</td -->
<td>v2、v1(已弃用)</td>
<td>v2</td>
<td>
<ul>
<!-- li>v2beta2 is removed, "action required" relnote</li -->
<li>v2beta2 被删除,发布说明中包含对应的 "action required(采取行动)" 说明</li>
</ul>
</td>
</tr>
</tbody>
</table>
<!--
### REST resources (aka API objects)
Consider a hypothetical REST resource named Widget, which was present in API v1
in the above timeline, and which needs to be deprecated. We document and
[announce](https://groups.google.com/forum/#!forum/kubernetes-announce) the
deprecation in sync with release X+1. The Widget resource still exists in API
version v1 (deprecated) but not in v2alpha1. The Widget resource continues to
exist and function in releases up to and including X+8. Only in release X+9,
when API v1 has aged out, does the Widget resource cease to exist, and the
behavior get removed.
-->
### REST 资源(也即 API 对象) {#rest-resources-aka-api-objects}
考虑一个假想的名为 Widget 的 REST 资源,在上述时间线中位于 API v1,
而现在打算将其弃用。
我们会在文档和
[声明](https://groups.google.com/forum/#!forum/kubernetes-announce)
中与 X+1 版本的发布同步记述此弃用决定。
Wdiget 资源仍会在 API 版本 v1(已弃用)中存在,但不会出现在 v2alpha1 中。
Widget 资源会 X+8 发布版本之前(含 X+8)一直存在并可用。
只有在发布版本 X+9 中,API v1 寿终正寝时,Widget
才彻底消失,相应的资源行为也被移除。
<!--
Starting in Kubernetes v1.19, making an API request to a deprecated REST API endpoint:
1. Returns a `Warning` header (as defined in [RFC7234, Section 5.5](https://tools.ietf.org/html/rfc7234#section-5.5)) in the API response.
2. Adds a `"k8s.io/deprecated":"true"` annotation to the [audit event](/docs/tasks/debug/debug-cluster/audit/) recorded for the request.
3. Sets an `apiserver_requested_deprecated_apis` gauge metric to `1` in the `kube-apiserver`
process. The metric has labels for `group`, `version`, `resource`, `subresource` that can be joined
to the `apiserver_request_total` metric, and a `removed_release` label that indicates the
Kubernetes release in which the API will no longer be served. The following Prometheus query
returns information about requests made to deprecated APIs which will be removed in v1.22:
```promql
apiserver_requested_deprecated_apis{removed_release="1.22"} * on(group,version,resource,subresource) group_right() apiserver_request_total
```
-->
从 Kubernetes v1.19 开始,当 API 请求被发送到一个已弃用的 REST API 末端时:
1. API 响应中会包含一个 `Warning` 头部字段(如 [RFC7234 5.5 节](https://tools.ietf.org/html/rfc7234#section-5.5)所定义);
2. 该请求会导致对应的
[审计事件](/zh/docs/tasks/debug/debug-cluster/audit/)
中会增加一个注解 `"k8s.io/deprecated":"true"`。
3. `kube-apiserver` 进程的 `apiserver_requested_deprecated_apis` 度量值会被
设置为 `1`。
该度量值还附带 `group`、`version`、`resource` 和 `subresource` 标签
(可供添加到度量值 `apiserver_request_total` 上),
和一个 `removed_release` 标签,标明该 API 将消失的 Kubernetes 发布版本。
下面的 Prometheus 查询会返回对 v1.22 中将移除的、已弃用的 API
的请求的信息:
```promql
apiserver_requested_deprecated_apis{removed_release="1.22"} * on(group,version,resource,subresource) group_right() apiserver_request_total
```
<!--
### Fields of REST resources
As with whole REST resources, an individual field which was present in API v1
must exist and function until API v1 is removed. Unlike whole resources, the
v2 APIs may choose a different representation for the field, as long as it can
be round-tripped. For example a v1 field named "magnitude" which was
deprecated might be named "deprecatedMagnitude" in API v2. When v1 is
eventually removed, the deprecated field can be removed from v2.
-->
### REST 资源的字段 {#fields-of-rest-resources}
就像整个 REST 资源一样,在 API v1 中曾经存在的各个字段在 API v1 被移除
之前必须一直存在且起作用。
与整个资源上的规定不同,v2 API 可以选择为字段提供不同的表示方式,
只要对应的资源对象可在不同版本之间来回转换即可。
例如,v1 版本中一个名为 "magnitude" 的已弃用字段可能在 API v2 中被命名
为 "deprecatedMagnitude"。当 v1 最终被移除时,废弃的字段也可以从 v2
中移除。
<!--
### Enumerated or constant values
As with whole REST resources and fields thereof, a constant value which was
supported in API v1 must exist and function until API v1 is removed.
-->
### 枚举值或常数值 {#enumerated-or-constant-values}
就像前文讲述的 REST 资源及其中的单个字段一样,API v1 中所支持的常数值
必须在 API v1 被移除之前一直存在且起作用。
<!--
### Component config structures
Component configs are versioned and managed similar to REST resources.
-->
### 组件配置结构 {#component-config-structures}
组件的配置也是有版本的,并且按 REST 资源的方式来管理。
<!--
### Future work
Over time, Kubernetes will introduce more fine-grained API versions, at which
point these rules will be adjusted as needed.
-->
### 将来的工作 {#future-work}
随着时间推移,Kubernetes 会引入粒度更细的 API 版本。
到那时,这里的规则会根据需要进行调整。
<!--
## Deprecating a flag or CLI
The Kubernetes system is comprised of several different programs cooperating.
Sometimes, a Kubernetes release might remove flags or CLI commands
(collectively "CLI elements") in these programs. The individual programs
naturally sort into two main groups - user-facing and admin-facing programs,
which vary slightly in their deprecation policies. Unless a flag is explicitly
prefixed or documented as "alpha" or "beta", it is considered GA.
-->
## 弃用一个标志或 CLI 命令
Kubernetes 系统中包含若干不同的、相互协作的程序。
有时,Kubernetes 可能会删除这些程序的某些标志或 CLI 命令(统称“命令行元素”)。
这些程序可以天然地划分到两个大组中:面向用户的和面向管理员的程序。
二者之间的弃用策略略有不同。
除非某个标志显示地通过前缀或文档来标明其为“alpha”或“beta”,
该标志要被视作正式发布的(GA)。
<!--
CLI elements are effectively part of the API to the system, but since they are
not versioned in the same way as the REST API, the rules for deprecation are as
follows:
-->
命令行元素相当于系统的 API 的一部分,不过因为它们并没有采用 REST API
一样的方式来管理版本,其弃用规则规定如下:
<!--
**Rule #5a: CLI elements of user-facing components (e.g. kubectl) must function
after their announced deprecation for no less than:**
* **GA: 12 months or 2 releases (whichever is longer)**
* **Beta: 3 months or 1 release (whichever is longer)**
* **Alpha: 0 releases**
-->
**规则 #5a:面向用户的命令行元素(例如,kubectl)必须在其宣布被弃用其
在以下时长内仍能使用:**
* **GA:12 个月或者 2 个发布版本(取其较长者)**
* **Beta:3 个月或者 1 个发布版本(取其较长者)**
* **Alpha0 发布版本**
<!--
**Rule #5b: CLI elements of admin-facing components (e.g. kubelet) must function
after their announced deprecation for no less than:**
* **GA: 6 months or 1 release (whichever is longer)**
* **Beta: 3 months or 1 release (whichever is longer)**
* **Alpha: 0 releases**
-->
**规则 #5b:面向管理员的命令行元素(例如,kubelet)必须在其被宣布弃用
之后以下时长内保持可用:**
* **GA:6 个月或 1 个发行版本(取其较长者)**
* **Beta: 3 个月或 1 个发行版本(取其较长者)**
* **Alpha: 0 个发布版本**
<!--
**Rule #6: Deprecated CLI elements must emit warnings (optionally disable)
when used.**
-->
**规则 #6:被弃用的 CLI 元素在被用到时必须能够产生警告,而警告的
产生是可以被禁止的。**
<!--
## Deprecating a feature or behavior
Occasionally a Kubernetes release needs to deprecate some feature or behavior
of the system that is not controlled by the API or CLI. In this case, the
rules for deprecation are as follows:
-->
## 弃用某功能特性或行为 {#deprecating-a-feature-or-behavior}
在一些较偶然的情形下,某 Kubernetes 发行版本需要弃用系统的某项功能
特性或者行为,而对应的功能特性或行为并不受 API 或 CLI 控制。在这种情况下,
其弃用规则如下:
<!--
**Rule #7: Deprecated behaviors must function for no less than 1 year after their
announced deprecation.**
-->
**规则 #7:被弃用的行为必须在被宣布弃用之后至少 1 年时间内必须保持能用。**
<!--
This does not imply that all changes to the system are governed by this policy.
This applies only to significant, user-visible behaviors which impact the
correctness of applications running on Kubernetes or that impact the
administration of Kubernetes clusters, and which are being removed entirely.
-->
这并不意味着对系统的所有更改都受此策略约束。
此规则仅适用于重大的、用户可见的行为;这些行为会影响到在 Kubernetes
中运行的应用的正确性,或者影响到 Kubernetes 集群的管理。
此规则也适用于那些被整个移除的功能特性或行为。
<!--
An exception to the above rule is _feature gates_. Feature gates are key=value
pairs that allow for users to enable/disable experimental features.
Feature gates are intended to cover the development life cycle of a feature - they
are not intended to be long-term APIs. As such, they are expected to be deprecated
and removed after a feature becomes GA or is dropped.
-->
上述规则的一个例外是 _特性门控(Feature Gates)_。特性门控是一些键值偶对,
允许用户启用或禁用一些试验性的功能特性。
特性门控意在覆盖功能特性的整个开发周期,它们无意成为长期的 API。
因此,它们会在某功能特性正式发布或被抛弃之后被弃用和删除。
<!--
As a feature moves through the stages, the associated feature gate evolves.
The feature life cycle matched to its corresponding feature gate is:
* Alpha: the feature gate is disabled by default and can be enabled by the user.
* Beta: the feature gate is enabled by default and can be disabled by the user.
* GA: the feature gate is deprecated (see ["Deprecation"](#deprecation)) and becomes
non-operational.
* GA, deprecation window complete: the feature gate is removed and calls to it are
no longer accepted.
-->
随着一个功能特性经过不同的成熟阶段,相关的特性门控也会演化。
与功能特性生命周期对应的特性门控状态为:
* Alpha:特性门控默认被禁用,只能由用户显式启用。
* Beta:特性门控默认被弃用,可被用户显式禁用。
* GA: 特性门控被弃用(参见[弃用](#deprecation)),并且不再起作用。
* GA,弃用窗口期结束:特性门控被删除,不再接受调用。
<!--
### Deprecation
Features can be removed at any point in the life cycle prior to GA. When features are
removed prior to GA, their associated feature gates are also deprecated.
When an invocation tries to disable a non-operational feature gate, the call fails in order
to avoid unsupported scenarios that might otherwise run silently.
-->
### 弃用 {#deprecation}
功能特性在正式发布之前的生命周期内任何时间点都可被移除。
当未正式发布的功能特性被移除时,它们对应的特性门控也被弃用。
当尝试禁用一个不再起作用的特性门控时,该调用会失败,这样可以避免
毫无迹象地执行一些不受支持的场景。
<!--
In some cases, removing pre-GA features requires considerable time. Feature gates can remain
operational until their associated feature is fully removed, at which point the feature gate
itself can be deprecated.
When removing a feature gate for a GA feature also requires considerable time, calls to
feature gates may remain operational if the feature gate has no effect on the feature,
and if the feature gate causes no errors.
-->
在某些场合,移除一个即将正式发布的功能特性需要很长时间。特性门控
可以保持其功能,直到对应的功能特性被彻底去除,直到那时特性门控
自身才可被弃用。
由于移除一个已经正式发布的功能特性对应的特性门控也需要一定时间,对特性
门控的调用可能一直被允许,前提是特性门控对功能本身无影响且特性门控不会
引发任何错误。
<!--
Features intended to be disabled by users should include a mechanism for disabling the
feature in the associated feature gate.
Versioning for feature gates is different from the previously discussed components,
therefore the rules for deprecation are as follows:
-->
意在允许用户禁用的功能特性应该包含一个在相关联的特性门控中禁用该功能的机制。
特性门控的版本管理与之前讨论的组件版本管理不同,因此其对应的弃用策略如下:
<!--
**Rule #8: Feature gates must be deprecated when the corresponding feature they control
transitions a lifecycle stage as follows. Feature gates must function for no less than:**
* **Beta feature to GA: 6 months or 2 releases (whichever is longer)**
* **Beta feature to EOL: 3 months or 1 release (whichever is longer)**
* **Alpha feature to EOL: 0 releases**
-->
**规则 #8:特性门控所对应的功能特性经历下面所列的成熟性阶段转换时,特性门控
必须被弃用。特性门控弃用时必须在以下时长内保持其功能可用:**
* **Beta 特性转为 GA:6 个月或者 2 个发布版本(取其较长者)**
* **Beta 特性转为丢弃:3 个月或者 1 个发布版本(取其较长者)**
* **Alpha 特性转为丢弃:0 个发布版本**
<!--
**Rule #9: Deprecated feature gates must respond with a warning when used. When a feature gate
is deprecated it must be documented in both in the release notes and the corresponding CLI help.
Both warnings and documentation must indicate whether a feature gate is non-operational.**
-->
**规则 #9:已弃用的特色门控再被使用时必须给出警告回应。当特性门控被
弃用时,必须在发布说明和对应的 CLI 帮助信息中通过文档宣布。
警告信息和文档都要标明是否某特性门控不再起作用。**
<!--
## Deprecating a metric
Each component of the Kubernetes control-plane exposes metrics (usually the
`/metrics` endpoint), which are typically ingested by cluster administrators.
Not all metrics are the same: some metrics are commonly used as SLIs or used
to determine SLOs, these tend to have greater import. Other metrics are more
experimental in nature or are used primarily in the Kubernetes development
process.
Accordingly, metrics fall under two stability classes (`ALPHA` and `STABLE`);
this impacts removal of a metric during a Kubernetes release. These classes
are determined by the perceived importance of the metric. The rules for
deprecating and removing a metric are as follows:
-->
### 弃用度量值 {#deprecating-a-metric}
Kubernetes 控制平面的每个组件都公开度量值(通常是 `/metrics` 端点),它们通常由集群管理员使用。
并不是所有的度量值都是同样重要的:一些度量值通常用作 SLIs 或被使用来确定 SLOs,这些往往比较重要。
其他度量值在本质上带有实验性,或者主要用于 Kubernetes 开发过程。
因此,度量值分为两个稳定性类别(`ALPHA` 和 `STABLE`;
此分类会影响在 Kubernetes 发布版本中移除某度量值。
所对应的分类取决于对该度量值重要性的预期。
弃用和移除度量值的规则如下:
<!--
**Rule #9a: Metrics, for the corresponding stability class, must function for no less than:**
* **STABLE: 4 releases or 12 months (whichever is longer)**
* **ALPHA: 0 releases**
**Rule #9b: Metrics, after their _announced deprecation_, must function for no less than:**
* **STABLE: 3 releases or 9 months (whichever is longer)**
* **ALPHA: 0 releases**
-->
**规则 #9a: 对于相应的稳定性类别,度量值起作用的周期必须不小于:**
* **STABLE: 4 个发布版本或者 12 个月 (取其较长者)**
* **ALPHA: 0 个发布版本**
**规则 #9b: 在度量值被宣布启用之后,它起作用的周期必须不小于:**
* **STABLE: 3 个发布版本或者 9 个月 (取其较长者)**
* **ALPHA: 0 个发布版本**
<!--
Deprecated metrics will have their description text prefixed with a deprecation notice
string '(Deprecated from x.y)' and a warning log will be emitted during metric
registration. Like their stable undeprecated counterparts, deprecated metrics will
be automatically registered to the metrics endpoint and therefore visible.
-->
已弃用的度量值将在其描述文本前加上一个已弃用通知字符串 '(Deprecated from x.y)'
并将在度量值被记录期间发出警告日志。就像稳定的、未被弃用的度量指标一样,
被弃用的度量值将自动注册到 metrics 端点,因此被弃用的度量值也是可见的。
<!--
On a subsequent release (when the metric's `deprecatedVersion` is equal to
_current_kubernetes_version - 3_)), a deprecated metric will become a _hidden_ metric.
**_Unlike_** their deprecated counterparts, hidden metrics will _no longer_ be
automatically registered to the metrics endpoint (hence hidden). However, they
can be explicitly enabled through a command line flag on the binary
(`--show-hidden-metrics-for-version=`). This provides cluster admins an
escape hatch to properly migrate off of a deprecated metric, if they were not
able to react to the earlier deprecation warnings. Hidden metrics should be
deleted after one release.
-->
在随后的版本中(当度量值 `deprecatedVersion` 等于_当前 Kubernetes 版本 - 3_),
被弃用的度量值将变成 _隐藏(Hidden)_ metric 度量值。
与被弃用的度量值不同,隐藏的度量值将不再被自动注册到 metrics 端点(因此被隐藏)。
但是,它们可以通过可执行文件的命令行标志显式启用
`--show-hidden-metrics-for-version=`)。
如果集群管理员不能对早期的弃用警告作出反应,这一设计就为他们提供了抓紧迁移弃用度量值的途径。
隐藏的度量值应该在再过一个发行版本后被删除。
<!--
## Exceptions
No policy can cover every possible situation. This policy is a living
document, and will evolve over time. In practice, there will be situations
that do not fit neatly into this policy, or for which this policy becomes a
serious impediment. Such situations should be discussed with SIGs and project
leaders to find the best solutions for those specific cases, always bearing in
mind that Kubernetes is committed to being a stable system that, as much as
possible, never breaks users. Exceptions will always be announced in all
relevant release notes.
-->
## 例外 {#exceptions}
没有策略可以覆盖所有情况。此策略文档是一个随时被更新的文档,会随着时间
推移演化。在实践中,会有一些情况无法很好地匹配到这里的弃用策略,或者
这里的策略变成了很严重的羁绊。这类情形要与 SIG 和项目牵头人讨论,
寻求对应场景的最佳解决方案。请一直铭记,Kubernetes 承诺要成为一个
稳定的系统,至少会尽力做到不会影响到其用户。此弃用策略的任何例外情况
都会在所有相关的发布说明中公布。
@@ -0,0 +1,145 @@
---
title: Kubernetes API 健康端点
content_type: concept
weight: 50
---
<!--
title: Kubernetes API health endpoints
reviewers:
- logicalhan
content_type: concept
weight: 50
-->
<!-- overview -->
<!--
The Kubernetes {{< glossary_tooltip term_id="kube-apiserver" text="API server" >}} provides API endpoints to indicate the current status of the API server.
This page describes these API endpoints and explains how you can use them.
-->
Kubernetes {{< glossary_tooltip term_id="kube-apiserver" text="API 服务器" >}} 提供 API 端点以指示 API 服务器的当前状态。
本文描述了这些 API 端点,并说明如何使用。
<!-- body -->
<!-- ## API endpoints for health -->
## API 健康端点 {#api-endpoints-for-health}
<!--
The Kubernetes API server provides 3 API endpoints (`healthz`, `livez` and `readyz`) to indicate the current status of the API server.
The `healthz` endpoint is deprecated (since Kubernetes v1.16), and you should use the more specific `livez` and `readyz` endpoints instead.
The `livez` endpoint can be used with the `--livez-grace-period` [flag](/docs/reference/command-line-tools-reference/kube-apiserver) to specify the startup duration.
For a graceful shutdown you can specify the `--shutdown-delay-duration` [flag](/docs/reference/command-line-tools-reference/kube-apiserver) with the `/readyz` endpoint.
Machines that check the `healthz`/`livez`/`readyz` of the API server should rely on the HTTP status code.
A status code `200` indicates the API server is `healthy`/`live`/`ready`, depending on the called endpoint.
The more verbose options shown below are intended to be used by human operators to debug their cluster or understand the state of the API server.
-->
Kubernetes API 服务器提供 3 个 API 端点(`healthz``livez``readyz`)来表明 API 服务器的当前状态。
`healthz` 端点已被弃用(自 Kubernetes v1.16 起),你应该使用更为明确的 `livez``readyz` 端点。
`livez` 端点可与 `--livez-grace-period` [标志](/zh/docs/reference/command-line-tools-reference/kube-apiserver)一起使用,来指定启动持续时间。
为了正常关机,你可以使用 `/readyz` 端点并指定 `--shutdown-delay-duration` [标志](/zh/docs/reference/command-line-tools-reference/kube-apiserver)。
检查 API 服务器的 `healthz`/`livez`/`readyz` 端点的机器应依赖于 HTTP 状态代码。
状态码 `200` 表示 API 服务器是 `healthy``live` 还是 `ready`,具体取决于所调用的端点。
以下更详细的选项供操作人员使用,用来调试其集群或了解 API 服务器的状态。
<!-- The following examples will show how you can interact with the health API endpoints. -->
以下示例将显示如何与运行状况 API 端点进行交互。
<!--
For all endpoints, you can use the `verbose` parameter to print out the checks and their status.
This can be useful for a human operator to debug the current status of the API server, it is not intended to be consumed by a machine:
-->
对于所有端点,都可以使用 `verbose` 参数来打印检查项以及检查状态。
这对于操作人员调试 API 服务器的当前状态很有用,这些不打算给机器使用:
```shell
curl -k https://localhost:6443/livez?verbose
```
<!-- or from a remote host with authentication: -->
或从具有身份验证的远程主机:
```shell
kubectl get --raw='/readyz?verbose'
```
<!-- The output will look like this: -->
输出将如下所示:
```
[+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
healthz check passed
```
<!--
The Kubernetes API server also supports to exclude specific checks.
The query parameters can also be combined like in this example:
-->
Kubernetes API 服务器也支持排除特定的检查项。
查询参数也可以像以下示例一样进行组合:
```shell
curl -k 'https://localhost:6443/readyz?verbose&exclude=etcd'
```
<!-- The output show that the `etcd` check is excluded: -->
输出显示排除了 `etcd` 检查:
```
[+]ping ok
[+]log ok
[+]etcd excluded: ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
[+]shutdown ok
healthz check passed
```
<!-- ## Individual health checks -->
## 独立健康检查 {#individual-health-check}
{{< feature-state state="alpha" >}}
<!--
Each individual health check exposes an HTTP endpoint and can be checked individually.
The schema for the individual health checks is `/livez/<healthcheck-name>` where `livez` and `readyz` and be used to indicate if you want to check the liveness or the readiness of the API server.
The `<healthcheck-name>` path can be discovered using the `verbose` flag from above and take the path between `[+]` and `ok`.
These individual health checks should not be consumed by machines but can be helpful for a human operator to debug a system:
-->
每个单独的健康检查都会公开一个 HTTP 端点,并且可以单独检查。
单个运行状况检查的模式为 `/livez/<healthcheck-name>`,其中 `livez``readyz` 表明你要检查的是 API 服务器是否存活或就绪。
`<healthcheck-name>` 的路径可以通过上面的 `verbose` 参数发现 ,并采用 `[+]``ok` 之间的路径。
这些单独的健康检查不应由机器使用,但对于操作人员调试系统而言,是有帮助的:
```shell
curl -k https://localhost:6443/livez/etcd
```
@@ -0,0 +1,890 @@
---
title: 服务器端应用(Server-Side Apply
content_type: concept
weight: 25
min-kubernetes-server-version: 1.16
---
<!--
title: Server-Side Apply
reviewers:
- smarterclayton
- apelisse
- lavalamp
- liggitt
content_type: concept
weight: 25
min-kubernetes-server-version: 1.16
-->
<!-- overview -->
{{< feature-state for_k8s_version="v1.22" state="stable" >}}
<!--
## Introduction
Server Side Apply helps users and controllers manage their resources through
declarative configurations. Clients can create and/or modify their
[objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/)
declaratively by sending their fully specified intent.
-->
## 简介 {#introduction}
服务器端应用协助用户、控制器通过声明式配置的方式管理他们的资源。
客户端可以发送完整描述的目标(A fully specified intent),
声明式地创建和/或修改
[对象](/zh/docs/concepts/overview/working-with-objects/kubernetes-objects/)。
<!--
A fully specified intent is a partial object that only includes the fields and
values for which the user has an opinion. That intent either creates a new
object or is [combined](#merge-strategy), by the server, with the existing object.
The system supports multiple appliers collaborating on a single object.
-->
一个完整描述的目标并不是一个完整的对象,仅包括能体现用户意图的字段和值。
该目标(intent)可以用来创建一个新对象,
也可以通过服务器来实现与现有对象的[合并](#merge-strategy)。
系统支持多个应用者(appliers)在同一个对象上开展协作。
<!--
Changes to an object's fields are tracked through a "[field management](#field-management)"
mechanism. When a field's value changes, ownership moves from its current
manager to the manager making the change. When trying to apply an object,
fields that have a different value and are owned by another manager will
result in a [conflict](#conflicts). This is done in order to signal that the
operation might undo another collaborator's changes. Conflicts can be forced,
in which case the value will be overridden, and the ownership will be
transferred.
-->
“[字段管理(field management](#field-management)”机制追踪对象字段的变化。
当一个字段值改变时,其所有权从当前管理器(manager)转移到施加变更的管理器。
当尝试将新配置应用到一个对象时,如果字段有不同的值,且由其他管理器管理,
将会引发[冲突](#conflicts)。
冲突引发警告信号:此操作可能抹掉其他协作者的修改。
冲突可以被刻意忽略,这种情况下,值将会被改写,所有权也会发生转移。
<!--
If you remove a field from a configuration and apply the configuration, server
side apply checks if there are any other field managers that also own the
field. If the field is not owned by any other field managers, it is either
deleted from the live object or reset to its default value, if it has one. The
same rule applies to associative list or map items.
-->
当你从配置文件中删除一个字段,然后应用这个配置文件,
这将触发服务端应用检查此字段是否还被其他字段管理器拥有。
如果没有,那就从活动对象中删除该字段;如果有,那就重置为默认值。
该规则同样适用于 list 或 map 项目。
<!--
Server side apply is meant both as a replacement for the original `kubectl
apply` and as a simpler mechanism for controllers to enact their changes.
If you have Server Side Apply enabled, the control plane tracks managed fields
for all newly created objects.
-->
服务器端应用既是原有 `kubectl apply` 的替代品,
也是控制器发布自身变化的一个简化机制。
如果你启用了服务器端应用,控制平面就会跟踪被所有新创建对象管理的字段。
<!--
## Field Management
Compared to the `last-applied` annotation managed by `kubectl`, Server Side
Apply uses a more declarative approach, which tracks a user's field management,
rather than a user's last applied state. This means that as a side effect of
using Server Side Apply, information about which field manager manages each
field in an object also becomes available.
-->
## 字段管理 {#field-management}
相对于通过 `kubectl` 管理的注解 `last-applied`
服务器端应用使用了一种更具声明式特点的方法:
它持续的跟踪用户的字段管理,而不仅仅是最后一次的执行状态。
这就意味着,作为服务器端应用的一个副作用,
关于用哪一个字段管理器负责管理对象中的哪个字段的这类信息,都要对外界开放了。
<!--
For a user to manage a field, in the Server Side Apply sense, means that the
user relies on and expects the value of the field not to change. The user who
last made an assertion about the value of a field will be recorded as the
current field manager. This can be done either by changing the value with
`POST`, `PUT`, or non-apply `PATCH`, or by including the field in a config sent
to the Server Side Apply endpoint. When using Server-Side Apply, trying to
change a field which is managed by someone else will result in a rejected
request (if not forced, see [Conflicts](#conflicts)).
-->
用户管理字段这件事,在服务器端应用的场景中,意味着用户依赖并期望字段的值不要改变。
最后一次对字段值做出断言的用户将被记录到当前字段管理器。
这可以通过发送 `POST``PUT`
或非应用(non-apply)方式的 `PATCH` 等命令来修改字段值的方式实现,
或通过把字段放在配置文件中,然后发送到服务器端应用的服务端点的方式实现。
当使用服务器端应用,尝试着去改变一个被其他人管理的字段,
会导致请求被拒绝(在没有设置强制执行时,参见[冲突](#conflicts))。
<!--
When two or more appliers set a field to the same value, they share ownership of
that field. Any subsequent attempt to change the value of the shared field, by any of
the appliers, results in a conflict. Shared field owners may give up ownership
of a field by removing it from their configuration.
Field management is stored in a`managedFields` field that is part of an object's
[`metadata`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#objectmeta-v1-meta).
A simple example of an object created by Server Side Apply could look like this:
-->
如果两个或以上的应用者均把同一个字段设置为相同值,他们将共享此字段的所有权。
后续任何改变共享字段值的尝试,不管由那个应用者发起,都会导致冲突。
共享字段的所有者可以放弃字段的所有权,这只需从配置文件中删除该字段即可。
字段管理的信息存储在 `managedFields` 字段中,该字段是对象的
[`metadata`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#objectmeta-v1-meta)
中的一部分。
服务器端应用创建对象的简单示例如下:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
namespace: default
labels:
test-label: test
managedFields:
- manager: kubectl
operation: Apply
apiVersion: v1
time: "2010-10-10T0:00:00Z"
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:labels:
f:test-label: {}
f:data:
f:key: {}
data:
key: some value
```
<!--
The above object contains a single manager in `metadata.managedFields`. The
manager consists of basic information about the managing entity itself, like
operation type, API version, and the fields managed by it.
This field is managed by the API server and should not be changed by
the user.
-->
上述对象在 `metadata.managedFields` 中包含了唯一的管理器。
管理器由管理实体自身的基本信息组成,比如操作类型、API 版本、以及它管理的字段。
{{< note >}}
该字段由 API 服务器管理,用户不应该改动它。
{{< /note >}}
<!--
Nevertheless it is possible to change `metadata.managedFields` through an
`Update` operation. Doing so is highly discouraged, but might be a reasonable
option to try if, for example, the `managedFields` get into an inconsistent
state (which clearly should not happen).
The format of the `managedFields` is described in the
[API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#fieldsv1-v1-meta).
-->
不过,执行 `Update` 操作修改 `metadata.managedFields` 也是可实现的。
强烈不鼓励这么做,但当发生如下情况时,
比如 `managedFields` 进入不一致的状态(显然不应该发生这种情况),
这么做也是一个合理的尝试。
`managedFields` 的格式在
[API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#fieldsv1-v1-meta)
文档中描述。
<!--
## Conflicts
A conflict is a special status error that occurs when an `Apply` operation tries
to change a field, which another user also claims to manage. This prevents an
applier from unintentionally overwriting the value set by another user. When
this occurs, the applier has 3 options to resolve the conflicts:
-->
## 冲突 {#conflicts}
冲突是一种特定的错误状态,
发生在执行 `Apply` 改变一个字段,而恰巧该字段被其他用户声明过主权时。
这可以防止一个应用者不小心覆盖掉其他用户设置的值。
冲突发生时,应用者有三种办法来解决它:
<!--
* **Overwrite value, become sole manager:** If overwriting the value was
intentional (or if the applier is an automated process like a controller) the
applier should set the `force` query parameter to true and make the request
again. This forces the operation to succeed, changes the value of the field,
and removes the field from all other managers' entries in managedFields.
* **Don't overwrite value, give up management claim:** If the applier doesn't
care about the value of the field anymore, they can remove it from their
config and make the request again. This leaves the value unchanged, and causes
the field to be removed from the applier's entry in managedFields.
* **Don't overwrite value, become shared manager:** If the applier still cares
about the value of the field, but doesn't want to overwrite it, they can
change the value of the field in their config to match the value of the object
on the server, and make the request again. This leaves the value unchanged,
and causes the field's management to be shared by the applier and all other
field managers that already claimed to manage it.
-->
* **覆盖前值,成为唯一的管理器:** 如果打算覆盖该值(或应用者是一个自动化部件,比如控制器),
应用者应该设置查询参数 `force` 为 true,然后再发送一次请求。
这将强制操作成功,改变字段的值,从所有其他管理器的 managedFields 条目中删除指定字段。
* **不覆盖前值,放弃管理权:** 如果应用者不再关注该字段的值,
可以从配置文件中删掉它,再重新发送请求。
这就保持了原值不变,并从 managedFields 的应用者条目中删除该字段。
* **不覆盖前值,成为共享的管理器:** 如果应用者仍然关注字段值,并不想覆盖它,
他们可以在配置文件中把字段的值改为和服务器对象一样,再重新发送请求。
这样在不改变字段值的前提下,
就实现了字段管理被应用者和所有声明了管理权的其他的字段管理器共享。
<!--
## Managers
Managers identify distinct workflows that are modifying the object (especially
useful on conflicts!), and can be specified through the `fieldManager` query
parameter as part of a modifying request. It is required for the apply endpoint,
though kubectl will default it to `kubectl`. For other updates, its default is
computed from the user-agent.
-->
## 管理器 {#managers}
管理器识别出正在修改对象的工作流程(在冲突时尤其有用),
管理器可以通过修改请求的参数 `fieldManager` 指定。
虽然 kubectl 默认发往 `kubectl` 服务端点,但它则请求到应用的服务端点(apply endpoint)。
对于其他的更新,它默认的是从用户代理计算得来。
<!--
## Apply and Update
The two operation types considered by this feature are `Apply` (`PATCH` with
content type `application/apply-patch+yaml`) and `Update` (all other operations
which modify the object). Both operations update the `managedFields`, but behave
a little differently.
Whether you are submitting JSON data or YAML data, use
`application/apply-patch+yaml` as the `Content-Type` header value.
All JSON documents are valid YAML.
-->
## 应用和更新 {#apply-and-update}
此特性涉及两类操作,分别是 `Apply`
(内容类型为 `application/apply-patch+yaml``PATCH` 请求)
`Update` (所有修改对象的其他操作)。
这两类操作都会更新字段 `managedFields`,但行为表现有一点不同。
{{< note >}}
不管你提交的是 JSON 数据还是 YAML 数据,
都要使用 `application/apply-patch+yaml` 作为 `Content-Type` 的值。
所有的 JSON 文档 都是合法的 YAML。
{{< /note >}}
<!--
For instance, only the apply operation fails on conflicts while update does
not. Also, apply operations are required to identify themselves by providing a
`fieldManager` query parameter, while the query parameter is optional for update
operations. Finally, when using the apply operation you cannot have
`managedFields` in the object that is being applied.
An example object with multiple managers could look like this:
-->
例如,在冲突发生的时候,只有 `apply` 操作失败,而 `update` 则不会。
此外,`apply` 操作必须通过提供一个 `fieldManager` 查询参数来标识自身,
而此查询参数对于 `update` 操作则是可选的。
最后,当使用 `apply` 命令时,你不能在应用中的对象中持有 `managedFields`
一个包含多个管理器的对象,示例如下:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
namespace: default
labels:
test-label: test
managedFields:
- manager: kubectl
operation: Apply
apiVersion: v1
fields:
f:metadata:
f:labels:
f:test-label: {}
- manager: kube-controller-manager
operation: Update
apiVersion: v1
time: '2019-03-30T16:00:00.000Z'
fields:
f:data:
f:key: {}
data:
key: new value
```
<!--
In this example, a second operation was run as an `Update` by the manager called
`kube-controller-manager`. The update changed a value in the data field which
caused the field's management to change to the `kube-controller-manager`.
If this update would have been an `Apply` operation, the operation
would have failed due to conflicting ownership.
-->
在这个例子中,
第二个操作被管理器 `kube-controller-manager``Update` 的方式运行。
`update` 更改 data 字段的值,
并使得字段管理器被改为 `kube-controller-manager`
如果把 `update` 操作改为 `Apply`,那就会因为所有权冲突的原因,导致操作失败。
<!--
## Merge strategy
The merging strategy, implemented with Server Side Apply, provides a generally
more stable object lifecycle. Server Side Apply tries to merge fields based on
the actor who manages them instead of overruling based on values. This way
multiple actors can update the same object without causing unexpected interference.
-->
## 合并策略 {#merge-strategy}
由服务器端应用实现的合并策略,提供了一个总体更稳定的对象生命周期。
服务器端应用试图依据负责管理它们的主体来合并字段,而不是根据值来否决。
这么做是为了多个主体可以更新同一个对象,且不会引起意外的相互干扰。
<!--
When a user sends a "fully-specified intent" object to the Server Side Apply
endpoint, the server merges it with the live object favoring the value in the
applied config if it is specified in both places. If the set of items present in
the applied config is not a superset of the items applied by the same user last
time, each missing item not managed by any other appliers is removed. For
more information about how an object's schema is used to make decisions when
merging, see
[sigs.k8s.io/structured-merge-diff](https://sigs.k8s.io/structured-merge-diff).
-->
当用户发送一个“完整描述的目标”对象到服务器端应用的服务端点,
服务器会将它和活动对象做一次合并,如果两者中有重复定义的值,那就以配置文件的为准。
如果配置文件中的项目集合不是此用户上一次操作项目的超集,
所有缺少的、没有其他应用者管理的项目会被删除。
关于合并时用来做决策的对象规格的更多信息,参见
[sigs.k8s.io/structured-merge-diff](https://sigs.k8s.io/structured-merge-diff).
<!--
A number of markers were added in Kubernetes 1.16 and 1.17, to allow API
developers to describe the merge strategy supported by lists, maps, and
structs. These markers can be applied to objects of the respective type,
in Go files or in the OpenAPI schema definition of the
[CRD](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io):
-->
Kubernetes 1.16 和 1.17 中添加了一些标记,
允许 API 开发人员描述由 list、map、和 structs 支持的合并策略。
这些标记可应用到相应类型的对象,在 Go 文件或在
[CRD](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io)
的 OpenAPI 的模式中定义:
<!--
| Golang marker | OpenAPI extension | Accepted values | Description | Introduced in |
|---|---|---|---|---|
| `//+listType` | `x-kubernetes-list-type` | `atomic`/`set`/`map` | Applicable to lists. `set` applies to lists that include only scalar elements. These elements must be unique. `map` applies to lists of nested types only. The key values (see `listMapKey`) must be unique in the list. `atomic` can apply to any list. If configured as `atomic`, the entire list is replaced during merge. At any point in time, a single manager owns the list. If `set` or `map`, different managers can manage entries separately. | 1.16 |
| `//+listMapKey` | `x-kubernetes-list-map-keys` | List of field names, e.g. `["port", "protocol"]` | Only applicable when `+listType=map`. A list of field names whose values uniquely identify entries in the list. While there can be multiple keys, `listMapKey` is singular because keys need to be specified individually in the Go type. The key fields must be scalars. | 1.16 |
| `//+mapType` | `x-kubernetes-map-type` | `atomic`/`granular` | Applicable to maps. `atomic` means that the map can only be entirely replaced by a single manager. `granular` means that the map supports separate managers updating individual fields. | 1.17 |
| `//+structType` | `x-kubernetes-map-type` | `atomic`/`granular` | Applicable to structs; otherwise same usage and OpenAPI annotation as `//+mapType`.| 1.17 |
-->
| Golang 标记 | OpenAPI extension | 可接受的值 | 描述 | 引入版本 |
|---|---|---|---|---|
| `//+listType` | `x-kubernetes-list-type` | `atomic`/`set`/`map` | 适用于 list。`set` 适用于仅包含标量元素的列表。这些元素必须是不重复的。`map` 仅适用于包含嵌套类型的列表。列表中的键(参见 `listMapKey`)不可以重复。`atomic` 适用于任何类型的列表。如果配置为 `atomic`,则合并时整个列表会被替换掉。任何时候,只有一个管理器负责管理指定列表。如果配置为 `set``map`,不同的管理器也可以分开管理条目。 | 1.16 |
| `//+listMapKey` | `x-kubernetes-list-map-keys` | 字段名称的列表,例如,`["port", "protocol"]` | 仅当 `+listType=map` 时适用。取值为字段名称的列表,这些字段值的组合能够唯一标识列表中的条目。尽管可以存在多个键,`listMapKey` 是单数的,这是因为键名需要在 Go 类型中各自独立指定。键字段必须是标量。 | 1.16 |
| `//+mapType` | `x-kubernetes-map-type` | `atomic`/`granular` | 适用于 map。 `atomic` 指 map 只能被单个的管理器整个的替换。 `granular` 指 map 支持多个管理器各自更新自己的字段。 | 1.17 |
| `//+structType` | `x-kubernetes-map-type` | `atomic`/`granular` | 适用于 structs;否则就像 `//+mapType` 有相同的用法和 openapi 注释.| 1.17 |
<!--
If `listType` is missing, the API server interprets a
`patchMergeStrategy=merge` marker as a `listType=map` and the
corresponding `patchMergeKey` marker as a `listMapKey`.
The `atomic` list type is recursive.
These markers are specified as comments and don't have to be repeated as
field tags.
-->
若未指定 `listType`API 服务器将 `patchMergeStrategy=merge` 标记解释为
`listType=map` 并且视对应的 `patchMergeKey` 标记为 `listMapKey` 取值。
`atomic` 列表类型是递归的。
这些标记都是用源代码注释的方式给出的,不必作为字段标签(tag)再重复。
<!--
### Compatibility across topology changes
-->
### 拓扑变化时的兼容性 {#compatibility-across-toplogy-changes}
<!--
On rare occurences, a CRD or built-in type author may want to change the
specific topology of a field in their resource without incrementing its
version. Changing the topology of types, by upgrading the cluster or
updating the CRD, has different consequences when updating existing
objects. There are two categories of changes: when a field goes from
`map`/`set`/`granular` to `atomic` and the other way around.
-->
在极少的情况下,CRD 或者内置类型的作者可能希望更改其资源中的某个字段的
拓扑配置,同时又不提升版本号。
通过升级集群或者更新 CRD 来更改类型的拓扑信息与更新现有对象的结果不同。
变更的类型有两种:一种是将字段从 `map`/`set`/`granular` 更改为 `atomic`
另一种是做逆向改变。
<!--
When the `listType`, `mapType`, or `structType` changes from
`map`/`set`/`granular` to `atomic`, the whole list, map or struct of
existing objects will end-up being owned by actors who owned an element
of these types. This means that any further change to these objects
would cause a conflict.
-->
`listType``mapType``structType``map`/`set`/`granular` 改为
`atomic` 时,现有对象的整个列表、映射或结构的属主都会变为这些类型的
元素之一的属主。这意味着,对这些对象的进一步变更会引发冲突。
<!--
When a list, map, or struct changes from `atomic` to
`map`/`set`/`granular`, the API server won't be able to infer the new
ownership of these fields. Because of that, no conflict will be produced
when objects have these fields updated. For that reason, it is not
recommended to change a type from `atomic` to `map`/`set`/`granular`.
Take for example, the custom resource:
-->
当一个列表、映射或结构从 `atomic` 改为 `map`/`set`/`granular` 之一
时,API 服务器无法推导这些字段的新的属主。因此,当对象的这些字段
再次被更新时不会引发冲突。出于这一原因,不建议将某类型从 `atomic` 改为
`map`/`set`/`granular`
以下面的自定义资源为例:
```yaml
apiVersion: example.com/v1
kind: Foo
metadata:
name: foo-sample
managedFields:
- manager: manager-one
operation: Apply
apiVersion: example.com/v1
fields:
f:spec:
f:data: {}
spec:
data:
key1: val1
key2: val2
```
<!--
Before `spec.data` gets changed from `atomic` to `granular`,
`manager-one` owns the field `spec.data`, and all the fields within it
(`key1` and `key2`). When the CRD gets changed to make `spec.data`
`granular`, `manager-one` continues to own the top-level field
`spec.data` (meaning no other managers can delete the map called `data`
without a conflict), but it no longer owns `key1` and `key2`, so another
manager can then modify or delete those fields without conflict.
-->
`spec.data``atomic` 改为 `granular` 之前,`manager-one`
`spec.data` 字段及其所包含字段(`key1``key2`)的属主。
当对应的 CRD 被更改,使得 `spec.data` 变为 `granular` 拓扑时,
`manager-one` 继续拥有顶层字段 `spec.data`(这意味着其他管理者想
删除名为 `data` 的映射而不引起冲突是不可能的),但不再拥有
`key1``key2`。因此,其他管理者可以在不引起冲突的情况下更改
或删除这些字段。
<!--
### Custom Resources
By default, Server Side Apply treats custom resources as unstructured data. All
keys are treated the same as struct fields, and all lists are considered atomic.
If the Custom Resource Definition defines a
[schema](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io)
that contains annotations as defined in the previous "Merge Strategy"
section, these annotations will be used when merging objects of this
type.
-->
### 自定义资源 {#custom-resources}
默认情况下,服务器端应用把自定义资源看做非结构化数据。
所有的键值(keys)就像 struct 的字段一样被处理,
所有的 list 被认为是原子性的。
如果自定义资源定义(Custom Resource DefinitionCRD)定义了一个
[模式](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io)
它包含类似以前“合并策略”章节中定义过的注解,
这些注解将在合并此类型的对象时使用。
<!--
## Using Server-Side Apply in a controller
As a developer of a controller, you can use server-side apply as a way to
simplify the update logic of your controller. The main differences with a
read-modify-write and/or patch are the following:
* the applied object must contain all the fields that the controller cares about.
* there are no way to remove fields that haven't been applied by the controller
before (controller can still send a PATCH/UPDATE for these use-cases).
* the object doesn't have to be read beforehand, `resourceVersion` doesn't have
to be specified.
It is strongly recommended for controllers to always "force" conflicts, since they
might not be able to resolve or act on these conflicts.
-->
## 在控制器中使用服务器端应用 {#using-server-side-apply-in-controller}
控制器的开发人员可以把服务器端应用作为简化控制器的更新逻辑的方式。
读-改-写 和/或 patch 的主要区别如下所示:
* 应用的对象必须包含控制器关注的所有字段。
* 对于在控制器没有执行过应用操作之前就已经存在的字段,不能删除。
(控制器在这种用例环境下,依然可以发送一个 PATCH/UPDATE
* 对象不必事先读取,`resourceVersion` 不必指定。
强烈推荐:设置控制器在冲突时强制执行,这是因为冲突发生时,它们没有其他解决方案或措施。
<!--
## Transferring Ownership
In addition to the concurrency controls provided by [conflict resolution](#conflicts),
Server Side Apply provides ways to perform coordinated
field ownership transfers from users to controllers.
This is best explained by example. Let's look at how to safely transfer
ownership of the `replicas` field from a user to a controller while enabling
automatic horizontal scaling for a Deployment, using the HorizontalPodAutoscaler
resource and its accompanying controller.
Say a user has defined deployment with `replicas` set to the desired value:
-->
## 转移所有权 {#transferring-ownership}
除了通过[冲突解决方案](#conflicts)提供的并发控制,
服务器端应用提供了一些协作方式来将字段所有权从用户转移到控制器。
最好通过例子来说明这一点。
让我们来看看,在使用 HorizontalPodAutoscaler 资源和与之配套的控制器,
且开启了 Deployment 的自动水平扩展功能之后,
怎么安全的将 `replicas` 字段的所有权从用户转移到控制器。
假设用户定义了 Deployment,且 `replicas` 字段已经设置为期望的值:
{{< codenew file="application/ssa/nginx-deployment.yaml" >}}
<!--
And the user has created the deployment using server side apply like so:
-->
并且,用户使用服务器端应用,像这样创建 Deployment
```shell
kubectl apply -f https://k8s.io/examples/application/ssa/nginx-deployment.yaml --server-side
```
<!--
Then later, HPA is enabled for the deployment, e.g.:
-->
然后,为 Deployment 启用 HPA,例如:
```shell
kubectl autoscale deployment nginx-deployment --cpu-percent=50 --min=1 --max=10
```
<!--
Now, the user would like to remove `replicas` from their configuration, so they
don't accidentally fight with the HPA controller. However, there is a race: it
might take some time before HPA feels the need to adjust `replicas`, and if
the user removes `replicas` before the HPA writes to the field and becomes
its owner, then apiserver will set `replicas` to 1, its default value. This
is not what the user wants to happen, even temporarily.
-->
现在,用户希望从他们的配置中删除 `replicas`,所以他们总是和 HPA 控制器冲突。
然而,这里存在一个竟态:
在 HPA 需要调整 `replicas` 之前会有一个时间窗口,
如果在 HPA 写入字段成为所有者之前,用户删除了`replicas`
那 API 服务器就会把 `replicas` 的值设为 1 也就是默认值。
这不是用户希望发生的事情,即使是暂时的。
<!--
There are two solutions:
- (basic) Leave `replicas` in the configuration; when HPA eventually writes to that
field, the system gives the user a conflict over it. At that point, it is safe
to remove from the configuration.
- (more advanced) If, however, the user doesn't want to wait, for example
because they want to keep the cluster legible to coworkers, then they can take
the following steps to make it safe to remove `replicas` from their
configuration:
First, the user defines a new configuration containing only the `replicas` field:
-->
这里有两个解决方案:
- (基本操作)把 `replicas` 留在配置文件中;当 HPA 最终写入那个字段,
系统基于此事件告诉用户:冲突发生了。在这个时间点,可以安全的删除配置文件。
- (高级操作)然而,如果用户不想等待,比如他们想为合作伙伴保持集群清晰,
那他们就可以执行以下步骤,安全的从配置文件中删除 `replicas`
首先,用户新定义一个只包含 `replicas` 字段的配置文件:
{{< codenew file="application/ssa/nginx-deployment-replicas-only.yaml" >}}
<!--
The user applies that configuration using the field manager name `handover-to-hpa`:
-->
用户使用名为 `handover-to-hpa` 的字段管理器,应用此配置文件。
```shell
kubectl apply -f https://k8s.io/examples/application/ssa/nginx-deployment-replicas-only.yaml \
--server-side --field-manager=handover-to-hpa \
--validate=false
```
<!--
If the apply results in a conflict with the HPA controller, then do nothing. The
conflict indicates the controller has claimed the field earlier in the
process than it sometimes does.
At this point the user may remove the `replicas` field from their configuration.
-->
如果应用操作和 HPA 控制器产生冲突,那什么都不做。
冲突表明控制器在更早的流程中已经对字段声明过所有权。
在此时间点,用户可以从配置文件中删除 `replicas`
{{< codenew file="application/ssa/nginx-deployment-no-replicas.yaml" >}}
<!--
Note that whenever the HPA controller sets the `replicas` field to a new value,
the temporary field manager will no longer own any fields and will be
automatically deleted. No clean up is required.
-->
注意,只要 HPA 控制器为 `replicas` 设置了一个新值,
该临时字段管理器将不再拥有任何字段,会被自动删除。
这里不需要执行清理工作。
<!--
### Transferring Ownership Between Users
Users can transfer ownership of a field between each other by setting the field
to the same value in both of their applied configs, causing them to share
ownership of the field. Once the users share ownership of the field, one of them
can remove the field from their applied configuration to give up ownership and
complete the transfer to the other user.
-->
### 在用户之间转移所有权 {#transferring-ownership-between-users}
通过在配置文件中把一个字段设置为相同的值,用户可以在他们之间转移字段的所有权,
从而共享了字段的所有权。
当用户共享了字段的所有权,任何一个用户可以从他的配置文件中删除该字段,
并应用该变更,从而放弃所有权,并实现了所有权向其他用户的转移。
<!--
## Comparison with Client Side Apply
A consequence of the conflict detection and resolution implemented by Server
Side Apply is that an applier always has up to date field values in their local
state. If they don't, they get a conflict the next time they apply. Any of the
three options to resolve conflicts results in the applied configuration being an
up to date subset of the object on the server's fields.
This is different from Client Side Apply, where outdated values which have been
overwritten by other users are left in an applier's local config. These values
only become accurate when the user updates that specific field, if ever, and an
applier has no way of knowing whether their next apply will overwrite other
users' changes.
Another difference is that an applier using Client Side Apply is unable to
change the API version they are using, but Server Side Apply supports this use
case.
-->
## 与客户端应用的对比 {#comparison-with-client-side-apply}
由服务器端应用实现的冲突检测和解决方案的一个结果就是,
应用者总是可以在本地状态中得到最新的字段值。
如果得不到最新值,下次执行应用操作时就会发生冲突。
解决冲突三个选项的任意一个都会保证:此应用过的配置文件是服务器上对象字段的最新子集。
这和客户端应用(Client Side Apply) 不同,如果有其他用户覆盖了此值,
过期的值被留在了应用者本地的配置文件中。
除非用户更新了特定字段,此字段才会准确,
应用者没有途径去了解下一次应用操作是否会覆盖其他用户的修改。
另一个区别是使用客户端应用的应用者不能改变他们正在使用的 API 版本,但服务器端应用支持这个场景。
<!--
## Upgrading from client-side apply to server-side apply
Client-side apply users who manage a resource with `kubectl apply` can start
using server-side apply with the following flag.
-->
## 从客户端应用升级到服务器端应用 {#upgrading-from-client-side-apply-to-server-side-apply}
客户端应用方式时,用户使用 `kubectl apply` 管理资源,
可以通过使用下面标记切换为使用服务器端应用。
```shell
kubectl apply --server-side [--dry-run=server]
```
<!--
By default, field management of the object transfers from client-side apply to
kubectl server-side apply without encountering conflicts.
Keep the `last-applied-configuration` annotation up to date.
The annotation infers client-side apply's managed fields.
Any fields not managed by client-side apply raise conflicts.
For example, if you used `kubectl scale` to update the replicas field after
client-side apply, then this field is not owned by client-side apply and
creates conflicts on `kubectl apply --server-side`.
This behavior applies to server-side apply with the `kubectl` field manager.
As an exception, you can opt-out of this behavior by specifying a different,
non-default field manager, as seen in the following example. The default field
manager for kubectl server-side apply is `kubectl`.
-->
默认情况下,对象的字段管理从客户端应用方式迁移到 kubectl 触发的服务器端应用时,不会发生冲突。
{{< caution >}}
保持注解 `last-applied-configuration` 是最新的。
从注解能推断出字段是由客户端应用管理的。
任何没有被客户端应用管理的字段将引发冲突。
举例说明,比如你在客户端应用之后,
使用 `kubectl scale` 去更新 `replicas` 字段,
可是该字段并没有被客户端应用所拥有,
在执行 `kubectl apply --server-side` 时就会产生冲突。
{{< /caution >}}
此操作以 `kubectl` 作为字段管理器来应用到服务器端应用。
作为例外,可以指定一个不同的、非默认字段管理器停止的这种行为,如下面的例子所示。
对于 kubectl 触发的服务器端应用,默认的字段管理器是 `kubectl`
```shell
kubectl apply --server-side --field-manager=my-manager [--dry-run=server]
```
<!--
## Downgrading from server-side apply to client-side apply
If you manage a resource with `kubectl apply --server-side`,
you can downgrade to client-side apply directly with `kubectl apply`.
Downgrading works because kubectl server-side apply keeps the
`last-applied-configuration` annotation up-to-date if you use
`kubectl apply`.
This behavior applies to server-side apply with the `kubectl` field manager.
As an exception, you can opt-out of this behavior by specifying a different,
non-default field manager, as seen in the following example. The default field
manager for kubectl server-side apply is `kubectl`.
-->
## 从服务器端应用降级到客户端应用 {#downgrading-from-server-side-apply-to-client-side-apply}
如果你用 `kubectl apply --server-side` 管理一个资源,
可以直接用 `kubectl apply` 命令将其降级为客户端应用。
降级之所以可行,这是因为 `kubectl server-side apply`
会保存最新的 `last-applied-configuration` 注解。
此操作以 `kubectl` 作为字段管理器应用到服务器端应用。
作为例外,可以指定一个不同的、非默认字段管理器停止这种行为,如下面的例子所示。
对于 kubectl 触发的服务器端应用,默认的字段管理器是 `kubectl`
```shell
kubectl apply --server-side --field-manager=my-manager [--dry-run=server]
```
<!--
## API Endpoint
With the Server Side Apply feature enabled, the `PATCH` endpoint accepts the
additional `application/apply-patch+yaml` content type. Users of Server Side
Apply can send partially specified objects as YAML to this endpoint. When
applying a configuration, one should always include all the fields that they
have an opinion about.
-->
## API 端点 {#api-endpoint}
启用了服务器端应用特性之后,
`PATCH` 服务端点接受额外的内容类型 `application/apply-patch+yaml`
服务器端应用的用户就可以把 YAMl 格式的
部分定义对象(partially specified objects)发送到此端点。
当一个配置文件被应用时,它应该包含所有体现你意图的字段。
<!--
## Clearing ManagedFields
It is possible to strip all managedFields from an object by overwriting them
using `MergePatch`, `StrategicMergePatch`, `JSONPatch` or `Update`, so every
non-apply operation. This can be done by overwriting the managedFields field
with an empty entry. Two examples are:
-->
## 清除 ManagedFields {#clearing-managedfields}
可以从对象中剥离所有 managedField
实现方法是通过使用 `MergePatch``StrategicMergePatch`
`JSONPatch``Update`、以及所有的非应用方式的操作来覆盖它。
这可以通过用空条目覆盖 managedFields 字段的方式实现。以下是两个示例:
```console
PATCH /api/v1/namespaces/default/configmaps/example-cm
Content-Type: application/merge-patch+json
Accept: application/json
Data: {"metadata":{"managedFields": [{}]}}
```
```console
PATCH /api/v1/namespaces/default/configmaps/example-cm
Content-Type: application/json-patch+json
Accept: application/json
Data: [{"op": "replace", "path": "/metadata/managedFields", "value": [{}]}]
```
<!--
This will overwrite the managedFields with a list containing a single empty
entry that then results in the managedFields being stripped entirely from the
object. Note that setting the managedFields to an empty list will not
reset the field. This is on purpose, so managedFields never get stripped by
clients not aware of the field.
In cases where the reset operation is combined with changes to other fields
than the managedFields, this will result in the managedFields being reset
first and the other changes being processed afterwards. As a result the
applier takes ownership of any fields updated in the same request.
-->
这一操作将用只包含一个空条目的列表覆写 managedFields
来实现从对象中整个的去除 managedFields。
注意,只把 managedFields 设置为空列表并不会重置字段。
这么做是有目的的,所以 managedFields 将永远不会被与该字段无关的客户删除。
在重置操作结合 managedFields 以外其他字段更改的场景中,
将导致 managedFields 首先被重置,其他改变被押后处理。
其结果是,应用者取得了同一个请求中所有字段的所有权。
<!--
Server Side Apply does not correctly track ownership on
sub-resources that don't receive the resource object type. If you are
using Server Side Apply with such a sub-resource, the changed fields
won't be tracked.
-->
{{< caution >}}
对于不接受资源对象类型的子资源(sub-resources),
服务器端应用不能正确地跟踪其所有权。
如果你对这样的子资源使用服务器端应用,变更的字段将不会被跟踪。
{{< /caution >}}