es master三节点中的一个节点提示容器状态未知
在这里插入图片描述
describe发现events有如下提示,这个是Kubernetes Pod因节点临时存储(ephemeral-storage)不足而被驱逐(Evicted)的事件日志。

Events:
  Type     Reason               Age   From     Message
  ----     ------               ----  ----     -------
  Warning  Evicted              15m   kubelet  The node was low on resource: ephemeral-storage. Threshold quantity: 3692958570, available: 3567316Ki. Container es-agent was using 1280Ki, request is 0, has larger consumption of ephemeral-storage. Container kbagent was using 4Ki, request is 0, has larger consumption of ephemeral-storage. Container exporter was using 20Ki, request is 0, has larger consumption of ephemeral-storage. Container elasticsearch was using 976Ki, request is 0, has larger consumption of ephemeral-storage.
  Normal   Killing              15m   kubelet  Stopping container elasticsearch
  Normal   Killing              15m   kubelet  Stopping container kbagent
  Normal   Killing              15m   kubelet  Stopping container es-agent
  Normal   Killing              15m   kubelet  Stopping container exporter
  Warning  ExceededGracePeriod  15m   kubelet  Container runtime did not kill the pod within specified grace period.
  Warning  FailedPreStopHook    14m   kubelet  PreStopHook failed

问题根因分析

  1. 直接原因:节点可用临时存储(available: 3567316Ki ≈ 3.4Gi)低于驱逐阈值(Threshold
    quantity: 3692958570 ≈ 3.52Gi)
  2. 触发机制:kubelet 的节点压力驱逐(Node Pressure Eviction)
  3. 连锁问题:
  • PreStop钩子执行失败(14m前)
  • 容器未在优雅终止期内停止(ExceededGracePeriod)
  • 最终被强制杀死

核心问题:容器未设置 ephemeral-storage 资源请求/限制

从日志看,所有容器 request is 0,这意味着:

  • 没有声明对临时存储的资源请求
  • QoS等级为 BestEffort(最低优先级)
  • 节点资源不足时,这类Pod会被最先驱逐

解决方案

1. 立即恢复(临时措施)

# 查看Pod当前状态
kubectl get pod <pod-name> -n <namespace>

# 如果Pod已被删除,检查是否有控制器(Deployment/StatefulSet)自动重建
kubectl get deploy,sts -n <namespace>

# 手动删除Pod让其重建(如果控制器存在)
kubectl delete pod <pod-name> -n <namespace>

2. 根本解决(资源配置)

在Pod/Deployment/StatefulSet中添加资源限制:

spec:
  containers:
  - name: elasticsearch
    resources:
      requests:
        ephemeral-storage: "2Gi"    # 请求量
      limits:
        ephemeral-storage: "4Gi"    # 限制量(防止容器写爆磁盘)
  - name: es-agent
    resources:
      requests:
        ephemeral-storage: "500Mi"
      limits:
        ephemeral-storage: "1Gi"
  - name: kbagent
    resources:
      requests:
        ephemeral-storage: "100Mi"
      limits:
        ephemeral-storage: "200Mi"
  - name: exporter
    resources:
      requests:
        ephemeral-storage: "50Mi"
      limits:
        ephemeral-storage: "100Mi"

3. 修复 PreStop 钩子

PreStop钩子失败会导致优雅终止超时,检查并修复:

# 查看Pod的PreStop配置
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 5 -B 5 preStop

# 常见问题:
# - 钩子中调用的命令/API不存在
# - 超时时间设置过短
# - 网络问题导致钩子无法完成

建议增加 terminationGracePeriodSeconds(默认30秒):

spec:
  terminationGracePeriodSeconds: 60  # 增加到60秒
  containers:
  - name: elasticsearch
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh", "-c", "curl -XPOST http://localhost:9200/_cluster/nodes/_local/shutdown"]

4. 节点层面优化

# 查看节点磁盘使用情况
kubectl describe node <node-name> | grep -A 5 "Allocated resources"

# 清理节点上的无用资源
# - 清理已终止的容器日志
# - 清理未使用的镜像
# - 清理已完成的Pod
docker system prune -f  # 如果是Docker运行时

5. 配置驱逐阈值(集群管理员)

修改kubelet配置,调整更合理的阈值:

# /var/lib/kubelet/config.yaml
evictionHard:
  imagefs.available: "15%"
  nodefs.available: "10%"
  ephemeral-storage.available: "10%"  # 当前是约15%
evictionSoft:
  ephemeral-storage.available: "15%"
evictionSoftGracePeriod:
  ephemeral-storage.available: "2m"

