kube-proxy

Kubernetes kube-proxy 代码结构 #

仓库地址: cmd/kube-proxypkg/proxy


整体代码布局 #

kubernetes/
├── cmd/kube-proxy/                          # 入口:二进制启动命令
│   ├── proxy.go                             # main() 入口
│   └── app/                                 # 应用初始化、配置解析
│       ├── server.go                        # ProxyServer 启动核心(NewProxyCommand → Run)
│       ├── server_linux.go                  # Linux 特定启动逻辑
│       ├── server_other.go                  # 非 Linux 平台启动逻辑
│       ├── server_windows.go                # Windows 特定启动逻辑
│       ├── options.go                       # 命令行选项解析(KubeProxyConfiguration)
│       ├── init_linux.go                    # Linux 初始化(加载内核模块)
│       ├── init_other.go                    # 非 Linux 平台初始化
│       └── init_windows.go                  # Windows 平台初始化
│
└── pkg/proxy/                               # 核心实现
    │
    ├── types.go                             # Provider 接口 + ProxyServer 主结构体
    ├── endpoint.go                          # Endpoint 抽象(IP/Port/Protocol)
    ├── serviceport.go                       # ServicePort 抽象(Service 端口映射)
    ├── node.go                               # 节点信息管理
    ├── topology.go                          # 拓扑感知路由(Topology Aware Hints)
    │
    ├── servicechangetracker.go              # Service 变更跟踪器(diff 计算)
    ├── endpointschangetracker.go            # EndpointSlice 变更跟踪器
    ├── endpointslicecache.go                 # EndpointSlice 本地缓存
    │
    ├── apis/                                # KubeProxyConfiguration API 定义
    ├── config/                              # 配置文件解析(config.conf)
    ├── conntrack/                           # Conntrack(连接跟踪)管理
    ├── healthcheck/                         # 服务健康检查器
    ├── metrics/                             # Prometheus 指标
    ├── runner/                              # 通用规则同步 Runner
    ├── util/                                # 工具函数
    ├── kubemark/                            # 性能测试用假 Proxier
    ├── metaproxier/                        # MetaProxier(多模式组合)
    ├── localnodeportproxy/                  # 本地 NodePort 代理
    │
    ├── iptables/                            # iptables 模式实现
    │   ├── proxier.go                       # Proxier 主结构体 + Sync() + 同步规则
    │   ├── cleanup.go                       # 旧规则清理
    │   └── doc.go                           # iptables 模式文档
    │
    ├── ipvs/                                # IPVS 模式实现
    │   ├── proxier.go                       # Proxier 主结构体 + Sync()
    │   ├── ipvs.go                          # IPVS 内核接口封装
    │   ├── graceful_termination.go          # 优雅终止(Zero-downtime)
    │   ├── graceful_termination_manager.go  # 优雅终止管理器
    │   ├── netlink_linux.go                 # Netlink 系统调用
    │   ├── server.go                        # IPVS Server 封装
    │   └── strict_arp.go                   # ARP 严格模式
    │
    ├── nftables/                            # nftables 模式实现(v1.29+ Alpha)
    │   ├── proxier.go                       # Proxier 主结构体
    │   ├── cleanup.go                       # 旧规则清理
    │   └── doc.go                           # nftables 模式文档
    │
    └── winkernel/                           # Windows 内核模式实现
        └── proxier.go                       # Windows Proxier

核心概念 #

kube-proxy 是什么 #

kube-proxy 是运行在每个节点上的网络代理,负责实现 Kubernetes Service 抽象:

客户端 Pod → ClusterIP:Port(虚拟 IP)
                 ↓
     ┌──── kube-proxy 配置的内核规则 ────┐
     │                                    │
     │  iptables / IPVS / nftables 规则    │
     │  DNAT: ClusterIP → Pod IP           │
     └────────────────────────────────────┘
                 ↓
           后端 Pod IP:targetPort

关键特性

特性说明
非转发型代理不在用户态转发数据包,而是配置内核规则(iptables/IPVS/nftables)
每节点运行以 DaemonSet 方式部署,每个节点一个实例
Watch 模式监听 API Server 的 Service 和 EndpointSlice 变更
幂等操作规则同步是幂等的,重复执行不会产生副作用

代理模式(Proxy Mode) #

kube-proxy 支持四种代理模式,通过 --proxy-mode 参数选择:

