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。
修复步骤
- 重新安装/升级两个Ingress控制器,使用正确的参数配置命名空间监听范围:
全局LoadBalancer类型控制器(nginx-global命名空间)执行:
第二层ClusterIP类型控制器(nginx-a命名空间)执行:helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx --namespace nginx-global \ --set controller.scope.enabled=true \ --set controller.watchNamespaceSelector[0]="namespace-type=nginx"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" - 替换两层Ingress配置,明确指定IngressClass,添加Host头透传注解:
第一层Ingress(nginx-a命名空间,负责全局流量转发到第二层控制器):
第二层Ingress(app-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: 80apiVersion: 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 - 验证配置生效:
- 分别查看两个控制器的日志,确认对应Ingress规则被加载、触发Nginx重载
- 集群内部直接curl第二层控制器的ClusterIP Service,携带
Host: test.example.com头,确认能正常返回echo1 - 访问
http://test.example.com验证整条流量链路
内容的提问来源于stack exchange,提问作者tobias
相关产品推荐
相关产品推荐

