k8s调度容器失败The node had condition: [DiskPressure]

现象

k8s调度pod时异常,会导致生成上百个失败的pod。

SQL 复制代码
pod分配异常:

The node had condition: [DiskPressure].
The node was low on resource: ephemeral-storage. Container join-services was using 27938016Ki, which exceeds its request of 0.

节点报异常:
(combined from similar events): wanted to free 2571046912 bytes, but freed 0 bytes space with errors in image deletion: [rpc error: code = Unknown desc = Error response from daemon: conflict: unable to remove repository reference "192.168.0.2:5000/rabbitmq:3.8.6-management" (must force) - container bfb421637474 is using its referenced image 64a1f920fb0d

问题分析:

Kubernetes 调度 Pod 失败,报错信息明确指出:节点的临时存储资源不足。调度策略为重启时先增后减实例。

在运行的容器 join-services 实际已经使用了约 27.3 GiB (27938016 KiB),但它在 Pod 的资源配置 (resources) 中没有声明任何临时存储的请求值 (request = 0)。

临时存储 ( ephemeral-storage): 指节点上用于存放容器日志、emptyDir 卷、容器可写层(容器运行时产生的临时文件)的磁盘空间。Pod 使用 emptyDir 类型的卷时,数据会写入节点的临时存储(默认路径为 /var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~emptydir/<volume-name>

请求值 ( request): Kubernetes 调度器在决定将 Pod 放在哪个节点上时,会考虑 Pod 声明的资源请求量。调度器会确保节点的剩余资源(包括 CPU、内存和临时存储)能够满足 Pod 的请求量。

原因

  • 由于 join-services 容器没有声明临时存储请求 (requests.ephemeral-storage: 0),调度器在调度时认为该容器不需要任何临时存储。

  • 然而,该容器在运行时实际消耗了大量临时存储(约 27.3 GiB)。

  • 当调度器尝试将 Pod 调度到一个节点时,它检查该节点是否有足够的资源来满足 Pod 的 请求(即 0)。节点当然满足 0 的请求。

  • 但当 Kubelet 真正在该节点上启动容器时,容器需要写入大量临时文件(总计 27.3 GiB),却发现节点的可用临时存储空间不足以容纳这些实际写入,导致启动失败并报出此错误。

  • kubelet 尝试清理镜像释放 2.5GB,但目标镜像被运行中容器引用导致GC 失败,0 bytes freed,磁盘空间无法释放。大量 Pod 处于 Pending/Failed 状态并持续重试,导致产生上百个失败 Pod 记录,可能触发 controller 级联创建。

  • 那为什么这个实例会占用27G如此大的临时空间?因为服务里面打了大量的服务日志和上传的临时文件全在/tmp目录里面,但此目录又没有挂载出来 程序又没有清理,导致空间一直上涨。

解决方案:

  1. 先止血:在k8s中将容器实例缩为0,完全释放实例占用的资源和镜像,再将实例数扩起来。

  2. 删除异常Pod,阻止级联创建:kubectl delete掉此服务状态为Failed的所有pod。

  3. 后续修复:为 join-services 容器明确声明一个合理的临时存储请求值,让调度器能够做出正确的调度决策。

    强制声明 ephemeral-storage 配额,不允许任何容器以 0 request 运行,添加 resources.requests 字段。
    2. 基于当前观察到的实际使用量 27.3 GiB,建议限制到10G就告警,防止影响其它pod。

    1. 你也可以考虑设置 limits 来防止容器无限制地消耗临时存储,导致节点问题(可选但推荐)。

修改后的 YAML 示例片段:

YAML 复制代码
apiVersion: apps/v1
kind: Deployment  # 也可能是 StatefulSet, DaemonSet 等
metadata:
  name: deployment-name
spec:
  template:
    spec:
      containers:
      - name: join-services  # 你的问题容器名称
        image: image:tag
        resources:  # 添加或修改这个 resources 块
          requests:
            ephemeral-storage: "5Gi"  # 关键:添加临时存储请求
          limits:  # 可选但推荐:设置临时存储上限
            ephemeral-storage: "10Gi"   # 例如设置为 10Gi,比请求量稍高
        # ... 其他容器配置 (如 ports, volumeMounts, env 等) ...
      # ... 其他 Pod 配置 (如 volumes, initContainers 等) ...

额外建议:

  • 清理空间: 程序定期清理日志和临时文件。

  • 挂载 :将占用的文件挂载到宿主机空间,定期用脚本清理。定期清理策略 编写脚本定期清理日志和 emptyDir 数据,或使用 Kubernetes 的 TTLController 自动清理过期资源。

  • 避免滥用 emptyDiremptyDir 数据量大,建议改用持久化存储(如 PVC)或优化数据写入逻辑。

监控与告警

监控 ephmeral-storage 使用 使用 Prometheus + Grafana 监控节点的 ephemeral-storage 使用情况,设置阈值告警(例如 80% 时触发警告)。

相关推荐
952362 小时前
Sentinel
java·后端·spring·sentinel·springcloud
不老刘19 小时前
【Java入门】Java服务部署方式全景对比:从java -jar到K8s
java·kubernetes·jar
mit6.82421 小时前
AKS--Azure Managed Kubernetes
kubernetes·flask·azure
爱莉希雅&&&1 天前
K8s NFS+StorageClass+PV/PVC+Deployment 实战笔记
笔记·容器·kubernetes
维核科技1 天前
大模型私有化部署:Docker与Kubernetes实战避坑
docker·容器·kubernetes
明天谭1 天前
EzCloud微服务SaaS平台架构解析:多租户零代码一体化企业系统整体设计
开源·springcloud·微服务架构·saas多租户·企业级开发·ezcloud
SLD_Allen1 天前
Kubernetes + Ray + Volcano:云原生AI训练调度体系
人工智能·云原生·kubernetes
A-刘晨阳1 天前
Kubernetes 非共享存储详解:emptyDir 与 hostPath 从入门到实践
运维·云原生·容器·kubernetes·hostpath·emptydir
2401_834636991 天前
K8s 控制器全解:Deployment/DaemonSet/Job/CronJob+Service 服务发现实战宝典
容器·kubernetes·服务发现
风曦Kisaki1 天前
# Kubernetes(K8s)笔记Day15:K8s网络工作原理【Pod 网络模型,CNI 网络插件,Calico 工作模式详解,BGP协议,路由反射器】
运维·网络·nginx·云原生·容器·kubernetes