模式状态原理性能适用场景
iptables默认iptables DNAT 规则中(O(n) 规则匹配)通用
IPVSStableIPVS 内核模块 + iptables 辅助高(O(1) 哈希查找)大规模集群
nftablesAlpha(v1.29+)nftables API高(改进的数据结构)新内核环境
userspace已废弃用户态进程转发旧版本兼容

模式对比 #

         userspace          iptables            IPVS              nftables
         (已废弃)           (默认)              (推荐)            (未来)

数据路径: 用户态转发        内核 DNAT           内核 DNAT           内核 DNAT
转发方式: 进程监听端口      iptables 规则      IPVS 负载均衡        nftables 规则
LB 算法:  轮询              随机                RR/LC/DH/SH/SED     随机
规则规模:  N               O(N) 链             O(1) 查找           优化查找
内核依赖:  无               iptables            ip_vs 模块          nf_tables 模块

iptables 模式(默认) #

工作原理 #

iptables 模式通过在 nat 表中创建规则链来实现 Service 路由:

nat 表
├── PREROUTING    → KUBE-SERVICES     # 入站流量入口
├── OUTPUT        → KUBE-SERVICES     # 本机出站流量入口
├── POSTROUTING   → KUBE-POSTROUTING  # SNAT/Masquerade
│
├── KUBE-SERVICES              # Service 分发链
│   ├── DNAT → KUBE-SVC-XXXX   # 匹配 ClusterIP:Port
│   ├── DNAT → KUBE-SVC-YYYY
│   └── REJECT                 # 无后端的 Service
│
├── KUBE-SVC-XXXX              # Service 链(负载均衡)
│   ├── --mode random → KUBE-SEP-AAAA  # 50% 概率
│   └── → KUBE-SEP-BBBB                # 50% 概率
│
├── KUBE-SEP-AAAA              # Endpoint 链(DNAT)
│   └── DNAT → 10.244.1.3:8080
│
└── KUBE-POSTROUTING           # Masquerade 链
    └── MASQUERADE  (SNAT)

iptables 规则示例 #

# 查看所有 kube-proxy 生成的规则
iptables-save | grep KUBE

# 查看 Service 链
iptables -t nat -L KUBE-SERVICES -n -v

# 查看某个 Service 的负载均衡规则
iptables -t nat -L KUBE-SVC-XXXX -n -v

# 查看某个 Endpoint 的 DNAT 规则
iptables -t nat -L KUBE-SEP-AAAA -n -v

随机负载均衡机制 #

iptables 模式使用 --mode random + --probability 实现负载均衡:

# 3 个 Endpoint 的 Service,概率分配:
KUBE-SVC-XXXX:
  - --mode random --probability 0.333 → KUBE-SEP-AAAA   # 1/3
  - --mode random --probability 0.500 → KUBE-SEP-BBBB   # 剩余 2/3 的 1/2 = 1/3
  - → KUBE-SEP-CCCC                                     # 剩余 = 1/3

注意:概率是累积的,不是独立的。规则按顺序匹配,前一个不命中才走下一个。

性能特点 #

维度表现
规则数量每 Service 约生成 8 条规则 × N 个 Endpoint
查找复杂度O(n) 线性遍历规则链
适用规模数百 Service
性能瓶颈数千 Service 时规则同步耗时显著增加

IPVS 模式(推荐) #

工作原理 #

IPVS 模式使用 Linux 内核的 IP Virtual Server 模块实现 L4 负载均衡:

IPVS 数据结构:
├── IPVS Service(虚拟服务)
│   ├── VIP:Port + Protocol
│   ├── Scheduler 调度算法
│   └── Real Servers(后端列表)
│       ├── Pod IP1:Port
│       ├── Pod IP2:Port
│       └── Pod IP3:Port
│
└── iptables(仅用于 Masquerade 和 NodePort 特殊处理)

IPVS 调度算法 #

算法说明适用场景
rr (Round Robin)轮询(默认)通用
lc (Least Connection)最少连接数长连接
dh (Destination Hashing)目标地址哈希缓存代理
sh (Source Hashing)源地址哈希会话亲和性
sed (Shortest Expected Delay)最短期望延迟性能不均
nq (Never Queue)永不排队避免空闲

前置条件 #

# 1. 确认 IPVS 内核模块已加载
lsmod | grep ip_vs

