diff --git a/content/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers.md b/content/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers.md index 5340fd3027..7c257e8286 100644 --- a/content/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers.md +++ b/content/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers.md @@ -16,7 +16,7 @@ In addition to [compiled-in admission plugins](/docs/reference/access-authn-auth admission plugins can be developed as extensions and run as webhooks configured at runtime. This page describes how to build, configure, use, and monitor admission webhooks. --> -除了[内置的 admission 插件](/zh/docs/reference/access-authn-authz/admission-controllers/), +除了[内置的 admission 插件](/zh-cn/docs/reference/access-authn-authz/admission-controllers/), 准入插件可以作为扩展独立开发,并以运行时所配置的 Webhook 的形式运行。 此页面描述了如何构建、配置、使用和监视准入 Webhook。 @@ -36,8 +36,8 @@ Mutating admission Webhooks are invoked first, and can modify objects sent to th --> 准入 Webhook 是一种用于接收准入请求并对其进行处理的 HTTP 回调机制。 可以定义两种类型的准入 webhook,即 -[验证性质的准入 Webhook](/zh/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook) 和 -[修改性质的准入 Webhook](/zh/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)。 +[验证性质的准入 Webhook](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook) 和 +[修改性质的准入 Webhook](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)。 修改性质的准入 Webhook 会先被调用。它们可以更改发送到 API 服务器的对象以执行自定义的设置默认值操作。 @@ -57,11 +57,9 @@ should use a validating admission webhook, since objects can be modified after b 则应使用验证性质的准入 Webhook,因为对象被修改性质 Webhook 看到之后仍然可能被修改。 {{< /note >}} - ### 先决条件 {#prerequisites} -* 确保 Kubernetes 集群版本至少为 v1.16(以便使用 `admissionregistration.k8s.io/v1` API) 或者 v1.9 (以便使用 `admissionregistration.k8s.io/v1beta1` API)。 - * 确保启用 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 控制器。 - [这里](/zh/docs/reference/access-authn-authz/admission-controllers/#is-there-a-recommended-set-of-admission-controllers-to-use) + [这里](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#is-there-a-recommended-set-of-admission-controllers-to-use) 是一组推荐的 admission 控制器,通常可以启用。 -* 确保启用了 `admissionregistration.k8s.io/v1beta1` API。 +* 确保启用了 `admissionregistration.k8s.io/v1` API。 请参阅 Kubernetes e2e 测试中的 [admission webhook 服务器](https://github.com/kubernetes/kubernetes/blob/release-1.21/test/images/agnhost/webhook/main.go) -的实现。webhook 处理由 apiserver 发送的 `AdmissionReview` 请求,并且将其决定 +的实现。webhook 处理由 API 服务器发送的 `AdmissionReview` 请求,并且将其决定 作为 `AdmissionReview` 对象以相同版本发送回去。 示例准入 Webhook 服务器置 `ClientAuth` 字段为 [空](https://github.com/kubernetes/kubernetes/blob/v1.22.0/test/images/agnhost/webhook/config.go#L38-L39), @@ -163,7 +155,7 @@ your webhook configurations accordingly. 你也可以在集群外部署 webhook。这样做需要相应地更新你的 webhook 配置。 ### 即时配置准入 Webhook @@ -184,8 +176,6 @@ See the [webhook configuration](#webhook-configuration) section for details abou --> 以下是一个 `ValidatingWebhookConfiguration` 示例,mutating webhook 配置与此类似。有关每个配置字段的详细信息,请参阅 [webhook 配置](#webhook-configuration) 部分。 -{{< tabs name="ValidatingWebhookConfiguration_example_1" >}} -{{% tab name="admissionregistration.k8s.io/v1" %}} ```yaml apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration @@ -203,43 +193,26 @@ webhooks: service: namespace: "example-namespace" name: "example-service" - caBundle: "Ci0tLS0tQk......tLS0K" - admissionReviewVersions: ["v1", "v1beta1"] + caBundle: + admissionReviewVersions: ["v1"] sideEffects: None timeoutSeconds: 5 ``` -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# 1.16 中被淘汰,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -metadata: - name: "pod-policy.example.com" -webhooks: -- name: "pod-policy.example.com" - rules: - - apiGroups: [""] - apiVersions: ["v1"] - operations: ["CREATE"] - resources: ["pods"] - scope: "Namespaced" - clientConfig: - service: - namespace: "example-namespace" - name: "example-service" - caBundle: "Ci0tLS0tQk......tLS0K" - admissionReviewVersions: ["v1beta1"] - timeoutSeconds: 5 -``` -{{% /tab %}} -{{< /tabs >}} +{{< note >}} + +你必须在以上示例中将 `` 替换为一个有效的 VA 证书包, +这是一个用 PEM 编码的 CA 证书包,用于校验 Webhook 的服务器证书。 +{{< /note >}} - -scope 字段指定是仅集群范围的资源(Cluster)还是名字空间范围的资源资源(Namespaced)将与此规则匹配。`*` 表示没有范围限制。 +scope 字段指定是仅集群范围的资源(Cluster)还是名字空间范围的资源资源(Namespaced)将与此规则匹配。 +`*` 表示没有范围限制。 {{< note >}} -对于使用 `admissionregistration.k8s.io/v1` 创建的 webhook 而言,其 webhook 调用的默认超时是 10 秒; -对于使用 `admissionregistration.k8s.io/v1beta1` 创建的 webhook 而言,其默认超时是 30 秒。 -从 kubernetes 1.14 开始,可以设置超时。建议对 webhooks 设置较短的超时时间。 +Webhook 调用的默认超时是 10 秒,你可以设置 `timeout` 并建议对 webhook 设置较短的超时时间。 如果 webhook 调用超时,则根据 webhook 的失败策略处理请求。 {{< /note >}} -当 apiserver 收到与 `rules` 相匹配的请求时,apiserver 按照 `clientConfig` 中指定的方式向 webhook 发送一个 `admissionReview` 请求。 +当一个 API 服务器收到与 `rules` 相匹配的请求时, +该 API 服务器将按照 `clientConfig` 中指定的方式向 webhook 发送一个 `admissionReview` 请求。 -创建 webhook 配置后,系统将花费几秒钟使新配置生效。 +创建 Webhook 配置后,系统将花费几秒钟使新配置生效。 -### 对 apiservers 进行身份认证 {#authenticate-apiservers} +### 对 API 服务器进行身份认证 {#authenticate-apiservers} -如果你的 webhook 需要身份验证,则可以将 apiserver 配置为使用基本身份验证、持有者令牌或证书来向 webhook 提供身份证明。完成此配置需要三个步骤。 +如果你的 Webhook 需要身份验证,则可以将 API 服务器配置为使用基本身份验证、持有者令牌或证书来向 +Webhook 提供身份证明。完成此配置需要三个步骤。 -* 启动 apiserver 时,通过 `--admission-control-config-file` 参数指定准入控制配置文件的位置。 +* 启动 API 服务器时,通过 `--admission-control-config-file` 参数指定准入控制配置文件的位置。 * 在准入控制配置文件中,指定 MutatingAdmissionWebhook 控制器和 ValidatingAdmissionWebhook 控制器应该读取凭据的位置。 凭证存储在 kubeConfig 文件中(是​​的,与 kubectl 使用的模式相同),因此字段名称为 `kubeConfigFile`。 以下是一个准入控制配置文件示例: - - - {{< tabs name="admissionconfiguration_example1" >}} {{% tab name="apiserver.config.k8s.io/v1" %}} ```yaml @@ -329,6 +294,7 @@ plugins: ``` {{% /tab %}} {{% tab name="apiserver.k8s.io/v1alpha1" %}} + ```yaml # 1.17 中被淘汰,推荐使用 apiserver.config.k8s.io/v1 apiVersion: apiserver.k8s.io/v1alpha1 @@ -347,6 +313,7 @@ plugins: kind: WebhookAdmission kubeConfigFile: "" ``` + {{% /tab %}} {{< /tabs >}} @@ -409,9 +376,9 @@ See the [webhook configuration](#webhook-configuration) section for details abou token: "" ``` -当然,你需要设置 webhook 服务器来处理这些身份验证。 +当然,你需要设置 Webhook 服务器来处理这些身份验证请求。 -创建 `admissionregistration.k8s.io/v1` webhook 配置时,`admissionReviewVersions` 是必填字段。 -Webhook 必须支持至少一个当前和以前的 apiserver 都可以解析的 `AdmissionReview` 版本。 -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被淘汰,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - admissionReviewVersions: ["v1beta1"] - ... -``` - - -如果未指定 `admissionReviewVersions`,则创建 `admissionregistration.k8s.io/v1beta1` Webhook 配置时的默认值为 `v1beta1`。 -{{% /tab %}} -{{< /tabs >}} +创建 webhook 配置时,`admissionReviewVersions` 是必填字段。 +Webhook 必须支持至少一个当前和以前的 API 服务器都可以解析的 `AdmissionReview` 版本。 @@ -647,7 +545,7 @@ Example of a minimal response from a webhook to allow a request: --> `response` 至少必须包含以下字段: -* `uid`,从发送到 webhook 的 `request.uid` 中复制而来 +* `uid`,从发送到 Webhook 的 `request.uid` 中复制而来 * `allowed`,设置为 `true` 或 `false` Webhook 允许请求的最简单响应示例: -{{< tabs name="AdmissionReview_response_allow" >}} -{{% tab name="admission.k8s.io/v1" %}} ```json { "apiVersion": "admission.k8s.io/v1", @@ -667,28 +563,12 @@ Webhook 允许请求的最简单响应示例: } } ``` -{{% /tab %}} -{{% tab name="admission.k8s.io/v1beta1" %}} -```json -{ - "apiVersion": "admission.k8s.io/v1beta1", - "kind": "AdmissionReview", - "response": { - "uid": "", - "allowed": true - } -} -``` -{{% /tab %}} -{{< /tabs >}} Webhook 禁止请求的最简单响应示例: -{{< tabs name="AdmissionReview_response_forbid_minimal" >}} -{{% tab name="admission.k8s.io/v1" %}} ```json { "apiVersion": "admission.k8s.io/v1", @@ -699,24 +579,11 @@ Webhook 禁止请求的最简单响应示例: } } ``` -{{% /tab %}} -{{% tab name="admission.k8s.io/v1beta1" %}} -```json -{ - "apiVersion": "admission.k8s.io/v1beta1", - "kind": "AdmissionReview", - "response": { - "uid": "", - "allowed": false - } -} -``` -{{% /tab %}} -{{< /tabs >}} + 当拒绝请求时,Webhook 可以使用 `status` 字段自定义 http 响应码和返回给用户的消息。 @@ -724,8 +591,6 @@ Example of a response to forbid a request, customizing the HTTP status code and [API 文档](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#status-v1-meta)。 禁止请求的响应示例,它定制了向用户显示的 HTTP 状态码和消息: -{{< tabs name="AdmissionReview_response_forbid_details" >}} -{{% tab name="admission.k8s.io/v1" %}} ```json { "apiVersion": "admission.k8s.io/v1", @@ -740,30 +605,12 @@ Example of a response to forbid a request, customizing the HTTP status code and } } ``` -{{% /tab %}} -{{% tab name="admission.k8s.io/v1beta1" %}} -```json -{ - "apiVersion": "admission.k8s.io/v1beta1", - "kind": "AdmissionReview", - "response": { - "uid": "", - "allowed": false, - "status": { - "code": 403, - "message": "You cannot do this because it is Tuesday and your name starts with A" - } - } -} -``` -{{% /tab %}} -{{< /tabs >}} 当允许请求时,mutating准入 Webhook 也可以选择修改传入的对象。 @@ -786,9 +633,8 @@ Base64-encoded, this would be `W3sib3AiOiAiYWRkIiwgInBhdGgiOiAiL3NwZWMvcmVwbGljY -因此,添加该标签的 webhook 响应为: -{{< tabs name="AdmissionReview_response_modify" >}} -{{% tab name="admission.k8s.io/v1" %}} +因此,添加该标签的 Webhook 响应为: + ```json { "apiVersion": "admission.k8s.io/v1", @@ -801,22 +647,50 @@ So a webhook response to add that label would be: } } ``` -{{% /tab %}} -{{% tab name="admission.k8s.io/v1beta1" %}} + + +准入 Webhook 可以选择性地返回在 HTTP `Warning` 头中返回给请求客户端的警告消息,警告代码为 299。 +警告可以与允许或拒绝的准入响应一起发送。 + + +如果你正在实现返回一条警告的 webhook,则: + +* 不要在消息中包括 "Warning:" 前缀 +* 使用警告消息描述该客户端进行 API 请求时会遇到或应意识到的问题 +* 如果可能,将警告限制为 120 个字符 + +{{< caution >}} + +超过 256 个字符的单条警告消息在返回给客户之前可能会被 API 服务器截断。 +如果超过 4096 个字符的警告消息(来自所有来源),则额外的警告消息会被忽略。 +{{< /caution >}} + ```json { - "apiVersion": "admission.k8s.io/v1beta1", + "apiVersion": "admission.k8s.io/v1", "kind": "AdmissionReview", "response": { "uid": "", "allowed": true, - "patchType": "JSONPatch", - "patch": "W3sib3AiOiAiYWRkIiwgInBhdGgiOiAiL3NwZWMvcmVwbGljYXMiLCAidmFsdWUiOiAzfV0=" + "warnings": [ + "duplicate envvar entries specified with name MY_ENV", + "memory request less than 4MB specified for container mycontainer, which will not start successfully" + ] } } ``` -{{% /tab %}} -{{< /tabs >}} + @@ -824,22 +698,23 @@ So a webhook response to add that label would be: -要注册准入 Webhook,请创建 `MutatingWebhookConfiguration` 或 -`ValidatingWebhookConfiguration` API 对象。 +要注册准入 Webhook,请创建 `MutatingWebhookConfiguration` 或 `ValidatingWebhookConfiguration` API 对象。 +`MutatingWebhookConfiguration` 或`ValidatingWebhookConfiguration` 对象的名称必须是有效的 +[DNS 子域名](/zh-cn/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)。 每种配置可以包含一个或多个 Webhook。如果在单个配置中指定了多个 -Webhook,则应为每个 webhook 赋予一个唯一的名称。 -这在 `admissionregistration.k8s.io/v1` 中是必需的,但是在使用 -`admissionregistration.k8s.io/v1beta1` 时强烈建议使用, -以使生成的审核日志和指标更易于与活动配置相匹配。 +Webhook,则应为每个 Webhook 赋予一个唯一的名称。 +这是必需的,以使生成的审计日志和指标更易于与激活的配置相匹配。 每个 Webhook 定义以下内容。 @@ -864,7 +739,7 @@ Each rule specifies one or more operations, apiGroups, apiVersions, and resource * `"*/*"` 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. Supported in v1.14+. Default is `"*"`, matching pre-1.14 behavior. +* `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. @@ -879,28 +754,27 @@ Each rule specifies one or more operations, apiGroups, apiVersions, and resource * `"pods/*"` 匹配 pod 的所有子资源。 * `"*/status"` 匹配所有 status 子资源。 * `scope` 指定要匹配的范围。有效值为 `"Cluster"`、`"Namespaced"` 和 `"*"`。 - 子资源匹配其父资源的范围。在 Kubernetes v1.14+ 版本中才被支持。 - 默认值为 `"*"`,对应 1.14 版本之前的行为。 + 子资源匹配其父资源的范围。默认值为 `"*"`。 * `"Cluster"` 表示只有集群作用域的资源才能匹配此规则(API 对象 Namespace 是集群作用域的)。 * `"Namespaced"` 意味着仅具有名字空间的资源才符合此规则。 - * `"*"` 表示没有范围限制。 + * `"*"` 表示没有作用域限制。 -如果传入请求与任何 Webhook 规则的指定操作、组、版本、资源和范围匹配,则该请求将发送到 Webhook。 +如果传入请求与任何 Webhook `rules` 的指定 `operations`、`groups`、`versions`、 +`resources` 和 `scope` 匹配,则该请求将发送到 Webhook。 以下是可用于指定应拦截哪些资源的规则的其他示例。 匹配针对 `apps/v1` 和 `apps/v1beta1` 组中 `deployments` 和 `replicasets` 资源的 `CREATE` 或 `UPDATE` 请求: -{{< tabs name="ValidatingWebhookConfiguration_rules_1" >}} -{{% tab name="admissionregistration.k8s.io/v1" %}} ```yaml apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration @@ -915,130 +789,64 @@ webhooks: scope: "Namespaced" ... ``` -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - rules: - - operations: ["CREATE", "UPDATE"] - apiGroups: ["apps"] - apiVersions: ["v1", "v1beta1"] - resources: ["deployments", "replicasets"] - scope: "Namespaced" - ... -``` -{{% /tab %}} -{{< /tabs >}} 匹配所有 API 组和版本中的所有资源(但不包括子资源)的创建请求: -{{< tabs name="ValidatingWebhookConfiguration_rules_2" >}} -{{% tab name="admissionregistration.k8s.io/v1" %}} ```yaml apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration -... webhooks: -- name: my-webhook.example.com - rules: - - operations: ["CREATE"] - apiGroups: ["*"] - apiVersions: ["*"] - resources: ["*"] - scope: "*" - ... + - name: my-webhook.example.com + rules: + - operations: ["CREATE"] + apiGroups: ["*"] + apiVersions: ["*"] + resources: ["*"] + scope: "*" ``` -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - rules: - - operations: ["CREATE"] - apiGroups: ["*"] - apiVersions: ["*"] - resources: ["*"] - scope: "*" - ... -``` -{{% /tab %}} -{{< /tabs >}} 匹配所有 API 组和版本中所有 `status` 子资源的更新请求: -{{< tabs name="ValidatingWebhookConfiguration_rules_2" >}} -{{% tab name="admissionregistration.k8s.io/v1" %}} ```yaml apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration -... webhooks: -- name: my-webhook.example.com - rules: - - operations: ["UPDATE"] - apiGroups: ["*"] - apiVersions: ["*"] - resources: ["*/status"] - scope: "*" - ... + - name: my-webhook.example.com + rules: + - operations: ["UPDATE"] + apiGroups: ["*"] + apiVersions: ["*"] + resources: ["*/status"] + scope: "*" ``` -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - rules: - - operations: ["UPDATE"] - apiGroups: ["*"] - apiVersions: ["*"] - resources: ["*/status"] - scope: "*" - ... -``` -{{% /tab %}} -{{< /tabs >}} -### 匹配请求:objectSelector{#matching-requests-objectselector} +### 匹配请求:objectSelector {#matching-requests-objectselector} -在版本 v1.15+ 中, 通过指定 `objectSelector`,Webhook 能够根据 -可能发送的对象的标签来限制哪些请求被拦截。 +通过指定 `objectSelector`,Webhook 能够根据可能发送的对象的标签来限制哪些请求被拦截。 如果指定,则将对 `objectSelector` 和可能发送到 Webhook 的 object 和 oldObject 进行评估。如果两个对象之一与选择器匹配,则认为该请求已匹配。 -空对象(对于创建操作而言为 oldObject,对于删除操作而言为 newObject), +空对象(对于创建操作而言为 `oldObject`,对于删除操作而言为 `newObject`), 或不能带标签的对象(例如 `DeploymentRollback` 或 `PodProxyOptions` 对象) 被认为不匹配。 @@ -1054,12 +862,9 @@ This example shows a mutating webhook that would match a `CREATE` of any resourc 这个例子展示了一个 mutating webhook,它将匹配带有标签 `foo:bar` 的任何资源的 `CREATE` 的操作: -{{< tabs name="objectSelector_example" >}} -{{% tab name="admissionregistration.k8s.io/v1" %}} ```yaml apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration -... webhooks: - name: my-webhook.example.com objectSelector: @@ -1071,34 +876,13 @@ webhooks: apiVersions: ["*"] resources: ["*"] scope: "*" - ... ``` -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: MutatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - objectSelector: - matchLabels: - foo: bar - rules: - - operations: ["CREATE"] - apiGroups: ["*"] - apiVersions: ["*"] - resources: ["*"] - scope: "*" - ... -``` -{{% /tab %}} -{{< /tabs >}} + -有关标签选择器的更多示例,请参见[标签](/zh/docs/concepts/overview/working-with-objects/labels)。 +有关标签选择器的更多示例,请参见[标签](/zh-cn/docs/concepts/overview/working-with-objects/labels)。 -通过指定 `namespaceSelector`,Webhook 可以根据具有名字空间的资源所处的 -名字空间的标签来选择拦截哪些资源的操作。 +通过指定 `namespaceSelector`, +Webhook 可以根据具有名字空间的资源所处的名字空间的标签来选择拦截哪些资源的操作。 有关标签选择器的更多示例,请参见 -[标签](/zh/docs/concepts/overview/working-with-objects/labels)。 +[标签](/zh-cn/docs/concepts/overview/working-with-objects/labels)。 API 服务器可以通过多个 API 组或版本来提供对象。 -例如,Kubernetes API 服务器允许通过 `extensions/v1beta1`、`apps/v1beta1`、 -`apps/v1beta2` 和 `apps/v1` API 创建和修改 `Deployment` 对象。 例如,如果一个 webhook 仅为某些 API 组/版本指定了规则(例如 -`apiGroups:["apps"], apiVersions:["v1","v1beta1"]`),而修改资源的请求 -是通过另一个 API 组/版本(例如 `extensions/v1beta1`)发出的, -该请求将不会被发送到 Webhook。 +`apiGroups:["apps"], apiVersions:["v1","v1beta1"]`),而修改资源的请求是通过另一个 +API 组/版本(例如 `extensions/v1beta1`)发出的,该请求将不会被发送到 Webhook。 -在 v1.15+ 中,`matchPolicy` 允许 webhook 定义如何使用其 `rules` 匹配传入的请求。 +`matchPolicy` 允许 webhook 定义如何使用其 `rules` 匹配传入的请求。 允许的值为 `Exact` 或 `Equivalent`。 当 API 服务器停止提供某资源时,该资源不再被视为等同于该资源的其他仍在提供服务的版本。 -例如,`extensions/v1beta1` 中的 Deployment 已被废弃,计划在 v1.16 中默认停止使用。 -在这种情况下,带有 `apiGroups:["extensions"], apiVersions:["v1beta1"], resources: ["deployments"]` -规则的 Webhook 将不再拦截通过 `apps/v1` API 来创建 Deployment 的请求。 -["deployments"] 规则将不再拦截通过 `apps/v1` API 创建的部署。 +例如,`extensions/v1beta1` 中的 Deployment 已被废弃,计划在 v1.16 中移除。 + +移除后,带有 `apiGroups:["extensions"], apiVersions:["v1beta1"], resources: ["deployments"]` +规则的 Webhook 将不再拦截通过 `apps/v1` API 来创建的 Deployment。 +因此,Webhook 应该优先注册稳定版本的资源。 -使用 `admissionregistration.k8s.io/v1` 创建的 admission webhhok 默认为 `Equivalent`。 - -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - matchPolicy: Equivalent - rules: - - operations: ["CREATE","UPDATE","DELETE"] - apiGroups: ["apps"] - apiVersions: ["v1"] - resources: ["deployments"] - scope: "Namespaced" - ... -``` - - -使用 `admissionregistration.k8s.io/v1beta1` 创建的准入 Webhook 默认为 `Exact`。 -{{% /tab %}} -{{< /tabs >}} +准入 Webhook 所用的 `matchPolicy` 默认为 `Equivalent`。 `host` 不应引用集群中运行的服务;通过指定 `service` 字段来使用服务引用。 -主机可以通过某些 apiserver 中的外部 DNS 进行解析。 +主机可以通过某些 API 服务器中的外部 DNS 进行解析。 (例如,`kube-apiserver` 无法解析集群内 DNS,因为这将违反分层规则)。`host` 也可以是 IP 地址。 +你必须在以上示例中将 `` 替换为一个有效的 VA 证书包, +这是一个用 PEM 编码的 CA 证书包,用于校验 Webhook 的服务器证书。 +{{< /note >}} @@ -1554,65 +1217,30 @@ or the dry-run request will not be sent to the webhook and the API request will Webhook 使用 webhook 配置中的 `sideEffects` 字段显示它们是否有副作用: -* `Unknown`:有关调用 Webhook 的副作用的信息是不可知的。 -如果带有 `dryRun:true` 的请求将触发对该 Webhook 的调用,则该请求将失败,并且不会调用该 Webhook。 + * `None`:调用 webhook 没有副作用。 -* `Some`:调用 webhook 可能会有副作用。 - 如果请求具有 `dry-run` 属性将触发对此 Webhook 的调用, - 则该请求将会失败,并且不会调用该 Webhook。 * `NoneOnDryRun`:调用 webhook 可能会有副作用,但是如果将带有 `dryRun: true` 属性的请求发送到 webhook,则 webhook 将抑制副作用(该 webhook 可识别 `dryRun`)。 - -允许值: -* 在 `admissionregistration.k8s.io/v1beta1` 中,`sideEffects` 可以设置为 - `Unknown`、`None`、`Some` 或者 `NoneOnDryRun`,并且默认值为 `Unknown`。 -* 在 `admissionregistration.k8s.io/v1` 中, `sideEffects` 必须设置为 - `None` 或者 `NoneOnDryRun`。 - 这是一个 validating webhook 的示例,表明它对 `dryRun: true` 请求没有副作用: -{{< tabs name="ValidatingWebhookConfiguration_sideEffects" >}} -{{% tab name="admissionregistration.k8s.io/v1" %}} ```yaml apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration -... webhooks: -- name: my-webhook.example.com - sideEffects: NoneOnDryRun - ... + - name: my-webhook.example.com + sideEffects: NoneOnDryRun ``` -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - sideEffects: NoneOnDryRun - ... -``` -{{% /tab %}} -{{< /tabs >}} -使用 `admissionregistration.k8s.io/v1` 创建的准入 Webhook 默认超时为 10 秒。 -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - timeoutSeconds: 2 - ... -``` - - -使用 `admissionregistration.k8s.io/v1beta1` 创建的准入 Webhook 默认超时为 30 秒。 -{{% /tab %}} -{{< /tabs >}} +准入 Webhook 所用的超时时间默认为 10 秒。 -在 v1.15+ 中,允许修改性质的准入插件感应到其他插件所做的更改, +要允许修改性质的准入插件感应到其他插件所做的更改, 如果修改性质的 Webhook 修改了一个对象,则会重新运行内置的修改性质的准入插件, 并且修改性质的 Webhook 可以指定 `reinvocationPolicy` 来控制是否也重新调用它们。 @@ -1740,31 +1345,13 @@ Here is an example of a mutating webhook opting into being re-invoked if later a --> 这是一个修改性质的 Webhook 的示例,该 Webhook 在以后的准入插件修改对象时被重新调用: -{{< tabs name="MutatingWebhookConfiguration_reinvocationPolicy" >}} -{{% tab name="admissionregistration.k8s.io/v1" %}} ```yaml apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration -... webhooks: - name: my-webhook.example.com reinvocationPolicy: IfNeeded - ... ``` -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: MutatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - reinvocationPolicy: IfNeeded - ... -``` -{{% /tab %}} -{{< /tabs >}} -使用 `admissionregistration.k8s.io/v1` 创建的准入 Webhook 将 -`failurePolicy` 默认设置为 `Fail`。 - -{{% /tab %}} -{{% tab name="admissionregistration.k8s.io/v1beta1" %}} -```yaml -# v1.16 中被废弃,推荐使用 admissionregistration.k8s.io/v1 -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: MutatingWebhookConfiguration -... -webhooks: -- name: my-webhook.example.com - failurePolicy: Fail - ... -``` - -使用 `admissionregistration.k8s.io/v1beta1` 创建的准入 Webhook 将 -`failurePolicy` 默认设置为 `Ignore`。 -{{% /tab %}} -{{< /tabs >}} +准入 Webhook 所用的默认 `failurePolicy` 是 `Fail`。 -API 服务器提供了监视准入 Webhook 行为的方法。这些监视机制可帮助集群管理员 -回答以下问题: +API 服务器提供了监视准入 Webhook 行为的方法。这些监视机制可帮助集群管理员回答以下问题: 1. 哪个修改性质的 webhook 改变了 API 请求中的对象? 2. 修改性质的 Webhook 对对象做了哪些更改? @@ -1868,19 +1429,19 @@ API 服务器提供了监视准入 Webhook 行为的方法。这些监视机制 Sometimes it's useful to know which mutating webhook mutated the object in a API request, and what change did the webhook apply. --> -有时,了解 API 请求中的哪个修改性质的 Webhook 使对象改变以及该 -Webhook 应用了哪些更改很有用。 +有时,了解 API 请求中的哪个修改性质的 Webhook 使对象改变以及该 Webhook 应用了哪些更改很有用。 -在 v1.16+ 中,kube-apiserver 针对每个修改性质的 Webhook 调用执行[审计](/zh/docs/tasks/debug/debug-cluster/audit/)操作。 +Kubernetes API 服务器针对每个修改性质的 Webhook 调用执行[审计](/zh-cn/docs/tasks/debug/debug-cluster/audit/)操作。 每个调用都会生成一个审计注解,记述请求对象是否发生改变, -可选地还可以根据 webhook 的准入响应生成一个注解,记述所应用的修补。 +可选地还可以根据 Webhook 的准入响应生成一个注解,记述所应用的修补。 针对给定请求的给定执行阶段,注解被添加到审计事件中, 然后根据特定策略进行预处理并写入后端。 @@ -1891,122 +1452,124 @@ The audit level of a event determines which annotations get recorded: -在 `Metadata` 或更高审计级别上,将使用 JSON 负载记录带有键名 +- 在 `Metadata` 或更高审计级别上,将使用 JSON 负载记录带有键名 `mutation.webhook.admission.k8s.io/round_{round idx}_index_{order idx}` 的注解, 该注解表示针对给定请求调用了 Webhook,以及该 Webhook 是否更改了对象。 - -例如,对于正在被重新调用的某 Webhook,所记录的注解如下。 -Webhook 在 mutating Webhook 链中排在第三个位置,并且在调用期间未改变请求对象。 + + 例如,对于正在被重新调用的某 Webhook,所记录的注解如下。 + Webhook 在 mutating Webhook 链中排在第三个位置,并且在调用期间未改变请求对象。 -```yaml -# 审计事件相关记录 -{ - "kind": "Event", - "apiVersion": "audit.k8s.io/v1", - "annotations": { - "mutation.webhook.admission.k8s.io/round_1_index_2": "{\"configuration\":\"my-mutating-webhook-configuration.example.com\",\"webhook\":\"my-webhook.example.com\",\"mutated\": false}" - # 其他注解 - ... - } - # 其他字段 - ... -} -``` + ```yaml + # 审计事件相关记录 + { + "kind": "Event", + "apiVersion": "audit.k8s.io/v1", + "annotations": { + "mutation.webhook.admission.k8s.io/round_1_index_2": "{\"configuration\":\"my-mutating-webhook-configuration.example.com\",\"webhook\":\"my-webhook.example.com\",\"mutated\": false}" + # 其他注解 + ... + } + # 其他字段 + ... + } + ``` -```yaml -# 反序列化的注解值 -{ - "configuration": "my-mutating-webhook-configuration.example.com", - "webhook": "my-webhook.example.com", - "mutated": false -} -``` + ```yaml + # 反序列化的注解值 + { + "configuration": "my-mutating-webhook-configuration.example.com", + "webhook": "my-webhook.example.com", + "mutated": false + } + ``` - -对于在第一轮中调用的 Webhook,所记录的注解如下。 -Webhook 在 mutating Webhook 链中排在第一位,并在调用期间改变了请求对象。 + + 对于在第一轮中调用的 Webhook,所记录的注解如下。 + Webhook 在 mutating Webhook 链中排在第一位,并在调用期间改变了请求对象。 -```yaml -# 审计事件相关记录 -{ - "kind": "Event", - "apiVersion": "audit.k8s.io/v1", - "annotations": { - "mutation.webhook.admission.k8s.io/round_0_index_0": "{\"configuration\":\"my-mutating-webhook-configuration.example.com\",\"webhook\":\"my-webhook-always-mutate.example.com\",\"mutated\": true}" - # 其他注解 - ... - } - # 其他字段 - ... -} -``` + ```yaml + # 审计事件相关记录 + { + "kind": "Event", + "apiVersion": "audit.k8s.io/v1", + "annotations": { + "mutation.webhook.admission.k8s.io/round_0_index_0": "{\"configuration\":\"my-mutating-webhook-configuration.example.com\",\"webhook\":\"my-webhook-always-mutate.example.com\",\"mutated\": true}" + # 其他注解 + ... + } + # 其他字段 + ... + } + ``` -```yaml -# 反序列化的注解值 -{ - "configuration": "my-mutating-webhook-configuration.example.com", - "webhook": "my-webhook-always-mutate.example.com", - "mutated": true -} -``` + ```yaml + # 反序列化的注解值 + { + "configuration": "my-mutating-webhook-configuration.example.com", + "webhook": "my-webhook-always-mutate.example.com", + "mutated": true + } + ``` -在 `Request` 或更高审计级别上,将使用 JSON 负载记录带有键名为 -`patch.webhook.admission.k8s.io/round_{round idx}_index_{order idx}` 的注解, -该注解表明针对给定请求调用了 Webhook 以及应用于请求对象之上的修改。 +- 在 `Request` 或更高审计级别上,将使用 JSON 负载记录带有键名为 + `patch.webhook.admission.k8s.io/round_{round idx}_index_{order idx}` 的注解, + 该注解表明针对给定请求调用了 Webhook 以及应用于请求对象之上的修改。 - -例如,以下是针对正在被重新调用的某 Webhook 所记录的注解。 -Webhook 在修改性质的 Webhook 链中排在第四,并在其响应中包含一个 JSON 补丁, -该补丁已被应用于请求对象。 + + 例如,以下是针对正在被重新调用的某 Webhook 所记录的注解。 + Webhook 在修改性质的 Webhook 链中排在第四,并在其响应中包含一个 JSON 补丁, + 该补丁已被应用于请求对象。 -```yaml -# 审计事件相关记录 -{ - "kind": "Event", - "apiVersion": "audit.k8s.io/v1", - "annotations": { - "patch.webhook.admission.k8s.io/round_1_index_3": "{\"configuration\":\"my-other-mutating-webhook-configuration.example.com\",\"webhook\":\"my-webhook-always-mutate.example.com\",\"patch\":[{\"op\":\"add\",\"path\":\"/data/mutation-stage\",\"value\":\"yes\"}],\"patchType\":\"JSONPatch\"}" - # 其他注解 - ... - } - # 其他字段 - ... -} -``` + ```yaml + # 审计事件相关记录 + { + "kind": "Event", + "apiVersion": "audit.k8s.io/v1", + "annotations": { + "patch.webhook.admission.k8s.io/round_1_index_3": "{\"configuration\":\"my-other-mutating-webhook-configuration.example.com\",\"webhook\":\"my-webhook-always-mutate.example.com\",\"patch\":[{\"op\":\"add\",\"path\":\"/data/mutation-stage\",\"value\":\"yes\"}],\"patchType\":\"JSONPatch\"}" + # 其他注解 + ... + } + # 其他字段 + ... + } + ``` -```yaml -# 反序列化的注解值 -{ - "configuration": "my-other-mutating-webhook-configuration.example.com", - "webhook": "my-webhook-always-mutate.example.com", - "patchType": "JSONPatch", - "patch": [ - { - "op": "add", - "path": "/data/mutation-stage", - "value": "yes" - } - ] -} -``` + ```yaml + # 反序列化的注解值 + { + "configuration": "my-other-mutating-webhook-configuration.example.com", + "webhook": "my-webhook-always-mutate.example.com", + "patchType": "JSONPatch", + "patch": [ + { + "op": "add", + "path": "/data/mutation-stage", + "value": "yes" + } + ] + } + ``` -Kube-apiserver 从 `/metrics` 端点公开 Prometheus 指标,这些指标可用于监控和诊断 -apiserver 状态。以下指标记录了与准入 Webhook 相关的状态。 +API 服务器从 `/metrics` 端点公开 Prometheus 指标,这些指标可用于监控和诊断 API 服务器状态。 +以下指标记录了与准入 Webhook 相关的状态。 `kube-system` 名字空间包含由 Kubernetes 系统创建的对象, 例如用于控制平面组件的服务账号,诸如 `kube-dns` 之类的 Pod 等。 -意外更改或拒绝 `kube-system` 名字空间中的请求可能会导致控制平面组件 -停止运行或者导致未知行为发生。 +意外更改或拒绝 `kube-system` +名字空间中的请求可能会导致控制平面组件停止运行或者导致未知行为发生。 如果你的准入 Webhook 不想修改 Kubernetes 控制平面的行为,请使用 -[`namespaceSelector`](#matching-requests-namespaceselector) 避免 -拦截 `kube-system` 名字空间。 +[`namespaceSelector`](#matching-requests-namespaceselector) +避免拦截 `kube-system` 名字空间。