Merge pull request #40640 from Zhuzhenghao/extensible-admission-controllers

[zh] sync 1.27 extensible-admission-controllers
pull/40850/head
Kubernetes Prow Robot 2023-04-26 00:00:16 -07:00 committed by GitHub
commit 7596dc6b76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 233 additions and 191 deletions

View File

@ -3,8 +3,14 @@ title: 动态准入控制
content_type: concept
weight: 40
---
<!--
reviewers:
- smarterclayton
- lavalamp
- caesarxuchao
- deads2k
- liggitt
- jpbetz
title: Dynamic Admission Control
content_type: concept
weight: 40
@ -21,6 +27,7 @@ This page describes how to build, configure, use, and monitor admission webhooks
此页面描述了如何构建、配置、使用和监视准入 Webhook。
<!-- body -->
<!--
## What are admission webhooks?
-->
@ -29,16 +36,16 @@ This page describes how to build, configure, use, and monitor admission webhooks
<!--
Admission webhooks are HTTP callbacks that receive admission requests and do
something with them. You can define two types of admission webhooks,
[validating admission Webhook](/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook)
[validating admission webhook](/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook)
and
[mutating admission webhook](/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook).
Mutating admission Webhooks are invoked first, and can modify objects sent to the API server to enforce custom defaults.
Mutating admission webhooks are invoked first, and can modify objects sent to the API server to enforce custom defaults.
-->
准入 Webhook 是一种用于接收准入请求并对其进行处理的 HTTP 回调机制。
可以定义两种类型的准入 webhook
[验证性质的准入 Webhook](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook) 和
[修改性质的准入 Webhook](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)。
修改性质的准入 Webhook 会先被调用。它们可以更改发送到 API
修改性质的准入 Webhook 会先被调用。它们可以更改发送到 API
服务器的对象以执行自定义的设置默认值操作。
<!--
@ -48,24 +55,25 @@ validating admission webhooks are invoked and can reject requests to enforce cus
在完成了所有对象修改并且 API 服务器也验证了所传入的对象之后,
验证性质的 Webhook 会被调用,并通过拒绝请求的方式来强制实施自定义的策略。
{{< note >}}
<!--
Admission webhooks that need to guarantee they see the final state of the object in order to enforce policy
should use a validating admission webhook, since objects can be modified after being seen by mutating webhooks.
-->
{{< note >}}
如果准入 Webhook 需要保证它们所看到的是对象的最终状态以实施某种策略。
则应使用验证性质的准入 Webhook因为对象被修改性质 Webhook 看到之后仍然可能被修改。
{{< /note >}}
<!--
### Experimenting with admission webhooks
## Experimenting with admission webhooks
write and deploy them with great caution. Please read the [user
guides](/docs/reference/access-authn-authz/extensible-admission-controllers/#write-an-admission-webhook-server) for
instructions if you intend to write/deploy production-grade admission webhooks.
Admission webhooks are essentially part of the cluster control-plane. You should
write and deploy them with great caution. Please read the
[user guides](/docs/reference/access-authn-authz/extensible-admission-controllers/#write-an-admission-webhook-server)
for instructions if you intend to write/deploy production-grade admission webhooks.
In the following, we describe how to quickly experiment with admission webhooks.
-->
### 尝试准入 Webhook {#experimenting-with-admission-webhooks}
## 尝试准入 Webhook {#experimenting-with-admission-webhooks}
准入 Webhook 本质上是集群控制平面的一部分。你应该非常谨慎地编写和部署它们。
如果你打算编写或者部署生产级准入 webhook请阅读[用户指南](/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers/#write-an-admission-webhook-server)以获取相关说明。
@ -101,19 +109,19 @@ that is validated in a Kubernetes e2e test. The webhook handles the
as an `AdmissionReview` object in the same version it received.
-->
请参阅 Kubernetes e2e 测试中的
[admission webhook 服务器](https://github.com/kubernetes/kubernetes/blob/release-1.21/test/images/agnhost/webhook/main.go)
[Admission Webhook 服务器](https://github.com/kubernetes/kubernetes/blob/release-1.21/test/images/agnhost/webhook/main.go)
的实现。webhook 处理由 API 服务器发送的 `AdmissionReview` 请求,并且将其决定
作为 `AdmissionReview` 对象以相同版本发送回去。
<!--
See the [webhook request](#request) section for details on the data sent to webhooks.
-->
有关发送到 webhook 的数据的详细信息,请参阅 [webhook 请求](#request)。
有关发送到 Webhook 的数据的详细信息,请参阅 [Webhook 请求](#request)。
<!--
See the [webhook response](#response) section for the data expected from webhooks.
-->
要获取来自 webhook 的预期数据,请参阅 [webhook 响应](#response)。
要获取来自 Webhook 的预期数据,请参阅 [Webhook 响应](#response)。
<!--
The example admission webhook server leaves the `ClientAuth` field
@ -125,7 +133,7 @@ how to [authenticate API servers](#authenticate-apiservers).
-->
示例准入 Webhook 服务器置 `ClientAuth` 字段为
[](https://github.com/kubernetes/kubernetes/blob/v1.22.0/test/images/agnhost/webhook/config.go#L38-L39)
默认为 `NoClientCert` 。这意味着 webhook 服务器不会验证客户端的身份,认为其是 apiservers。
默认为 `NoClientCert` 。这意味着 Webhook 服务器不会验证客户端的身份,认为其是 apiservers。
如果你需要双向 TLS 或其他方式来验证客户端,请参阅
如何[对 apiservers 进行身份认证](#authenticate-apiservers)。
@ -141,18 +149,18 @@ The test also creates a [service](/docs/reference/generated/kubernetes-api/{{< p
as the front-end of the webhook server. See
[code](https://github.com/kubernetes/kubernetes/blob/v1.22.0/test/e2e/apimachinery/webhook.go#L748).
-->
e2e 测试中的 webhook 服务器通过
e2e 测试中的 Webhook 服务器通过
[deployment API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deployment-v1-apps)
部署在 Kubernetes 集群中。该测试还将创建一个
[service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core)
作为 webhook 服务器的前端。参见
作为 Webhook 服务器的前端。参见
[相关代码](https://github.com/kubernetes/kubernetes/blob/v1.22.0/test/e2e/apimachinery/webhook.go#L748)。
<!--
You may also deploy your webhooks outside of the cluster. You will need to update
your webhook configurations accordingly.
-->
你也可以在集群外部署 webhook。这样做需要相应地更新你的 webhook 配置。
你也可以在集群外部署 Webhook。这样做需要相应地更新你的 Webhook 配置。
<!--
### Configure admission webhooks on the fly
@ -166,15 +174,16 @@ webhooks via
or
[MutatingWebhookConfiguration](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#mutatingwebhookconfiguration-v1-admissionregistration-k8s-io).
-->
你可以通过
你可以通过
[ValidatingWebhookConfiguration](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#validatingwebhookconfiguration-v1-admissionregistration-k8s-io)
或者
或者
[MutatingWebhookConfiguration](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#mutatingwebhookconfiguration-v1-admissionregistration-k8s-io) 动态配置哪些资源要被哪些准入 Webhook 处理。
<!--
The following is an example `ValidatingWebhookConfiguration`, a mutating webhook configuration is similar.
See the [webhook configuration](#webhook-configuration) section for details about each config field.
-->
以下是一个 `ValidatingWebhookConfiguration` 示例,mutating webhook 配置与此类似。有关每个配置字段的详细信息,请参阅 [webhook 配置](#webhook-configuration) 部分。
以下是一个 `ValidatingWebhookConfiguration` 示例,Mutating Webhook 配置与此类似。有关每个配置字段的详细信息,请参阅 [Webhook 配置](#webhook-configuration) 部分。
```yaml
apiVersion: admissionregistration.k8s.io/v1
@ -184,11 +193,11 @@ metadata:
webhooks:
- name: "pod-policy.example.com"
rules:
- apiGroups: [""]
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]
scope: "Namespaced"
operations: ["CREATE"]
resources: ["pods"]
scope: "Namespaced"
clientConfig:
service:
namespace: "example-namespace"
@ -198,6 +207,7 @@ webhooks:
sideEffects: None
timeoutSeconds: 5
```
{{< note >}}
<!--
You must replace the `<CA_BUNDLE>` in the above example by a valid CA bundle
@ -207,30 +217,30 @@ which is a PEM-encoded CA bundle for validating the webhook's server certificate
这是一个用 PEM 编码的 CA 证书包,用于校验 Webhook 的服务器证书。
{{< /note >}}
<!--
<!--
The `scope` field specifies if only cluster-scoped resources ("Cluster") or namespace-scoped
resources ("Namespaced") will match this rule. "&lowast;" means that there are no scope restrictions.
-->
`scope` 字段指定是仅集群范围的资源Cluster还是名字空间范围的资源资源Namespaced将与此规则匹配。
`*` 表示没有范围限制。
{{< note >}}
<!--
When using `clientConfig.service`, the server cert must be valid for
`<svc_name>.<svc_namespace>.svc`.
-->
{{< note >}}
当使用 `clientConfig.service` 时,服务器证书必须对 `<svc_name>.<svc_namespace>.svc` 有效。
{{< /note >}}
{{< note >}}
<!--
Default timeout for a webhook call is 10 seconds,
You can set the `timeout` and it is encouraged to use a short timeout for webhooks.
If the webhook call times out, the request is handled according to the webhook's
failure policy.
-->
{{< note >}}
Webhook 调用的默认超时是 10 秒,你可以设置 `timeout` 并建议对 webhook 设置较短的超时时间。
如果 webhook 调用超时,则根据 webhook 的失败策略处理请求。
Webhook 调用的默认超时是 10 秒,你可以设置 `timeout` 并建议对 Webhook 设置较短的超时时间。
如果 Webhook 调用超时,则根据 Webhook 的失败策略处理请求。
{{< /note >}}
<!--
@ -242,12 +252,12 @@ After you create the webhook configuration, the system will take a few seconds
to honor the new configuration.
-->
当一个 API 服务器收到与 `rules` 相匹配的请求时,
该 API 服务器将按照 `clientConfig` 中指定的方式向 webhook 发送一个 `admissionReview` 请求。
该 API 服务器将按照 `clientConfig` 中指定的方式向 Webhook 发送一个 `admissionReview` 请求。
创建 Webhook 配置后,系统将花费几秒钟使新配置生效。
<!--
### Authenticate API servers
### Authenticate API servers {#authenticate-apiservers}
-->
### 对 API 服务器进行身份认证 {#authenticate-apiservers}
@ -322,71 +332,74 @@ For more information about `AdmissionConfiguration`, see the
[AdmissionConfiguration (v1) reference](/docs/reference/config-api/apiserver-webhookadmission.v1/).
See the [webhook configuration](#webhook-configuration) section for details about each config field.
* In the kubeConfig file, provide the credentials:
In the kubeConfig file, provide the credentials:
-->
有关 `AdmissionConfiguration` 的更多信息,请参见
[AdmissionConfiguration (v1) reference](/docs/reference/config-api/apiserver-webhookadmission.v1/)。
有关每个配置字段的详细信息,请参见 [webhook 配置](#webhook-配置)部分。
有关每个配置字段的详细信息,请参见 [Webhook 配置](#webhook-配置)部分。
* 在 kubeConfig 文件中,提供证书凭据:
在 kubeConfig 文件中,提供证书凭据:
```yaml
apiVersion: v1
kind: Config
users:
# 名称应设置为服务的 DNS 名称或配置了 Webhook 的 URL 的主机名(包括端口)。
# 如果将非 443 端口用于服务,则在配置 1.16+ API 服务器时,该端口必须包含在名称中。
#
# 对于配置在默认端口443上与服务对话的 Webhook请指定服务的 DNS 名称:
# - name: webhook1.ns1.svc
# user: ...
#
# 对于配置在非默认端口(例如 8443上与服务对话的 Webhook请在 1.16+ 中指定服务的 DNS 名称和端口:
# - name: webhook1.ns1.svc:8443
# user: ...
# 并可以选择仅使用服务的 DNS 名称来创建第二节,以与 1.15 API 服务器版本兼容:
# - name: webhook1.ns1.svc
# user: ...
#
# 对于配置为使用 URL 的 webhook请匹配在 webhook 的 URL 中指定的主机(和端口)。
# 带有 `url: https://www.example.com` 的 webhook
# - name: www.example.com
# user: ...
#
# 带有 `url: https://www.example.com:443` 的 webhook
# - name: www.example.com:443
# user: ...
#
# 带有 `url: https://www.example.com:8443` 的 webhook
# - name: www.example.com:8443
# user: ...
#
- name: 'webhook1.ns1.svc'
user:
client-certificate-data: "<pem encoded certificate>"
client-key-data: "<pem encoded key>"
# `name` 支持使用 * 通配符匹配前缀段。
- name: '*.webhook-company.org'
user:
password: "<password>"
username: "<name>"
# '*' 是默认匹配项。
- name: '*'
user:
token: "<token>"
```
```yaml
apiVersion: v1
kind: Config
users:
# 名称应设置为服务的 DNS 名称或配置了 Webhook 的 URL 的主机名(包括端口)。
# 如果将非 443 端口用于服务,则在配置 1.16+ API 服务器时,该端口必须包含在名称中。
#
# 对于配置在默认端口443上与服务对话的 Webhook请指定服务的 DNS 名称:
# - name: webhook1.ns1.svc
# user: ...
#
# 对于配置在非默认端口(例如 8443上与服务对话的 Webhook请在 1.16+ 中指定服务的 DNS 名称和端口:
# - name: webhook1.ns1.svc:8443
# user: ...
# 并可以选择仅使用服务的 DNS 名称来创建第二节,以与 1.15 API 服务器版本兼容:
# - name: webhook1.ns1.svc
# user: ...
#
# 对于配置为使用 URL 的 webhook请匹配在 webhook 的 URL 中指定的主机(和端口)。
# 带有 `url: https://www.example.com` 的 webhook
# - name: www.example.com
# user: ...
#
# 带有 `url: https://www.example.com:443` 的 webhook
# - name: www.example.com:443
# user: ...
#
# 带有 `url: https://www.example.com:8443` 的 webhook
# - name: www.example.com:8443
# user: ...
#
- name: 'webhook1.ns1.svc'
user:
client-certificate-data: "<pem encoded certificate>"
client-key-data: "<pem encoded key>"
# `name` 支持使用 * 通配符匹配前缀段。
- name: '*.webhook-company.org'
user:
password: "<password>"
username: "<name>"
# '*' 是默认匹配项。
- name: '*'
user:
token: "<token>"
```
<!--
Of course you need to set up the webhook server to handle these authentication requests.
-->
当然,你需要设置 Webhook 服务器来处理这些身份验证请求。
<!-- ## Webhook request and response -->
<!--
## Webhook request and response
-->
## Webhook 请求与响应 {#webhook-request-and-response}
<!--
### Request
Webhooks are sent as POST request, with `Content-Type: application/json`,
Webhooks are sent as POST requests, with `Content-Type: application/json`,
with an `AdmissionReview` API object in the `admission.k8s.io` API group
serialized to JSON as the body.
@ -396,7 +409,8 @@ with the `admissionReviewVersions` field in their configuration:
### 请求 {#request}
Webhook 发送 POST 请求时,请设置 `Content-Type: application/json` 并对 `admission.k8s.io` API 组中的 `AdmissionReview` 对象进行序列化,将所得到的 JSON 作为请求的主体。
Webhook 发送 POST 请求时,请设置 `Content-Type: application/json` 并对 `admission.k8s.io` API
组中的 `AdmissionReview` 对象进行序列化,将所得到的 JSON 作为请求的主体。
Webhook 可以在配置中的 `admissionReviewVersions` 字段指定可接受的 `AdmissionReview` 对象版本:
@ -414,7 +428,7 @@ webhooks:
Webhooks are required to support at least one `AdmissionReview`
version understood by the current and previous API server.
-->
创建 webhook 配置时,`admissionReviewVersions` 是必填字段。
创建 Webhook 配置时,`admissionReviewVersions` 是必填字段。
Webhook 必须支持至少一个当前和以前的 API 服务器都可以解析的 `AdmissionReview` 版本。
<!--
@ -455,24 +469,24 @@ request:
subResource: scale
# 在对 API 服务器的原始请求中,传入对象的标准 group/version/kind
# 仅当 webhook 指定 `matchPolicy: Equivalent` 且将对 API 服务器的原始请求
# 转换为 webhook 注册的版本时,这才与 `kind` 不同。
# 仅当 Webhook 指定 `matchPolicy: Equivalent` 且将对 API 服务器的原始请求
# 转换为 Webhook 注册的版本时,这才与 `kind` 不同。
requestKind:
group: autoscaling
version: v1
kind: Scale
# 在对 API 服务器的原始请求中正在修改的资源的标准 group/version/kind
# 仅当 webhook 指定了 `matchPolicyEquivalent` 并且将对 API 服务器的原始请求转换为
# webhook 注册的版本时,这才与 `resource` 不同。
# 仅当 Webhook 指定了 `matchPolicyEquivalent` 并且将对 API 服务器的原始请求转换为
# Webhook 注册的版本时,这才与 `resource` 不同。
requestResource:
group: apps
version: v1
resource: deployments
# subResource如果请求是针对 subResource 的)
# 仅当 webhook 指定了 `matchPolicyEquivalent` 并且将对
# API 服务器的原始请求转换为该 webhook 注册的版本时,这才与 `subResource` 不同。
# 仅当 Webhook 指定了 `matchPolicyEquivalent` 并且将对
# API 服务器的原始请求转换为该 Webhook 注册的版本时,这才与 `subResource` 不同。
requestSubResource: scale
# 被修改资源的名称
@ -585,9 +599,10 @@ Webhook 禁止请求的最简单响应示例:
```
<!--
When rejecting a request, the webhook can customize the http code and message returned to the user using the `status` field.
The specified status object is returned to the user.
See the [API documentation](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#status-v1-meta) for details about the `status` type.
When rejecting a request, the webhook can customize the http code and message returned to the user
using the `status` field. The specified status object is returned to the user.
See the [API documentation](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#status-v1-meta)
for details about the `status` type.
Example of a response to forbid a request, customizing the HTTP status code and message presented to the user:
-->
当拒绝请求时Webhook 可以使用 `status` 字段自定义 http 响应码和返回给用户的消息。
@ -624,7 +639,8 @@ For `patchType: JSONPatch`, the `patch` field contains a base64-encoded array of
对于 `patchType: JSONPatch``patch` 字段包含一个以 base64 编码的 JSON patch 操作数组。
<!--
As an example, a single patch operation that would set `spec.replicas` would be `[{"op": "add", "path": "/spec/replicas", "value": 3}]`
As an example, a single patch operation that would set `spec.replicas` would be
`[{"op": "add", "path": "/spec/replicas", "value": 3}]`
Base64-encoded, this would be `W3sib3AiOiAiYWRkIiwgInBhdGgiOiAiL3NwZWMvcmVwbGljYXMiLCAidmFsdWUiOiAzfV0=`
-->
@ -652,18 +668,19 @@ So a webhook response to add that label would be:
}
```
<!--
Admission webhooks can optionally return warning messages that are returned to the requesting client in HTTP `Warning` headers with a warning code of 299. Warnings can be sent with allowed or rejected admission responses.
<!--
Admission webhooks can optionally return warning messages that are returned to the requesting client
in HTTP `Warning` headers with a warning code of 299. Warnings can be sent with allowed or rejected admission responses.
-->
准入 Webhook 可以选择性地返回在 HTTP `Warning` 头中返回给请求客户端的警告消息,警告代码为 299。
警告可以与允许或拒绝的准入响应一起发送。
<!--
<!--
If you're implementing a webhook that returns a warning:
* Don't include a "Warning:" prefix in the message
* Use warning messages to describe problems the client making the API request should correct or be aware of
* Limit warnings to 120 characters if possible
* Limit warnings to 120 characters if possible
-->
如果你正在实现返回一条警告的 webhook
@ -674,7 +691,7 @@ If you're implementing a webhook that returns a warning:
{{< caution >}}
<!--
Individual warning messages over 256 characters may be truncated by the API server before being returned to clients.
If more than 4096 characters of warning messages are added (from all sources), additional warning messages are ignored.
If more than 4096 characters of warning messages are added (from all sources), additional warning messages are ignored.
-->
超过 256 个字符的单条警告消息在返回给客户之前可能会被 API 服务器截断。
如果超过 4096 个字符的警告消息(来自所有来源),则额外的警告消息会被忽略。
@ -731,37 +748,44 @@ Webhook则应为每个 Webhook 赋予一个唯一的名称。
Each webhook must specify a list of rules used to determine if a request to the API server should be sent to the webhook.
Each rule specifies one or more operations, apiGroups, apiVersions, and resources, and a resource scope:
-->
每个 webhook 必须指定用于确定是否应将对 apiserver 的请求发送到 webhook 的规则列表。
每个 Webhook 必须指定用于确定是否应将对 apiserver 的请求发送到 webhook 的规则列表。
每个规则都指定一个或多个 operations、apiGroups、apiVersions 和 resources 以及资源的 scope
<!--
* `operations` lists one or more operations to match. Can be `"CREATE"`, `"UPDATE"`, `"DELETE"`, `"CONNECT"`, or `"*"` to match all.
* `operations` lists one or more operations to match. Can be `"CREATE"`, `"UPDATE"`, `"DELETE"`, `"CONNECT"`,
or `"*"` to match all.
* `apiGroups` lists one or more API groups to match. `""` is the core API group. `"*"` matches all API groups.
* `apiVersions` lists one or more API versions to match. `"*"` matches all API versions.
* `resources` lists one or more resources to match.
* `"*"` matches all resources, but not subresources.
* `"*/*"` matches all resources and subresources.
* `"pods/*"` matches all subresources of pods.
* `"*/status"` matches all status subresources.
* `scope` specifies a scope to match. Valid values are `"Cluster"`, `"Namespaced"`, and `"*"`. Subresources match the scope of their parent resource. Default is `"*"`.
* `"Cluster"` means that only cluster-scoped resources will match this rule (Namespace API objects are cluster-scoped).
* `"Namespaced"` means that only namespaced resources will match this rule.
* `"*"` means that there are no scope restrictions.
* `"*"` matches all resources, but not subresources.
* `"*/*"` matches all resources and subresources.
* `"pods/*"` matches all subresources of pods.
* `"*/status"` matches all status subresources.
* `scope` specifies a scope to match. Valid values are `"Cluster"`, `"Namespaced"`, and `"*"`.
Subresources match the scope of their parent resource. Default is `"*"`.
* `"Cluster"` means that only cluster-scoped resources will match this rule (Namespace API objects are cluster-scoped).
* `"Namespaced"` means that only namespaced resources will match this rule.
* `"*"` means that there are no scope restrictions.
-->
* `operations` 列出一个或多个要匹配的操作。
可以是 `CREATE`、`UPDATE`、`DELETE`、`CONNECT` 或 `*` 以匹配所有内容。
* `apiGroups` 列出了一个或多个要匹配的 API 组。`""` 是核心 API 组。`"*"` 匹配所有 API 组。
* `apiVersions` 列出了一个或多个要匹配的 API 版本。`"*"` 匹配所有 API 版本。
* `resources` 列出了一个或多个要匹配的资源。
* `"*"` 匹配所有资源,但不包括子资源。
* `"*/*"` 匹配所有资源,包括子资源。
* `"pods/*"` 匹配 pod 的所有子资源。
* `"*/status"` 匹配所有 status 子资源。
* `"*"` 匹配所有资源,但不包括子资源。
* `"*/*"` 匹配所有资源,包括子资源。
* `"pods/*"` 匹配 pod 的所有子资源。
* `"*/status"` 匹配所有 status 子资源。
* `scope` 指定要匹配的范围。有效值为 `"Cluster"`、`"Namespaced"` 和 `"*"`
子资源匹配其父资源的范围。默认值为 `"*"`
* `"Cluster"` 表示只有集群作用域的资源才能匹配此规则API 对象 Namespace 是集群作用域的)。
* `"Namespaced"` 意味着仅具有名字空间的资源才符合此规则。
* `"*"` 表示没有作用域限制。
* `"Cluster"` 表示只有集群作用域的资源才能匹配此规则API 对象 Namespace 是集群作用域的)。
* `"Namespaced"` 意味着仅具有名字空间的资源才符合此规则。
* `"*"` 表示没有作用域限制。
<!--
If an incoming request matches one of the specified `operations`, `groups`, `versions`,
@ -855,9 +879,10 @@ is not considered to match.
被认为不匹配。
<!--
Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels.
Use the object selector only if the webhook is opt-in, because end users may skip
the admission webhook by setting the labels.
-->
仅当选择使用 webhook 时才使用对象选择器,因为最终用户可以通过设置标签来
仅当选择使用 Webhook 时才使用对象选择器,因为最终用户可以通过设置标签来
跳过准入 Webhook。
<!--
@ -926,7 +951,7 @@ webhooks:
matchExpressions:
- key: runlevel
operator: NotIn
values: ["0","1"]
values: ["0", "1"]
rules:
- operations: ["CREATE"]
apiGroups: ["*"]
@ -936,8 +961,8 @@ webhooks:
```
<!--
This example shows a validating webhook that matches a `CREATE` of any namespaced resource inside a namespace
that is associated with the "environment" of "prod" or "staging":
This example shows a validating webhook that matches a `CREATE` of any namespaced resource inside
a namespace that is associated with the "environment" of "prod" or "staging":
-->
此示例显示了一个验证性质的 Webhook它将匹配到对某名字空间中的任何具名字空间的资源的
`CREATE` 请求,前提是该名字空间具有值为 "prod" 或 "staging" 的 "environment" 标签:
@ -951,7 +976,7 @@ webhooks:
matchExpressions:
- key: environment
operator: In
values: ["prod","staging"]
values: ["prod", "staging"]
rules:
- operations: ["CREATE"]
apiGroups: ["*"]
@ -983,7 +1008,7 @@ For example, if a webhook only specified a rule for some API groups/versions
and a request was made to modify the resource via another API group/version (like `extensions/v1beta1`),
the request would not be sent to the webhook.
-->
例如,如果一个 webhook 仅为某些 API 组/版本指定了规则(例如
例如,如果一个 Webhook 仅为某些 API 组/版本指定了规则(例如
`apiGroups:["apps"], apiVersions:["v1","v1beta1"]`),而修改资源的请求是通过另一个
API 组/版本(例如 `extensions/v1beta1`)发出的,该请求将不会被发送到 Webhook。
@ -991,25 +1016,28 @@ API 组/版本(例如 `extensions/v1beta1`)发出的,该请求将不会被
The `matchPolicy` lets a webhook define how its `rules` are used to match incoming requests.
Allowed values are `Exact` or `Equivalent`.
-->
`matchPolicy` 允许 webhook 定义如何使用其 `rules` 匹配传入的请求。
`matchPolicy` 允许 Webhook 定义如何使用其 `rules` 匹配传入的请求。
允许的值为 `Exact``Equivalent`
<!--
* `Exact` means a request should be intercepted only if it exactly matches a specified rule.
* `Equivalent` means a request should be intercepted if modifies a resource listed in `rules`, even via another API group or version.
* `Equivalent` means a request should be intercepted if modifies a resource listed in `rules`,
even via another API group or version.
In the example given above, the webhook that only registered for `apps/v1` could use `matchPolicy`:
* `matchPolicy: Exact` would mean the `extensions/v1beta1` request would not be sent to the webhook
* `matchPolicy: Equivalent` means the `extensions/v1beta1` request would be sent to the webhook (with the objects converted to a version the webhook had specified: `apps/v1`)
* `matchPolicy: Equivalent` means the `extensions/v1beta1` request would be sent to the webhook
(with the objects converted to a version the webhook had specified: `apps/v1`)
-->
* `Exact` 表示仅当请求与指定规则完全匹配时才应拦截该请求。
* `Equivalent` 表示如果某个请求意在修改 `rules` 中列出的资源,
即使该请求是通过其他 API 组或版本发起,也应拦截该请求。
在上面给出的示例中,仅为 `apps/v1` 注册的 webhook 可以使用 `matchPolicy`
在上面给出的示例中,仅为 `apps/v1` 注册的 Webhook 可以使用 `matchPolicy`
* `matchPolicy: Exact` 表示不会将 `extensions/v1beta1` 请求发送到 Webhook
* `matchPolicy:Equivalent` 表示将 `extensions/v1beta1` 请求发送到 webhook
(将对象转换为 webhook 指定的版本:`apps/v1`
* `matchPolicy:Equivalent` 表示将 `extensions/v1beta1` 请求发送到 Webhook
(将对象转换为 Webhook 指定的版本:`apps/v1`
<!--
Specifying `Equivalent` is recommended, and ensures that webhooks continue to intercept the
@ -1019,7 +1047,8 @@ resources they expect when upgrades enable new versions of the resource in the A
Webhook 继续拦截他们期望的资源。
<!--
When a resource stops being served by the API server, it is no longer considered equivalent to other versions of that resource that are still served.
When a resource stops being served by the API server, it is no longer considered equivalent to
other versions of that resource that are still served.
For example, `extensions/v1beta1` deployments were first deprecated and then removed (in Kubernetes v1.16).
Since that removal, a webhook with a `apiGroups:["extensions"], apiVersions:["v1beta1"], resources:["deployments"]` rule
@ -1029,7 +1058,7 @@ for stable versions of resources.
当 API 服务器停止提供某资源时,该资源不再被视为等同于该资源的其他仍在提供服务的版本。
例如,`extensions/v1beta1` 中的 Deployment 已被废弃,计划在 v1.16 中移除。
移除后,带有 `apiGroups:["extensions"], apiVersions:["v1beta1"], resources: ["deployments"]`
移除后,带有 `apiGroups:["extensions"], apiVersions:["v1beta1"], resources: ["deployments"]`
规则的 Webhook 将不再拦截通过 `apps/v1` API 来创建的 Deployment。
因此Webhook 应该优先注册稳定版本的资源。
@ -1054,8 +1083,8 @@ webhooks:
scope: "Namespaced"
```
<!--
The `matchPolicy` for an admission webhooks defaults to `Equivalent`.
<!--
The `matchPolicy` for an admission webhooks defaults to `Equivalent`.
-->
准入 Webhook 所用的 `matchPolicy` 默认为 `Equivalent`
@ -1144,7 +1173,7 @@ webhooks:
expression: '!authorizer.group("admissionregistration.k8s.io").resource("validatingwebhookconfigurations").name("my-webhook.example.com").check("breakglass").allowed()'
```
<!--
<!--
Match conditions have access to the following CEL variables:
-->
匹配条件可以访问以下 CEL 变量:
@ -1217,8 +1246,8 @@ stanza of the webhook configuration.
Webhooks can either be called via a URL or a service reference,
and can optionally include a custom CA bundle to use to verify the TLS connection.
-->
API 服务器确定请求应发送到 webhook 后,它需要知道如何调用 webhook。
此信息在 webhook 配置的 `clientConfig` 节中指定。
API 服务器确定请求应发送到 Webhook 后,它需要知道如何调用 webhook。
此信息在 Webhook 配置的 `clientConfig` 节中指定。
Webhook 可以通过 URL 或服务引用来调用,并且可以选择包含自定义 CA 包,以用于验证 TLS 连接。
@ -1231,7 +1260,7 @@ Webhook 可以通过 URL 或服务引用来调用,并且可以选择包含自
`url` gives the location of the webhook, in standard URL form
(`scheme://host:port/path`).
-->
`url` 以标准 URL 形式给出 webhook 的位置(`scheme://host:port/path`)。
`url` 以标准 URL 形式给出 Webhook 的位置(`scheme://host:port/path`)。
<!--
The `host` should not refer to a service running in the cluster; use
@ -1247,12 +1276,12 @@ be a layering violation). `host` may also be an IP address.
<!--
Please note that using `localhost` or `127.0.0.1` as a `host` is
risky unless you take great care to run this webhook on all hosts
which run an apiserver which might need to make calls to this
webhook. Such installations are likely to be non-portable, i.e., not easy
to turn up in a new cluster.
which run an API server which might need to make calls to this
webhook. Such installations are likely to be non-portable or not readily
run in a new cluster.
-->
请注意,将 `localhost``127.0.0.1` 用作 `host` 是有风险的,
除非你非常小心地在所有运行 apiserver 的、可能需要对此 webhook
除非你非常小心地在所有运行 apiserver 的、可能需要对此 Webhook
进行调用的主机上运行。这样的安装方式可能不具有可移植性,即很难在新集群中启用。
<!--
@ -1261,8 +1290,8 @@ The scheme must be "https"; the URL must begin with "https://".
scheme 必须为 "https"URL 必须以 "https://" 开头。
<!--
Attempting to use a user or basic auth e.g. "user:password@" is not allowed.
Fragments ("#...") and query parameters ("?...") are also not allowed.
Attempting to use a user or basic auth (for example `user:password@`) is not allowed.
Fragments (`#...`) and query parameters (`?...`) are also not allowed.
-->
使用用户或基本身份验证(例如:"user:password@")是不允许的。
使用片段("#...")和查询参数("?...")也是不允许的。
@ -1321,14 +1350,16 @@ webhooks:
path: /my-path
port: 1234
```
{{< note >}}
<!--
You must replace the `<CA_BUNDLE>` in the above example by a valid CA bundle
which is a PEM-encoded CA bundle for validating the webhook's server certificate.
which is a PEM-encoded CA bundle for validating the webhook's server certificate.
-->
你必须在以上示例中将 `<CA_BUNDLE>` 替换为一个有效的 VA 证书包,
这是一个用 PEM 编码的 CA 证书包,用于校验 Webhook 的服务器证书。
{{< /note >}}
<!--
### Side effects
-->
@ -1342,7 +1373,7 @@ Webhook 通常仅对发送给他们的 `AdmissionReview` 内容进行操作。
但是,某些 Webhook 在处理 admission 请求时会进行带外更改。
<!--
Webhooks that make out-of-band changes ("side effects") must also have a reconcilation mechanism
Webhooks that make out-of-band changes ("side effects") must also have a reconciliation mechanism
(like a controller) that periodically determines the actual state of the world, and adjusts
the out-of-band data modified by the admission webhook to reflect reality.
This is because a call to an admission webhook does not guarantee the admitted object will be persisted as is, or at all.
@ -1372,16 +1403,16 @@ Webhooks indicate whether they have side effects using the `sideEffects` field i
`dryRun: true` is sent to the webhook, the webhook will suppress the side effects (the webhook
is `dryRun`-aware).
-->
Webhook 使用 webhook 配置中的 `sideEffects` 字段显示它们是否有副作用:
Webhook 使用 Webhook 配置中的 `sideEffects` 字段显示它们是否有副作用:
* `None`:调用 webhook 没有副作用。
* `NoneOnDryRun`:调用 webhook 可能会有副作用,但是如果将带有 `dryRun: true`
属性的请求发送到 webhookwebhook 将抑制副作用(该 webhook 可识别 `dryRun`)。
* `None`:调用 Webhook 没有副作用。
* `NoneOnDryRun`:调用 Webhook 可能会有副作用,但是如果将带有 `dryRun: true`
属性的请求发送到 webhookWebhook 将抑制副作用(该 Webhook 可识别 `dryRun`)。
<!--
Here is an example of a validating webhook indicating it has no side effects on `dryRun: true` requests:
-->
这是一个 validating webhook 的示例,表明它对 `dryRun: true` 请求没有副作用:
这是一个 validating Webhook 的示例,表明它对 `dryRun: true` 请求没有副作用:
```yaml
apiVersion: admissionregistration.k8s.io/v1
@ -1427,8 +1458,8 @@ webhooks:
timeoutSeconds: 2
```
<!--
The timeout for an admission webhook defaults to 10 seconds.
<!--
The timeout for an admission webhook defaults to 10 seconds.
-->
准入 Webhook 所用的超时时间默认为 10 秒。
@ -1464,9 +1495,9 @@ and mutating webhooks can specify a `reinvocationPolicy` to control whether they
可以将 `reinvocationPolicy` 设置为 `Never``IfNeeded`。 默认为 `Never`
<!--
* `Never`: the webhook must not be called more than once in a single admission evaluation
* `Never`: the webhook must not be called more than once in a single admission evaluation.
* `IfNeeded`: the webhook may be called again as part of the admission evaluation if the object
being admitted is modified by other admission plugins after the initial webhook call.
being admitted is modified by other admission plugins after the initial webhook call.
-->
* `Never`: 在一次准入测试中,不得多次调用 Webhook。
* `IfNeeded`: 如果在最初的 Webhook 调用之后被其他对象的插件修改了被接纳的对象,
@ -1479,9 +1510,11 @@ The important elements to note are:
<!--
* The number of additional invocations is not guaranteed to be exactly one.
* If additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again.
* If additional invocations result in further modifications to the object, webhooks are not
guaranteed to be invoked again.
* Webhooks that use this option may be reordered to minimize the number of additional invocations.
* To validate an object after all mutations are guaranteed complete, use a validating admission webhook instead (recommended for webhooks with side-effects).
* To validate an object after all mutations are guaranteed complete, use a validating admission
webhook instead (recommended for webhooks with side-effects).
-->
* 不能保证附加调用的次数恰好是一。
* 如果其他调用导致对该对象的进一步修改,则不能保证再次调用 Webhook。
@ -1490,7 +1523,8 @@ The important elements to note are:
(推荐用于有副作用的 Webhook
<!--
Here is an example of a mutating webhook opting into being re-invoked if later admission plugins modify the object:
Here is an example of a mutating webhook opting into being re-invoked if later admission plugins
modify the object:
-->
这是一个修改性质的 Webhook 的示例,该 Webhook 在以后的准入插件修改对象时被重新调用:
@ -1510,7 +1544,7 @@ in an object could already exist in the user-provided object, but it is essentia
修改性质的 Webhook 必须具有[幂等](#idempotence)性,并且能够成功处理
已被接纳并可能被修改的对象的修改性质的 Webhook。
对于所有修改性质的准入 Webhook 都是如此,因为它们可以在对象中进行的
任何更改可能已经存在于用户提供的对象中,但是对于选择重新调用的 webhook
任何更改可能已经存在于用户提供的对象中,但是对于选择重新调用的 Webhook
来说是必不可少的。
<!--
@ -1527,10 +1561,10 @@ are handled. Allowed values are `Ignore` or `Fail`.
Here is a mutating webhook configured to reject an API request if errors are encountered calling the admission webhook:
-->
`failurePolicy` 定义了如何处理准入 webhook 中无法识别的错误和超时错误。允许的值为 `Ignore``Fail`
`failurePolicy` 定义了如何处理准入 Webhook 中无法识别的错误和超时错误。允许的值为 `Ignore``Fail`
* `Ignore` 表示调用 webhook 的错误将被忽略并且允许 API 请求继续。
* `Fail` 表示调用 webhook 的错误导致准入失败并且 API 请求被拒绝。
* `Ignore` 表示调用 Webhook 的错误将被忽略并且允许 API 请求继续。
* `Fail` 表示调用 Webhook 的错误导致准入失败并且 API 请求被拒绝。
这是一个修改性质的 webhook配置为在调用准入 Webhook 遇到错误时拒绝 API 请求:
@ -1542,8 +1576,8 @@ webhooks:
failurePolicy: Fail
```
<!--
The default `failurePolicy` for an admission webhooks is `Fail`.
<!--
The default `failurePolicy` for an admission webhooks is `Fail`.
-->
准入 Webhook 所用的默认 `failurePolicy``Fail`
@ -1560,14 +1594,13 @@ monitoring mechanisms help cluster admins to answer questions like:
2. What change did the mutating webhook applied to the object?
3. Which webhooks are frequently rejecting API requests? What's the reason for a
rejection?
3. Which webhooks are frequently rejecting API requests? What's the reason for a rejection?
-->
API 服务器提供了监视准入 Webhook 行为的方法。这些监视机制可帮助集群管理员回答以下问题:
1. 哪个修改性质的 webhook 改变了 API 请求中的对象?
1. 哪个修改性质的 Webhook 改变了 API 请求中的对象?
2. 修改性质的 Webhook 对对象做了哪些更改?
3. 哪些 webhook 经常拒绝 API 请求?是什么原因拒绝?
3. 哪些 Webhook 经常拒绝 API 请求?是什么原因拒绝?
<!--
### Mutating webhook auditing annotations
@ -1601,12 +1634,13 @@ The audit level of a event determines which annotations get recorded:
<!--
- At `Metadata` audit level or higher, an annotation with key
`mutation.webhook.admission.k8s.io/round_{round idx}_index_{order idx}` gets logged with JSON payload indicating
a webhook gets invoked for given request and whether it mutated the object or not.
- At `Metadata` audit level or higher, an annotation with key
`mutation.webhook.admission.k8s.io/round_{round idx}_index_{order idx}` gets logged with JSON
payload indicating a webhook gets invoked for given request and whether it mutated the object or not.
-->
- 在 `Metadata` 或更高审计级别上,将使用 JSON 负载记录带有键名
`mutation.webhook.admission.k8s.io/round_{round idx}_index_{order idx}` 的注解,
该注解表示针对给定请求调用了 Webhook以及该 Webhook 是否更改了对象。
`mutation.webhook.admission.k8s.io/round_{round idx}_index_{order idx}` 的注解,
该注解表示针对给定请求调用了 Webhook以及该 Webhook 是否更改了对象。
<!--
For example, the following annotation gets recorded for a webhook being reinvoked. The webhook is
@ -1741,7 +1775,7 @@ API 服务器从 `/metrics` 端点公开 Prometheus 指标,这些指标可用
Sometimes it's useful to know which admission webhooks are frequently rejecting API requests, and the
reason for a rejection.
In v1.16+, kube-apiserver exposes a Prometheus counter metric recording admission webhook rejections. The
The API server exposes a Prometheus counter metric recording admission webhook rejections. The
metrics are labelled to identify the causes of webhook rejection(s):
-->
有时,了解哪些准入 Webhook 经常拒绝 API 请求以及拒绝的原因是很有用的。
@ -1757,20 +1791,22 @@ metrics are labelled to identify the causes of webhook rejection(s):
- `type`: the admission webhook type, can be one of `admit` and `validating`.
- `error_type`: identifies if an error occurred during the webhook invocation
that caused the rejection. Its value can be one of:
- `calling_webhook_error`: unrecognized errors or timeout errors from the admission webhook happened and the
webhook's [Failure policy](#failure-policy) is set to `Fail`.
- `no_error`: no error occurred. The webhook rejected the request with `allowed: false` in the admission
response. The metrics label `rejection_code` records the `.status.code` set in the admission response.
- `apiserver_internal_error`: an API server internal error happened.
- `calling_webhook_error`: unrecognized errors or timeout errors from the admission webhook happened and the
webhook's [Failure policy](#failure-policy) is set to `Fail`.
- `no_error`: no error occurred. The webhook rejected the request with `allowed: false` in the admission
response. The metrics label `rejection_code` records the `.status.code` set in the admission response.
- `apiserver_internal_error`: an API server internal error happened.
- `rejection_code`: the HTTP status code set in the admission response when a
webhook rejected a request.
-->
- `name`:拒绝请求 Webhook 的名称。
- `operation`:请求的操作类型可以是 `CREATE`、`UPDATE`、`DELETE` 和 `CONNECT` 其中之一。
- `type`Admission webhook 类型,可以是 `admit``validating` 其中之一。
- `error_type`:标识在 webhook 调用期间是否发生了错误并且导致了拒绝。其值可以是以下之一:
- `type`Admission Webhook 类型,可以是 `admit``validating` 其中之一。
- `error_type`:标识在 Webhook 调用期间是否发生了错误并且导致了拒绝。其值可以是以下之一:
- `calling_webhook_error`:发生了来自准入 Webhook 的无法识别的错误或超时错误,
并且 webhook 的 [失败策略](#failure-policy) 设置为 `Fail`
并且 Webhook 的 [失败策略](#failure-policy) 设置为 `Fail`
- `no_error`未发生错误。Webhook 在准入响应中以 `allowed: false` 值拒绝了请求。
度量标签 `rejection_code` 记录了在准入响应中设置的 `.status.code`
- `apiserver_internal_error`apiserver 发生内部错误。
@ -1815,7 +1851,8 @@ the initial application.
2. For a `CREATE` pod request, if the field `.spec.containers[].resources.limits`
of a container is not set, set default resource limits.
3. For a `CREATE` pod request, inject a sidecar container with name `foo-sidecar` if no container with the name `foo-sidecar` already exists.
3. For a `CREATE` pod request, inject a sidecar container with name `foo-sidecar` if no container
with the name `foo-sidecar` already exists.
In the cases above, the webhook can be safely reinvoked, or admit an object that already has the fields set.
-->
@ -1891,16 +1928,18 @@ versions. See [Matching requests: matchPolicy](#matching-requests-matchpolicy) f
<!--
### Availability
It is recommended that admission Webhooks should evaluate as quickly as possible (typically in milliseconds), since they add to API request latency.
It is recommended that admission webhooks should evaluate as quickly as possible (typically in
milliseconds), since they add to API request latency.
It is encouraged to use a small timeout for webhooks. See [Timeouts](#timeouts) for more detail.
It is recommended that admission webhooks should leverage some format of load-balancing, to provide high availability and
performance benefits. If a webhook is running within the cluster, you can run multiple webhook backends behind a service
to leverage the load-balancing that service supports.
It is recommended that admission webhooks should leverage some format of load-balancing, to
provide high availability and performance benefits. If a webhook is running within the cluster,
you can run multiple webhook backends behind a service to leverage the load-balancing that service
supports.
-->
### 可用性 {#availability}
建议准入 webhook 尽快完成执行(时长通常是毫秒级),因为它们会增加 API 请求的延迟。
建议准入 Webhook 尽快完成执行(时长通常是毫秒级),因为它们会增加 API 请求的延迟。
建议对 Webhook 使用较小的超时值。有关更多详细信息,请参见[超时](#timeouts)。
建议 Admission Webhook 应该采用某种形式的负载均衡机制,以提供高可用性和高性能。
@ -1912,9 +1951,11 @@ to leverage the load-balancing that service supports.
Admission webhooks that need to guarantee they see the final state of the object in order to enforce policy
should use a validating admission webhook, since objects can be modified after being seen by mutating webhooks.
For example, a mutating admission webhook is configured to inject a sidecar container with name "foo-sidecar" on every
`CREATE` pod request. If the sidecar *must* be present, a validating admisson webhook should also be configured to intercept `CREATE` pod requests, and validate
that a container with name "foo-sidecar" with the expected configuration exists in the to-be-created object.
For example, a mutating admission webhook is configured to inject a sidecar container with name
"foo-sidecar" on every `CREATE` pod request. If the sidecar *must* be present, a validating
admisson webhook should also be configured to intercept `CREATE` pod requests, and validate that a
container with name "foo-sidecar" with the expected configuration exists in the to-be-created
object.
-->
### 确保看到对象的最终状态 {#guaranteeing-the-final-state-of-the-object-is-seen}
@ -1923,7 +1964,7 @@ that a container with name "foo-sidecar" with the expected configuration exists
则应该使用一个验证性质的 webhook
因为可以通过 mutating Webhook 看到对象后对其进行修改。
例如一个修改性质的准入Webhook 被配置为在每个 `CREATE` Pod 请求中
例如,一个修改性质的准入 Webhook 被配置为在每个 `CREATE` Pod 请求中
注入一个名称为 "foo-sidecar" 的 sidecar 容器。
如果*必须*存在边车容器,则还应配置一个验证性质的准入 Webhook 以拦截
@ -1942,7 +1983,8 @@ When a node that runs the webhook server pods
becomes unhealthy, the webhook deployment will try to reschedule the pods to another node. However the requests will
get rejected by the existing webhook server since the `"env"` label is unset, and the migration cannot happen.
It is recommended to exclude the namespace where your webhook is running with a [namespaceSelector](#matching-requests-namespaceselector).
It is recommended to exclude the namespace where your webhook is running with a
[namespaceSelector](#matching-requests-namespaceselector).
-->
### 避免自托管的 Webhooks 中出现死锁 {#avoiding-deadlocks-in-self-hosted-webhooks}
@ -1971,7 +2013,7 @@ set to `NoneOnDryRun`. See [Side effects](#side-effects) for more detail.
-->
### 副作用 {#side-effects}
建议准入 Webhook 应尽可能避免副作用,这意味着该准入 webhook 仅对发送给他们的
建议准入 Webhook 应尽可能避免副作用,这意味着该准入 Webhook 仅对发送给他们的
`AdmissionReview` 的内容起作用,并且不要进行额外更改。
如果 Webhook 没有任何副作用,则 `.webhooks[].sideEffects` 字段应设置为
`None`