# 2. 手动加载所需模块(kube-proxy 也会自动加载)
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh

# 3. 检查 IPVS 规则
ipvsadm -L -n

IPVS 规则示例 #

# 查看所有 IPVS 规则
ipvsadm -L -n

# 输出示例:
# Prot LocalAddress:Port Scheduler -> Backend
# TCP  10.96.0.1:443 rr -> 172.20.0.2:6443
# TCP  10.96.0.10:53 rr -> 10.244.0.3:53
#                          -> 10.244.0.4:53
# TCP  10.96.100.1:80 rr -> 10.244.1.3:8080
#                          -> 10.244.2.3:8080

何时 IPVS 回退到 iptables #

IPVS 模式下仍需要 iptables 处理以下场景:

场景原因
Masquerade(SNAT)IPVS 不支持 SNAT,需 iptables POSTROUTING
NodePort + externalTrafficPolicy=Local需 iptables 过滤非本地 Endpoint
Hairpin(回环流量)Pod 访问自身 Service 的 SNAT
LoadBalancerSourceRanges源 IP 白名单过滤

性能特点 #

维度表现
规则数量每 Service 1 个 IPVS Service + N 个 Real Server
查找复杂度O(1) 哈希表查找
适用规模数千 Service
规则同步增量更新,无需全量重写

nftables 模式(Alpha) #

v1.29 引入,作为 iptables 的继任者。通过 nftables API 配置内核 netfilter 子系统。

设计动机 #

iptables 的问题nftables 的改进
规则链线性扫描使用集合(set)和映射(map)优化查找
全量替换规则(replace)增量更新规则(add/delete)
多表分散管理统一 nftables 表管理
IPv4/IPv6 分离原生支持 IPv4/IPv6 一体化

Netfilter Hook 使用 #

kube-proxy 在 nftables 中使用 7 个功能:

1. DNAT(prerouting + output)    # ClusterIP → Pod IP
2. SNAT(postrouting)             # Masquerade
3. Drop(filter)                  # LoadBalancerSourceRanges 过滤
4. Drop(filter)                  # Local 策略 + 无本地 Endpoint
5. Reject(filter)                # 无任何 Endpoint 的 Service
6. Drop(forward + output)        # 未分配的 ClusterIP
7. Reject(filter)                # 未定义的 ClusterIP 端口

集成注意事项 #

第三方网络组件(CNI、Service Mesh)与 nftables 模式交互时:

  • 各组件应使用独立的 nftables 表,不修改 kube-proxy 的表
  • 通过**优先级(priority)**控制规则执行顺序
  • DNAT 发生在 priority dstnat,SNAT 发生在 priority srcnat

启动流程 #

main()  [cmd/kube-proxy/proxy.go]
  └── NewProxyCommand()  [app/server.go]
        └── command.Run()
              ├── config.Complete()        # 补全配置
              ├── ApplyConfiguration()     # 应用运行时配置
              ├── createProxier()          # 根据模式创建 Proxier
              │     ├── iptables.NewProxier()
              │     ├── ipvs.NewProxier()
              │     ├── nftables.NewProxier()
              │     └── winkernel.NewProxier()
              │
              ├── SetupSignalHandler()    # 信号处理
              └── proxyServer.Run()
                    │
                    ├── 启动 Informer
                    │     ├── ServiceInformer.Run()
                    │     └── EndpointSliceInformer.Run()
                    │
                    ├── 启动 Proxier 同步循环
                    │     └── SyncLoop()
                    │           ├── 事件触发 → syncProxyRules()
                    │           └── 定时触发 → syncProxyRules()
                    │                 ├── 读取 Service/Endpoint 缓存
                    │                 ├── 计算规则 diff
                    │                 └── 调用 Proxier.Sync()
                    │                       ├── iptables: iptables-restore
                    │                       ├── ipvs: ipvs + iptables-restore
                    │                       └── nftables: nft 命令
                    │
                    └── 启动 Healthz Server
                          └── /healthz  → 探针检查

Service & EndpointSlice Watch 机制 #

变更跟踪 #

