欢迎光临
我们一直在努力

rancher rke搭建的集群将某个负载设置specific node的调度策略,发现大量的Evicted状态的pod的原因

在使用Rancher RKE部署的Kubernetes集群中,AI/ML负载(如训练任务、推理服务)经常需要精确调度到特定的GPU节点上。我们通常使用nodeSelectornodeAffinity来实现这一目标。然而,当这些负载被集中调度到少数几个节点上时,运维人员可能会发现大量的Pod进入Evicted状态,而不是预期的CrashLoopBackOffPending。本文将深入分析这一现象的根源,并提供具体的诊断和解决步骤。

1. 理解Kubernetes Eviction机制

Pod状态为Evicted意味着Kubernetes Kubelet主动将Pod驱逐(删除)以回收节点资源,而不是因为应用程序自身的错误崩溃。Kubelet执行驱逐的根本原因在于节点资源压力过大,最常见的压力类型包括:

  1. Disk Pressure (磁盘压力): 节点的磁盘使用率超过阈值。
  2. Inode Pressure (Inode压力): 节点上的文件数量过多,Inodes耗尽。
  3. Memory Pressure (内存压力): 节点内存使用率超过硬性驱逐阈值。
  4. PID Pressure (进程ID压力): 节点上进程数量过多。

对于AI/ML负载,特定的调度策略往往导致局部资源热点,其中最容易被忽视和触发Evicted状态的是临时存储(Ephemeral Storage)

2. 为什么特定节点调度会引发Eviction?

当您将所有高I/O或日志密集的AI负载调度到少数几个节点时,这些节点上的以下资源消耗会急剧增加:

  • 日志和Cache堆积: 容器的标准输出和标准错误(stdout/stderr)会被Kubelet收集并存储在本地磁盘上(通常是/var/log/pods/var/lib/docker/containers)。如果负载日志量巨大且没有设置ephemeral-storage限制,它将迅速耗尽节点的根文件系统或专门的Kubelet存储目录。
  • 镜像层解压和存储: 虽然镜像层通常不计入临时存储限制,但如果节点频繁拉取新镜像或更新,存储空间会快速消耗。

当Kubelet检测到磁盘利用率(通常是根目录或/var/lib/kubelet)达到硬性驱逐阈值(如默认的95%)或软性驱逐阈值时,它会开始驱逐Pod,首先驱逐的是不设置Request/Limit的Pod,或占用资源最大的Pod。

3. 诊断:定位Evicted的真正原因

第一步是检查具体的Pod和Node状态,找出Kubelet报告的压力类型。

步骤 3.1 检查Pod的详细状态

# 替换为你的命名空间和Pod名称
kubectl describe pod <pod_name> -n <namespace>

在输出的Events部分,你会看到明确的驱逐原因,通常是类似如下的描述:

Events:
  Type     Reason       Age   From       Message
  ----     ------       ----  ----       -------
  Warning  Evicted      5m    kubelet    The node was low on resource: ephemeral-storage. Container <container_name> was using 80Gi, which exceeds its request of 5Gi.

步骤 3.2 检查目标节点的资源状况

检查被驱逐Pod所在的节点,查看其Conditions

kubectl describe node <node_name>

查找Conditions字段:

Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  MemoryPressure       False   Thu, 1 Jan 1970 00:00:00 +0000    Thu, 1 Jan 1970 00:00:00 +0000    KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         True    Thu, 1 Jan 1970 00:00:00 +0000    Thu, 1 Jan 1970 00:00:00 +0000    KubeletHasDiskPressure       kubelet has less than 10% of ephemeral-storage available
  ... (其他条件)

如果DiskPressure: True,则确认问题出在磁盘空间或临时存储。

4. 解决与缓解方案

方案 4.1 实施临时存储(Ephemeral Storage)限制

这是解决问题的最根本和最推荐的方法。通过在Pod Spec中明确设置ephemeral-storage的Requests和Limits,可以防止单个Pod耗尽整个节点的本地存储。

apiVersion: v1
kind: Pod
metadata:
  name: ai-workload-limited
spec:
  nodeSelector:
    gpu: 'true' # 假设这是特定调度标签
  containers:
  - name: heavy-logging-container
    image: my-ai-image:latest
    resources:
      limits:
        # 限制CPU和内存
        cpu: "2"
        memory: "4Gi"
        # 限制临时存储的上限(硬限制)
        ephemeral-storage: "20Gi"
      requests:
        # 预留临时存储(软请求)
        cpu: "1"
        memory: "2Gi"
        ephemeral-storage: "10Gi"

关键点: 如果Pod实际使用的临时存储超过了Limits.ephemeral-storage,Kubelet会立即驱逐该Pod,从而保护节点资源。

方案 4.2 调整日志策略或存储位置

对于日志量巨大的应用,考虑以下策略:

  1. Log Rotation: 确保Docker/Containerd配置了合理的日志轮换策略(RKE通常会配置默认值,但需确认其有效性)。
  2. 外部日志系统: 将日志直接发送到Elasticsearch或Loki等外部系统,而不是依赖本地存储。
  3. 配置单独的存储卷: 如果可以,配置ReadWriteOnce或ReadWriteMany的持久化存储卷(PV/PVC)来存储AI任务的中间结果,避免占用临时存储。

方案 4.3 调整Kubelet驱逐阈值 (RKE Kubelet Extra Args)

对于RKE集群,您可以通过cluster.yml配置Kubelet的额外参数,调整驱逐的软硬阈值。但这通常是最后的手段,需要谨慎操作。

例如,如果希望在磁盘占用达到90%才触发硬驱逐,可以修改Kubelet配置:

# cluster.yml (Rancher RKE 配置)
services:
  kubelet:
    extra_args:
      eviction-hard: 'imagefs.available<10%,nodefs.available<10%,nodefs.inodesFree<5%'
      eviction-soft: 'imagefs.available<15%,nodefs.available<15%,nodefs.inodesFree<10%'
      eviction-soft-grace-period: 'nodefs.available=2m'

在修改RKE配置后,需要运行 rke up 更新集群配置。

通过以上诊断和配置优化,可以有效地管理特定AI节点上的临时存储压力,从而消除Pod的频繁Evicted状态。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » rancher rke搭建的集群将某个负载设置specific node的调度策略,发现大量的Evicted状态的pod的原因
分享到: 更多 (0)

评论 抢沙发

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