go应用必须暴露/health和/ready端点,分别验证依赖连通性与服务监听状态;需设置resources.requests以支持hpa;必须捕获sigterm并调用http.server.shutdown()实现优雅退出。

Go应用必须暴露/health和/ready端点
Kubernetes的livenessProbe和readinessProbe依赖这两个HTTP路径判断实例状态。没实现会导致Pod反复重启或流量被错误转发。
常见错误是只写了/health但没写/ready,或者两个都返回200但逻辑没区分:健康检查应验证依赖(如DB连通性),就绪检查只需确认服务已启动并监听端口。
- 用
http.Server时,在main()里注册两个独立handler,不要复用同一函数 - 避免在
/ready中做耗时操作(如查DB),否则periodSeconds设太小会触发误判 - Go标准库无内置就绪语义,需自己控制——比如在HTTP服务器
ListenAndServe前设一个atomic.Bool标记“已就绪”
Deployment必须设置resources.requests
HPA(Horizontal Pod Autoscaler)无法基于CPU或内存自动扩缩,除非每个容器明确声明resources.requests。Kubernetes靠这个值计算资源使用率百分比,没设就默认为0,导致HPA报错missing request for cpu。
典型配置中requests.cpu和requests.memory要略低于limits,留出缓冲空间:
-
requests.cpu: "100m"对应0.1核,适合轻量HTTP服务;高并发场景可设到"200m" -
requests.memory: "128Mi"是常见起点,注意单位是Mi(mebibytes),不是M(megabytes) - 若Go程序有大量goroutine或大内存缓存,
limits要设得比requests高至少1.5倍,防止OOMKilled
HPA配置需匹配指标类型和命名空间
用kubectl autoscale或YAML创建HPA时,最容易漏掉的是scaleTargetRef中的apiVersion和kind——必须和目标Deployment完全一致,且Deployment必须在同一命名空间下。
例如,你的Deployment在default命名空间,HPA也必须指定namespace: default,否则HPA找不到目标:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: go-app-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: go-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- 如果用自定义指标(如QPS),需提前部署Metrics Server和Prometheus Adapter,且指标名称必须和
metrics[].resource.name完全匹配 - HPA默认每15秒同步一次,不要指望秒级响应;突发流量建议配合KEDA监听消息队列积压
优雅退出必须处理SIGTERM并调用Shutdown()
滚动更新或HPA缩容时,Kubernetes先发SIGTERM,30秒后强制SIGKILL。Go程序若不捕获信号并主动关闭HTTP服务器,正在处理的请求会被中断,客户端收到connection reset。
关键代码只有几行,但漏掉就等于放弃零停机:
srv := &http.Server{Addr: ":8080", Handler: mux}
go func() {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatal(err)
}
}()
// 捕获SIGTERM
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
-
Shutdown()会停止接收新请求,但等待已有请求完成,超时时间建议设5–10秒 - 别用
os.Exit(0)代替Shutdown(),它跳过清理逻辑,连接池、数据库连接等资源不会释放 - 如果用了第三方框架(如Gin),确保其
Run()方法支持传入http.Server,否则无法注入Shutdown()逻辑
实际部署链路里,最常被忽略的是resources.requests和SIGTERM处理——前者让HPA失效,后者让缩容变成随机断连。这两处不补全,自动扩容只是纸上谈兵。