┌────────────┐   Watch    ┌──────────────┐   事件    ┌───────────────────────┐
│ API Server │ ─────────→ │  Informer    │ ────────→ │  ChangeTracker        │
│            │            │ (本地缓存)    │           │  (ServiceChangeTracker │
│ Service    │            │              │           │   EndpointChangeTracker)│
│ Endpoint   │            │              │           │                       │
│ Slice      │            │              │           │  计算 diff → 触发 Sync │
└────────────┘            └──────────────┘           └───────────────────────┘
                                                            │
                                                            ↓
                                                      ┌──────────┐
                                                      │ Proxier  │
                                                      │ .Sync()  │
                                                      └──────────┘

ServiceChangeTracker #

servicechangetracker.go 记录 Service 增删改:

// 核心数据结构
type ServiceChangeTracker struct {
    mu         sync.Mutex           // 并发保护
    items      map[types.NamespacedName]*serviceChange
    // serviceChange 记录了变更前后的 Service 信息
    // Sync 时按变更计算 iptables/IPVS 规则 diff
}

EndpointSliceChangeTracker #

endpointschangetracker.go 记录 EndpointSlice 增删改:

// 现代 kube-proxy 监听 EndpointSlice(而非 Endpoints)
// 因为 EndpointSlice 更适合大规模端点场景
// 一个 Service 可对应多个 EndpointSlice

定时同步 #

即使没有事件触发,kube-proxy 也会定时全量同步规则:

参数默认值说明
--sync-period60siptables/IPVS 规则全量同步间隔
--iptables-min-sync-period1siptables 最小同步间隔
--ipvs-min-sync-period1sIPVS 最小同步间隔

配置文件 #

kube-proxy 使用 YAML 配置文件(/var/lib/kube-proxy/config.conf):

apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration

# 代理模式:iptables / ipvs / nftables / userspace
mode: "iptables"

# 同步周期
iptables:
  masqueradeAll: false              # 是否对所有流量 SNAT
  masqueradeBit: 14                  # Mark 位
  minSyncPeriod: 1s                  # 最小同步间隔
  syncPeriod: 30s                    # 同步周期
  localhostNodePorts: true          # 允许回环访问 NodePort

ipvs:
  scheduler: "rr"                   # 调度算法
  excludeCIDRs: []                  # 排除的 CIDR
  minSyncPeriod: 1s
  syncPeriod: 30s
  strictARP: false                  # 严格 ARP 模式
  tcpTimeout: 0s                    # TCP 连接超时
  tcpFinTimeout: 0s                 # TCP FIN 超时
  udpTimeout: 0s                    # UDP 超时

nftables:
  masqueradeAll: false
  minSyncPeriod: 1s
  syncPeriod: 30s

# 连接跟踪
conntrack:
  maxPerCore: 32768                 # 每核心最大连接数
  min: 131072                       # 最小连接表大小
  tcpCloseWaitTimeout: 1h0m0s
  tcpEstablishedTimeout: 8h0m0s

# 节点信息
clientConnection:
  kubeconfig: /var/lib/kube-proxy/kubeconfig.conf

clusterCIDR: "10.244.0.0/16"        # Pod CIDR(用于 masquerade)
hostnameOverride: "node-1"           # 节点名覆盖

# NodePort 监听地址
nodePortAddresses: []               # 空=所有地址

# Feature Gates
featureGates:
  GRPCContainerProbe: true

Metrics(监控指标) #

核心指标 #

指标类型说明
sync_proxy_rules_countCounter规则同步总次数
sync_proxy_rules_latency_msHistogram规则同步耗时
sync_proxy_rules_last_timestamp_secondsGauge最近同步时间
endpoint_slice_cache_countGauge缓存的 EndpointSlice 数
service_cache_countGauge缓存的 Service 数
iptables_rules_totalGaugeiptables 规则总数
network_programming_duration_secondsHistogramService 编程延迟

PromQL 示例 #

# 规则同步延迟 P99
histogram_quantile(0.99, rate(sync_proxy_rules_latency_ms_bucket[5m]))

# Service 编程延迟(Service 创建到规则生效)
histogram_quantile(0.99, rate(network_programming_duration_seconds_bucket[5m]))

# 同步失败率
rate(sync_proxy_rules_count{result="failed"}[5m])

调试与排查 #

查看 kube-proxy 状态 #

# 查看 kube-proxy 日志
kubectl logs -n kube-system kube-proxy-xxxx

# 查看 kube-proxy 配置
cat /var/lib/kube-proxy/config.conf

# 确认运行模式
kubectl logs -n kube-system kube-proxy-xxxx | grep "proxy-mode"

