跳转至

IPVS 深入理解与 Kubernetes Service 转发实践

这篇文章解决什么问题

在 Kubernetes 集群里,kube-proxy 常见有两种工作模式:

  • iptables
  • ipvs

如果你使用的是阿里云 ACK 托管版集群或 ACK Edge 边缘集群,并且确认 kube-proxy 模式都是 ipvs,那就说明 Service 转发不是简单依赖一堆 iptables DNAT 规则完成,而是主要交给 Linux 内核里的 IPVS 模块完成。

这篇文章重点回答:

  • IPVS 是什么
  • IPVS 和 LVS 是什么关系
  • IPVS 为什么比 iptables 更适合大规模 Service
  • kube-proxy IPVS 模式到底做了什么
  • ClusterIP、NodePort 在 IPVS 模式下怎么转发
  • 为什么 IPVS 模式下仍然能看到 iptables 规则
  • IPVS 常见调度算法有哪些
  • 如何排查 Kubernetes Service 转发问题
  • ACK / ACK Edge 都使用 IPVS 时,运维上应该关注什么

IPVS 是什么

IPVS 全称是 IP Virtual Server

它是 Linux 内核中的四层负载均衡能力,属于 LVS 项目的核心组成部分。

一句话解释:

IPVS 是 Linux 内核里专门用于四层负载均衡的模块,可以根据虚拟服务地址把流量转发到多个真实后端。

典型结构是:

Client
  |
  | 访问 VIP:Port
  v
IPVS Virtual Server
  |
  | 按调度算法选择后端
  v
Real Server 1 / Real Server 2 / Real Server 3

在 Kubernetes 里,可以把它类比成:

Client / Pod
  |
  | 访问 Service ClusterIP:Port
  v
IPVS Virtual Server
  |
  | 选择一个 Endpoint
  v
Pod IP:Port

所以,IPVS 并不是 Kubernetes 专属组件。它本来就是 Linux 内核里的负载均衡能力,只是 Kubernetes 的 kube-proxy 可以利用它来实现 Service 转发。

IPVS 和 LVS 的关系

LVS 全称是 Linux Virtual Server,是 Linux 上经典的四层负载均衡方案。

IPVS 是 LVS 在内核里的核心转发模块。

可以这样理解:

LVS:整套 Linux 四层负载均衡方案
IPVS:LVS 的内核转发模块
ipvsadm:管理 IPVS 规则的用户态命令

常见命令:

ipvsadm -Ln
ipvsadm -Ln --stats
ipvsadm -Ln --rate

Kubernetes 的 kube-proxy IPVS 模式,本质上就是:

watch Service / EndpointSlice
  |
生成 IPVS virtual server 和 real server
  |
由 Linux 内核 IPVS 负责四层转发

为什么 Kubernetes 会使用 IPVS

早期 Kubernetes Service 转发主要依赖 iptables。

iptables 模式的问题是:当 Service 和 Endpoint 数量很多时,规则数量会快速膨胀。

例如:

1000 个 Service
每个 Service 10 个 Endpoint

iptables 需要维护大量链和规则。每次 Service 或 Endpoint 变化,kube-proxy 都要重新计算并同步规则。

IPVS 的优势在于:

  • 专门为四层负载均衡设计
  • 内核态查找效率更高
  • 支持成熟的负载均衡算法
  • Service 数量多时性能更稳定
  • Endpoint 频繁变化时规则维护压力相对更小

简单说:

iptables:通用包过滤和 NAT 工具,能做 Service 转发
IPVS:专门的四层负载均衡模块,更适合大规模 Service 转发

kube-proxy 负责什么

在 Kubernetes 里,kube-proxy 不是 CNI。

它主要负责 Service 转发。

它会监听:

  • Service
  • EndpointSlice
  • Node

然后在每个节点上维护本地转发规则。

