Go服务在Kubernetes中起不来,八成是监听地址、端口或探针未对齐:代码必须监听0.0.0.0:PORT(不能用127.0.0.1),且containerPort、探针httpGet.port、Service的targetPort三者严格一致;必须配置readinessProbe和livenessProbe并暴露/healthz与/readyz路径;Dockerfile需禁用CGO并以非root用户运行。

Go服务在Kubernetes里起不来,八成是监听地址、端口或探针没对齐——不是代码写得不对,而是没按容器网络模型来适配。
Go代码必须监听 0.0.0.0:PORT,不能用 127.0.0.1 或 localhost
Kubernetes Pod 的网络命名空间是独立的,127.0.0.1 只指向容器自己,kube-proxy、Service、其他 Pod 都连不上。本地 go run 能通,不代表部署后能通。
- 错误写法:
http.ListenAndServe("127.0.0.1:8080", nil)→ 外部连接直接被拒绝 - 正确写法:
http.ListenAndServe(":8080", nil)(Go 默认绑定所有接口)或显式写"0.0.0.0:8080" - 更稳妥做法:从环境变量读端口,强制绑定
0.0.0.0:port := os.Getenv("PORT")<br>if port == "" { port = "8080" }<br>log.Fatal(http.ListenAndServe("0.0.0.0:"+port, nil))
containerPort、探针 port、Service targetPort 必须完全一致
这四个地方只要一个错位,就会出现 connection refused 或 CrashLoopBackOff,且 kubectl describe pod 里常只显示模糊事件,不报具体哪错了。
-
containerPort字段不是可选项,它是 Kubernetes 探针和服务发现的唯一依据 - 探针中的
httpGet.port必须等于containerPort,不能写成 Service 的port -
Service的targetPort必须等于containerPort;port是 Service 暴露的端口(如 80),和容器无关 - 常见翻车点:
containerPort: 8080,但代码监听:3000→ 探针失败,Pod 卡在Ready: 0/1
Deployment 必须配 readinessProbe 和 livenessProbe,且 handler 路径要真实存在
Kubernetes 不看进程是否 running,只认 HTTP 状态码。没探针,或路径返回 404、端口错、状态码不是 2xx/3xx,Pod 就永远无法 Ready 或反复重启。
立即学习“go语言免费学习笔记(深入)”;
- Go 代码至少提供两个 handler:
/healthz(基础存活)、/readyz(带依赖检查,比如 DB 连通性) -
livenessProbe.initialDelaySeconds建议 ≥30s:Go 启动慢(尤其带 DB 迁移或缓存预热) -
readinessProbe.initialDelaySeconds可设 5–10s,但别早于应用实际就绪时间 - 别用 TCP 探针代替 HTTP 探针:TCP 成功只说明端口开了,不代表业务 ready
Dockerfile 必须禁用 CGO,运行镜像推荐 scratch 或 distroless
CGO 开启时,默认链接 glibc,而 Alpine/musl 或 scratch 镜像没有它,运行时直接崩溃,日志只显示 no such file or directory。
- 构建阶段加
CGO_ENABLED=0:RUN CGO_ENABLED=0 go build -a -ldflags '-extldflags "-static"' -o main . - 运行阶段用
FROM scratch或FROM gcr.io/distroless/static-debian12,体积小、无 shell、无包管理器 - 必须
USER 65532:65532(非 root)运行,避免逃逸后提权 - 别漏
EXPOSE 8080:虽非强制,但能强化端口意识,防止 YAML 里写错
最易被忽略的是 label 一致性:Deployment 的 selector.matchLabels 和 Pod template 的 metadata.labels 必须逐字相同,空格、大小写、顺序都不容差错——Kubernetes API Server 会硬校验,错一点就 apply 失败,且字段 immutable,只能删掉重建。


