iptables 模式排查 #

# 查看完整规则
iptables-save | grep -E "KUBE"

# 查看 Service 分发链
iptables -t nat -L KUBE-SERVICES -n -v --line-numbers

# 追踪某个 ClusterIP 的规则链
CLUSTER_IP=10.96.0.1
iptables -t nat -L -n -v | grep $CLUSTER_IP

# 统计 kube-proxy 规则数量
iptables-save | grep -c "KUBE"

IPVS 模式排查 #

# 查看 IPVS 规则
ipvsadm -L -n

# 查看特定 Service
ipvsadm -L -n -t 10.96.0.1:443

# 查看连接统计
ipvsadm -L -n --stats

# 确认内核模块
lsmod | grep -E "ip_vs|nf_conntrack"

# 查看 conntrack 表
conntrack -L | grep <ClusterIP>

常见问题 #

问题原因排查
Service 不通规则未同步检查 iptables-save | grep KUBEipvsadm -L
延迟高iptables 规则过多切换到 IPVS 模式
Pod 无法访问 ClusterIPmasquerade 未配置检查 --masquerade-all 或 clusterCIDR
NodePort 不通绑定地址限制检查 nodePortAddresses 配置
连接重置conntrack 表满调整 conntrack.maxPerCore
IPVS 模式启动失败内核模块缺失modprobe ip_vs

iptables vs IPVS vs nftables vs eBPF 选型 #

维度iptablesIPVSnftableseBPF(Cilium)
规则匹配O(n) 线性扫描O(1) 哈希查找O(1) 集合/映射查找O(1) 哈希映射(XDP/TC)
LB 算法随机(random)RR/LC/DH/SH/SED/NQ 等 10+ 种同 iptables(随机为主)Maglev/随机/自定义
规则更新全量替换(iptables-restore)增量更新(ipvsadm)增量更新(原子操作)增量更新(Map 热更新)
规模上限~1000 Service~10000+ Service~10000+ Service~10000+ Service
Masquerade原生支持仍需 iptables 辅助原生支持由 datapath 处理
会话亲和性recent 模块SH 调度算法原生支持Maglev 一致性哈希
内核依赖iptables(通用)ip_vs 模块(需加载)nft 内核模块(≥3.13)BPF 子系统(≥4.18)
kube-proxy 状态默认模式GAAlpha(v1.29+)非 kube-proxy(替代方案)
推荐场景小型集群、通用中大型集群、生产环境新内核环境、未来方向大规模集群、高性能网络

选型建议

集群规模 < 500 Service         → iptables(默认,零依赖)
集群规模 ≥ 500 Service         → IPVS(性能更优)
新内核 5.10+ 环境              → 关注 nftables(未来方向)
大规模集群 + Cilium/高性能网络  → eBPF(绕过 kube-proxy,极致性能)

与其他组件的关系 #

                    ┌─────────────────┐
                    │  API Server     │
                    │  (Service/      │
                    │   EndpointSlice) │
                    └───────┬─────────┘
                            │ Watch
                    ┌───────┴─────────┐
                    │  kube-proxy     │
                    │  (每节点一个)    │
                    │                 │
            ┌───────┤  配置内核规则    ├───────┐
            │       └─────────────────┘       │
            ↓                                   ↓
  ┌──────────────────┐              ┌──────────────────┐
  │  iptables/IPVS   │              │  CoreDNS          │
  │  (DNAT 规则)      │              │  (Service 名称解析)│
  └──────────────────┘              └──────────────────┘
            │                                   │
            ↓                                   ↓
  ┌──────────────────────────────────────────────────────┐
  │                    Pod                               │
  │  访问 my-svc → DNS 解析 → ClusterIP → DNAT → Pod IP  │
  └──────────────────────────────────────────────────────┘
组件与 kube-proxy 的关系
CoreDNS解析 Service 名 → ClusterIP,kube-proxy 负责路由 ClusterIP → Pod IP
kubeletkubelet 管理 Pod 生命周期,Endpoint Controller 据此更新 EndpointSlice
Endpoint Controller维护 EndpointSlice,kube-proxy Watch 后更新规则
CNI 插件提供 Pod 网络连通性,kube-proxy 提供 Service 层路由
kube-apiserver提供 Service/EndpointSlice 的 Watch 接口

Reference #