Go服务必须监听0.0.0.0而非127.0.0.1,否则kube-proxy等外部组件无法访问;containerPort需与代码监听端口一致,Service流量才可正常转发;必须配置readinessProbe和livenessProbe,且探针路径、端口、状态码须正确;Service selector必须严格匹配Pod labels;镜像须静态编译(CGO_ENABLED=0)、以非root用户运行,并输出纯文本日志到stdout。

containerPort 必须和 Go 代码监听地址一致
Go 服务启动时如果写成 http.ListenAndServe("127.0.0.1:8080", nil),容器内其他进程(比如 kube-proxy)根本连不上,Kubernetes 的 Service 流量会直接被丢弃。Pod IP 是绑定在容器网卡上的,必须监听 0.0.0.0:8080 才能被访问。
常见翻车点:
- 本地
go run main.go能通,但部署后kubectl get pods显示 Running 却无法 curl —— 八成是监听地址错了 -
containerPort字段填了8080,但代码里监听的是:3000,Service 转发失败,kubectl describe pod里能看到Failed to connect to port类似事件 - 没加
EXPOSE 8080到 Dockerfile(虽非强制,但不写容易漏掉端口意识)
Deployment 必须配 readinessProbe 和 livenessProbe
Kubernetes 不看进程是否 running,只认探针返回码。没配探针,或路径不存在、端口不对、HTTP 状态码不是 2xx/3xx,Pod 就永远卡在 Ready: 0/1 或反复重启。
实操要点:
立即学习“go语言免费学习笔记(深入)”;
- Go 代码里至少暴露两个 handler:
/healthz(基础存活)、/readyz(依赖就绪,比如 DB 连通性检查) - YAML 中
livenessProbe.httpGet.port和readinessProbe.httpGet.port必须和containerPort一致,不能写错成 Service 的port -
initialDelaySeconds得留够时间:Go 启动慢(尤其带 DB 迁移或缓存预热),livenessProbe建议 ≥30s,readinessProbe可设 5–10s - 别用 TCP 探针替代 HTTP 探针——TCP 成功只说明端口开了,不代表业务 ready
Service selector 必须严格匹配 Pod label
Service 不认 Deployment 名、不认镜像名、不认容器名,只靠 selector 字段去 match Pod 的 labels。哪怕只差一个空格或大小写,流量就进不去。
典型错误场景:
- Deployment 里写
app: go-service,Service 里写app: go_service(下划线 vs 短横)→ 0 个 Endpoint - 多个 Deployment(如
user-api、order-api)想共用一个 Service,但各自 label 不统一 → 只有第一个创建的 Pod 被选中 - 忘记在 Pod template 的
metadata.labels里重复定义 label → selector 匹配失败,kubectl get endpoints返回空
验证命令:kubectl get pods -l app=go-service 和 kubectl get endpoints go-service 输出必须一致且非空。
镜像必须是静态编译 + 非 root 用户运行
用 golang:alpine 直接跑编译产物,大概率 panic:Alpine 默认用 musl libc,而 CGO 启用时依赖 glibc;若禁用 CGO 但镜像仍含 shell 工具链,体积大、攻击面宽、权限高。
安全构建要点:
- Dockerfile 第一阶段用完整 Go 环境,第二阶段切
FROM scratch或FROM alpine:latest - 编译命令必须含
CGO_ENABLED=0 GOOS=linux,否则二进制动态链接 libc,scratch镜像直接报No such file or directory -
USER指令不能省:比如USER 65532:65532,避免容器逃逸后拿到 root 权限 - 镜像推送到私有 registry 后,Deployment 的
image字段要写全路径,如harbor.example.com/myapp/go-service:v1.2,别用本地 tag
最易忽略的一点:日志必须输出到 stdout,且不能带 ANSI 颜色控制符——Kubernetes 日志采集器(如 fluentbit)只收纯文本流,颜色字符会导致解析失败或截断。


















