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

Kubernetes串联使用Nginx Ingress暴露服务返回404问题排查

问题根因

你的配置有3个核心错误,直接导致404问题:

  • 参数用错,命名空间筛选规则完全不生效:你在Helm安装时用的controller.scope.namespaceSelector参数,只有在controller.scope.enabled=true开启访问范围限制时才会生效,作用是限制Ingress可引用的后端Service所属命名空间,根本不是用来控制控制器监听哪些命名空间下Ingress资源的参数。真正用来按命名空间标签筛选监听Ingress的参数是controller.watchNamespaceSelector,且该参数是数组格式,直接传逗号分隔字符串会被解析错误。
    这个错误本身不会直接触发404(默认配置下两个控制器会监听全集群对应Class的Ingress),但会让你原本设计的命名空间隔离逻辑完全失效。
  • Ingress未指定新版ingressClassName,规则未被控制器加载:你两个Ingress都只用了旧版kubernetes.io/ingress.class注解,在v1.0+版本的ingress-nginx中,默认优先识别spec.ingressClassName字段,若安装时未显式开启controller.watchIngressWithoutClass=true,控制器会直接忽略仅配置旧版注解的Ingress,根本不会生成对应的转发规则,所有请求匹配不到规则就会返回默认404页面。
  • 级联转发未显式配置Host头传递:两层Ingress转发时,部分版本的ingress-nginx不会自动将原始Host头透传给第二层Nginx实例,导致第二层控制器收到请求时找不到匹配test.example.com的规则,返回404。
修复步骤
  1. 重新安装/升级两个Ingress控制器,使用正确的参数配置命名空间监听范围:
    全局LoadBalancer类型控制器(nginx-global命名空间)执行:
    helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx --namespace nginx-global \
      --set controller.scope.enabled=true \
      --set controller.watchNamespaceSelector[0]="namespace-type=nginx"
    
    第二层ClusterIP类型控制器(nginx-a命名空间)执行:
    helm upgrade --install ingress-nginx-a ingress-nginx/ingress-nginx --namespace nginx-a \
      --set controller.scope.enabled=true \
      --set controller.watchNamespaceSelector[0]="namespace-type=apps" \
      --set controller.watchNamespaceSelector[1]="project=a" \
      --set controller.service.type="ClusterIP" \
      --set controller.ingressClassResource.name="nginx-a"
    
  2. 替换两层Ingress配置,明确指定IngressClass,添加Host头透传注解:
    第一层Ingress(nginx-a命名空间,负责全局流量转发到第二层控制器):
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx2-ingress
      namespace: nginx-a
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        nginx.ingress.kubernetes.io/upstream-vhost: "$host"
    spec:
      ingressClassName: nginx
      rules:
      - host: "*.example.com"
        http:
            paths:
            - pathType: Prefix
              path: "/"
              backend:
                service:
                  name: ingress-nginx-a-controller
                  port:
                    number: 80
    
    第二层Ingress(app-a命名空间,负责转发到业务服务):
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: echo-ingress
      namespace: app-a
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
    spec:
      ingressClassName: nginx-a
      rules:
      - host: "test.example.com"
        http:
            paths:
            - pathType: Prefix
              path: "/"
              backend:
                service:
                  name: echo1
                  port:
                    number: 80
    
  3. 验证配置生效:
    • 分别查看两个控制器的日志,确认对应Ingress规则被加载、触发Nginx重载
    • 集群内部直接curl第二层控制器的ClusterIP Service,携带Host: test.example.com头,确认能正常返回echo1
    • 访问http://test.example.com验证整条流量链路

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:01:03