Kubernetes-05-Kube Proxy-概览
模块职责
kube-proxy 是运行在每个节点上的网络代理,负责实现 Kubernetes Service 的网络规则。它将访问 Service 的流量负载均衡到后端 Pod。
核心职责
-
Service 负载均衡
- 监听 Service 和 Endpoints/EndpointSlice 变化
- 生成网络规则(iptables/IPVS/nftables)
- 将 Service ClusterIP/NodePort 流量转发到 Pod IP
-
三种代理模式
- iptables 模式:使用 iptables 规则(默认模式)
- IPVS 模式:使用 IPVS 负载均衡(高性能)
- nftables 模式:使用 nftables 规则(新一代防火墙)
-
NodePort 和 LoadBalancer 支持
- 在节点上监听 NodePort 端口
- 将外部流量转发到 Pod
三种代理模式对比
| 特性 | iptables | IPVS | nftables |
|---|---|---|---|
| 性能 | 中(线性查找) | 高(哈希表) | 高 |
| 负载均衡算法 | 随机 | 多种(RR/LC/DH/SH/SED/NQ) | 随机 |
| 规则数量 | O(n)(n=Service 数) | O(1)(虚拟服务器) | O(n) |
| 内核支持 | 通用 | 需加载 IPVS 模块 | Linux 3.13+ |
| 适用场景 | 小规模集群(< 1000 Service) | 大规模集群 | 新一代替代 iptables |
iptables 模式架构
flowchart LR
CLIENT[Client] --> CLUSTERIP[Service ClusterIP<br/>10.96.0.1:80]
CLUSTERIP --> KUBE_SVC[KUBE-SVC-XXX Chain]
KUBE_SVC --> KUBE_SEP1[KUBE-SEP-XXX Chain<br/>Pod-1: 10.244.1.5:8080]
KUBE_SVC --> KUBE_SEP2[KUBE-SEP-YYY Chain<br/>Pod-2: 10.244.2.6:8080]
KUBE_SVC --> KUBE_SEP3[KUBE-SEP-ZZZ Chain<br/>Pod-3: 10.244.3.7:8080]
style KUBE_SVC fill:#FF6B6B,color:#fff
style KUBE_SEP1 fill:#4ECDC4,color:#fff
iptables 规则示例
# Service 规则(KUBE-SERVICES chain)
-A KUBE-SERVICES -d 10.96.0.1/32 -p tcp -m tcp --dport 80 -j KUBE-SVC-NGINX
# 负载均衡规则(KUBE-SVC-NGINX chain)
-A KUBE-SVC-NGINX -m statistic --mode random --probability 0.33333 -j KUBE-SEP-POD1
-A KUBE-SVC-NGINX -m statistic --mode random --probability 0.50000 -j KUBE-SEP-POD2
-A KUBE-SVC-NGINX -j KUBE-SEP-POD3
# Endpoint 规则(KUBE-SEP-POD1 chain)
-A KUBE-SEP-POD1 -p tcp -m tcp -j DNAT --to-destination 10.244.1.5:8080
IPVS 模式架构
flowchart LR
CLIENT[Client] --> VS[Virtual Server<br/>10.96.0.1:80]
VS --> RS1[Real Server<br/>10.244.1.5:8080]
VS --> RS2[Real Server<br/>10.244.2.6:8080]
VS --> RS3[Real Server<br/>10.244.3.7:8080]
style VS fill:#FF6B6B,color:#fff
style RS1 fill:#4ECDC4,color:#fff
IPVS 配置示例
# 查看 IPVS 规则
ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.96.0.1:80 rr
-> 10.244.1.5:8080 Masq 1 0 0
-> 10.244.2.6:8080 Masq 1 0 0
-> 10.244.3.7:8080 Masq 1 0 0
核心代码片段
规则同步流程
// pkg/proxy/iptables/proxier.go
func (proxier *Proxier) syncProxyRules() {
// 1. 获取所有 Service 和 Endpoints
services := proxier.serviceMap
endpoints := proxier.endpointsMap
// 2. 生成 iptables 规则
for _, svc := range services {
for _, endpoint := range endpoints[svc.Name()] {
// 创建 KUBE-SEP chain
proxier.natRules.Write(
"-A", sepChain,
"-p", protocol,
"-m", protocol,
"-j", "DNAT",
"--to-destination", endpoint.String(),
)
}
// 创建 KUBE-SVC chain(负载均衡)
n := len(endpoints[svc.Name()])
for i, endpoint := range endpoints[svc.Name()] {
prob := 1.0 / float64(n-i)
proxier.natRules.Write(
"-A", svcChain,
"-m", "statistic",
"--mode", "random",
"--probability", fmt.Sprintf("%.5f", prob),
"-j", sepChain,
)
}
}
// 3. 应用 iptables 规则
proxier.iptables.RestoreAll(proxier.natRules.Bytes(), NoFlushTables, RestoreCounters)
}
最佳实践
1. 选择合适的代理模式
iptables 模式
- 适用于小规模集群(< 1000 Service)
- 无需额外配置
IPVS 模式
- 适用于大规模集群(> 1000 Service)
- 需加载 IPVS 内核模块:
modprobe ip_vs
2. 性能调优
IPVS 模式配置
mode: ipvs
ipvs:
scheduler: rr # 轮询算法
strictARP: true # 严格 ARP(用于 MetalLB)
Kubernetes-05-Kube Proxy-时序图
时序图概述
本文档提供 Kube-Proxy 的核心场景时序图:
- Service 创建与规则同步流程
- Client 访问 Service 的数据包转发流程
场景 1:Service 创建与规则同步流程
sequenceDiagram
autonumber
participant U as User (kubectl)
participant API as API Server
participant EP as Endpoints Controller
participant KP as Kube-Proxy
participant IPT as iptables/IPVS
Note over U,IPT: 场景:用户创建 Service 和 Deployment
U->>API: POST /api/v1/services<br/>{name: "nginx", clusterIP: "10.96.0.1", port: 80}
API-->>U: 201 Created
U->>API: POST /apis/apps/v1/deployments<br/>{replicas: 3, selector: {app: nginx}}
API-->>U: 201 Created
Note over API,EP: Endpoints Controller 监听 Service 和 Pod
API->>EP: Watch Event: Service/nginx (ADDED)
API->>EP: Watch Event: Pod/nginx-1 (ADDED, Ready=true)
API->>EP: Watch Event: Pod/nginx-2 (ADDED, Ready=true)
API->>EP: Watch Event: Pod/nginx-3 (ADDED, Ready=true)
EP->>API: POST /api/v1/endpoints<br/>{<br/> name: "nginx",<br/> subsets: [{<br/> addresses: [<br/> {ip: "10.244.1.5"},<br/> {ip: "10.244.2.6"},<br/> {ip: "10.244.3.7"}<br/> ],<br/> ports: [{port: 8080}]<br/> }]<br/>}
API-->>EP: 201 Created
Note over API,KP: Kube-Proxy 监听 Service 和 Endpoints
API->>KP: Watch Event: Service/nginx (ADDED)
KP->>KP: serviceMap.Update(service)
API->>KP: Watch Event: Endpoints/nginx (ADDED)
KP->>KP: endpointsMap.Update(endpoints)
KP->>KP: 标记需要同步规则<br/>(needFullSync = true)
Note over KP,IPT: syncProxyRules(定时触发,默认每秒)
KP->>KP: syncProxyRules()
alt iptables 模式
KP->>KP: 生成 iptables 规则<br/>- KUBE-SERVICES chain<br/>- KUBE-SVC-NGINX chain<br/>- KUBE-SEP chains
KP->>IPT: iptables-restore < rules.txt
IPT->>IPT: 原子替换规则
IPT-->>KP: Success
else IPVS 模式
KP->>IPT: ip addr add 10.96.0.1 dev kube-ipvs0
KP->>IPT: ipvsadm -A -t 10.96.0.1:80 -s rr
IPT-->>KP: Virtual Server created
loop 遍历所有 Endpoints
KP->>IPT: ipvsadm -a -t 10.96.0.1:80 -r 10.244.1.5:8080 -m -w 1
KP->>IPT: ipvsadm -a -t 10.96.0.1:80 -r 10.244.2.6:8080 -m -w 1
KP->>IPT: ipvsadm -a -t 10.96.0.1:80 -r 10.244.3.7:8080 -m -w 1
end
end
Note over KP: 规则同步完成
要点说明
1. 规则同步时机
- 定时同步:每秒检查一次(
syncPeriod=1s) - 事件驱动:Service/Endpoints 变化时立即标记需要同步
- 最小同步间隔:避免频繁更新(
minSyncPeriod=100ms)
2. iptables 原子更新
# iptables-restore 原子替换所有规则
iptables-save > /tmp/iptables.old
iptables-restore --noflush < /tmp/iptables.new
场景 2:Client 访问 Service 的数据包转发流程
iptables 模式
sequenceDiagram
autonumber
participant C as Client Pod<br/>(10.244.1.10)
participant IPT as iptables (PREROUTING)
participant SVC as KUBE-SVC-NGINX
participant SEP as KUBE-SEP chains
participant POD as Backend Pod<br/>(10.244.2.6:8080)
Note over C,POD: 场景:Client 访问 Service ClusterIP
C->>IPT: TCP SYN<br/>src: 10.244.1.10:54321<br/>dst: 10.96.0.1:80
IPT->>IPT: 匹配 KUBE-SERVICES chain<br/>-d 10.96.0.1/32 --dport 80 -j KUBE-SVC-NGINX
IPT->>SVC: 进入 KUBE-SVC-NGINX chain
SVC->>SVC: 概率选择 Endpoint<br/>- probability 0.33333 → EP1<br/>- probability 0.50000 → EP2<br/>- 兜底 → EP3<br/><br/>假设选中 EP2
SVC->>SEP: 跳转到 KUBE-SEP-EP2
SEP->>SEP: DNAT<br/>dst: 10.96.0.1:80 → 10.244.2.6:8080
SEP->>POD: TCP SYN<br/>src: 10.244.1.10:54321<br/>dst: 10.244.2.6:8080
POD-->>SEP: TCP SYN-ACK<br/>src: 10.244.2.6:8080<br/>dst: 10.244.1.10:54321
SEP->>SEP: 反向 NAT(连接跟踪)<br/>src: 10.244.2.6:8080 → 10.96.0.1:80
SEP-->>C: TCP SYN-ACK<br/>src: 10.96.0.1:80<br/>dst: 10.244.1.10:54321
Note over C,POD: 建立 TCP 连接,开始传输数据
IPVS 模式
sequenceDiagram
autonumber
participant C as Client Pod<br/>(10.244.1.10)
participant IPVS as IPVS (kube-ipvs0)
participant POD as Backend Pod<br/>(10.244.2.6:8080)
Note over C,POD: 场景:Client 访问 Service ClusterIP
C->>IPVS: TCP SYN<br/>src: 10.244.1.10:54321<br/>dst: 10.96.0.1:80
IPVS->>IPVS: 查找 Virtual Server<br/>10.96.0.1:80 (存在)
IPVS->>IPVS: 根据调度算法选择 Real Server<br/>- 算法:rr(Round Robin)<br/>- 候选:10.244.1.5, 10.244.2.6, 10.244.3.7<br/>- 选中:10.244.2.6:8080
IPVS->>IPVS: DNAT<br/>dst: 10.96.0.1:80 → 10.244.2.6:8080
IPVS->>POD: TCP SYN<br/>src: 10.244.1.10:54321<br/>dst: 10.244.2.6:8080
POD-->>IPVS: TCP SYN-ACK
IPVS->>IPVS: 反向 NAT(连接跟踪)
IPVS-->>C: TCP SYN-ACK<br/>src: 10.96.0.1:80
要点说明
1. 连接跟踪(Connection Tracking)
- Linux Netfilter 的 conntrack 模块记录连接状态
- 返回数据包自动执行反向 NAT(无需额外规则)
2. IPVS vs iptables 性能对比
| 指标 | iptables | IPVS |
|---|---|---|
| 规则匹配 | 线性查找(逐条匹配) | 哈希表查找 |
| 延迟 | 0.5-1ms | 0.05-0.1ms |
| CPU 占用 | 高(规则多时) | 低 |
| 适用规模 | < 1000 Service | > 10000 Service |
性能指标
关键指标
| 指标 | 类型 | 说明 |
|---|---|---|
kubeproxy_sync_proxy_rules_duration_seconds |
Histogram | 规则同步延迟 |
kubeproxy_sync_proxy_rules_last_timestamp_seconds |
Gauge | 最后同步时间 |
kubeproxy_network_programming_duration_seconds |
Histogram | 网络编程延迟 |
Kubernetes-05-Kube Proxy-数据结构
数据结构概述
Kube-Proxy 的核心数据结构围绕 Service 和 Endpoints 映射 设计:
- ServiceMap:Service 的缓存
- EndpointsMap:Endpoints 的缓存
- Proxier:代理器(生成规则)
核心数据结构 UML 图
classDiagram
class Proxier {
+ServiceMap serviceMap
+EndpointsMap endpointsMap
+iptables.Interface iptables
+ipvs.Interface ipvs
+syncProxyRules()
}
class ServiceMap {
+map~ServicePortName~ServicePort items
+Update(changes ServiceChangeTracker)
}
class EndpointsMap {
+map~ServicePortName~[]Endpoint items
+Update(changes EndpointChangeTracker)
}
class ServicePort {
+ClusterIP net.IP
+Port int
+NodePort int
+Protocol Protocol
+SessionAffinity SessionAffinity
}
class Endpoint {
+IP string
+Port int
+NodeName string
+Ready bool
}
Proxier "1" --> "1" ServiceMap : uses
Proxier "1" --> "1" EndpointsMap : uses
ServiceMap "1" --> "*" ServicePort : contains
EndpointsMap "1" --> "*" Endpoint : contains
数据结构详解
1. ServicePort(Service 端口信息)
// pkg/proxy/service.go
type ServicePort struct {
// Service 标识
NamespacedName types.NamespacedName
// ClusterIP Service ClusterIP
ClusterIP net.IP
// Port Service 端口
Port int
// Protocol 协议(TCP/UDP/SCTP)
Protocol v1.Protocol
// NodePort NodePort 端口(0 表示无 NodePort)
NodePort int
// LoadBalancerIP LoadBalancer IP
LoadBalancerIP string
// SessionAffinity 会话保持
SessionAffinity v1.ServiceAffinity // None / ClientIP
// SessionAffinityTimeout 会话保持超时时间
SessionAffinityTimeout int
// HealthCheckNodePort 健康检查端口
HealthCheckNodePort int
// ExternalIPs 外部 IP 列表
ExternalIPs []string
// LoadBalancerSourceRanges 允许访问的源 IP 范围
LoadBalancerSourceRanges []string
}
2. Endpoint(后端端点)
type Endpoint struct {
// IP Endpoint IP
IP string
// Port Endpoint 端口
Port int
// NodeName 节点名称
NodeName string
// Ready Endpoint 是否就绪
Ready bool
// Serving Endpoint 是否正在服务(Terminating 时为 false)
Serving bool
// Terminating Endpoint 是否正在终止
Terminating bool
// Zone 可用区
Zone string
}
3. iptables 规则缓存
// pkg/proxy/iptables/proxier.go
type Proxier struct {
// Service 和 Endpoints 缓存
serviceMap ServiceMap
endpointsMap EndpointsMap
// iptables 接口
iptables utiliptables.Interface
// 规则缓存(避免重复生成)
natRules bytes.Buffer
natChains utiliptables.ChainList
filterRules bytes.Buffer
filterChains utiliptables.ChainList
// 规则同步标志
needFullSync bool
// 性能统计
syncProxyRulesLatency metrics.HistogramVec
}
4. IPVS 配置
// pkg/proxy/ipvs/proxier.go
type Proxier struct {
// IPVS 接口
ipvs utilipvs.Interface
ipvsScheduler string // rr/lc/dh/sh/sed/nq
// 网络接口管理
netlinkHandle NetLinkHandle
// Service 和 Endpoints 缓存
serviceMap ServiceMap
endpointsMap EndpointsMap
// IPVS 规则缓存
ipvsServices map[string]*libipvs.VirtualServer
}
关键算法
1. iptables 负载均衡算法
概率计算:
假设有 3 个 Endpoint:EP1、EP2、EP3
第 1 条规则:probability = 1/3 = 0.33333 → 跳转到 EP1
第 2 条规则:probability = 1/2 = 0.50000 → 跳转到 EP2(在剩余 2 个中选择)
第 3 条规则:无需概率 → 跳转到 EP3(兜底)
结果:每个 Endpoint 被选中的概率 = 1/3
代码实现:
n := len(endpoints)
for i, ep := range endpoints {
probability := 1.0 / float64(n-i)
if i < n-1 {
// 使用概率跳转
natRules.Write(
"-A", svcChain,
"-m", "statistic",
"--mode", "random",
"--probability", fmt.Sprintf("%.5f", probability),
"-j", sepChain,
)
} else {
// 最后一个 Endpoint(兜底)
natRules.Write("-A", svcChain, "-j", sepChain)
}
}
2. IPVS 会话保持算法
Source Hashing(源地址哈希):
// 相同源 IP 总是转发到同一个 Real Server
hash := hashFunc(sourceIP)
rsIndex := hash % len(realServers)
selectedRS := realServers[rsIndex]
性能与容量考虑
1. iptables 模式
规则数量:
- 每个 Service:约 2 + n 条规则(n = Endpoint 数量)
- 1000 个 Service × 平均 5 个 Endpoint = 约 7000 条规则
性能影响:
- 规则查找:O(n) 线性查找
- 每个数据包需要遍历所有规则
2. IPVS 模式
规则数量:
- 每个 Service:1 个 Virtual Server + n 个 Real Server
性能影响:
- 规则查找:O(1) 哈希表查找
- 延迟低(< 0.1ms)