欢迎光临
我们一直在努力

K8s IPVS 转发模式优化:就绪探针与容器跨集群节点负载分配路径

K8s IPVS 转发模式优化:就绪探针与容器跨集群节点负载分配路径

信息图

前言

"老王,我们线上服务又出现流量不均衡了!" 凌晨三点的告警电话把我从梦中惊醒。

"别急,先看看 IPVS 的权重分布。" 我打开笔记本电脑,远程连接到 K8s 集群。

"权重都是 100 啊,但节点负载差了三倍!" 运维小哥的声音带着疲惫。

"哦,我知道了,看看就绪探针的配置。"

五分钟后,问题定位:就绪探针超时导致 Pod 状态漂移,IPVS 的健康检查与 Kubelet 不同步。

这个凌晨的排查让我意识到:IPVS 负载均衡的优化,不只是调整权重那么简单。今天我们就深入聊聊 IPVS 转发模式与就绪探针的联动机制。

一、 底层原理

1.1 IPVS 负载均衡核心机制

IPVS(IP Virtual Server)是 Linux 内核层的负载均衡器,Kubernetes 使用它来实现 Service 的负载分发。其核心组件包括:

flowchart TB
A[Client Request] –> B[Kube-proxy]
B –> C[IPVS Rules]
C –> D[IPVS Scheduler]
D –> E{Algorithm}
E –>|rr| F[Round Robin]
E –>|lc| G[Least Connection]
E –>|wlc| H[Weighted LC]
E –>|sh| I[Source Hash]
F –> J[Backend Pods]
G –> J
H –> J
I –> J
J –> K[Real Server]

1.2 就绪探针与 IPVS 健康检查联动

Kubernetes 的就绪探针(Readiness Probe)决定 Pod 是否接收流量。IPVS 的健康检查机制与 Kubelet 的探针状态需要保持同步:

组件职责状态判断影响范围
Kubelet 执行就绪探针 通过/失败 单 Pod 级别
Kube-proxy 同步 Endpoints Ready/NotReady Service 级别
IPVS 负载分发 权重调整 节点级别

1.3 动态权重调整策略

IPVS 支持基于 Pod 状态动态调整权重:

sequenceDiagram
participant Kubelet as Kubelet
participant Endpoint as Endpoints Controller
participant KubeProxy as Kube-proxy
participant IPVS as IPVS Kernel

Kubelet->>Endpoint: Pod Ready/NotReady
Endpoint->>KubeProxy: Endpoints Updated
KubeProxy->>IPVS: ipvsadm -w <weight>
Note over IPVS: 权重=0 时停止转发
IPVS–>>KubeProxy: Weight Applied

二、 快速上手

2.1 检查 IPVS 模式状态

# 检查 kube-proxy 模式
kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode

# 查看 IPVS 规则
ipvsadm -Ln

# 查看后端服务器权重
ipvsadm -Ln –stats

2.2 配置就绪探针

apiVersion: v1
kind: Pod
metadata:
name: nginx-probe
spec:
containers:
– name: nginx
image: nginx:1.21
ports:
– containerPort: 80
readinessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
successThreshold: 2
failureThreshold: 3

2.3 配置 TopologySpreadConstraints

apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 6
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
topologySpreadConstraints:
– maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web
containers:
– name: web
image: nginx:1.21
ports:
– containerPort: 80

三、 核心 API 与深水区

3.1 IPVS Service 配置 API

type IPVSService struct {
ClusterIP net.IP
Port int
Protocol string
Scheduler string
Persistence *PersistenceConfig
BackendWeight map[string]int
}

func (s *IPVSService) UpdateBackendWeight(podName string, weight int) error {
cmd := exec.Command("ipvsadm", "-e",
fmt.Sprintf("-t %s:%d", s.ClusterIP, s.Port),
"-r", podName,
"-w", strconv.Itoa(weight))
return cmd.Run()
}

3.2 自定义权重计算逻辑

type WeightCalculator struct {
NodeCapacity map[string]int64
CurrentLoad map[string]int64
ProbeSuccess map[string]bool
}

func (wc *WeightCalculator) Calculate(podName string) int {
node := getNodeFromPod(podName)

if !wc.ProbeSuccess[podName] {
return 0
}

capacity := wc.NodeCapacity[node]
load := wc.CurrentLoad[node]
usage := float64(load) / float64(capacity)

baseWeight := 100
if usage > 0.8 {
baseWeight = int(float64(baseWeight) * (1 – (usage – 0.8) * 2))
}

return max(baseWeight, 10)
}

3.3 TopologySpreadConstraints 解析器

func ParseTopologySpreadConstraints(pod *v1.Pod) []TopologyConstraint {
var constraints []TopologyConstraint

for _, tc := range pod.Spec.TopologySpreadConstraints {
constraints = append(constraints, TopologyConstraint{
TopologyKey: tc.TopologyKey,
MaxSkew: tc.MaxSkew,
WhenUnsatisfiable: tc.WhenUnsatisfiable,
LabelSelector: tc.LabelSelector,
})
}

return constraints
}

四、 实战演练

4.1 场景:跨节点负载均衡优化

问题描述:3 节点集群,6 个 Pod,出现节点负载不均衡。

步骤 1:部署测试应用

kubectl apply -f deployment.yaml

步骤 2:观察初始分布

kubectl get pods -o wide
# 查看节点分布
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\\t"}{.status.allocatable.cpu}{"\\n"}{end}'

步骤 3:配置 TopologySpreadConstraints

apiVersion: apps/v1
kind: Deployment
metadata:
name: balanced-app
spec:
replicas: 6
template:
spec:
topologySpreadConstraints:
– maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: balanced-app

步骤 4:验证效果

# 等待调度完成
sleep 60

# 检查 Pod 分布
kubectl get pods -o wide | awk '{print $7}' | sort | uniq -c

五、 避坑指南

5.1 就绪探针配置不当导致流量黑洞

现象:Pod 已 Ready 但 IPVS 权重仍为 0

原因:Kube-proxy 同步延迟或 Endpoints 状态不同步

解决方案:

readinessProbe:
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3

5.2 TopologySpreadConstraints 导致调度失败

现象:Pod 处于 Pending 状态,事件显示无法满足 topology spread 约束

原因:maxSkew 设置过严,节点资源不足

解决方案:

topologySpreadConstraints:
– maxSkew: 2 # 放宽约束
whenUnsatisfiable: ScheduleAnyway # 允许调度

5.3 IPVS 调度算法选择不当

现象:流量分布不均匀,部分 Pod 负载过高

原因:使用了不适合场景的调度算法

推荐配置:

  • rr:简单轮询,适合同构集群
  • wlc:加权最小连接,适合异构集群
  • sh:源 IP 哈希,适合会话保持

5.4 节点级负载感知缺失

现象:节点间负载差异大,但 Pod 分布均匀

原因:TopologySpreadConstraints 只考虑 Pod 数量,不考虑实际负载

解决方案:结合 Vertical Pod Autoscaler 和自定义调度器

总结

IPVS 负载均衡的优化是一个系统性工程,涉及:

  • 就绪探针与 IPVS 健康检查的同步 – 确保只有健康 Pod 接收流量
  • 动态权重调整策略 – 根据实际负载实时调整分发比例
  • TopologySpreadConstraints 配置 – 实现跨节点的均匀分布
  • 调度算法选择 – 根据业务场景选择合适的算法
  • 赞(0)
    未经允许不得转载:171主机测评 » K8s IPVS 转发模式优化:就绪探针与容器跨集群节点负载分配路径
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址