Skip to content

澄清:Kubernetes Service 不是 iptables 虚拟出来的 namespace

目标读者:Kubernetes 初学者、运维、后端研发
文档版本:v1.0


一句话结论

不是。 Kubernetes Service 不是 iptables 虚拟出来的 namespace,也不是 iptables 创建的虚拟网卡或网络设备。Service 只是 Kubernetes API 中的一个声明式对象,真正转发流量的是内核中的 Netfilter/iptables 规则


目录

  1. 常见误解
  2. Service 到底是什么
  3. iptables 在这里扮演什么角色
  4. Linux network namespace vs iptables chain
  5. ClusterIP 不是真实 IP
  6. 数据包如何被转发
  7. 验证方法
  8. 总结

第1章 常见误解

误解一:"每个 Service 是 iptables 虚拟出来的一个 namespace"

错误。 iptables 不会为每个 Service 创建 namespace。iptables 创建的是规则链(chain)规则(rule),不是网络命名空间。

误解二:"ClusterIP 是 iptables 创建的虚拟网卡 IP"

错误。 ClusterIP 不是任何网卡上的 IP 地址。它只是一个逻辑地址,存在于 iptables/ipvs 规则的匹配条件中。

误解三:"Service 端口有进程在监听"

错误。 没有任何进程监听 ClusterIP:port。Pod 中监听的是容器自己的 targetPort


第2章 Service 到底是什么

2.1 Service 是 Kubernetes API 对象

Service 是存储在 etcd 中的资源定义:

yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080

它声明了:

  • 我想为一组 Pod 提供一个统一的访问入口
  • 这个入口的 IP 是 ClusterIP
  • 这个入口的端口是 80
  • 后端 Pod 的标签是 app=web
  • 后端容器实际监听 8080

2.2 Service 本身不处理流量

Service 只是元数据,类似数据库中的一条记录。它不运行任何进程,不创建任何网络设备。

2.3 谁把 Service 变成可工作的网络规则

三个组件协作:

组件作用
EndpointSlice Controller根据 selector 找到 Pod,生成 EndpointSlice
kube-proxy监听 Service 和 EndpointSlice,生成 iptables/ipvs 规则
Linux 内核 Netfilter数据包到达时,按规则直接转发

第3章 iptables 在这里扮演什么角色

3.1 iptables 创建的是规则链,不是 namespace

当 kube-proxy 使用 iptables 模式时,它会创建:

KUBE-SERVICES      # 一个链,匹配所有 Service

  ├─ KUBE-SVC-XXX  # 某个 Service 的链
  │     │
  │     ├─ KUBE-SEP-AAA  # 后端 Pod 1 的规则
  │     └─ KUBE-SEP-BBB  # 后端 Pod 2 的规则

  └─ KUBE-NODEPORTS  # NodePort 规则链

这些都是 iptables 规则链(chain),不是 Linux network namespace。

3.2 iptables chain 是什么

iptables chain 是规则的集合。数据包进入某条链后,会按顺序匹配链中的规则。

可以这样理解:

概念类比
iptables table(表)图书馆
iptables chain(链)书架
iptables rule(规则)书架上的书

3.3 不是 namespace 的证据

bash
# 查看 Linux network namespace
ip netns list

# 你不会看到 KUBE-SVC-XXX 或 Service 名称
bash
# 查看网卡
ip addr show

# 你不会看到 ClusterIP 绑定在任何网卡上
bash
# 查看 iptables 链
iptables -t nat -L -n -v

# 你会看到 KUBE-SERVICES、KUBE-SVC-XXX、KUBE-SEP-XXX 等链

第4章 Linux network namespace vs iptables chain

4.1 Linux network namespace 是什么

Linux network namespace 是内核提供的网络隔离机制:

  • 每个 namespace 有独立的网络栈
  • 独立的网卡、路由表、iptables 规则、socket
  • Pod 就是运行在独立的 network namespace 中
Host Network Namespace
├─ eth0, lo, docker0
├─ iptables 规则
└─ routing table

Pod Network Namespace
├─ eth0, lo
├─ 独立的 iptables 规则(通常为空)
└─ 独立的路由表

4.2 iptables chain 是什么

iptables chain 是 iptables 内部组织规则的方式,不是隔离机制:

  • 存在于某个 network namespace 内
  • 同一个 namespace 内的所有进程共享这些规则
  • 用于决定数据包如何被处理

4.3 关键区别

特性Linux network namespaceiptables chain
作用网络隔离规则组织
是否独立网络栈
是否有独立网卡
Pod 是否使用
Service 是否对应否(Service 对应规则)

