Go应用本身不暴露服务,Kubernetes才负责暴露;需监听0.0.0.0:8080、提供/healthz和/readyz端点、镜像轻量、端口与YAML严格一致,否则Service返回503,Pod卡在CrashLoopBackOff或ContainerCreating。

Go 应用本身不暴露服务,Kubernetes 才负责暴露;你只需确保 Go 进程监听 0.0.0.0:8080、提供 /healthz 和 /readyz 端点、镜像轻量且端口与 YAML 一致——否则 Service 会 503,Pod 会卡在 CrashLoopBackOff 或 ContainerCreating。
Go 代码必须监听 0.0.0.0,不能只 listen localhost
Kubernetes Pod 内部网络是独立的,localhost 或 127.0.0.1 只对容器自身生效,外部(包括 kube-proxy 和探针)根本连不上。常见错误现象:日志显示 “server started on :8080”,但 kubectl get pods 显示 Running 却 kubectl port-forward 失败,或探针持续 Connection refused。
- 正确写法:
http.ListenAndServe(":8080", nil)(冒号开头即绑定所有接口) - 错误写法:
http.ListenAndServe("127.0.0.1:8080", nil)或http.ListenAndServe("localhost:8080", nil) - 用
netstat -tuln进入容器验证:netstat -tuln | grep :8080应显示*:8080,不是127.0.0.1:8080
Deployment 中 containerPort 必须和 Go 监听端口、探针 port 完全一致
三者不一致是导致探针失败最隐蔽的原因之一。Kubernetes 不会自动映射端口,containerPort 是声明式“我这个容器对外暴露哪个端口”,liveness/readiness 探针的 port 字段必须引用它,否则探针发请求时直接找不到目标端口。
- 假设 Go 监听
:8080,则containerPort: 8080必须写死 - 探针中
httpGet.port: 8080(不能写成 80 或字符串 "http") - Service 的
targetPort也应设为8080(可省略,但显式写更安全) - 如果改用
:3000,YAML 里所有相关字段都要同步改,不能只改一处
Service 类型选错会导致服务无法访问
ClusterIP 是默认类型,只在集群内可用;想从本地或公网访问,必须选对类型并理解其行为边界。
-
ClusterIP:适合微服务间调用,Service 分配一个虚拟 IP,仅集群内 Pod/Node 可访问 -
NodePort:在每个 Node 上开一个固定端口(如30080),通过http://<node-ip>:30080</node-ip>访问;开发测试够用,但端口范围受限(30000–32767) -
LoadBalancer:云厂商自动创建 LB 并绑定 NodePort,对外暴露域名/IP;生产环境推荐,但需云平台支持 - 别用
hostNetwork: true暴露端口——它绕过 kube-proxy,破坏网络策略,且多个 Pod 会端口冲突
健康探针路径必须和代码注册路径一字不差
探针是 HTTP GET 请求,路径名大小写、斜杠、拼写都必须严格匹配。写错一个字符,就永远 404,Kubernetes 就认为服务不健康。
- 代码里注册的是
http.HandleFunc("/healthz", ...),YAML 里就得写path: /healthz - 写成
/health、/healthz/或/HEALTHZ都会失败 -
/healthz应只返回 200,不做 DB 查询;/readyz可查依赖,但建议加timeoutSeconds: 10防止阻塞 - 用
kubectl logs <pod-name>看是否打印了探针请求日志,能快速定位路径是否被命中
最容易被忽略的是:探针的 initialDelaySeconds 设得太小,Go 服务还没初始化完就被杀;或者 resources.requests 没填,调度器直接拒收 Pod。这两项不报错,但 Pod 永远起不来。


