在 IPVS 模式下,kube-proxy 主要做三件事:

  1. 创建 IPVS Virtual Server
  2. 把后端 Pod Endpoint 加为 Real Server
  3. 配合 iptables、ipset、路由和 dummy 网卡完成 Service 流量接入

IPVS 模式下的核心对象

Virtual Server

Virtual Server 是虚拟服务。

在 Kubernetes 里,它通常对应一个 Service IP + Port。

例如:

Service: nginx
ClusterIP: 10.96.12.34
Port: 80

对应 IPVS 里可能看到:

TCP  10.96.12.34:80 rr

意思是:

访问 10.96.12.34:80 的流量,由 IPVS 按 rr 算法转发

Real Server

Real Server 是真实后端。

在 Kubernetes 里,它通常对应 Pod IP + Container Port。

例如:

Pod 1: 10.244.1.21:80
Pod 2: 10.244.2.33:80

在 IPVS 里可能看到:

-> 10.244.1.21:80 Masq 1 0 0
-> 10.244.2.33:80 Masq 1 0 0

这表示 Service 流量可以被转发到这两个后端 Pod。

Scheduler

Scheduler 是 IPVS 的调度算法。

比如:

rr
wrr
lc
wlc
sh

Kubernetes 默认常见是 rr,也就是 round-robin 轮询。

kube-ipvs0 是什么

在 Kubernetes IPVS 模式下,节点上通常会有一个 dummy 网卡:

ip addr show kube-ipvs0

你会看到很多 Service IP 被绑定在这个接口上。

例如:

kube-ipvs0:
  10.96.0.1/32
  10.96.12.34/32
  10.96.200.10/32

它的作用可以理解为:

让本节点认为这些 ClusterIP 是本机可接收的地址,从而把访问 Service IP 的流量引入本机网络栈,再交给 IPVS 处理。

ClusterIP 本身不是某台真实机器的物理 IP。它是一个虚拟 IP。

在 IPVS 模式下,kube-proxy 会把这些虚拟 IP 绑到 kube-ipvs0,让内核能够接住访问 ClusterIP 的流量。

Service ClusterIP 转发过程

假设有一个 Service:

Service: nginx
ClusterIP: 10.96.12.34
Port: 80
Endpoints:
  10.244.1.21:80
  10.244.2.33:80

Pod A 访问:

curl http://10.96.12.34

IPVS 模式下的大致过程:

Pod A
  |
  | 访问 10.96.12.34:80
  v
Node 网络栈接收流量
  |
  | 10.96.12.34 绑定在 kube-ipvs0
  v
IPVS 匹配 Virtual Server
  |
  | 根据调度算法选择 Endpoint
  v
Real Server: 10.244.2.33:80
  |
  | 交给 CNI 网络转发
  v
Pod B

这里要注意:

IPVS 负责 Service IP -> Pod IP
CNI 负责 Pod IP 怎么跨节点可达

所以在 ACK 托管版集群里:

Terway 负责 Pod 网络
IPVS 负责 Service 转发

在 ACK Edge 集群里:

Flannel 负责 Pod 网络
IPVS 负责 Service 转发

这就是为什么两个集群 CNI 不同,但 kube-proxy 模式可以都是 IPVS。

NodePort 转发过程

NodePort 是把 Service 暴露到每个节点的某个端口。

例如:

NodeIP: 192.168.1.10
NodePort: 30080
Service: 10.96.12.34:80

访问:

curl http://192.168.1.10:30080

大致过程:

Client
  |
  | 访问 NodeIP:30080
  v
节点 iptables 规则捕获 NodePort 流量
  |
  v
进入 IPVS Virtual Server
  |
  | 选择一个 Real Server
  v
Pod IP:80

这里能看出一个关键点:

IPVS 模式不是完全不使用 iptables。

NodePort、Masquerade、转发入口、特殊流量处理等场景仍然会依赖一部分 iptables 规则。

为什么 IPVS 模式下还有 iptables 规则

很多人会误以为:

