必须用多阶段构建+静态编译,cgo_enabled=0 goos=linux go build -a -ldflags="-w -s"生成无依赖二进制;运行镜像选scratch或alpine并显式加载证书;deployment须配全replicas、strategy、minreadyseconds、revisionhistorylimit、progressdeadlineseconds五项;livenessprobe与readinessprobe须分离端点且超时合理;必须设置resources requests/limits并实现sigterm优雅终止。

不能只靠 kubectl apply -f 一把梭部署 Go 应用到生产环境。缺了关键配置,Pod 很可能刚上线就 OOMKill、反复重启、流量打到假死实例,或者更新卡死、回滚失效。
Go 应用镜像必须用多阶段构建 + 静态编译
Go 二进制本身不依赖 libc,但默认构建会带 CGO 支持,导致 Alpine 镜像运行失败或 DNS 解析异常。不关掉它,http.Get 可能静默超时。
- 构建阶段加
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./cmd/api - 运行阶段别用
golang:alpine,改用纯 distroless 或alpine:latest+apk add ca-certificates - 镜像里别留
go、git、sh—— 不仅增大体积,还增加攻击面 - 验证方式:
docker run --rm <image> ldd ./main</image>输出应显示not a dynamic executable
Deployment 必须显式写全这 5 个字段
replicas、strategy、minReadySeconds、revisionHistoryLimit、progressDeadlineSeconds 缺一不可。Kubernetes 默认值全是为“能跑”设计的,不是为“扛住线上流量”设计的。
针对 Kubernetes 仪表板和 Web UI 的浏览器自动化。适用于与 Kubernetes Dashboard、Grafana、ArgoCD UI 或其他 Web 界面交互。需要设置 MCP_BROWSER_ENABLED=true。
-
replicas: 3起步,配合topologySpreadConstraints强制跨节点/可用区调度 -
strategy.rollingUpdate.maxUnavailable: 1或25%,别设0—— 否则新 Pod 没 Ready 前,旧 Pod 不会下线,滚动更新直接挂住 -
minReadySeconds: 15,确保 Pod 启动后至少稳定运行 15 秒才接入流量(尤其 Spring Boot/Go-restful 类冷启动长的服务) -
revisionHistoryLimit: 3,否则kubectl rollout undo找不到上个可用版本 -
progressDeadlineSeconds: 600(10 分钟),避免更新卡在某一步无限等待
livenessProbe 和 readinessProbe 必须拆开、且路径分离
用同一个 /health 端点同时做存活和就绪检查,等于把“是否该重启”和“是否能收流量”绑死。一个网络抖动或 DB 连接慢,就可能触发误杀 + 流量中断双杀。
- Go 服务里实现两个端点:
/livez只检查进程是否活着(比如return http.StatusOK);/readyz检查 DB、Redis、下游依赖是否就绪 -
livenessProbe.initialDelaySeconds至少设成应用冷启动耗时 + 5 秒(Node.js 常 30s+,Go-restful 建议 45s 起) -
readinessProbe.failureThreshold: 3,别用默认 1 —— 允许短暂抖动,避免 Service Endpoints 频繁震荡 - 两者都禁用
timeoutSeconds: 1这种拍脑袋值;HTTP 探针超时建议 ≥3s,TCP 探针 ≥2s
resources 和 LimitRange 是上线前的硬性准入门槛
没配 resources.requests,Kubernetes 调度器根本不知道往哪塞你的 Pod;没设 limits,一个 goroutine 泄漏就能拖垮整台 Node。
- CPU
requests决定调度位置,limits过低会导致cpu.shares不足、被 throttling(kubectl top pods看 CPU usage 是否长期贴着 limit) - 内存
limits必须设,且建议是requests的 1.5–2 倍(如requests: 256Mi→limits: 512Mi),给 GC 和临时 buffer 留余地 - 在 namespace 级配
LimitRange,兜底防止单个开发者漏写resources就apply上线 - 别信“压测后再调”——压测前
Exit Code 137就已刷屏日志
最易被忽略的其实是优雅终止:Go 服务必须监听 SIGTERM,并在收到信号后关闭 HTTP server、等待活跃请求完成(用 srv.Shutdown),再退出。否则滚动更新时,连接会被粗暴断开,客户端看到大量 502/504。