第5章 ClusterIP 不是真实 IP

5.1 ClusterIP 没有绑定到任何网卡

bash
# 在节点上查看所有 IP
ip addr show

# 你不会看到 10.96.123.45 这个 IP

5.2 ClusterIP 只是 iptables 规则中的匹配条件

bash
iptables -t nat -L KUBE-SERVICES -n -v

输出示例:

Chain KUBE-SERVICES (2 references)
 target     prot opt source    destination
KUBE-SVC-ABC123  tcp  --  0.0.0.0/0  10.96.123.45    /* default/web-service:http cluster IP */ tcp dpt:80

含义:当数据包的目的 IP 是 10.96.123.45 且目的端口是 80 时,跳转到 KUBE-SVC-ABC123 链。

5.3 为什么 ping ClusterIP 不通

因为 ClusterIP 不是真实 IP,没有进程监听 ICMP:

bash
ping 10.96.123.45
# 通常无响应或不可达

只有访问 ClusterIP:port 时,iptables 规则才会匹配并转发。


第6章 数据包如何被转发

6.1 完整流程

Pod A 发起请求

    │ curl http://10.96.123.45:80

Pod A 所在节点内核


PREROUTING / OUTPUT 链


KUBE-SERVICES 链


匹配到目的 10.96.123.45:80


KUBE-SVC-ABC123 链


按概率选择 KUBE-SEP-XXX


DNAT 到 Pod IP:targetPort


通过 CNI 网络转发到后端 Pod

6.2 与 namespace 的关系

  • Pod A 在自己的 network namespace 中发出数据包
  • 数据包进入宿主机 network namespace
  • 宿主机 network namespace 中的 iptables 规则处理数据包
  • 没有任何 Service 对应的 network namespace 被创建

第7章 验证方法

7.1 验证 ClusterIP 不在网卡上

bash
# 在任意节点执行
ip addr show | grep 10.96.123.45
# 无输出

7.2 验证没有 Service namespace

bash
ip netns list
# 看不到 Service 名称

7.3 验证 iptables 规则存在

bash
# 查看 Service 对应的链
kubectl get svc web-service

# 假设 ClusterIP 是 10.96.123.45
iptables -t nat -L KUBE-SERVICES -n -v | grep 10.96.123.45

# 查看具体 Service 链
iptables -t nat -L -n -v | grep KUBE-SVC | grep 10.96.123.45

7.4 验证流量转发

bash
# 在 Pod A 内多次访问 Service
kubectl exec -it pod-a -- sh
for i in $(seq 1 10); do curl -s http://10.96.123.45; done

# 观察后端 Pod 日志
kubectl logs pod-backend-1
kubectl logs pod-backend-2

第8章 总结

8.1 正确认知

问题正确答案
Service 是 iptables 虚拟出来的 namespace 吗?不是
Service 是什么?Kubernetes API 对象,声明式配置
iptables 创建了什么?规则链(chain)和规则(rule)
ClusterIP 是什么?iptables/ipvs 规则中的匹配条件
谁真正转发流量?Linux 内核 Netfilter/iptables
流量转发经过 Service 进程吗?不经过

8.2 形象类比

可以把 Service 理解为:

  • 餐厅菜单上的菜名(Service 名称)
  • 菜名后面标注的厨房窗口号(ClusterIP)
  • 厨房窗口并不真实存在(ClusterIP 不是真实 IP)
  • 服务员(iptables)看到菜名后,把订单转给真正的厨师(Pod)

iptables 是"服务员的规则手册",不是"餐厅的分店(namespace)"。

8.3 最终结论

Service 不是网络命名空间,不是虚拟网卡,不是 iptables 虚拟出来的任何东西。 它只是一个 Kubernetes 资源对象,由 kube-proxy 根据它的定义生成内核转发规则,实现流量的负载均衡和后端选择。


第9章 延伸:ipvs 模式下 Service 是否创建虚拟设备?

9.1 ipvs 模式也不创建虚拟网卡

与 iptables 模式类似,ipvs 模式下:

  • ClusterIP 仍然不是任何网卡上的 IP
  • Service 仍然不对应任何 namespace 或虚拟设备
  • ipvs 使用的是内核中的 IPVS virtual server,不是网卡

9.2 ipvs virtual server 是什么

ipvs virtual server 是内核 IPVS 模块中的数据结构:

ipvs virtual server: 10.96.123.45:80
  ├── real server: 10.244.1.10:8080
  └── real server: 10.244.1.11:8080

你可以通过 ipvsadm -Ln 看到它,但它不是网卡,也不是 namespace。

9.3 ipvs 与网卡的区别

