Go微服务在K8s中必须配置livenessProbe和readinessProbe以避免“假就绪”,镜像需多阶段构建并以非root用户运行,配置应支持热更新且敏感信息须加密,资源操作须用client-go结构体而非硬编码YAML。

Deployment配置必须包含livenessProbe和readinessProbe
不加健康探针的Go微服务在K8s里大概率会陷入“假就绪”状态:Pod Running了,但HTTP服务还没监听端口,流量进来就502。K8s默认只看容器进程是否存活,而Go服务启动常有延迟(比如加载配置、连接DB、初始化gRPC server)。
-
livenessProbe用于重启卡死的服务:建议用HTTP GET调/healthz,initialDelaySeconds设为10–15秒(避开Go服务冷启动耗时),failureThreshold不要低于3 -
readinessProbe控制流量接入时机:同样指向/healthz,但initialDelaySeconds可设更小(如5秒),periodSeconds建议10秒以内,避免新Pod上线后长时间无流量 - 两个探针的
port必须和Go服务实际监听端口一致(比如http.ListenAndServe(":8080", nil),探针里就得写port: 8080) - 别用
exec探针执行netstat或curl——Alpine镜像里可能没这些命令,且增加启动依赖
镜像构建要用多阶段+非root用户
直接FROM golang:alpine跑生产环境,等于把编译器和调试工具全塞进线上容器,既增大攻击面又浪费内存。Go静态二进制天然适合最小化镜像。
- 第一阶段用
golang:1.22-alpine编译,关键要设CGO_ENABLED=0和GOOS=linux,确保生成纯静态二进制 - 第二阶段用
alpine:latest或scratch,COPY --from=0 /app/app /app/app只复制最终二进制 - 务必加
USER nobody:nogroup,否则容器默认以root运行,违反K8s PodSecurityPolicy和多数企业安全基线 - 镜像标签别用
latest——CI流水线中应取git rev-parse HEAD作为tag,方便回溯和灰度发布
配置热更新不能靠重启,得监听etcd或Consul变更
把配置写死在ConfigMap里,改完还得kubectl rollout restart,这不算自动化。真正的热更新是服务自己感知变化并重载。
- Go代码里别用
viper.ReadInConfig()一次性读取,而是用viper.WatchConfig()配合回调函数,当etcd/Consul中对应key变更时触发viper.Unmarshal() - 敏感配置(如数据库密码)不要明文存etcd,用
Secret挂载+KMS解密,或者走Vault sidecar注入 - 监听逻辑要加锁,避免并发修改全局配置结构体导致panic;回调里别做耗时操作(如重建DB连接池),应发消息到channel由worker异步处理
- 注意etcd租约(Lease)过期问题:客户端心跳失败后配置会自动删除,需在
Watch断连时主动重连并重新Get全量配置
用client-go操作资源时,别手写YAML字符串
硬编码"apiVersion: apps/v1\nkind: Deployment..."看似省事,但字段拼错、缩进错误、类型不匹配都会导致Create()静默失败或创建出错配的资源。
立即学习“go语言免费学习笔记(深入)”;
- 一律用官方struct,比如
appsv1.Deployment,IDE能提示字段,编译期可捕获Replicas写成replicas这种低级错误 -
spec.selector和template.metadata.labels必须严格一致,否则Deployment会卡在0/3 available——这是最常被忽略的坑 - 更新Deployment时用
Patch()而非Update(),避免覆盖掉K8s自动注入的annotations(如kubectl.kubernetes.io/last-applied-configuration) - 轮询确认滚动更新完成:检查
dep.Status.UpdatedReplicas == *dep.Spec.Replicas且dep.Status.AvailableReplicas == *dep.Spec.Replicas,超时设300秒,间隔2秒


















