如何解决EKS Fargate节点磁盘压力问题
EKS Fargate节点磁盘压力解决办法
问题情况
- 节点状态显示磁盘压力:
Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- MemoryPressure False Tue, 12 Jul 2022 03:10:33 +0000 Wed, 29 Jun 2022 13:21:17 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure True Tue, 12 Jul 2022 03:10:33 +0000 Wed, 06 Jul 2022 19:46:54 +0000 KubeletHasDiskPressure kubelet has disk pressure PIDPressure False Tue, 12 Jul 2022 03:10:33 +0000 Wed, 29 Jun 2022 13:21:17 +0000 KubeletHasSufficientPID kubelet has sufficient PID available Ready True Tue, 12 Jul 2022 03:10:33 +0000 Wed, 29 Jun 2022 13:21:27 +0000 KubeletReady kubelet is posting ready status
- 出现垃圾回收失败警告:
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FreeDiskSpaceFailed 11m (x844 over 2d22h) kubelet failed to garbage collect required amount of images. Wanted to free 6314505830 bytes, but freed 0 bytes Warning EvictionThresholdMet 65s (x45728 over 5d7h) kubelet Attempting to reclaim ephemeral-storage
- 使用logrotate sidecar无效,日志显示找不到目标文件:
rotating pattern: /var/log/containers/*.log 52428800 bytes (5 rotations) empty log files are not rotated, old logs are removed considering log /var/log/containers/*.log log /var/log/containers/*.log does not exist -- skipping reading config file /etc/logrotate.conf Reading state from file: /var/lib/logrotate.status Allocating hash table for state file, size 64 entries Creating new state
对应的Deployment配置:
apiVersion: apps/v1 kind: Deployment metadata: name: my-apis namespace: kube-system spec: replicas: 3 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: my-apis image: 111111xxxxx.dkr.ecr.us-west-2.amazonaws.com/my-apis:1.0.3 ports: - containerPort: 8080 resources: limits: cpu: "1000m" memory: "1200Mi" requests: cpu: "1000m" memory: "1200Mi" readinessProbe: httpGet: path: "/ping" port: 8080 initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 2 livenessProbe: httpGet: path: "/ping" port: 8080 initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 5 - name: logrotate image: realz/logrotate volumeMounts: - mountPath: /var/log/containers name: my-app-logs env: - name: CRON_EXPR value: "*/5 * * * *" - name: LOGROTATE_LOGFILES value: "/var/log/containers/*.log" - name: LOGROTATE_FILESIZE value: "50M" - name: LOGROTATE_FILENUM value: "5" volumes: - name: my-app-logs emptyDir: {}
问题根源
- Fargate节点上,容器的stdout/stderr日志由容器运行时存储在节点特定路径,但无法SSH进入节点访问;当前logrotate挂载的是空目录,未指向实际日志存储路径,因此找不到目标文件。
- Fargate内置的Fluent Bit仅负责将日志推送到OpenSearch,不会自动清理节点上的旧日志,日志累积后占满磁盘。
解决办法
1. 修改Fluent Bit配置,启用日志清理
Fargate的Fluent Bit默认不清理已收集的日志,可通过自定义配置添加清理逻辑:
- 创建ConfigMap,修改Fluent Bit的
output部分,添加clean_logs参数,或使用exec过滤器执行清理命令。 - 注意:Fluent Bit由AWS托管,自定义配置需符合EKS Fargate日志收集规则,确保配置生效。
2. 减少应用日志输出量
- 降低应用日志级别(如从DEBUG改为INFO),减少非必要日志生成。
- 对日志进行采样,仅保留关键内容。
3. 正确配置logrotate(仅限应用日志写入容器内文件的场景)
若应用将日志写入容器内部文件而非stdout,需将应用日志目录挂载给sidecar:
修改Deployment配置,将应用日志目录挂载到共享卷,再让logrotate sidecar挂载同一卷:
containers: - name: my-apis image: 111111xxxxx.dkr.ecr.us-west-2.amazonaws.com/my-apis:1.0.3 # 其他配置不变 volumeMounts: - mountPath: /app/logs # 替换为应用实际日志存储路径 name: app-log-volume - name: logrotate image: realz/logrotate volumeMounts: - mountPath: /app/logs name: app-log-volume env: - name: LOGROTATE_LOGFILES value: "/app/logs/*.log" # 其他环境变量不变 volumes: - name: app-log-volume emptyDir: {}
若应用日志输出到stdout,此方法无效(stdout日志存储在节点上,容器无法直接访问)。
4. 调整Pod资源配置,获取更大临时存储
Fargate节点的临时存储大小与CPU/内存配置挂钩:
- 0.25vCPU对应20GB
- 1vCPU对应40GB
- 2vCPU对应80GB
可调高Pod的CPU请求/限制(如从1000m改为2000m),获得更大临时存储容量。
5. 调整Kubernetes日志垃圾回收参数
虽Fargate为托管节点,但可通过EKS Fargate配置文件或AWS控制台调整kubelet参数:
- 修改
imageGCHighThresholdPercent、imageGCLowThresholdPercent调整镜像垃圾回收阈值 - 修改
evictionHard中的ephemeral-storage阈值,调整磁盘压力触发回收的条件
总结
优先尝试减少应用日志输出或修改Fluent Bit配置启用日志清理;若为容器内文件日志,修正logrotate挂载路径;必要时调整Pod资源配置获取更大临时存储。
内容的提问来源于stack exchange,提问作者anujprashar
相关产品推荐
相关产品推荐

