Service的核心作用是“稳定寻址”,通过不变的ClusterIP和DNS名屏蔽Pod动态变化;依赖selector匹配Ready Pod,由endpoints controller同步至Endpoints对象;kube-proxy将规则写入内核(iptables/ipvs)实现DNAT转发。

Service 的核心作用不是“转发流量”,而是“稳定寻址”——它用一个不变的虚拟 IP(ClusterIP)和 DNS 名,屏蔽后端 Pod 的动态变化。
Service 怎么找到后端 Pod?靠 selector + Endpoints
Service 本身不持有 Pod 地址,它只声明一个 selector(比如 app: nginx),然后由 Kubernetes 内置的 endpoints controller 实时监听:哪些 Pod 满足这个 label、且处于 Ready 状态。满足条件的 Pod IP+端口会被自动写入同名的 Endpoints 对象中。
你执行 kubectl get endpoints app-service 就能看到真实生效的后端列表。如果列表为空,常见原因有:
-
Deployment或Pod的 label 写错了,和 Service 的selector不匹配 - Pod 处于
Pending或CrashLoopBackOff,没通过 readiness probe - Service 创建早于 Pod,而 endpoints controller 还没来得及同步(通常几秒内会自动修复)
流量怎么真正转发到 Pod?kube-proxy 是关键中间人
Service 的 ClusterIP 是个“虚地址”,不能直接响应网络请求。真正干活的是每个 Node 上的 kube-proxy 组件——它持续监听 Service 和 Endpoints 变化,并把规则刷进系统内核:
- 默认模式是
iptables:为每个 Service 生成一堆 NAT 规则,请求命中 ClusterIP:Port 后,随机选一个 Endpoint 做 DNAT - 大规模集群建议用
ipvs模式:性能更高、连接跟踪更稳定,但需内核支持ip_vs模块 -
userspace模式已弃用;kernelspace(即 eBPF)是较新方向,但尚未成为默认
注意:kube-proxy 不参与数据包转发路径,它只负责“写规则”。实际转发由 Linux 内核 netfilter 完成,所以延迟极低,也几乎不消耗 CPU。
为什么访问 ClusterIP 有时失败?先查这三件事
不是所有 ClusterIP 都能从任意位置访问。典型故障链路是:
- Pod 自身网络不通(比如 CNI 插件异常,
ping不通其他 Pod) - Service 的
targetPort和容器实际监听端口不一致(如容器监听8080,但写成了80) - 集群 DNS 不工作(
kube-dns或CoreDNSPod 异常,或/etc/resolv.conf配置错误)
验证顺序建议:curl http:// → curl http:// → 直连某个 Pod IP。这样能快速定位是 DNS、Service 还是底层网络问题。
最容易被忽略的一点:ClusterIP 只在集群内部有效,它根本不会路由到 Node 主机网络——这意味着你在 master 节点上 curl ClusterIP 成功,不代表应用 Pod 里也能成功,因为后者走的是 Pod 网络平面,前者可能走的是 host 网络。务必在 Pod 内部测试。










