go项目不部署到kubernetes,而是打包为容器镜像后由deployment和service调度运行;必须暴露/healthz和/readyz端点、监听0.0.0.0、禁用cgo构建轻量镜像、严格匹配labels与端口、配置合理探针及优雅关闭,否则pod易卡在containercreating或crashloopbackoff。

Go 项目本身不“部署”到 Kubernetes,而是打包成容器镜像后,由 Kubernetes 的 Deployment 和 Service 等资源对象来调度、运行和暴露——你写的 Go 代码只是镜像里的一个二进制文件。
写好 Go 服务并暴露健康探针
Kubernetes 不会猜你的服务是否就绪,它只依赖 HTTP 探针。没配 /healthz 和 /readyz,livenessProbe 和 readinessProbe 就会失败,Pod 反复重启或卡在 ContainerCreating。
-
/healthz返回200即可,不用连 DB 或查外部依赖 -
/readyz可加轻量检查(比如 DB 连通性),但别超 1s,否则影响滚动更新 - 端口必须和
Deployment中的containerPort一致,比如都设为8080 - 启动日志里打一句
log.Printf("server started on :8080"),方便排查CrashLoopBackOff
用多阶段 Dockerfile 构建轻量镜像
Go 编译出的是静态二进制,没必要把 golang 镜像整个塞进生产环境。镜像过大不仅拉取慢,还容易触发 ImagePullBackOff。
- 构建阶段用
golang:1.22-alpine,关键命令:CGO_ENABLED=0 GOOS=linux go build -a -o main . - 运行阶段用
scratch(最干净)或alpine:latest(需apk add ca-certificates) - 如果用了 cgo(如某些 crypto 库),就不能用
scratch,得保留alpine并装对应依赖 - 绝对不要写
go run main.go—— 那会把 Go 工具链全打进镜像
Deployment YAML 必须带 label 匹配和资源限制
Kubernetes 不认“微服务”这个词,只认字段。少一个 selector.matchLabels 或 template.metadata.labels 不匹配,Deployment 就起不来 Pod。
-
replicas别留空,默认是 1,建议显式写成3起步 -
selector.matchLabels和template.metadata.labels必须完全一致,比如都含app: go-app -
resources.limits和requests必填,否则调度器无法分配节点,尤其在资源紧张时 -
containerPort必须和 Go 服务监听端口一致(比如8080),且要和探针配置的端口对齐
Service 和 Ingress 要按访问场景选型
Service 是集群内通信的基础,但对外暴露方式取决于实际需求——不是所有服务都要开公网。
- 内部调用:用
ClusterIP(默认),通过 DNS 名go-app.default.svc.cluster.local访问 - 测试调试:用
NodePort,但注意端口范围(30000–32767)和节点防火墙 - 生产 HTTP/HTTPS:用
Ingress,配合ingress-nginx或云厂商 LB,路径重写和 TLS 终止都在这里配 - 别漏掉
Service的selector,必须和Deployment的labels对上,否则 endpoint 为空
最容易被忽略的是探针路径与端口的一致性、label 的严格匹配、以及镜像构建阶段的 CGO_ENABLED=0 —— 这三处出错,90% 的部署卡在 Pod 启动不起来。其他都是 YAML 字段填错,kubectl describe pod 一眼就能定位。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