特性网卡 / 虚拟网卡ipvs virtual server
是否有 MAC 地址
是否存在于 ip addr
是否收发物理帧
是否存在协议栈钩子
是否对应 Service

9.4 为什么 ipvs 不需要网卡

ipvs 工作在内核 Netfilter 框架中,通过 LOCAL_IN / FORWARD 钩子拦截数据包:

数据包进入内核


PREROUTING


路由决策


LOCAL_IN(目标为本机)


ipvs 钩子匹配 virtual server


DNAT 到 real server

ipvs 只需要知道目的 IP:port 匹配 virtual server,不需要这个 IP 绑定在网卡上。

9.5 验证 ipvs 模式

bash
# 查看 ipvs 虚拟服务
ipvsadm -Ln

# 输出示例
# TCP  10.96.123.45:80 rr
#   -> 10.244.1.10:8080             Masq    1
#   -> 10.244.1.11:8080             Masq    1

# 确认 ClusterIP 不在网卡上
ip addr show | grep 10.96.123.45
# 无输出

# 确认没有 Service namespace
ip netns list
# 无 Service 名称

第10章 延伸:为什么 kube-proxy 不能用纯 namespace 实现 Service?

10.1 假设用 namespace 实现 Service

如果每个 Service 对应一个 namespace,需要:

  1. 为每个 Service 创建一个独立的 network namespace
  2. 在这个 namespace 中创建虚拟网卡并绑定 ClusterIP
  3. 运行一个代理进程监听这个 IP 的端口
  4. 将流量转发到后端 Pod
Service A namespace
  ├─ veth-a1: 10.96.123.45
  ├─ proxy process 监听 10.96.123.45:80
  └─ 转发到 Pod A-1, Pod A-2

Service B namespace
  ├─ veth-b1: 10.96.124.45
  ├─ proxy process 监听 10.96.124.45:80
  └─ 转发到 Pod B-1, Pod B-2

10.2 这种方式的问题

问题说明
资源开销巨大每个 Service 都需要一个 namespace、网卡、进程
扩展性差Service 数量多时,系统资源耗尽
性能差用户态代理增加上下文切换
管理复杂namespace 间路由、veth pair 管理困难
实时性差Pod 变化时,代理进程需要重新配置

10.3 实际方案的优势

Kubernetes 实际使用 声明式对象 + 内核态规则

Service (API 对象)


EndpointSlice (API 对象)


kube-proxy (用户态配置工具)


iptables / ipvs (内核态转发)

优势:

  • 无额外进程:数据包在内核态直接转发
  • 无额外 namespace:不需要为 Service 创建隔离
  • 无虚拟网卡:ClusterIP 只是规则匹配条件
  • 高性能:内核态处理,接近原生网络性能
  • 易扩展:新增 Service 只需增加规则,不增加进程

10.4 namespace 的适用场景

Linux network namespace 适合:

  • Pod 隔离(每个 Pod 一个 namespace)
  • 容器网络隔离
  • 网络测试和仿真

不适合:

  • 大规模 Service 负载均衡
  • 频繁的 Service 增删改

10.5 核心设计思想

Kubernetes Service 的设计思想是:

用内核已有的网络框架(Netfilter/ipvs)实现负载均衡,而不是在用户态创建大量代理。

这体现了云原生设计的核心原则:

  • 声明式:用户声明意图,系统生成规则
  • 无代理 sidecar 化基础设施:核心网络功能下沉到内核
  • 高性能:避免用户态/内核态切换

第11章 终极总结

11.1 三个关键事实

  1. Service 不是 namespace
  2. Service 不是虚拟网卡
  3. Service 不是 iptables/ipvs 创建的虚拟设备

11.2 Service 到底是什么

Service 是:

  • Kubernetes API 对象
  • 一段 YAML 配置
  • 描述了一组 Pod 的访问方式

本身不处理任何流量

11.3 流量如何到达 Pod

用户访问 Service


DNS 解析为 ClusterIP


数据包目的 IP = ClusterIP


内核中的 iptables/ipvs 规则匹配 ClusterIP


负载均衡选择后端 Pod


DNAT 到 Pod IP:targetPort


Pod 处理请求

11.4 学习建议

理解 Kubernetes Service 的关键是:

  1. 不要把 Service 想象成物理或虚拟设备
  2. 理解 Netfilter/iptables/ipvs 在内核中的作用
  3. 掌握 iptables -L -n -vipvsadm -Lnconntrack -L 等命令
  4. 多观察集群中的实际规则

文档生成时间:2026-07-18更新时间:2026-07-18(补充 ipvs 与 namespace 实现章节)