预防建议

  1. 监控告警:对节点磁盘使用率设置告警(如 > 80%)
  2. 日志轮转:配置容器日志轮转策略(max-size, max-file)
  3. 持久化存储:对需要大量存储的组件使用PVC而非emptyDir
  4. 资源配额:在命名空间级别设置ResourceQuota限制总存储使用
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: your-namespace
spec:
  hard:
    requests.ephemeral-storage: "20Gi"
    limits.ephemeral-storage: "40Gi"

验证修复

# 查看Pod资源请求/限制是否生效
kubectl describe pod <pod-name> -n <namespace> | grep -A 3 "QoS"

# 期望输出:QoS Class: Burstable 或 Guaranteed(有requests)

如果问题持续,需要检查:

  • 是否有日志文件过大未轮转
  • 是否有应用产生大量临时文件
  • 节点的emptyDir目录(/var/lib/kubelet)是否被其他Pod占满

怎么看出来是临时存储的

1. 直接从事件消息中识别

日志里明确写了:

The node was low on resource: ephemeral-storage
  • ephemeral-storage 就是"临时存储"的英文术语
  • 中文翻译:临时存储、临时存储空间、临时卷存储

2. 关键词对照表

英文关键词中文含义说明
ephemeral-storage临时存储Kubernetes官方术语
ephemeral临时/短暂的表示非持久化
emptyDir临时卷Pod级别临时存储的一种实现
nodefs节点文件系统包含 /var/lib/kubelet
imagefs镜像文件系统存放容器镜像

3. 阈值表达式的含义

Threshold quantity: 3692958570, available: 3567316Ki

这两个值的单位不一样:

3692958570 → 没有单位后缀,默认是字节(bytes)

换算:3692958570 bytes ≈ 3.52 GiB

3567316Ki → KiB(Kibibyte)

换算:3567316 KiB ≈ 3.4 GiB

所以实际含义是:

阈值: 3.52 GiB (硬驱逐阈值)
可用: 3.40 GiB
可用 < 阈值 → 触发驱逐

4. Kubernetes存储类型对比

存储类型生命周期是否临时典型用途
ephemeral-storagePod生命周期✅ 是容器日志、镜像层、emptyDir
emptyDirPod生命周期✅ 是临时缓存、共享数据
hostPath节点生命周期❌ 否宿主机目录挂载
PersistentVolume (PVC)独立于Pod❌ 否持久化数据(数据库)
configMap/secretPod生命周期✅ 是配置文件、密钥

5. ephemeral-storage 包含哪些内容?

/var/lib/kubelet/
├── containers/         # 容器可写层
├── volumes/            # emptyDir等临时卷
├── pods/               # Pod相关文件
└── ... 
/var/log/containers/    # 容器日志
/var/lib/docker/        # 镜像层(部分计入)
  1. 如何查看当前Pod的临时存储使用?
# 方法1:查看Pod的详细状态
kubectl describe pod <pod-name> -n <namespace>
# 查找 "Ephemeral Storage" 相关行

# 方法2:查看节点上所有Pod的存储使用
kubectl top pod -n <namespace> --containers
# 注:top命令不直接显示存储,需要结合以下命令

# 方法3:查看节点的存储分配情况
kubectl describe node <node-name>
# 输出示例:
# Allocated resources:
#   ephemeral-storage: 15Gi (40%)

7. 实际查看节点存储的命令

# 登录到节点,查看实际磁盘使用
df -h /var/lib/kubelet
# 输出示例:
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda1       100G   85G   15G  85% /var/lib/kubelet

# 查看详细的目录占用
du -sh /var/lib/kubelet/* | sort -hr | head -10

8. 日志中的"request is 0"含义

Container es-agent was using 1280Ki, request is 0
  • 容器实际使用了 1280 KiB 的临时存储
  • 但没有设置资源请求(request=0)
  • 这意味着该Pod的QoS是 BestEffort(最低优先级)
  • 当节点资源不足时,这种Pod会被最先驱逐

9.快速验证命令

bash
# 查看Pod的QoS等级(如果是BestEffort则没有requests)
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.qosClass}'

# 查看Pod的资源请求
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 10 "resources:"

总结:如何一眼识别"临时存储驱逐

  1. 看关键词:ephemeral-storage 或 临时存储
  2. 看资源类型:不是 memory 或 cpu
  3. 看驱逐原因:Evicted + resource: ephemeral-storage
  4. 看数值单位:Ki、Mi、Gi(或纯数字表示字节)
  5. 看容器使用:using 多少,request 是多少

如果日志写的是 disk pressure 或 nodefs,也是指磁盘/存储相关,但 ephemeral-storage 是Kubernetes 1.8+后的标准术语。

更多推荐