kube-proxy IPVS 模式 = 节点上没有 iptables 规则

这是错的。

更准确地说:

IPVS 负责核心负载均衡
iptables 负责辅助流量捕获、标记、SNAT/Masquerade 等

比如:

  • NodePort 流量入口
  • ExternalIP
  • LoadBalancer 类型 Service 的入口处理
  • SNAT/Masquerade
  • hairpin 场景
  • localhost 访问 Service 的特殊处理
  • 防火墙标记

所以排查时,看到 KUBE-SERVICESKUBE-NODEPORTSKUBE-MARK-MASQ 这类 iptables 链,并不代表 kube-proxy 是 iptables 模式。

判断 kube-proxy 模式,应该看配置:

kubectl -n kube-system get cm kube-proxy -o jsonpath='{.data.config\.conf}' | grep '^mode:'

或者看 kube-proxy 启动日志。

IPVS 常见调度算法

IPVS 支持多种调度算法。

rr

rr 是 round-robin,轮询。

请求按顺序分配给后端。

Pod 1 -> Pod 2 -> Pod 3 -> Pod 1

简单、常用,Kubernetes 默认常见就是它。

wrr

wrr 是 weighted round-robin,加权轮询。

适合后端能力不同的场景。

例如:

Pod A weight 5
Pod B weight 1

Pod A 会分到更多请求。

lc

lc 是 least-connection,最少连接。

优先把新连接分配给当前连接数更少的后端。

适合长连接比较多的场景。

wlc

wlc 是 weighted least-connection,加权最少连接。

同时考虑连接数和权重。

sh

sh 是 source hashing,源地址哈希。

同一个源地址倾向于转发到同一个后端。

适合需要一定会话粘性的场景。

不过在 Kubernetes 里,如果真的需要会话保持,通常还要结合 Service 的 sessionAffinity 或上层网关能力一起看。

IPVS 的转发模式

传统 LVS/IPVS 有几种经典转发模式:

  • NAT
  • DR
  • TUN

Kubernetes kube-proxy IPVS 模式主要使用类似 NAT/Masquerade 的方式,把 Service 流量转发到后端 Pod。

ipvsadm -Ln 输出里,你经常会看到:

Masq

例如:

TCP  10.96.12.34:80 rr
  -> 10.244.1.21:80 Masq 1 0 0
  -> 10.244.2.33:80 Masq 1 0 0

这里的 Masq 可以理解为 IPVS 的 NAT 转发方式。

和 iptables 模式相比有什么优势

规则规模更可控

iptables 模式下,Service 和 Endpoint 越多,规则越多。

IPVS 模式下,Service 和 Endpoint 会进入 IPVS 表,查找更适合大规模场景。

转发性能更稳定

IPVS 是专门做四层负载均衡的内核模块。

在 Service 数量多、Endpoint 数量多、变更频繁的场景里,IPVS 通常比大量 iptables 规则更稳定。

支持更多调度算法

iptables 模式的负载均衡能力相对简单。

IPVS 支持 rr、wrr、lc、wlc、sh 等成熟算法。

更接近传统负载均衡模型

对于熟悉 LVS 的运维来说,IPVS 模式非常直观:

Virtual Server -> Real Server

这比在大量 iptables 链里追 DNAT 规则更容易建立 mental model。

IPVS 模式也不是银弹

IPVS 解决的是 Service 转发效率问题,但不解决所有网络问题。

它不负责:

  • Pod IP 分配
  • Pod 跨节点网络可达
  • CNI Overlay/BGP/eBPF 转发路径
  • DNS 解析
  • Ingress 七层路由
  • 应用连接池和超时策略

所以 Service 不通时,要拆开看:

Service 是否存在
EndpointSlice 是否正常
kube-proxy 是否同步 IPVS 规则
IPVS 是否选到了后端 Pod
CNI 是否能把流量送到目标 Pod
回程路由是否正常

