K8s中Nginx Ingress Controller自定义端口配置问题咨询
问题背景
在K8s中部署多个PHP应用,其中一个自定义服务监听8800端口,原本通过Nginx将80端口的流量转发至该端口。已完成Deployment与Service的配置,但配置Ingress后出现502 Bad Gateway错误,流量无法到达服务。
原Nginx配置片段
location / { add_header Access-Control-Allow-Origin $http_origin always; add_header Access-Control-Allow-Credentials true always; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache off; proxy_pass http://localhost:8800; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Credentials; }
当前Ingress配置
--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-[service] annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1 spec: rules: - host: [my domain name] http: paths: - path: /api/ pathType: Prefix backend: service: name: [service] port: number: 8800 ingressClassName: nginx
更新后的Deployment与Service配置
--- apiVersion: apps/v1 kind: Deployment metadata: name: some-service spec: replicas: 1 ... spec: containers: - name: [some-name] image: [image] imagePullPolicy: Always env: ... ports: - containerPort: 8800 name: some-web-svc --- apiVersion: v1 kind: Service metadata: name: some-service spec: type: ClusterIP ports: - name: some-service-port protocol: TCP port: 8800 targetPort: some-web-svc # - name: tcp # port: 8800 # targetPort: 8800 selector: app: some-service
配置问题分析
你的Ingress配置存在几个关键问题,这是导致502错误的主要原因:
路径重写规则不匹配原Nginx逻辑
原Nginx是直接将根路径/的流量转发到后端,而当前Ingress配置了rewrite-target: /$1和path: /api/,这会把/api/xxx的请求重写成/xxx转发给后端。如果你的后端服务期望接收/api/开头的路径,或者原服务监听根路径但Ingress的路径匹配与转发逻辑不一致,会导致后端返回404,进而Ingress返回502。缺失原Nginx中的关键请求头与配置
原Nginx中配置的CORS头、代理请求头(X-Real-IP、X-Forwarded系列)、WebSocket支持(Upgrade/Connection头)、缓存禁用等,当前Ingress没有通过对应的annotations配置,可能导致后端服务无法正确处理请求,甚至连接失败。标签匹配性待确认
Service的selector为app: some-service,但你提供的Deployment配置中省略了Pod模板的标签部分,请确认spec.template.metadata.labels中是否包含app: some-service。如果标签不匹配,Service无法找到对应的Pod,必然会返回502。
修正后的Ingress配置
根据原Nginx逻辑,调整Ingress配置如下:
--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-some-service annotations: # 移除不必要的路径重写(如果后端期望接收/api/路径,请调整path和rewrite规则) # nginx.ingress.kubernetes.io/rewrite-target: /$1 # 配置CORS支持 nginx.ingress.kubernetes.io/enable-cors: "true" nginx.ingress.kubernetes.io/cors-allow-origin: "$http_origin" nginx.ingress.kubernetes.io/cors-allow-credentials: "true" # 配置代理请求头 nginx.ingress.kubernetes.io/proxy-set-header: "X-Real-IP $remote_addr" nginx.ingress.kubernetes.io/proxy-set-header: "X-Forwarded-For $proxy_add_x_forwarded_for" nginx.ingress.kubernetes.io/proxy-set-header: "X-Forwarded-Proto $scheme" # 禁用代理缓存 nginx.ingress.kubernetes.io/proxy-cache: "off" # 配置HTTP/1.1与WebSocket支持 nginx.ingress.kubernetes.io/proxy-http-version: "1.1" nginx.ingress.kubernetes.io/configuration-snippet: | proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Credentials; spec: rules: - host: your-domain.com http: paths: - path: / pathType: Prefix backend: service: name: some-service port: number: 8800 ingressClassName: nginx
额外检查步骤
验证Service与Pod的标签匹配
确保Deployment的Pod模板包含正确的标签:spec: template: metadata: labels: app: some-service测试集群内服务连通性
在集群内任意Pod执行命令,测试Service是否能正常访问后端:curl http://some-service:8800如果返回正常响应,说明Service与Pod的连通性没问题;如果超时或报错,排查Pod是否正常运行、端口是否监听。
查看Ingress控制器日志
检查Ingress控制器的日志,获取具体错误信息:kubectl logs -n ingress-nginx <ingress-controller-pod-name>日志中会显示连接后端失败的具体原因,比如连接超时、拒绝连接等。
内容的提问来源于stack exchange,提问作者prosto.vint

