先用 docker run 本地验证镜像:确认能启动、端口监听、/health 返回200;常见问题包括架构不匹配、alpine缺库、启动后退出、deployment三字段未对齐、oomkilled及livenessprobe过早触发。

部署前先确认镜像能本地跑通
别急着 kubectl apply,Go 应用镜像在集群里起不来,80% 的原因出在镜像本身。先用 docker run 在本地验证:是否能启动、端口是否监听、健康接口是否返回 200。
常见卡点:
-
exec format error:镜像架构和节点不匹配(比如 x86_64 镜像推到了 arm64 节点),构建时加GOOS=linux GOARCH=arm64 -
standard_init_linux.go:228: exec user process caused: no such file or directory:Alpine 镜像缺 glibc 或动态库,要么改用debian:slim,要么编译时加CGO_ENABLED=0 - 启动后立刻退出:没加
CMD ["./main"]或二进制没给执行权限(chmod +x)
Deployment YAML 必须对齐的三个字段
Go 应用的 Deployment 不是写完就能连上 Service,关键靠三处硬匹配:
-
spec.template.metadata.labels(Pod 标签)必须和spec.selector.matchLabels完全一致,一个字母都不能错 -
spec.template.spec.containers[].ports[].containerPort值,必须等于Service中spec.ports[].targetPort -
Service的spec.selector必须能命中至少一个 Pod 的标签,否则kubectl get endpoints返回空
漏掉任意一项,Service 就成“断头路”,流量根本到不了 Go 进程。
Pod 启动失败时,按顺序查这四条命令
看到 CrashLoopBackOff 或 Pending,别猜,直接敲:
-
kubectl get pods -n <namespace></namespace>:看状态和重启次数 -
kubectl describe pod <pod-name> -n <namespace></namespace></pod-name>:重点看Events区域——FailedScheduling是资源不够,ImagePullBackOff是镜像拉不到,OOMKilled是内存超限 -
kubectl logs <pod-name> -n <namespace> --previous</namespace></pod-name>:查上一轮崩溃的日志(Go panic、配置文件打开失败、DB 连接超时都藏在这) -
kubectl exec -it <pod-name> -n <namespace> -- /bin/sh</namespace></pod-name>:进容器手动试netstat -tuln看端口、ls -l看配置文件路径、curl -v http://localhost:8080/health测健康接口
Go 程序在 K8s 里容易被误杀的两个隐性原因
即使日志显示正常启动,Go 服务仍可能被 kubelet 强制终止,常见于:
-
resources.limits.memory设太小:Go GC 触发时瞬时内存飙升超过 limit,直接 OOMKill。建议初始设512Mi,上线后根据container_memory_usage_bytes指标调优 -
livenessProbe配得太激进:比如initialDelaySeconds: 5,但 Go 应用加载配置+连 DB 要 8 秒,探针提前失败导致反复重启。应设为实际冷启动耗时的 1.5 倍以上
这两个点不报错、不打日志,只在 kubectl describe pod 的 Events 里留一行 Container killed due to OOM 或 Liveness probe failed,很容易被忽略。











