Docker端口映射后外部无法访问的主因是应用监听127.0.0.1而非0.0.0.0;需检查容器内服务是否绑定0.0.0.0、宿主机IPv4转发是否启用、防火墙是否放行端口、Docker端口映射是否真实生效。

Go服务监听地址必须是:8080,不是127.0.0.1:8080
Kubernetes Pod 网络中,localhost 只指向容器自身,Service 和 kube-proxy 无法访问 127.0.0.1 绑定的端口。哪怕日志显示 “server started”,实际是“假活”,探针失败后进 CrashLoopBackOff。
- 正确写法:
http.ListenAndServe(":8080", nil)(空 host 表示绑定所有接口) - 更健壮做法:读取环境变量
PORT,拼成":" + os.Getenv("PORT") - 若用
net/http.Server,先调用net.Listen("tcp", addr)获取 listener,再传给.Serve(lis),避免探针在 bind 完成前就发起请求
Dockerfile 必须禁用 CGO 并用多阶段构建
默认开启 CGO 的 Go 二进制在 Alpine 或 scratch 镜像里会报 standard_init_linux.go:228: exec user process caused: no such file or directory —— 实际是找不到 glibc,但错误信息不提示具体缺失哪个库。
- 构建阶段加
CGO_ENABLED=0 GOOS=linux,确保生成静态链接二进制 - 推荐运行基础镜像:
FROM scratch或gcr.io/distroless/static-debian12,无 shell、体积小、攻击面低 - 别用
golang:alpine直接当运行镜像,它带编译器和包管理器,纯属冗余 - 加
-ldflags="-s -w -buildmode=pie"去除调试符号、减小体积、启用位置无关可执行文件
Deployment 的 selector.matchLabels 和 template.labels 必须逐字一致
这是 Kubernetes API Server 的硬校验,不是松散匹配。哪怕一个空格、大小写错位、键值顺序不同,都会报 field is immutable 或 invalid label selector,后续 kubectl apply 全部失败,只能删掉重建。
- 两个地方 label 必须完全相同,例如都写成
app: go-service - 不能一边是
app: go-service,另一边是app: GoService或APP: go-service -
replicas字段类型是*int32,YAML 里写replicas: 2是合法的 int 类型,Kubernetes 会自动转换
健康探针路径、端口、启动时序必须对齐
探针配置和实际服务暴露能力不一致,是 ReadinessProbe failed 或 LivenessProbe timeout 的主因。常见于 HTTP 路由未注册、中间件拦截、或监听尚未 ready 就开始探测。
立即学习“go语言免费学习笔记(深入)”;
-
containerPort必须和http.ListenAndServe绑定端口一致(如都用 8080) -
livenessProbe.httpGet.path和readinessProbe.httpGet.path对应的真实 handler 必须存在且返回 2xx -
initialDelaySeconds要足够长,确保服务完成初始化(比如 DB 连接池建立、gRPC server 启动完成)再开始探测 - 避免在 handler 里做耗时同步操作(如未加缓存的 config reload),否则探针超时直接 kill 容器
Pending 或反复重启,日志里还看不出明显异常。


















