Deployment和Service缺一不可:Deployment管理Pod副本与更新,Service提供稳定网络入口和负载均衡;二者selector必须严格匹配,端口、探针路径、资源限制等须与Go应用实际行为一致。

Deployment 和 Service 是必须写的两个最小资源,缺一不可。只写 Deployment 会导致服务无法被访问;漏掉 Service,Pod 就没有稳定网络入口。
Deployment YAML 必须匹配 Go 应用的真实行为
常见错误是 YAML 里写的端口、探针路径、环境变量,和 Go 代码对不上——Kubernetes 不会猜你的意图,它只按配置执行。
-
containerPort必须等于 Go 代码中实际监听的端口(比如http.ListenAndServe(":"+os.Getenv("PORT"), nil)),不能硬写8080后又在 YAML 里设containerPort: 80 -
livenessProbe.httpGet.path和readinessProbe.httpGet.path必须与 Go 中注册的路由完全一致,比如代码里是http.HandleFunc("/healthz", ...),YAML 就不能写path: /health - 探针的
initialDelaySeconds要差异化:建议readinessProbe.initialDelaySeconds: 5(快点接入流量),livenessProbe.initialDelaySeconds: 30(等冷启动完成再开始健康检查),否则容易陷入CrashLoopBackOff - Go 进程必须能响应
SIGTERM:在http.Server.Shutdown()里做优雅关闭,否则 Kubernetes 发送终止信号后容器直接 kill,连接被断开
Service 配置要区分访问场景
不是所有 Go 服务都需要对外暴露,但 Service 类型选错或没配 selector,就会导致 kubectl get endpoints 显示 <none>,流量根本进不来。
在 Go 中使用 google/wire 实现编译时依赖注入——wire.NewSet、wire.Build、wire.Bind(接口→实现)、wire.Struct、wire.Value、wire.Interface
- 集群内调用:用
ClusterIP(默认),确保spec.selector和 Deployment 的template.metadata.labels完全一致(键和值都要对) - 本地调试或临时暴露:用
NodePort,注意nodePort值要在 30000–32767 范围内,且节点防火墙要放行 - 生产对外服务:搭配
Ingress使用ClusterIP,不要直接用LoadBalancer(云厂商费用高、收敛慢) - 如果 Go 服务只做后台任务(如 cron job),可以不配 Service —— 但 Deployment 仍需存在
镜像和资源限制要写进 container spec
不写 resources.requests/limits 或镜像 tag 用 latest,上线后大概率触发调度失败或 OOMKilled。
-
image必须带明确 tag(如v1.2.0),禁止用latest;CI 构建时应自动打带 Git SHA 的 tag -
resources.requests影响调度:Kubernetes 按这个值决定把 Pod 分配到哪个 Node;太小会挤占其他服务,太大则浪费资源 -
resources.limits.memory设得太低(如128Mi)会导致 Go runtime 触发 GC 频繁,甚至OOMKilled;建议从256Mi起步,压测后再调 - 若镜像来自私有仓库,必须加
imagePullSecrets,否则卡在ImagePullBackOff
SIGTERM 后等待活跃请求结束——这些都不会在 kubectl apply -f 时报错,但会在 kubectl get pods 里持续显示 Running 却无流量,查日志也看不到明显异常。

















