GKE共享VPC环境中Gateway API仅依赖Ingress可用问题排查
问题描述
我在版本为1.27.5-gke.200的GKE集群(使用共享VPC)中运行Web应用,需通过VPC网络和公司VPN访问。
原有正常运行的Ingress配置
最初采用内部应用负载均衡+Ingress控制器的配置,运行正常,配置如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: *****-ingress namespace: ****** annotations: kubernetes.io/ingress.class: "gce-internal" kubernetes.io/ingress.regional-static-ip-name: "rilb-vip-europe-west1-01" kubernetes.io/ingress.allow-http: "false" spec: tls: - hosts: - ****** secretName: s0015-prd-ssl-certificate rules: - host: "paketmap.s0015.prd.gcp.hc.de" http: paths: - pathType: Prefix path: / backend: service: name: ***-service port: number: 80 apiVersion: v1 kind: Service metadata: name: ****-service namespace: **** annotations: cloud.google.com/neg: '{"ingress": true}' spec: type: ClusterIP selector: app: **** ports: - name: http port: 80 protocol: TCP targetPort: 8080
Gateway API测试环境配置
因需要重定向、跨命名空间共享等特性,基于Gateway API搭建测试环境,配置如下:
- 创建带匹配标签的命名空间:
apiVersion: v1 kind: Namespace metadata: name: infra-ns labels: # Value of the matchLabel does not matter shared-gateway-access: "not-important"
- 部署测试服务与应用:
apiVersion: apps/v1 kind: Deployment metadata: name: site-v1 namespace: infra-ns spec: replicas: 1 selector: matchLabels: app: site version: v1 template: metadata: labels: app: site version: v1 spec: containers: - name: whereami image: gcr.io/google-samples/whereami:v1.1.3 ports: - containerPort: 8080 env: - name: METADATA value: "site-v1" --- apiVersion: v1 kind: Service metadata: name: site-v1 namespace: infra-ns annotations: cloud.google.com/neg: '{"ingress": true}' spec: selector: app: site version: v1 ports: - port: 80 targetPort: 8080
- Gateway API配置:
apiVersion: gateway.networking.k8s.io/v1beta1 kind: Gateway metadata: name: internal-http namespace: my-test spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Selector selector: matchLabels: shared-gateway-access: "not-important"
- HTTPRoute配置:
apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: site namespace: infra-ns spec: parentRefs: - kind: Gateway name: internal-http namespace: my-test rules: - backendRefs: - name: site-v1 port: 80
核心问题
该Gateway API仅在集群中存在任意Ingress(无论是否关联服务)时才能正常工作;若删除所有Ingress,会出现NEG不健康,访问测试应用时提示no healthy upstream。而在私有GKE环境中相同配置可正常运行,请问此关联关系的原因是什么?是否与Only-proxy-subnet仅绑定Ingress有关?
原因分析
1. Only-proxy-subnet的绑定逻辑差异
你的推测完全正确,仅代理子网(Only-proxy-subnet)在共享VPC与私有VPC环境下的绑定逻辑存在差异:
- 私有GKE集群中,Gateway API创建的内部负载均衡会自动完成仅代理子网的绑定;
- 但在共享VPC环境中,默认仅传统Ingress资源会触发仅代理子网的绑定流程,Gateway API的负载均衡资源在你使用的
1.27.5-gke.200版本中,尚未完善该场景下的自动绑定逻辑。当集群存在Ingress时,Ingress控制器完成的子网绑定会被Gateway API的负载均衡复用;删除所有Ingress后,子网绑定关系被清理,Gateway API的负载均衡失去合法网络通路,导致NEG健康检查失败。
2. 共享VPC的权限与资源限制
共享VPC环境中,GKE集群对子网的操作权限受宿主项目管控:
- 传统Ingress控制器在共享VPC场景下有预设的权限流程,可自动申请仅代理子网绑定;
- 而
gke-l7-rilb网关类的Gateway API实现,在该版本中未适配共享VPC的权限模型,无法独立完成仅代理子网的绑定操作,依赖已有Ingress触发的绑定状态维持网络连通性。
3. NEG健康检查的依赖条件
NEG的健康检查需要负载均衡通过仅代理子网访问集群节点:
- 仅代理子网未绑定时,Gateway API的负载均衡无法通过正确路径触达后端Pod,健康检查探针失效,NEG被标记为不健康;
- 存在Ingress时,已绑定的仅代理子网为Gateway API的负载均衡提供了合法网络路径,健康检查可正常执行。
解决方案
- 手动绑定仅代理子网
通过gcloud命令将仅代理子网关联到Gateway创建的内部负载均衡:
gcloud compute backend-services update [GATEWAY_BACKEND_SERVICE_NAME] \ --region [REGION] \ --enable-proxy-only-subnets \ --proxy-only-subnets [PROXY_SUBNET_NAME]
其中GATEWAY_BACKEND_SERVICE_NAME可通过查看Gateway资源的status字段获取。
升级GKE版本
Google在后续GKE版本(如1.28及以上)中修复了Gateway API在共享VPC下仅代理子网的自动绑定问题,升级集群可彻底解决该兼容性问题。保留占位Ingress(临时方案)
在集群中保留一个不关联任何有效服务的空Ingress,维持仅代理子网的绑定状态:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: placeholder-ingress annotations: kubernetes.io/ingress.class: "gce-internal" spec: rules: - http: paths: - path: /placeholder pathType: Prefix backend: service: name: non-existent-service port: number: 80
内容的提问来源于stack exchange,提问作者Asis
相关产品推荐
相关产品推荐

