最小可用 deployment.yaml 必须包含 image、ports、livenessProbe 和 readinessProbe,且 containerPort 与 Go 程序 ListenAndServe 端口一致,probe 的 path(如 /health)需在代码中真实实现并确保注册早于服务启动。

怎么生成最小可用的 deployment.yaml
Go 项目本身不参与 Kubernetes YAML 编写,但你需要围绕它的运行时特征来写——比如镜像名、端口、健康检查路径。最简 deployment 必须包含 image、ports、livenessProbe(至少 HTTP GET)和 readinessProbe。别直接复制网上“通用模板”,Go 程序默认不监听 /healthz,你得先在代码里暴露一个真实能响应的路径(比如 /health),再在 YAML 里对齐。
常见错误:livenessProbe 指向一个没实现的 endpoint,导致 Pod 反复重启;或者把 port 写成服务端口(如 8080),却忘了容器内实际监听的是 8080,而 containerPort 漏写或写错。
- 用
net/http在main()启一个轻量 health handler,例如http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }) -
deployment.yaml中containerPort必须和 Go 程序http.ListenAndServe(":8080", ...)的端口一致 - probe 的
path和port要匹配:如果程序监听:8080,probe 就该设port: 8080+path: /health
如何让 Go 应用适配 K8s 的生命周期管理
Kubernetes 发送 SIGTERM 时,Go 进程必须优雅退出:关掉 listener、等活跃请求完成、释放资源。否则滚动更新会丢请求,或触发 readiness probe 失败后被强制 kill。
关键不是“写完 signal.Notify 就完事”,而是要控制 shutdown 顺序和超时。K8s 默认给 30 秒 terminationGracePeriodSeconds,你的 http.Server.Shutdown() 超时应略小于它(比如 25 秒)。
立即学习“go语言免费学习笔记(深入)”;
- 不要用
os.Exit()响应SIGTERM—— 它跳过 defer 和 cleanup - 用
server.Shutdown(context.WithTimeout(ctx, 25*time.Second)),并在 defer 里 close listener - 在
readinessProbe中避免依赖未就绪的下游(比如 DB 连接池还没建好就返回 200)
env、configmap、secret 怎么安全传给 Go 程序
Go 程序读环境变量很自然,但硬编码 os.Getenv("DB_HOST") 不够健壮。K8s 的 envFrom 或 env 字段只是把键值注入容器环境,你要确保 Go 侧有 fallback、类型转换和校验逻辑。
容易踩的坑是:configmap/secret 挂载为文件后,Go 程序仍试图从 env 读——因为挂载路径和 env key 是两套机制。选一种并保持一致。
- 推荐优先用
env+valueFrom:在 deployment 中写env: [{name: DB_HOST, valueFrom: {configMapKeyRef: {name: app-config, key: db-host}}}] - 如果用 volume mount,Go 侧要用
ioutil.ReadFile("/etc/config/db-host"),而不是os.Getenv("DB_HOST") - secret 的 key 名不要带下划线(如
API_KEY),某些 base64 解码后可能含不可见字符,建议统一用小写字母+连字符
怎么验证 deployment.yaml 是否真能跑起来
本地验证不能只靠 kubectl apply -f 看是否报错。很多问题(比如 probe 超时、权限不足、volume 权限拒绝)只在 Pod 启动后才暴露。
最有效的三步检查法:先 dry-run,再看 events,最后进容器抓日志和网络。别跳过 kubectl describe pod —— 它的 Events 区域往往直接告诉你为什么 CrashLoopBackOff。
- 用
kubectl apply --dry-run=client -o yaml -f deployment.yaml | kubectl diff -f -检查变更意图 - Pod 启动失败时,立刻执行
kubectl describe pod <name></name>,重点看 “Events” 和 “Containers” 下的 State/Ready/Restart Count - 如果容器启动了但 probe 失败,用
kubectl exec -it <pod> -- curl -v http://localhost:8080/health</pod>直接测试 endpoint
复杂点在于 probe 配置和 Go 程序启动时序的耦合:比如 health handler 注册晚于 server.ListenAndServe,就会导致 probe 在 handler 就绪前就开始探测。这个时间差没法靠 YAML 调整,只能在 Go 代码里加初始化同步逻辑。


















