You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GKE集群中GCE健康检查与Ingress Nginx Controller部署异常求助

解决GKE上Deployment部署ingress-nginx的健康检查失败问题

这个问题在GKE环境里用Deployment模式部署ingress-nginx控制器时非常典型,根源在于GCE负载均衡默认会对集群所有节点的NodePort执行健康检查,但你的Deployment只在部分节点上运行Pod,没有Pod的节点没有进程监听那个NodePort,自然会返回503,导致LB把这些节点标记为不健康。

下面是几个不用改成DaemonSet就能解决的方案,按推荐度排序:

方案一:用BackendConfig自定义健康检查(推荐,保留源IP)

GKE提供了BackendConfig资源,可以直接配置GCE LB的健康检查规则,让它跳过节点的NodePort,直接通过Service转发到ingress-nginx Pod的健康端点。

步骤:

  1. 创建BackendConfig资源,指定健康检查的目标端口和路径(ingress-nginx默认健康端口是8080,路径/healthz):
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: ingress-nginx-healthcheck
spec:
  healthCheck:
    checkIntervalSec: 5
    port: 8080
    type: HTTP
    requestPath: /healthz

执行kubectl apply -f <filename>.yaml创建这个资源。

  1. 修改ingress-nginx的Service,添加annotation关联刚才的BackendConfig:
    找到你的ingress-nginx控制器的Service(通常叫ingress-nginx-controller),编辑它的配置:
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  annotations:
    # 关联BackendConfig,"default"表示对所有端口生效
    cloud.google.com/backend-config: '{"default": "ingress-nginx-healthcheck"}'
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: http
      nodePort: 32203 # 你的NodePort
    - name: https
      port: 443
      targetPort: https
  selector:
    # 对应你的ingress-nginx Pod的标签
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller

执行kubectl apply -f <service-file>.yaml更新服务。

原理:

配置后,GCE LB的健康检查请求会先打到Service的ClusterIP,再由kube-proxy转发到任意一个运行中的ingress-nginx Pod,不管当前节点有没有Pod,都会返回200,健康检查自然就正常了。而且这个方案不会影响源IP的保留(如果你的Service之前设置了externalTrafficPolicy: Local)。

方案二:修改Service的externalTrafficPolicy为Cluster

如果不需要保留客户端源IP,这个方案更简单:

步骤:

编辑ingress-nginx的Service,把externalTrafficPolicy改成Cluster:

spec:
  externalTrafficPolicy: Cluster
  # 其他配置保持不变

执行kubectl apply -f <service-file>.yaml更新。

原理:

默认如果是Local模式,kube-proxy只会把节点NodePort的流量转发到本地节点的Pod,健康检查请求到无Pod的节点时就会失败。改成Cluster模式后,kube-proxy会把所有节点的NodePort流量转发到集群中任意一个运行的Pod,所以即使节点上没有Pod,访问localhost:32203/healthz也会被转发到有Pod的节点,返回200,健康检查就通过了。

缺点:

这个模式会丢失客户端的真实源IP,因为流量经过kube-proxy转发后,源IP会变成节点的IP,而不是客户端的IP。如果你的业务需要获取客户端真实IP,不建议用这个方案。

方案三:节点亲和性+PodDisruptionBudget(不推荐)

这个方案本质是让Deployment的Pod尽量分布到更多节点,但和DaemonSet的思路类似,只是可以控制副本数,比如你有3个节点就部署3个副本,让每个节点都有一个Pod。但这违背了你“避免资源浪费”的初衷,所以只作为补充选项,不推荐使用。


内容的提问来源于stack exchange,提问作者Diego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:37:49