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 自动清理过期资源。

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

监控与告警

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

相关推荐
无言听风雨丶11 小时前
Linux 容器本质探秘:Cgroup 与 Namespace 深度解析与实战
linux·运维·服务器·kubernetes
无言听风雨丶15 小时前
Kubernetes GitOps 持续交付实战:用 Argo CD 让 Git 成为集群事实源
git·elasticsearch·kubernetes
无言听风雨丶1 天前
Kubernetes 控制平面深度剖析:从 kubectl apply 到 etcd 写入的全链路
平面·kubernetes·etcd
openFuyao1 天前
openFuyao x 复旦大学软件工程实验室 Panel 回顾:Agentic时代,集群调度技术体系将如何演进?
kubernetes·openfuyao
螺蛳粉 螺蛳粉1 天前
第 05 篇:etcd 深入:Raft 共识、watch 机制与快照备份恢复实战(底座认知 05)
docker·云原生·容器·kubernetes·etcd·分布式存储·kube-apiserver
相思难忘成疾1 天前
从零搭建 Kubernetes 1.30 集群:kubeadm 部署一主多从实战(RHEL 9.3 + Docker + flannel)
linux·运维·kubernetes
weirong1 天前
给 K8s 加一个自动值班员:分级故障自愈引擎
kubernetes
云和数据.ChenGuang1 天前
Python 闭包详解:从原理到实战
linux·开发语言·人工智能·python·kubernetes
weirong1 天前
为什么 HPA 会震荡?手写一个带冷却窗口的伸缩决策引擎
kubernetes
-星空下无敌2 天前
Windows Docker K8s 安装部署Naocs ,SpringBoot 3.x 4.x 整合Naocs 版本兼容 配置中心、服务注册与发现
windows·docker·nacos·kubernetes·springboot·alibaba