Kubernetes 里如何确认 IPVS 模式

查看 kube-proxy ConfigMap

kubectl -n kube-system get cm kube-proxy -o jsonpath='{.data.config\.conf}' | grep '^mode:'

输出:

mode: ipvs

说明 kube-proxy 使用 IPVS 模式。

查看 kube-proxy 日志

kubectl -n kube-system logs -l k8s-app=kube-proxy --tail=100 | grep -Ei 'ipvs|proxier|proxy mode'

可能看到类似:

Using ipvs Proxier

查看节点 IPVS 规则

需要进入节点执行:

ipvsadm -Ln

也可以看统计:

ipvsadm -Ln --stats
ipvsadm -Ln --rate

查看 kube-ipvs0

ip addr show kube-ipvs0

如果是 IPVS 模式,通常可以看到很多 Service IP 绑定在这个接口上。

查看内核模块

lsmod | grep '^ip_vs'

常见模块:

ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack

Service 不通排查路径

假设一个 Service 访问不通。

第一步:看 Service 和 Endpoint

kubectl get svc -n <ns>
kubectl describe svc <svc-name> -n <ns>
kubectl get endpointslice -n <ns> -l kubernetes.io/service-name=<svc-name>

重点确认:

  • ClusterIP 是否正确
  • Port / TargetPort 是否正确
  • Endpoint 是否存在
  • Endpoint IP 是否是预期 Pod
  • Pod readiness 是否正常

如果 Endpoint 为空,问题不在 IPVS,而在 Service selector、Pod label 或 readiness。

第二步:看 IPVS 是否生成规则

在节点上执行:

ipvsadm -Ln | grep -A5 '<cluster-ip>'

如果没有对应 Virtual Server,检查:

  • kube-proxy 是否运行
  • kube-proxy 是否能访问 apiserver
  • kube-proxy 日志是否有同步失败
  • ConfigMap 是否正确

第三步:看后端 Real Server

如果有 Virtual Server,但没有 Real Server,说明 Service 有,但后端没有同步进去。

继续查:

  • EndpointSlice 是否存在
  • Pod 是否 Ready
  • kube-proxy 是否有权限 watch EndpointSlice
  • kube-proxy 日志是否报错

第四步:看 CNI 网络是否通

如果 IPVS 规则正常,但访问 Pod IP 不通,就要查 CNI。

ping <pod-ip>
curl http://<pod-ip>:<port>
ip route get <pod-ip>

ACK 托管版 Terway 场景要关注:

  • Pod ENI / 弹性网卡模式
  • 安全组规则
  • Pod 与节点网络路由
  • VPC 路由和策略

ACK Edge Flannel 场景要关注:

  • Flannel Pod 是否正常
  • VXLAN 设备是否正常
  • 节点间 UDP 8472 是否连通
  • MTU 是否合适
  • 边缘节点到云端或其他边缘节点链路是否稳定

第五步:看 SNAT 和回程

有时请求能到后端 Pod,但响应回不去。

重点查:

  • externalTrafficPolicy
  • internalTrafficPolicy
  • Masquerade 规则
  • Pod 到客户端的回程路由
  • 安全组、防火墙、边缘网络 NAT

ACK 托管版和 ACK Edge 都是 IPVS,意味着什么

如果你确认:

ACK 托管版 + Terway -> kube-proxy: ipvs
ACK Edge + Flannel  -> kube-proxy: ipvs

可以得出几个结论。

Service 转发模型相同

两者在 kube-proxy 层面都使用:

Service IP -> IPVS Virtual Server -> Pod Endpoint

所以你排查 ClusterIP、NodePort、EndpointSlice、kube-proxy 同步问题时,思路基本一致。

Pod 网络模型不同

真正不同的是 CNI 层。

ACK 托管版 Terway:

Pod 网络更贴近阿里云 VPC / ENI / 弹性网卡模型

ACK Edge Flannel:

Pod 网络通常依赖 Flannel Overlay,例如 VXLAN

所以当 Service 已经正确转到某个 Pod IP 后,后续 Pod 网络可达性问题要按不同 CNI 排查。

性能瓶颈位置可能不同

IPVS 本身通常不是最先出现瓶颈的地方。

更常见的瓶颈可能在:

  • CNI Overlay 封装和 MTU
  • 边缘网络链路质量
  • 安全组/ACL
  • Pod 所在节点资源
  • 应用连接池和超时
  • DNS 解析
  • 跨地域网络延迟

运维命令可以统一一部分

两个集群都可以使用类似命令:

kubectl -n kube-system get cm kube-proxy -o yaml
kubectl -n kube-system logs -l k8s-app=kube-proxy
ipvsadm -Ln
ipvsadm -Ln --stats
ip addr show kube-ipvs0

但 CNI 层命令和排障入口不同。

IPVS 常见问题

ipvsadm 看不到 Service

可能原因:

  • kube-proxy 没运行
  • kube-proxy 不是 IPVS 模式
  • kube-proxy 访问 apiserver 异常
  • Service 没有创建成功
  • 节点上 IPVS 模块异常

Service 有 IPVS 规则,但没有后端

可能原因:

  • Pod 没 Ready
  • Service selector 匹配不到 Pod
  • EndpointSlice 没生成
  • TargetPort 配错
  • kube-proxy 同步延迟或异常

有后端,但访问超时

可能原因:

  • CNI 跨节点不通
  • Pod 端口没监听
  • NetworkPolicy 拦截
  • 安全组/防火墙拦截
  • 回程路由异常
  • MTU 导致大包异常

NodePort 不通,但 ClusterIP 正常

可能原因:

  • 节点安全组没放行 NodePort
  • externalTrafficPolicy 配置影响转发
  • 访问的节点没有可用本地 Endpoint
  • iptables 辅助规则异常
  • 云厂商负载均衡或边缘网络入口没打通

面试里怎么讲 IPVS

可以这样回答:

IPVS 是 Linux 内核里的四层负载均衡模块,也是 LVS 的核心能力。Kubernetes 里 kube-proxy 可以使用 IPVS 模式实现 Service 转发,它会监听 Service 和 EndpointSlice,把 ClusterIP:Port 创建成 IPVS Virtual Server,把后端 Pod IP:Port 创建成 Real Server,再由内核 IPVS 根据调度算法做转发。

和 iptables 模式相比,IPVS 更适合 Service 和 Endpoint 数量较多的集群,规则查找和同步更稳定,也支持 rr、wrr、lc、sh 等调度算法。但 IPVS 模式并不是完全不用 iptables,NodePort、Masquerade、流量标记等辅助逻辑仍然会用到 iptables。

在 ACK 托管版 Terway 和 ACK Edge Flannel 都使用 IPVS 的情况下,Service 转发层模型基本一致,差异主要在 CNI 层:Terway 负责云上 Pod 网络,Flannel 负责边缘集群 Overlay 网络。排障时我会先看 Service/EndpointSlice,再看 ipvsadm 规则,最后按对应 CNI 查 Pod 网络可达性。

总结

IPVS 是 Kubernetes Service 转发链路里的关键能力之一。

它的核心价值是:

  • 把 Service IP 抽象成内核四层 Virtual Server
  • 把 Pod Endpoint 抽象成 Real Server
  • 用成熟的调度算法完成负载均衡
  • 在大规模 Service/Endpoint 场景下比纯 iptables 模式更稳定

但要记住:

IPVS 解决 Service 转发
CNI 解决 Pod 网络
DNS 解决服务名解析
Ingress/Gateway 解决七层入口

ACK 托管版和 ACK Edge 都使用 IPVS,只说明它们在 Service 转发层采用相同模式;真正的网络差异仍然要回到 Terway 和 Flannel 的 Pod 网络实现上去分析。