kube-proxy 流量转发与代理模式详解
📖 kube-proxy 工作原理
kube-proxy 并不”智能判断”,它通过监听 K8s 的 Service + EndpointSlice,实时把”虚拟IP → 后端 PodIP 列表”同步到本机内核规则。
完整工作流程
1. kube-apiserver 是信息中心
所有 Service、Pod、Endpoint 存在 ETCD,由 apiserver 暴露
2. kube-proxy 启动后长连接监听 apiserver
只监听 2 类资源变化:
- Service → 知道 ClusterIP、端口
- EndpointSlice / Endpoints → 知道每个 Service 对应的后端 Pod IP + 端口
3. 拿到信息后翻译成节点内核规则
iptables 模式:生成 KUBE-SVC / KUBE-SEP 链规则
IPVS 模式:创建 Virtual Server + Real Server 映射
4. 流量转发时 kube-proxy 不参与
内核 netfilter 直接匹配规则 → 选择 PodIP → DNAT 转发
EndpointSlice 是什么?
它就是 Service 的后端 Pod 通讯录:
Service: my-service
ClusterIP: 10.96.1.1
Port: 80
Endpoints:
- 10.244.1.5:80 (PodA)
- 10.244.1.6:80 (PodB)
⚡ 三种代理模式对比
1. userspace 模式(废弃淘汰)
- 在节点创建监听端口,iptables 把访问 ClusterIP 的流量 DNAT 转发至 kube-proxy 进程
- kube-proxy 在用户态收到报文后转发
- 缺点:用户态转发,报文多次拷贝,性能极差,新版本默认关闭
2. iptables 模式(默认原生模式)
工作逻辑:
- kube-proxy watch apiserver,同步 Service、EndpointSlice 数据
- 在本机内核 iptables 的 nat 链生成两级规则:
- SVC 链:匹配 Service 的 ClusterIP+端口,随机跳转至某个 SEP 子链
- SEP 链:对应单个后端 Pod,做 DNAT 将目标 IP 改为 PodIP
- 流量经过内核 netfilter 自动匹配规则,全程内核转发
| 特性 | 说明 |
|---|---|
| 负载均衡算法 | 仅支持随机(random) |
| 性能 | Service >5000 时链式规则过长,性能衰减 |
| 规则刷新 | Pod 增删全链刷新,开销高 |
3. IPVS 模式(生产推荐)
工作逻辑:
- 调用 IPVS 内核接口,创建虚拟服务 VS(ClusterIP:port),绑定多个真实 RS(PodIP:port)
- iptables 仅保留少量规则处理 SNAT、端口映射
- 流量命中 VS 后由内核 IPVS 模块自主调度转发
内置调度算法:
| 算法 | 说明 |
|---|---|
| rr | 轮询(默认) |
| lc | 最小连接数 |
| sh | 源地址哈希(实现会话粘滞) |
| dh | 目标地址哈希 |
优势:
- 规则为哈希表结构,海量 Service 查询性能稳定
- 算法丰富,性能远优于 iptables
- 后端 Pod 变更只修改单个 RS 条目,无需全量刷新
4. eBPF 模式(新一代,Cilium/Calico 实现)
- 脱离 iptables、ipvs,eBPF 程序挂载在内核网络钩子点
- CNI 组件监听 Service/Endpoint 变化,动态下发 eBPF 转发逻辑
- 内核直接执行 BPF 程序完成四层负载均衡、DNAT、网络策略
🔧 会话保持实现
Service 原生 ClientIP(四层)
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
- iptables 模式:依靠 conntrack 记录源 IP→Pod 映射
- IPVS 模式:自动切换 sh(源地址哈希)调度算法
Nginx Ingress Cookie(七层,生产推荐)
metadata:
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "ROUTEID"
生产选型
| 场景 | 方案 |
|---|---|
| HTTP 网站业务 | Nginx Ingress Cookie |
| TCP 长连接/数据库 | Service ClientIP |
| 公网入口 + 云 LB | 云厂商 SLB 会话保持 |
| 微服务 Istio 架构 | DestinationRule 一致性哈希 |
⚙️ SPDY 与 socat(kubectl port-forward 底层原理)
SPDY(跨机器加密隧道)
SPDY 是 HTTP/2 的前身,K8s 用来做 kubectl ↔ APIServer ↔ kubelet 之间的加密长隧道。
核心特点:
- 单 TCP 多路复用:一条连接里同时跑多条数据流
- 全链路 TLS 加密:kubectl→APIServer→kubelet 全程加密
- HTTP CONNECT 升级:不走 kube-proxy、不走集群四层网络
socat(本地数据流转发)
socat 在目标节点本机运行,打通宿主机和 Pod 网络命名空间。
port-forward 完整链路:
本地浏览器 → kubectl(本地端口监听)
→ SPDY(跨机器加密隧道)
→ APIServer
→ SPDY(跨机器加密隧道)
→ 目标节点 kubelet
→ socat + nsenter(进入 Pod netns)
→ Pod 容器端口
一句话区分
- SPDY:跨机器、远距离、加密隧道(外网/跨节点传输)
- socat:本机、本地、跨命名空间端口搭桥(节点内部进容器)
关联文档
- ../service/K8s Service 核心原理 — Service 基础与类型
- K8s 组件详解#kube-proxy — kube-proxy 组件功能
- ../../network/technology/eBPF 技术详解 — eBPF 模式底层技术
- ../service/K8s Service DNS 实现原理 — CoreDNS 解析
关联文档