Go应用在Kubernetes中启动失败主因是端口未对齐或镜像未瘦身;代码须监听0.0.0.0:PORT而非localhost,containerPort、targetPort、探针端口及代码端口必须字面一致,并用多阶段构建精简镜像。

Go应用在Kubernetes里起不来,八成是端口没对齐或镜像没瘦身——这两点踩中任意一个,CrashLoopBackOff 和 connection refused 就会准时报到。
Go代码监听地址必须是 0.0.0.0:PORT,不能用 localhost 或 127.0.0.1
Kubernetes Pod 是独立网络命名空间,127.0.0.1 只通本容器内部,kubelet 探针、Service 流量、其他 Pod 都连不上。常见错误写法:http.ListenAndServe(":8080", nil),它等价于 127.0.0.1:8080。
- 正确做法:显式绑定
0.0.0.0:8080,例如http.ListenAndServe("0.0.0.0:8080", nil) - 更健壮的做法:从环境变量读端口,并强制前缀
0.0.0.0:,避免硬编码 - 别依赖 Dockerfile 的
EXPOSE—— 它不生效,纯文档用途;真正起作用的是代码监听地址 +containerPort
containerPort 不是可选项,是探针和服务发现的元数据依据
Deployment 中的 containerPort 字段虽不强制校验,但缺失或错位会导致:livenessProbe 连接被拒、Service 的 targetPort 找不到目标、某些 CNI 插件直接丢包。
- 它必须和 Go 代码中
ListenAndServe的端口完全一致(包括字符串形式) - 如果代码用
os.Getenv("PORT"),YAML 里也要同步设环境变量,且containerPort值保持为该端口数字 - 别混淆
Service.port(集群内访问端口)和targetPort(转发到 Pod 的端口)——后者必须等于containerPort
用多阶段构建压镜像体积,别直接 FROM golang 跑生产环境
直接用 golang:alpine 镜像跑 Go 二进制,会把编译器、go toolchain、/usr/src 全带上,镜像动辄 300MB+,启动慢、攻击面大、拉取耗时。
立即学习“go语言免费学习笔记(深入)”;
- 构建阶段用
golang:1.21编译,运行阶段切到alpine:latest或scratch - 编译时加
-ldflags="-s -w"去符号表和调试信息,二进制可小 30%~50% - 加
CGO_ENABLED=0 GOOS=linux确保静态链接,避免 Alpine 上缺 libc 报错
探针路径和信号处理不配好,滚动更新就容易丢请求
没定义 readinessProbe,新 Pod 启动瞬间就被 Service 加入 endpoints,流量打进来时服务可能还没 ready;没处理 SIGTERM,Pod 被删时连接被粗暴断开。
-
readinessProbe.httpGet.path必须返回 200,且逻辑要真检查依赖(比如 DB 连通性),不能只 return 200 - 用
http.Server.Shutdown()替代直接退出,给正在处理的请求留出完成时间 -
livenessProbe别和 readiness 共用一个 endpoint —— 存活探针应只检查进程是否卡死,不查下游依赖
最常被忽略的是四端口一致性:代码监听地址里的端口、containerPort、探针 port、Service.targetPort —— 少一个对齐,整个链路就断在中间。不是“差不多就行”,是必须字面一致。


















