GCP GKE Ingress访问/sso-dev/报404 路径服务规则不存在
问题背景
需要通过配置了/sso-dev/路径规则的Ingress访问Kubernetes集群内部署的后端服务,目前服务已完成容器化,Deployment、Service、Ingress资源均已创建。
- 直接通过Service自身的负载均衡IP访问后端服务,功能正常
- 通过Ingress提供的负载均衡IP访问
/sso-dev/路径时,返回错误:response 404 (backend NotFound), service rules for the path non-existent
目标为定位问题,实现Ingress路径正常转发到后端服务,相关配置如下。
现有资源配置
Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: ingress.kubernetes.io/backends: '{"k8s-be-30969--6d0e236a1c7d6409":"HEALTHY","k8s1-6d0e236a-default-sso-dev-service-80-849fdb46":"HEALTHY"}' ingress.kubernetes.io/forwarding-rule: k8s2-fr-uwdva40x-default-my-ingress-h98d0sfl ingress.kubernetes.io/target-proxy: k8s2-tp-uwdva40x-default-my-ingress-h98d0sfl ingress.kubernetes.io/url-map: k8s2-um-uwdva40x-default-my-ingress-h98d0sfl kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"nginx.ingress.kubernetes.io/backend-protocol":"HTTP","nginx.ingress.kubernetes.io/rewrite-target":"/"},"name":"my-ingress","namespace":"default"},"spec":{"rules":[{"http":{"paths":[{"backend":{"service":{"name":"sso-dev-service","port":{"number":80}}},"path":"/sso-dev/*","pathType":"ImplementationSpecific"}]}}]}} nginx.ingress.kubernetes.io/backend-protocol: HTTP nginx.ingress.kubernetes.io/rewrite-target: / creationTimestamp: "2022-06-22T12:30:49Z" finalizers: - networking.gke.io/ingress-finalizer-V2 generation: 1 name: my-ingress namespace: default resourceVersion: "13073497" uid: 253e067f-0711-4d24-a706-497692dae4d9 spec: rules: - http: paths: - backend: service: name: sso-dev-service port: number: 80 path: /sso-dev/* pathType: ImplementationSpecific status: loadBalancer: ingress: - ip: 34.111.49.35
Deployment配置
apiVersion: apps/v1 kind: Deployment metadata: labels: app: sso-dev name: sso-dev namespace: default spec: replicas: 3 selector: matchLabels: app: sso-dev template: metadata: labels: app: sso-dev spec: containers: - image: us-east4-docker.pkg.dev/centegycloud-351515/sso/cent@sha256:64b50553219db358945bf3cd6eb865dd47d0d45664464a9c334602c438bbaed9 imagePullPolicy: IfNotPresent name: cent-sha256-1 resources: {} dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 status: availableReplicas: 3 readyReplicas: 3 replicas: 3 updatedReplicas: 3
Service配置
apiVersion: v1 kind: Service metadata: annotations: cloud.google.com/neg: '{"ingress":true}' cloud.google.com/neg-status: '{"network_endpoint_groups":{"80":"k8s1-6d0e236a-default-sso-dev-service-80-849fdb46"},"zones":["us-central1-c"]}' labels: app: sso-dev name: sso-dev-service namespace: default spec: clusterIP: 10.32.6.103 ports: - nodePort: 30584 port: 80 protocol: TCP targetPort: 8080 selector: app: sso-dev sessionAffinity: None type: LoadBalancer status: loadBalancer: ingress: - ip: 104.197.93.226
负载均衡配置参考

问题根因
- Ingress控制器与注解不匹配:从Ingress的finalizer
networking.gke.io/ingress-finalizer-V2、自动注入的ingress.kubernetes.io/*系列GCP专属注解可以判断,当前使用的是GKE原生GCE Ingress控制器,不是Nginx Ingress控制器。配置中添加的nginx.ingress.kubernetes.io/rewrite-target、nginx.ingress.kubernetes.io/backend-protocol是Nginx Ingress专属注解,对GCE Ingress完全无效,路径重写逻辑根本没有执行。
访问http://<ingress-ip>/sso-dev/xxx时,GCE负载均衡会把完整路径/sso-dev/xxx直接透传给后端服务,而后端服务本身没有配置/sso-dev上下文根,仅根路径/可正常访问,因此返回404。 - 路径规则与控制器能力不匹配:GCE原生Ingress默认不支持路径前缀剥离/重写能力,即使路径匹配成功,也会把原始路径转发给后端,和预期的“访问/sso-dev/实际转发到后端/路径”的逻辑不符。
修复方案
二选一即可,根据实际需求选择:
方案1:保留GCE原生Ingress,调整后端应用配置
GCE Ingress没有原生路径重写能力,直接调整后端应用适配路径规则:
- 修改后端服务启动配置,将服务的上下文根(Context Path)设置为
/sso-dev,让应用可以直接处理带/sso-dev前缀的请求,不需要负载均衡做路径改写。 - 删除Ingress中所有
nginx.ingress.kubernetes.io开头的无效注解,保留原有路径规则即可。 - 等待1-3分钟让GCP负载均衡规则同步完成,再测试访问。
方案2:切换到Nginx Ingress,保留后端应用现有配置
如果不想修改后端应用配置,使用Nginx Ingress实现路径重写:
- 确认集群中已正确部署Nginx Ingress控制器,且有可用的负载均衡入口。
- 修改Ingress配置,指定使用Nginx Ingress控制器,修正重写规则和路径匹配逻辑:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress namespace: default annotations: # 指定Ingress控制器为Nginx kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/backend-protocol: HTTP # 配置重写规则,剥离/sso-dev前缀 nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - http: paths: - backend: service: name: sso-dev-service port: number: 80 # 正则匹配/sso-dev开头的路径,捕获前缀后的路径内容 path: /sso-dev(/|$)(.*) pathType: ImplementationSpecific - 应用配置后等待Nginx Ingress同步规则(通常10-30秒),通过Nginx Ingress对应的负载均衡IP访问即可。此时访问
/sso-dev/xxx会被重写为/xxx转发给后端服务,匹配后端根路径的访问规则。
额外验证点
- Service端口映射正常:Service配置80端口映射到容器8080端口,之前通过Service LB访问正常,说明端口映射、后端服务本身无问题。
- 健康检查配置:当前Ingress注解显示后端状态为HEALTHY,说明GCE健康检查配置正常,不需要额外调整。如果后续修改后端路径,需要通过
cloud.google.com/healthcheck-path注解指定正确的健康检查路径,避免后端实例被判定为不健康。
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

