Kubernetes

kube-proxy 流量转发与代理模式详解

·7 分钟阅读·2752 字
📋 目录

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 模式(默认原生模式)

工作逻辑

  1. kube-proxy watch apiserver,同步 Service、EndpointSlice 数据
  2. 在本机内核 iptables 的 nat 链生成两级规则:
    • SVC 链:匹配 Service 的 ClusterIP+端口,随机跳转至某个 SEP 子链
    • SEP 链:对应单个后端 Pod,做 DNAT 将目标 IP 改为 PodIP
  3. 流量经过内核 netfilter 自动匹配规则,全程内核转发
特性说明
负载均衡算法仅支持随机(random)
性能Service >5000 时链式规则过长,性能衰减
规则刷新Pod 增删全链刷新,开销高

3. IPVS 模式(生产推荐)

工作逻辑

  1. 调用 IPVS 内核接口,创建虚拟服务 VS(ClusterIP:port),绑定多个真实 RS(PodIP:port)
  2. iptables 仅保留少量规则处理 SNAT、端口映射
  3. 流量命中 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 之间的加密长隧道。

核心特点

  1. 单 TCP 多路复用:一条连接里同时跑多条数据流
  2. 全链路 TLS 加密:kubectl→APIServer→kubelet 全程加密
  3. 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 解析

关联文档