Go应用上Kubernetes关键在镜像构建、探针设计、服务注册三步:CGO_ENABLED=1避免DNS解析失败;liveness/readiness路径须与代码路由严格匹配;etcd服务注册必须用Lease机制并显式续约与释放。

Go 应用上 Kubernetes 不是“配好环境跑起来”就完事,关键在镜像构建、探针设计、服务注册这三步踩不踩坑。错一个,滚动更新卡住、健康检查反复失败、服务发现连不上——都是线上高频故障。
Go 多阶段 Dockerfile 里 CGO_ENABLED=0 导致 DNS 解析失败
很多教程直接写 CGO_ENABLED=0 图省事,结果上线后服务连不上 etcd 或 Prometheus:Go 的纯静态解析器不读 /etc/resolv.conf 的 search 域,etcd.default.svc.cluster.local 这类内部域名直接解析失败。
- 保留
CGO_ENABLED=1,用golang:1.21-alpine构建(Alpine 自带 musl libc) - 运行镜像仍用
alpine:latest,但需加RUN apk add --no-cache ca-certificates - 若坚持静态链接,必须手动拼全 FQDN,比如把
etcd改成etcd.default.svc.cluster.local:2379
Deployment 中 livenessProbe 和 readinessProbe 路径不匹配 handler
goctl 自动生成的 YAML 默认用 /healthz,但你代码里没注册这个路由,probe 就永远 404,Pod 会被反复 kill-restart。
- 检查
main.go是否调用了http.HandleFunc("/healthz", healthHandler) - 若用 go-zero 框架,确认
etc/user-api.yaml中HealthCheckPath配置和 probe 路径一致 -
initialDelaySeconds别设太小:Go HTTP server 启动后还要加载配置、连 DB,5 秒不够,建议livenessProbe设 30s,readinessProbe设 10s
etcd 服务注册漏掉 Lease,导致“假健康”节点残留
进程崩溃后,etcd 里还挂着 /services/order-svc/10.244.1.5:8080 这种 key,客户端持续发请求到已死 IP,错误率飙升。
- 注册时必须显式申请 Lease:
client.Grant(ctx, 15)(TTL 15 秒较稳妥) - Put key 时绑定 Lease ID:
client.Put(ctx, key, val, clientv3.WithLease(leaseID)) - 进程退出前调用
client.Revoke(ctx, leaseID),别只靠租约自动过期 - 监听服务变更时,用
client.Get(ctx, "/services/", clientv3.WithPrefix()),避免漏事件
最易被忽略的是:Kubernetes 的 readinessProbe 成功只代表端口通,不代表 DB 连上了、配置加载完了、etcd 注册完成了——这些必须在 handler 里做真实检查,不能只返回 200。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











