service是kubernetes中为解决pod ip动态变化和负载均衡问题而设计的稳定访问入口,它通过固定clusterip、nodeport或loadbalancer类型提供持久化服务地址,并基于label selector自动关联后端pod。

Service 是什么,为什么不能直接用 Pod IP 访问 Go 应用
Pod IP 不稳定,每次重启或滚动更新都会变,Service 就是为解决这个问题而生的——它提供一个固定的 ClusterIP(或 NodePort / LoadBalancer),背后自动负载均衡到健康 Pod。如果你在 kubectl get pods 里看到 Pod IP 是 10.244.1.5,但过几分钟变成 10.244.1.6,那直接写死这个 IP 的调用必然失败。
Go 应用本身不需要改代码,只要确保它监听的是 0.0.0.0:8080(不是 127.0.0.1:8080),否则容器内其他进程(比如 Service 的 kube-proxy)根本连不上。
创建 Service 必须匹配 Deployment 的 label selector
Service 和 Pod 的关联靠的是 selector 字段,必须和 Deployment 模板里的 metadata.labels 完全一致,一个字母都不能错。常见错误是:
-
Deployment中写了app: go-service,但Service的selector写成app: backend→ 流量压根进不去 - Deployment 用了多层 label(如
tier: backend+track: stable),但 Service 只写了其中一条 → 匹配不到任何 Pod - 忘记给 Pod 模板加
labels,只写了 Deployment 自身的metadata.labels→ Service 查无此 Pod
验证方式很简单:kubectl get pods -l app=go-service 能列出 Pod,kubectl get service 看 ENDPOINTS 列是不是有 IP:PORT(比如 10.244.1.5:8080),没有就说明 selector 没对上。
NodePort 类型 Service 在开发环境最实用
ClusterIP 只能在集群内访问,LoadBalancer 依赖云厂商,NodePort 是本地测试和预发环境最直接的选择:它把 Service 绑定到每个节点的固定端口(默认 30000–32767),你用 http://<node-ip>:30080</node-ip> 就能访问 Go 服务。
注意几个硬性限制:
- 端口必须在 30000–32767 范围内,写
nodePort: 8080会报错invalid value '8080': provided port is not in the valid range - 如果集群跑在虚拟机或云主机上,得手动开防火墙(比如
ufw allow 30080或安全组放行) - 多个 Service 不能用同一个
nodePort值,否则创建失败
示例片段:
apiVersion: v1
kind: Service
metadata:
name: go-service-svc
spec:
type: NodePort
selector:
app: go-service
ports:
- port: 80
targetPort: 8080
nodePort: 30080
前端如何通过 Service 名称访问后端 Go 服务
在 Kubernetes 集群内,Service 名就是 DNS 名。比如你有个 go-service-svc,前端 Pod(Nginx 或另一个 Go 服务)可以直接用 http://go-service-svc:80 请求,不用记 ClusterIP。
但要注意三点:
- 必须在同一个 namespace,跨 namespace 要写完整域名:
go-service-svc.default.svc.cluster.local - 前端容器的 /etc/resolv.conf 里得有
search default.svc.cluster.local svc.cluster.local cluster.local,KubeDNS 默认会配好,除非你手动覆盖了 DNS 配置 - 如果前端是静态 HTML + JS,在浏览器里发请求,那走的是用户本地网络,不是集群 DNS —— 这时得用反向代理(比如 Nginx 把
/api/代理到go-service-svc)或者让前端也跑在集群里
最容易被忽略的一点:Go 服务返回的 HTTP 响应头里如果带了绝对 URL(比如重定向跳转到 http://localhost:8080/health),前端拿到后会去连自己本地的 8080,而不是集群里的 Service。务必让 Go 代码读取 X-Forwarded-Host 或配置 baseURL,别硬编码 localhost。











