跳到主要内容

了解准入 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-csrftrue 时,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,请同时更新规则与路径。