K8s学习笔记:03-辅助讲义-Service网络深度解析
对应章节:第三章 Service 网络 / 3.1~3.7
定位:讲透 Service 底层原理——虚拟 IP 的真相、流量转发机制、DNS 解析链路
日期:2026年7月13日
前置:已完成第二章 Deployment,理解了 Pod IP 不稳定的问题
一、一句话总结 Service
Service 给一组 Pod 一个固定不变的虚拟 IP + DNS 名字,kube-proxy 在每台节点上把流量转发到后端 Pod。
三层关键角色:
1 | |
二、Service 的 ClusterIP 到底是什么?
2.1 它不是一个”网卡”
如果你登录到任何一台节点执行 ip addr,你找不到 ClusterIP。它不绑定在任何网络接口上。
ClusterIP 是一个仅存在于 kube-proxy 规则表中的虚拟地址:
1 | |
2.2 那数据包是怎么到达 Pod 的?
流程图(以 iptables 模式为例):
1 | |
关键认知:Service 不做代理,不经过任何用户态进程转发。iptables 在内核层面直接改写数据包的目标地址(DNAT),性能开销极小。
三、kube-proxy 的三种转发模式
kube-proxy 是运行在每台节点上的 DaemonSet Pod(或系统进程),它 watch API server 监听 Service 和 Endpoints 的变化,然后改写本机规则。
3.1 三种模式对比
| 模式 | 规则位置 | 性能 | 负载均衡算法 | 适用规模 |
|---|---|---|---|---|
| userspace(旧) | kube-proxy 进程自己转发 | 最差(用户态↔内核态来回切) | 轮询 | 已被淘汰 |
| iptables(默认) | iptables 规则链 | 好(内核态,O(n) 规则匹配) | 随机(statistic 模块) | 中小集群 |
| IPVS(推荐) | IPVS 内核模块 | 最好(内核态,O(1) 哈希查找) | rr / lc / sh 等多种 | 1000+ Service |
3.2 iptables 模式(Kind 默认)
每增加一个 Service + 后端 Pod 组合,kube-proxy 就往 iptables 里写规则:
1 | |
规律:N 个后端 → N 条规则串成链,匹配是 O(n) 的。所以 iptables 模式下 Service + Pod 多了之后规则爆炸,影响性能。
3.3 IPVS 模式
IPVS 是 Linux 内核的传输层负载均衡模块(LVS 项目的核心)。kube-proxy 在 IPVS 模式下创建一个虚拟服务 + 多个真实后端,哈希 O(1) 查找,支持多种调度算法:
| 算法缩写 | 全称 | 含义 |
|---|---|---|
| rr | Round Robin | 轮询 |
| lc | Least Connection | 最少连接数 |
| sh | Source Hashing | 源地址哈希(同一客户端固定到同一后端) |
生产环境 Service 超过 100 个就应考虑切 IPVS。但 Kind 环境 iptables 完全够用。
3.4 为什么理解这个有用?
- 排障时:Pod 明明活着但 Service 访问不通 → 可能是本地 iptables 规则没更新
- 性能调优:大规模集群 iptables 规则爆炸 → 切 IPVS
- 你访问 ClusterIP,包不会经过 kube-proxy 进程——它在控制面写规则,数据面是内核
四、Endpoints:Service 和 Pod 之间的”动态电话本”
4.1 Endpoints 是什么
Endpoints 是一个 API 对象,记录”当前匹配 Service selector 的所有 Pod IP + 端口”。它不是转发路径中的一跳,而是 kube-proxy 用来生成转发规则的数据源。
1 | |
4.2 Endpoints vs EndpointSlice
| 对象 | 版本 | 特点 |
|---|---|---|
| Endpoints | 老 | 单个对象存所有后端 IP,后端超多时对象过大,更新慢 |
| EndpointSlice | 新(1.21 GA) | 每个 Service 拆成多个 Slice(每个最多 100 条),增量更新 |
新集群默认用 EndpointSlice,kubectl get endpoints 看到的其实是 EndpointSlice 的汇总视图。
4.3 没了 selector 的 Service(手动 Endpoints)
可以不写 selector,自己手动建 Endpoints:
1 | |
这时候 kube-proxy 照常生成转发规则,把流量发到 192.168.1.100:3306——给集群外资源起了一个集群内 DNS 名字。
五、DNS 服务发现:CoreDNS 的解析链路
5.1 整体架构
1 | |
5.2 Pod 的 /etc/resolv.conf 长什么样
1 | |
search 域就是为什么同 namespace 内只用写 my-nginx-svc 而不是完整 FQDN——系统自动拼接后缀逐个尝试。
5.3 完整 FQDN 结构
1 | |
5.4 同 namespace vs 跨 namespace
| 场景 | 写法 | 原因 |
|---|---|---|
| 同 namespace | my-nginx-svc |
search 域自动补全 |
| 跨 namespace | my-nginx-svc.production |
需指定 namespace |
| 跨 namespace 完整 | my-nginx-svc.production.svc.cluster.local |
显式全路径 |
5.5 DNS 缓存与 TTL
每次查询的 TTL 默认 30 秒。Service 的 ClusterIP 是不变的,所以即使后端 Pod 全换了,缓存也是有效的——真正变化的 Endpoints 由 kube-proxy 管,不是 DNS 管。
六、三种 Service 类型的数据流全景
6.1 流量路径对比
1 | |
NodePort 的本质是:在每台节点的 iptables 里加一条规则,把 节点IP:31234 的流量 DNAT 到 ClusterIP:80,后续和 ClusterIP 一模一样。
6.2 哪种场景用哪种
| 类型 | 使用场景 | 原因 |
|---|---|---|
| ClusterIP | 集群内微服务互调(前端→后端→数据库) | 不暴露到集群外,安全,默认选择 |
| NodePort | 开发测试临时对外,云 LB 的后端 | 简单,但端口范围受限(30000-32767) |
| LoadBalancer | 生产对外暴露 HTTP/HTTPS | 自动化配置云 LB + 公网 IP + 健康检查 |
七、Kind 环境下的网络真相
7.1 Kind 的节点是 Docker 容器
真实集群:节点 = 物理机/虚拟机 → NodePort 直接在宿主机网络栈上监听端口。
Kind 集群:节点 = Docker 容器 → NodePort 端口开在容器内部,宿主机默认看不到。
1 | |
7.2 三种解法
| 办法 | 原理 | 何时用 |
|---|---|---|
kubectl port-forward svc/xxx 8080:80 --address 0.0.0.0 |
kubectl 在宿主机起代理,通过 API server 隧道转发 | 临时测试,最快 |
extraPortMappings 建集群时配置 |
建 Kind 集群时在容器上做 -p 31234:31234 |
建集群时就确定要用 NodePort |
| NodePort 不用,直接用 Ingress | Ingress Controller 通过 hostPort/hostNetwork 对外暴露 80/443 | 生产方式,第五章讲 |
kubectl port-forward 是开发测试最方便的方式,它的转发路径和真实 NodePort 不同(走 API server 隧道),但效果相同。
八、Service、Endpoints、kube-proxy 三者协作全貌
把前面各节串起来,一张图:
1 | |
数据面(你的请求包经过的):iptables 规则 → Pod
控制面(配置如何生效的):API Server → Endpoints Controller / kube-proxy → 更新 iptables
九、常见误区纠正
| 误区 | 真相 |
|---|---|
| “ClusterIP 是一个虚拟网卡” | 不是,仅存在于 iptables/IPVS 规则中,ip addr 看不到 |
| “Service 是代理,流量经过它” | 不是,K8s Service 无进程,是内核规则转发(DNAT) |
| “kube-proxy 转发每个请求” | 不对,kube-proxy 只写规则,不参与数据面转发 |
| “NodePort 在 Kind 里直接能用” | 不能,因为 Kind 节点是 Docker 容器,宿主机看不到容器端口 |
| “Service 用 DNS 做负载均衡” | DNS 只做名字解析(返回 ClusterIP),负载均衡靠 iptables/IPVS |
| “删掉 Service 后 Pod 也受影响” | 不受影响,Service 只是 Pod 前面的入口,删 Service 不影响 Pod 运行 |
| “Endpoints 变化需要等 DNS 缓存过期” | 不需要,DNS 只到 ClusterIP(不变的),Endpoints 变化由 kube-proxy 实时更新 |
十、与主章节的对照关系
| 主章节 | 本辅助讲义对应内容 |
|---|---|
| 3.1 Pod 网络困境 | 第二节:ClusterIP 是什么 |
| 3.2 Service 靠 label 关联 Pod | 第四节:Endpoints 机制 |
| 3.3 三种 Service 类型 | 第六节:三种类型数据流全景 |
| 3.4 ClusterIP 实操 | 第三节:kube-proxy 三种转发模式 |
| 3.5 NodePort | 第七节:Kind 环境 NodePort 真相 |
| 3.6 DNS 服务发现 | 第五节:CoreDNS 解析链路 |
| 3.7 章节练习 | 全文作为练习时的参考答案 |
本章核心认知回顾
1 | |