go服务必须暴露/healthz和/readyz端点,前者仅检查本地进程存活(如端口监听、goroutine数),后者验证下游依赖(db/redis等)并缓存结果,两者均需独立端口、禁用中间件、设超时与非空json响应体。

Go服务必须暴露/healthz和/readyz端点
不暴露这两个端点,Kubernetes就无法判断Pod是否就绪或存活,HPA扩容后新实例可能一直卡在Pending或CrashLoopBackOff状态。/healthz只检查本地状态(如HTTP server是否监听),/readyz则要验证下游依赖(如数据库连接池、Redis连接、etcd健康)。别在/readyz里调用其他微服务——这会把探针变成分布式雪崩触发器。
-
/healthz返回200即可,建议用http.StatusOK硬编码,不查任何外部依赖 -
/readyz应检查db.PingContext()、redis.Ping()等,任一失败返回503 - Kubernetes的
readinessProbe默认每10秒调一次,initialDelaySeconds必须大于服务冷启动耗时(比如加载配置+建DB连接池常需3~8秒) - 避免用
gin.HandlerFunc直接写逻辑,封装成可单元测试的函数,例如func checkDBReady() error
必须监听SIGTERM并调用srv.Shutdown()
缩容时Kubernetes发SIGTERM,若Go进程没响应或用os.Exit(0)硬退出,正在处理的请求会被立即切断,用户收到502或超时。Shutdown不是“立刻关”,而是拒绝新请求、等待存量请求完成——但得设超时,否则可能卡死。
针对 Kubernetes 仪表板和 Web UI 的浏览器自动化。适用于与 Kubernetes Dashboard、Grafana、ArgoCD UI 或其他 Web 界面交互。需要设置 MCP_BROWSER_ENABLED=true。
- 用
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)捕获信号,别漏os.Interrupt(本地调试时Ctrl+C也得优雅停) -
srv.Shutdown()必须传带超时的context.Context,建议10秒;超过时间强制退出,不能无限等 - Shutdown后要显式关闭DB连接池:
db.Close(),取消后台ticker:ticker.Stop(),否则goroutine泄漏 - 绝对不要在信号处理里调
log.Fatal()或panic(),它们会绕过defer和cleanup逻辑
Deployment中resources.requests必须设置
没设requests,Kubernetes调度器不知道Pod要多少CPU和内存,HPA也拿不到利用率基准值,扩缩容会失效或误判。更糟的是,节点资源紧张时,未设requests的Pod会被优先OOMKilled。
-
resources.requests.cpu建议按单核100m起步(即0.1核),Go服务通常不需要满核,但得留出runtime调度开销 -
resources.limits可以略高于requests(如1.5倍),防止突发GC或goroutine暴涨打满节点 - 别信“Go轻量所以requests设10m”,实测Gin+DB+Redis的API服务冷启动后常驻内存>80Mi,requests设太低会导致频繁OOM
- HPA基于
averageUtilization计算时,分母就是requests值,设错会导致扩缩阈值漂移
用client-go对接HPA前先确认RBAC和指标源
自己写伸缩控制器时,最常卡在权限或指标不可达。HPA本身不拉指标,它通过Metrics Server或Custom Metrics Adapter间接获取——而你的Go服务只是指标提供方,不是指标搬运工。
- ServiceAccount必须绑定
scale子资源权限:verbs: ["get", "patch"]onresource: "deployments/scale" - 若用Prometheus指标,确保
prometheus-adapter已部署,且CRDservicemonitors.monitoring.coreos.com能抓到你的/metrics端点 - 自定义指标名要严格匹配HPA配置中的
metric.name,比如http_requests_total和http_requests_per_second是两个不同指标 - 本地调试时用
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta2/...直连验证指标是否可查,别等HPA日志报错才排查
terminationGracePeriodSeconds和srv.Shutdown()超时时间的对齐——前者是Kubernetes给Pod的“宽限期”,后者是Go代码里自己设的context timeout。两者必须满足:Kubernetes宽限期 ≥ Go shutdown超时,否则系统会在你清理完DB连接前就发SIGKILL。线上环境见过太多因差2秒导致连接池泄漏的案例。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










