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

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搭建测试环境,配置如下:

  1. 创建带匹配标签的命名空间:
apiVersion: v1
kind: Namespace
metadata:
  name: infra-ns
  labels:
    # Value of the matchLabel does not matter 
    shared-gateway-access: "not-important"
  1. 部署测试服务与应用:
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
  1. 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"
  1. 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的负载均衡提供了合法网络路径,健康检查可正常执行。

解决方案
  1. 手动绑定仅代理子网
    通过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字段获取。

  1. 升级GKE版本
    Google在后续GKE版本(如1.28及以上)中修复了Gateway API在共享VPC下仅代理子网的自动绑定问题,升级集群可彻底解决该兼容性问题。

  2. 保留占位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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:07:02