Go服务监听端口必须与Service的targetPort严格一致,否则导致404或连接拒绝;健康检查路径需返回2xx且与Ingress Controller默认探测路径(如/healthz)匹配;Ingress pathType和rewrite-target影响Go服务接收到的URL路径,路由注册须基于重写后路径。

Go服务必须监听的端口要和Service的targetPort严格一致
很多404或连接拒绝问题,根源不在Ingress YAML,而在Go进程监听端口和Kubernetes Service配置不匹配。比如你在代码里写http.ListenAndServe(":8080", handler),那Service的targetPort就必须是8080(数字)或"8080"(字符串),不能写成80或"http"——后者只在Service里定义了named port时才有效,且Pod container ports也得显式声明name: http。
常见错误:用ListenAndServeTLS但没在Service里暴露443端口,或Ingress没配TLS section,导致HTTP流量被转发到HTTPS监听端口,直接EOF。
- Go服务启动前加日志:
log.Printf("serving on :%s", os.Getenv("PORT")),然后在Deployment里通过env: [{name: PORT, value: "8080"}]统一控制 - Service的
port(集群内访问端口)可以是任意值,但targetPort必须和Go实际监听端口一致 - 若用非标准端口(如9000),Ingress Controller默认可能不代理该端口,需确认Controller配置支持(ingress-nginx默认只处理80/443)
健康检查路径必须返回2xx,且路径要和Ingress Controller默认探测路径对齐
Ingress Controller(如ingress-nginx)会主动向Pod发起健康检查,默认路径是/healthz或/,HTTP方法为GET。如果Go服务没实现这个Endpoint,或者返回503/404,Controller会把Pod从上游摘除,导致流量完全打不进。
不要依赖Kubernetes livenessProbe来“代替”Ingress健康检查——二者触发时机、目标地址、失败阈值完全不同。Ingress Controller的探测走的是Service ClusterIP + targetPort,不是Pod IP。
- 最简实现:
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }) - 若Service配置了
path: /api且用了rewrite-target,健康检查仍走根路径,不受Ingress path影响 - 某些Controller(如Traefik)可通过annotation指定探测路径,但ingress-nginx不支持,只能改Go服务逻辑
Ingress的host和path匹配逻辑直接影响Go路由注册方式
Ingress本身不改写请求路径,但ingress-nginx等Controller会根据pathType和rewrite-target注解重写。Go服务看到的r.URL.Path已经是重写后的结果,不是原始URL。
例如Ingress配置path: /backend/ + nginx.ingress.kubernetes.io/rewrite-target: /,客户端访问https://myapp.com/backend/users,Go收到的r.URL.Path是/users,不是/backend/users。
- Go的mux注册必须基于重写后路径:
r.PathPrefix("/users").Handler(...),而不是/backend/users - 想保留原始路径做业务判断?用
nginx.ingress.kubernetes.io/configuration-snippet注入头:add_header X-Original-Path $request_uri always;,Go里读r.Header.Get("X-Original-Path") -
pathType: Exact要求Ingress path和请求路径完全一致(含尾部斜杠),Prefix则按前缀匹配,别混用
调试时绕过DNS和证书验证的实操技巧
curl报connection refused或SSL certificate problem,大概率不是Go或Ingress YAML写错,而是网络层没通。
先跳过host校验和TLS验证,直连Ingress Controller的NodePort或LoadBalancer IP:
- 查Controller Service IP:
kubectl get svc -n ingress-nginx ingress-nginx-controller,取EXTERNAL-IP或NODE-PORT(如31405) - 本地测试:
curl -v http://NODE_IP:31405/healthz -H "Host: myapp.example.com",成功说明Ingress规则生效,失败再查Service或Pod - 证书问题临时绕过:
curl -k https://myapp.example.com/api --resolve "myapp.example.com:443:NODE_IP" - 别在/etc/hosts硬编码——Ingress Controller Pod未必运行在你编辑hosts的那台机器上
真正容易被忽略的是Ingress Controller自身的就绪状态:kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=ingress-nginx -n ingress-nginx没通过,所有Ingress都无效。


















