跳到主要内容

了解准入 Webhook

准入 Webhook 会在 Kubernetes 接受创建或更新请求前校验 Ingress Controller 资源,从而在配置错误造成运行时故障或服务中断之前将其发现。

独立的 APISIX 与 API7 Ingress Controller Chart 默认通过 webhook.enabled=true 启用 webhook。APISIX umbrella Chart 默认不启用;需设置 ingress-controller.webhook.enabled=true,设置教程已显式启用该值。

启用后,webhook 会校验:

  • Schema 校验:资源规格符合要求。
  • 配置安全性:立即发现不存在的 Secret 或 Service 等无效资源引用。
  • 冲突预防:在部署前识别重复或冲突配置。
  • TLS/SSL 验证:校验证书配置的正确性。

只有请求中存在潜在配置问题时,webhook 才会返回消息。

如果由 Argo CD 渲染 Controller Chart,请参阅使用 Argo CD 管理,了解当前 Webhook 证书限制和内容确定的配置方式。

本文介绍常见 webhook 消息,并帮助你理解如何解决这些问题。

SSL 证书冲突​

当看到证书冲突错误时,表示你正在同一个 GatewayProxy 范围内的多个资源中,为同一主机名使用不同 TLS 证书。准入 Webhook 会阻止这种情况,以避免路由歧义和安全问题。

SSL configuration conflicts detected:
- Host '<hostname>' is already configured with a different certificate in <resource-type>/<namespace>/<resource-name>

SSL 证书冲突通常发生在为同一主机名创建重复 TLS 资源时,或证书轮换操作失误导致创建了新的 TLS 资源而不是更新现有资源时。无论哪种情况,webhook 都会拒绝新资源来阻止冲突,并指出已有哪个资源正在为该主机名使用不同证书。

GatewayProxy 冲突​

创建或更新 GatewayProxy 资源时,准入 Webhook 会验证它是否与现有 GatewayProxy 资源冲突。这些错误会阻止资源创建,避免多个控制器干扰同一个控制面实例。

gateway proxy configuration conflict: GatewayProxy <namespace>/<new-gatewayproxy-name> and <namespace>/<existing-gatewayproxy-name> both target Service <namespace>/<service-name> port <port> while sharing <admin-key>

gateway proxy configuration conflict: GatewayProxy <namespace>/<new-gatewayproxy-name> and <namespace>/<existing-gatewayproxy-name> both target control plane endpoints [<endpoint-url>] while sharing <admin-key>

GatewayProxy 冲突通常发生在两个 GatewayProxy 资源使用相同 admin key(相同内联值或相同 Secret 引用)管理同一个控制面实例时。

如需解决冲突,请找出所有 GatewayProxy 资源,并确定应保留哪一个。如果确实需要多个 GatewayProxy 资源,请确保它们指向不同的控制面实例。

Service 引用缺失​

创建或更新将流量路由到后端服务的资源时,准入 Webhook 会验证被引用的 Kubernetes Service 是否存在。如果资源引用的 Service 不存在,你会看到类似如下警告:

Warning: Referenced Service '<namespace>/<service-name>' not found

与错误不同,警告会允许资源创建,但在后端 Service 存在之前,流量路由会失败。

Service 引用缺失通常由 Service 名称或命名空间拼写错误,或被引用 Service 尚未创建导致。如需解决该问题,请确认 Service 存在于正确命名空间,检查 Service 引用是否有拼写错误,并在应用依赖它的资源之前先创建该 Service。

Secret 引用缺失​

创建或更新引用 Kubernetes Secret 的资源时,准入 Webhook 会验证这些 Secret 是否存在,以及是否包含所需 key。Secret 可能用于 TLS 证书、认证凭证或插件配置。

如果资源引用的 Secret 不存在,你会看到类似如下警告:

Warning: Referenced Secret '<namespace>/<secret-name>' not found

如果资源引用的 Secret 不包含所需 key(例如 basic authentication 缺少 password key),你会看到类似如下警告:

Warning: Secret key '<key-name>' not found in Secret '<namespace>/<secret-name>'

与错误不同,警告会允许资源创建,但在被引用 Secret 正确配置前,受影响功能无法正常工作。

如需解决该问题,请确保在应用引用 Secret 的资源之前先创建所需 Secret,确认 Secret 包含所有必要 key,并再次检查 Secret 名称和命名空间。

跨命名空间 Consumer Secret​

Consumer 引用另一命名空间中的凭证 Secret 时,Secret 命名空间中必须有允许该引用的 ReferenceGrant,否则请求会被拒绝,错误中包含:

not permitted by any ReferenceGrant

响应不会泄露 Secret 是否存在。请先创建授权再应用 Consumer。参阅配置跨命名空间引用。

无效 CSRF 注解​

当 k8s.apisix.apache.org/enable-csrf 为 true 时,Ingress 还必须设置非空的 k8s.apisix.apache.org/csrf-key,否则 webhook 会拒绝创建与更新请求:

annotation "k8s.apisix.apache.org/enable-csrf" is enabled but "k8s.apisix.apache.org/csrf-key" is missing or empty

为 Ingress 注解添加强 key 后重新应用资源。参阅 CSRF 注解参考。

Gateway 引用缺失​

创建或更新引用 GatewayProxy 的 Gateway 或 IngressClass 时,准入 Webhook 会验证 GatewayProxy 是否存在。如果资源引用的 GatewayProxy 不存在,你会看到类似如下警告:

Warning: Referenced GatewayProxy '<namespace>/<gatewayproxy-name>' not found

与错误不同,警告会允许资源创建,但在被引用 GatewayProxy 正确配置之前,受影响功能无法正常工作。

如需解决该问题,请确保 GatewayProxy 存在于正确命名空间,并检查 GatewayProxy 引用是否存在拼写错误。

Webhook 连接​

Webhook Service 监听端口 443,并将请求转发到容器端口 9443。若有 NetworkPolicy 选择了 Controller Pod,它必须允许访问 Pod 的 TCP 9443,而不只是 Service 端口 443。

升级后校验 TCPRoute 或 UDPRoute 返回 404 时,请检查手工维护的 ValidatingWebhookConfiguration。当前 API 版本与路径如下:

资源rules[].apiVersionsclientConfig.service.path
TCPRoutev1/validate-gateway-networking-k8s-io-v1-tcproute
UDPRoutev1/validate-gateway-networking-k8s-io-v1-udproute

Chart 管理的 webhook 资源会随 Chart 更新;自定义资源需手工更新。可用以下命令检查 endpoint:

kubectl get validatingwebhookconfiguration \
-o jsonpath='{range .items[*].webhooks[*]}{.clientConfig.service.path}{"\t"}{range .rules[*].apiVersions[*]}{.}{" "}{end}{"\n"}{end}' \
| grep -E 'v1-(tcp|udp)route'

每个 TCPRoute 与 UDPRoute 行都应显示其 v1 webhook 路径和 v1 API 版本。若版本仍为 v1alpha2,请同时更新规则与路径。