news 2026/10/27 23:50:51

Kubernetes节点磁盘告警:镜像日志清理与kubelet回收

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes节点磁盘告警:镜像日志清理与kubelet回收

1. 节点磁盘告警的现场:先搞清楚谁在吃盘

凌晨两点被 NodeDiskPressure 的告警叫起来,这种经历做过几年 Kubernetes 运维的人基本都有一两次。登录节点一看df -h根分区 98%,kubectl describe node里 Conditions 挂着DiskPressure True,紧接着就是 Pod 被 kubelet 驱逐、新 Pod 调度不上去、业务方在群里问"为什么服务一直在重启"。集群节点磁盘清理这件事,看起来只是运维操作里的一个体力活,真落到生产环境里,它牵扯的是容器运行时、kubelet 驱逐策略、日志采集链路、存储卷生命周期四条线的交汇点。

这篇文章想聊的就是这个场景:一个正在跑业务的 Kubernetes 集群,某个或某几个节点的磁盘水位突然飙到危险区,你需要在最短时间内定位占用来源、安全地回收空间、并且把"下次还会满"这个问题压下去。适合已经能熟练敲kubectl get pods、但对节点层面的磁盘构成还比较模糊的同学,也适合那些已经被磁盘告警折腾过几轮、想整理一套标准动作的老手。

先说结论性的判断:绝大多数 Kubernetes 节点的磁盘不是被业务数据撑爆的,而是被容器运行时垃圾、容器日志、以及一堆"以为已经删了其实还占着"的文件撑爆的。搞清楚这个前提,后面的排查方向就不会跑偏。下面按"为什么会满 → 怎么定位 → 怎么清 → 怎么防 → 怎么避坑"的顺序展开,每一步都给出可以直接抄的命令和参数。

1.1 从一次典型的 DiskPressure 告警说起

某公司的业务集群,二十多个工作节点,跑着几百个 Pod,日志统一走 sidecar 采集。某天开始,连续三天都有节点报磁盘压力,而且都是同一批节点——跑离线计算任务的那几台。运维同学的第一反应是"日志太多了",于是登上去rm -rf /var/log/pods/*,磁盘确实降下来了,但第二天又满了。

这个案例里其实藏着三个信息点,值得单独拎出来讲。

第一,告警集中出现在同一批节点,说明问题是"负载特征"而不是"全局配置"。离线任务的特点是大镜像、频繁拉取、短生命周期 Pod 多,这三条正好对应镜像层堆积和容器日志暴增两个占用源。

第二,rm -rf /var/log/pods/*能生效,说明日志确实是主要占用之一,但它只是"当下能看到的"部分,镜像层和其他缓存没动,所以第二天必然复发。

第三,清理动作本身有风险。直接删/var/log/pods下的文件,会导致正在运行的容器日志句柄悬空,日志采集组件读不到新内容,业务侧排查问题时会发现"日志断档"。安全做法是truncate而不是rm,这一点后面会细说。

所以节点磁盘清理不是一条命令的事,它需要一套"先看清账本、再分类处理、最后固化策略"的流程。

1.2 节点磁盘的四大占用来源

在动手之前,先把一个 Kubernetes 节点上的磁盘占用拆成可管理的四块,这是后面所有排查动作的基础框架。

占用来源典型路径增长特征清理难度
容器镜像与运行时层/var/lib/containerd、/var/lib/docker随镜像拉取次数阶梯式增长低,可用运行时命令回收
容器日志/var/log/pods、/var/log/containers随业务日志量线性增长中,需注意句柄与采集链路
可写层与临时卷/var/lib/kubelet/pods/*/volumes随 Pod 生命周期累积中,需确认 Pod 已彻底删除
操作系统自身/var/log/journal、/var/cache、旧内核缓慢增长,容易长期被忽略低,但需要知道哪些能删

镜像与运行时层是大头。一个 500MB 的镜像在节点上被拉取十次不同 tag,占用的可能远不止 5GB,因为镜像层是复用的,但不同 tag 指向不同 manifest 时复用率会下降。很多团队 CI 里给镜像打的是latest加时间戳,每次发布都是新 tag,节点上的旧 tag 镜像如果没被 GC 掉就会一直躺着。

容器日志是第二大来源,也是最容易失控的。kubelet 默认的containerLogMaxSize是 10Mi,containerLogMaxFiles是 5,理论上单容器日志上限 50Mi。但很多集群在初始化时把这两个值调大了,或者干脆没配,某些运行时版本下默认行为又不一样,结果就是单个容器写到几个 GB。

可写层与临时卷比较隐蔽。emptyDir卷在 Pod 删除后会被清理,但如果 Pod 卡在Terminating状态,或者 kubelet 与 API Server 通信异常导致 Pod 元数据残留,目录就会留在/var/lib/kubelet/pods下面。另外容器内往非挂载路径写文件,写的是可写层,这部分空间在容器删除前一直占着。

操作系统自身的占用经常被低估。systemd journal 默认可以涨到宿主磁盘的 10%,/var/cache/apt或dnf的包缓存、旧内核、core dump 文件,这些加起来几个 GB 很常见。

2. 清理前的定位:别急着 rm -rf

磁盘清理最大的风险不是"清不干净",而是"清错了"。生产节点上误删一个正在被进程打开的文件,可能引发的问题比磁盘满本身更严重。所以清理前的定位环节,投入的时间应该占到整个处理流程的一半以上。

2.1 三层排查法:大盘、目录、文件句柄

我习惯把定位拆成三层,从粗到细,每层都有明确的判据。

第一层看大盘水位和 inode。df -h看容量,df -i看 inode。有些节点容量还有 30%,但 inode 用光了,表现同样是"写不进去"。日志类场景里小文件极多,inode 耗尽是真实存在的。

df -h df -i

如果发现某个挂载点容量和 inode 都很宽松,但 kubelet 仍然报 DiskPressure,那要怀疑 kubelet 监控的imagefs和nodefs不是同一个文件系统,报的是另一个分区的问题。

第二层看目录分布。用du从根往下逐层收窄,注意加-x参数避免跨文件系统统计,否则会跑到挂载的 PV 里去,既慢又不准。

du -x -h --max-depth=1 / 2>/dev/null | sort -hr | head -20 du -x -h --max-depth=1 /var/lib 2>/dev/null | sort -hr | head -20 du -x -h --max-depth=2 /var/log 2>/dev/null | sort -hr | head -20

这一轮基本能锁定是/var/lib/containerd还是/var/log/pods出了问题。如果节点上装了ncdu,交互式浏览会舒服很多,但生产环境不一定允许临时装包,du够用。

第三层看文件句柄。这一步是很多人会漏掉的。如果du统计出来的总量和df报的已用空间差了好几 GB,说明有文件被删除但句柄没释放——进程还开着这个文件,空间就不会归还。

lsof +L1 2>/dev/null | head -30

+L1表示列出 link count 小于 1 的文件,也就是已被删除但仍被打开的文件。输出里重点看 SIZE 列大的那几行,对应的进程通常是日志采集组件、容器运行时或者某个还在写日志的应用。

2.2 用运行时命令把镜像和容器的账算清楚

du只能告诉你目录多大,说不清"哪些能删"。要精确判断镜像和容器的占用,得用容器运行时自己的命令。现在主流集群用的是 containerd,对应的 CLI 是crictl;老一些的集群可能还是 Docker,命令换成docker即可,逻辑一样。

先看镜像总量和各个镜像的大小:

crictl images crictl imagefsinfo

imagefsinfo会返回imageFilesystem的usedBytes和inodesUsed,这个数值和 kubelet 看到的是一致的,可以拿来和df对照,确认 kubelet 监控的确实是这个分区。

再看容器,重点区分运行中和已退出的:

crictl ps -a crictl ps -a --state exited

已退出的容器如果数量很多,它们的可写层都是垃圾。正常情况下 kubelet 会按--maximum-dead-containers之类的策略回收,但如果节点上 Pod 频繁重启、或者 kubelet 的 GC 没跑起来,残留会很多。

还有一个容易被忽略的点:镜像的"引用计数"。同一个镜像 ID 可能被多个 tag 引用,crictl rmi删一个 tag 不一定释放空间。判断某个镜像能不能安全删掉,要看它是否还被某个容器(包括已退出的)或者 Pod sandbox 引用着。

crictl inspecti <image-id> | grep -A5 "repoTags"

真正安全的批量清理,是只删"没有被任何容器引用"的镜像,crictl rmi --prune做的就是这件事,后面会展开。

3. 分类清理实操:按占用来源逐个击破

定位清楚之后,清理动作要按来源分类做,顺序上建议先清日志和运行时垃圾(低风险、见效快),再处理卷和系统层(需要确认)。每做一步,用df -h复查一次,避免多个动作叠加导致误判。

3.1 运行时层:无用镜像、停止容器与沙箱残留

镜像清理分三档,风险从低到高。

第一档:清理悬空镜像。悬空镜像指的是没有 tag 指向的镜像层,通常是重新构建同名 tag 后留下的旧层。这类镜像没有任何引用价值,直接清。

# containerd crictl rmi --prune # docker docker image prune -f

第二档:清理未被容器引用的镜像。这一步会删掉所有"当前没有容器在用"的镜像,包括某些你打算回滚用的旧版本镜像。执行前确认一下回滚窗口,别在发布刚完成时跑。

crictl images | awk 'NR>1 && $2=="<none>" {print $3}' | xargs -r crictl rmi

如果集群用的是自定义脚本管理镜像,更稳的做法是先导出引用清单再对比:

# 导出所有容器正在使用的镜像 ID crictl ps -a -q | xargs -r crictl inspect --output go-template \ --template '{{.status.imageRef}}{{"\n"}}' 2>/dev/null | sort -u > /tmp/in-use-images.txt # 列出所有镜像,人工比对后删除不在清单里的 crictl images --no-trunc

第三档:清理已退出的容器和沙箱。已退出容器的可写层和日志都会占空间。kubelet 通常在 Pod 删除时一起清理,但异常情况下会有残留。

# 删除所有已退出的容器 crictl ps -a --state exited -q | xargs -r crictl rm # 清理无主的 Pod sandbox crictl pods --state notready -q | xargs -r crictl rmp

注意:crictl rmp删的是 sandbox,如果对应的 Pod 其实还在运行只是状态上报有问题,删掉会导致容器异常。执行前用kubectl get pod -o wide交叉核对节点上的 Pod 列表。

执行完之后再跑一次crictl imagefsinfo看usedBytes是否下降。如果降幅远小于预期,很可能就是 2.1 节说的"文件被删但句柄没释放",这时候要去找持有句柄的进程,而不是继续删。

3.2 容器日志:truncate 而不是 rm

容器日志的路径结构是这样的:/var/log/pods/<namespace>_<pod>_<uid>/<container>/<restart>.log,/var/log/containers下面是指向这些文件的软链接。日志采集组件一般从/var/log/containers读。

清理日志的核心原则是:能截断就不删除,能按文件截断就不批量删目录。原因有两个,一是删除文件会让采集组件的读取偏移失效,二是rm之后空间不一定立刻释放(句柄还在)。

先找出大文件:

# 找出超过 200MB 的容器日志 find /var/log/pods -type f -name "*.log" -size +200M -exec ls -lh {} \; 2>/dev/null # 按大小排序,看前 20 du -ah /var/log/pods 2>/dev/null | sort -hr | head -20

然后截断:

# 单个文件截断,保留 inode,采集组件不受影响 truncate -s 0 /var/log/pods/<ns>_<pod>_<uid>/<container>/0.log # 批量截断所有超过 200MB 的日志 find /var/log/pods -type f -name "*.log" -size +200M -exec truncate -s 0 {} \;

truncate -s 0保留文件本身,只把内容清空,采集组件的 tail 逻辑会看到文件被截断,多数实现能正确处理。相比之下rm会让采集组件的文件句柄指向一个已删除的 inode,表现为"日志采集卡住"。

如果确认要删(比如 Pod 已经不存在了,只是目录残留),那就先确认没有采集组件在跟踪:

# 查一下有没有进程打开这些文件 lsof /var/log/pods/<残留目录> 2>/dev/null

没有输出再删。

日志清理只能解决当下,要让它不再涨,得回到 kubelet 的日志轮转配置,这部分放到第 4 节。

3.3 卷与临时目录:EmptyDir、残留 Pod 目录与镜像构建缓存

/var/lib/kubelet/pods下面每个 Pod 一个目录,包含 volumes、containers、plugins 等子目录。正常删除的 Pod 目录会被 kubelet 清掉,但如果 kubelet 在处理删除时被打断(比如节点重启、kubelet 重启、API Server 不可达),就会留下"孤儿目录"。

判断孤儿目录的方法是和 API Server 上的 Pod UID 做对比:

# 节点上实际存在的 Pod 目录 ls /var/lib/kubelet/pods > /tmp/node-pod-uids.txt # API Server 上该节点所有 Pod 的 UID(含 Terminating) kubectl get pods --all-namespaces --field-selector spec.nodeName=<node-name> \ -o jsonpath='{range .items[*]}{.metadata.uid}{"\n"}{end}' > /tmp/api-pod-uids.txt # 差集就是孤儿目录 comm -23 <(sort /tmp/node-pod-uids.txt) <(sort /tmp/api-pod-uids.txt)

差集里的目录,先确认对应 Pod 确实不存在了(包括 DaemonSet 重建的场景),再删除:

comm -23 <(sort /tmp/node-pod-uids.txt) <(sort /tmp/api-pod-uids.txt) \ | xargs -r -I{} rm -rf /var/lib/kubelet/pods/{}

注意:删除顺序建议先停 kubelet 或者至少确认 Pod 已经不在 API Server 里,否则可能出现 kubelet 正在写入而你在删除的竞争情况。生产环境稳妥的做法是systemctl stop kubelet,清完再start,代价是节点短暂不可调度,需要提前 cordon。

emptyDir的清理依赖 Pod 生命周期,这个没法手动干预,但有一个配置项值得关注:emptyDir.sizeLimit。设置了之后,kubelet 会在卷超过限制时驱逐 Pod,等于给临时卷加了一道闸。没设置的话,一个写疯了的应用理论上能把整个节点写满。

volumes: - name: cache emptyDir: sizeLimit: 5Gi

另外节点上如果有构建类负载(比如跑 CI Runner 的节点),/var/lib/docker(如果还在用 Docker)或者 buildkit 的缓存目录也要看一眼。构建缓存的特点是单个文件不大但数量极多,清理时用docker builder prune或buildctl prune更安全。

3.4 操作系统层:journal 日志、包缓存与旧内核

系统层清理相对独立,不涉及 Kubernetes 对象,但一样要小心。

systemd journal是最常见的"隐形大户"。默认配置下 journal 可以占用/var/log/journal所在文件系统的 10%,在 100GB 的盘上就是 10GB。

journalctl --disk-usage journalctl --vacuum-size=500M journalctl --vacuum-time=7d

--vacuum-size和--vacuum-time二选一即可,同时用取更严格的那个。想永久改的话,编辑/etc/systemd/journald.conf,设置SystemMaxUse=500M和MaxRetentionSec=7day,然后systemctl restart systemd-journald。

包管理缓存:Debian 系apt-get clean,RHEL 系dnf clean all。这些目录通常在/var/cache下,几百 MB 到几 GB 不等,清了没有副作用。

旧内核:只保留当前运行版本和上一个版本,其余的可以删。RHEL 系用package-cleanup --oldkernels --count=2,Debian 系用apt-get autoremove --purge。这条要谨慎,删错了内核会导致节点重启后起不来。

core dump 和其他杂项:/var/crash、/var/lib/systemd/coredump、/tmp下的旧文件,都可以顺手看一眼。/tmp特别容易被遗忘,有些应用会把临时文件写到那儿且不清理。

du -xh --max-depth=1 /var 2>/dev/null | sort -hr | head -15 find /tmp -type f -mtime +7 -size +100M -exec ls -lh {} \; 2>/dev/null

4. 从救火到预防:让磁盘不再月月告警

手工清理解决的是"这次",要让它不复发,得从 kubelet 的回收机制、日志轮转策略、以及节点巡检三个方向同时下手。这三件事做完,节点磁盘告警的频率通常能从"每周"降到"每季度"甚至更低。

4.1 imageGC 与驱逐阈值:四个参数决定回收行为

kubelet 有两套独立的回收机制,很多人会搞混。

镜像回收(ImageGC)由两个阈值控制:imageGCHighThresholdPercent和imageGCLowThresholdPercent。磁盘使用率超过高水位时触发回收,一直删到低于低水位为止。默认值是 85 和 80,但这两个默认值在现代大容量磁盘上偏激进——一个 1TB 的盘,85% 意味着要涨到 850GB 才开始回收,往往等不到那时候就被驱逐了。

驱逐(Eviction)由evictionHard、evictionSoft等参数控制,是直接驱逐 Pod,比镜像回收更"重"。两者的关系是:镜像回收先跑,把水位降下来;如果降不下来,驱逐兜底。

一个比较稳妥的配置组合(写成 kubelet 的配置文件):

apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration imageGCHighThresholdPercent: 75 imageGCLowThresholdPercent: 65 evictionHard: nodefs.available: "10%" nodefs.inodesFree: "5%" imagefs.available: "15%" memory.available: "500Mi" evictionSoft: nodefs.available: "15%" imagefs.available: "20%" evictionSoftGracePeriod: nodefs.available: "1m30s" imagefs.available: "1m30s" evictionMinimumReclaim: nodefs.available: "2Gi" imagefs.available: "2Gi"

几个参数的选择逻辑值得解释一下。

imageGCHighThresholdPercent设成 75,比默认的 85 提前 10 个百分点。这样在磁盘还没到危险区的时候就开始回收镜像,回收动作对业务无感——只是删掉无人使用的镜像层。低水位设成 65,留出 10 个百分点的回收区间,避免"删一点就停、停一下就涨回去"的抖动。

evictionHard是硬阈值,达到就立刻驱逐,没有宽限期。nodefs.available设 10%,imagefs.available设 15%,后者高一些是因为镜像层增长通常更陡。nodefs.inodesFree单独设 5% 是防 inode 耗尽,这个指标在日志密集的节点上很容易先于容量告警。

evictionSoft配GracePeriod是软驱逐,给 Pod 一段缓冲时间自己退出,比硬驱逐温和得多。evictionMinimumReclaim的作用是防止"每次只回收一点点就停",导致频繁触发。设成 2Gi 表示一次至少回收 2Gi,减少抖动。

注意:imagefs和nodefs在某些部署下是同一个文件系统(比如只有一个数据盘的节点),这时候两个阈值会互相影响,建议先确认节点上docker info或crictl info报的根目录和/var/lib/kubelet是不是同一分区。

4.2 日志轮转:kubelet 与采集端要配对

kubelet 的containerLogMaxSize和containerLogMaxFiles决定了单容器日志的硬上限。默认 10Mi 和 5,也就是 50Mi 封顶,实际场景里这个值偏小,容易被应用日志刷爆导致丢日志,很多团队会调大到 100Mi x 5 或者 200Mi x 3。

containerLogMaxSize: "100Mi" containerLogMaxFiles: 5

这两个参数在 kubelet 配置文件里生效,改完要systemctl restart kubelet。重启 kubelet 不会重启业务容器,但会让节点短暂不可调度,建议在维护窗口做,或者先cordon。

轮转生效之后,日志总占用就变成可预测的:Pod 数量 × 申明周期内的容器数 × 100Mi × 5。一个节点上跑 50 个 Pod、每个 Pod 1 个容器,理论上限就是 25GB,实际远低于此。

但这里有个坑:日志采集端的配置必须和轮转策略对齐。如果采集组件是按 inode 跟踪文件的(比如某些 filebeat 配置),轮转产生的新文件可能不被跟踪,导致日志丢失。稳妥的做法是让采集端按文件名通配 + 记录读取位置,并且显式配置多文件读取。

另一个坑是应用自身的日志写入方式。如果应用往容器内的文件写日志而不是输出到 stdout/stderr,那 kubelet 的轮转完全不生效,这部分日志写在可写层里,既占空间又不受控。这类应用要改造成输出到标准输出,或者在容器内配置 logrotate。

4.3 一套可落地的巡检脚本与自愈思路

策略配好之后,还需要一个兜底的巡检,把"某天某个节点突然飙高"的情况尽早发现。思路是:每天定时跑一次巡检,输出每个节点的磁盘水位、镜像占用、大日志文件清单,超过阈值就告警。

巡检脚本的核心逻辑:

#!/bin/bash # 节点磁盘巡检,输出 JSON 供采集 THRESHOLD=80 ROOT_USAGE=$(df -h / | awk 'NR==2 {gsub(/%/,"",$5); print $5}') IMAGE_USAGE=$(crictl imagefsinfo 2>/dev/null | \ awk '/usedBytes/{gsub(/[^0-9]/,"",$0); print $0; exit}') BIG_LOGS=$(find /var/log/pods -type f -name "*.log" -size +100M 2>/dev/null | wc -l) echo "{\"node\":\"$(hostname)\",\"root_usage_pct\":${ROOT_USAGE},\"image_bytes\":${IMAGE_USAGE:-0},\"big_log_count\":${BIG_LOGS}}" if [ "${ROOT_USAGE}" -ge "${THRESHOLD}" ]; then # 触发告警,可对接你们现有的告警通道 echo "ALERT: root usage ${ROOT_USAGE}% on $(hostname)" fi

这个脚本用 DaemonSet 挂 hostPath 跑,或者用 node-exporter 的 textfile collector 上报。前者的好处是不依赖额外组件,后者可以直接复用现有的监控栈。

自愈的部分要谨慎。我见过有团队写了"磁盘超过 90% 自动跑crictl rmi --prune"的 CronJob,短期看有效,但长期跑下来会把一些本来该保留的镜像删掉,导致 Pod 重启时拉不到镜像。自动清理只建议做三件事:截断超过阈值的日志、清理悬空镜像(--prune)、清理悬空卷。其他的都留给人工判断。

还有一个成本低但效果好的做法:给不同业务类型的节点打标签,用不同的 kubelet 配置。离线计算节点和在线服务节点的磁盘特征完全不同,前者镜像多、Pod 短命,后者日志多、Pod 长寿,用同一套阈值必然有一边不合适。

5. 踩过的坑与排查速查表

清理这件事,做十次可能九次顺利,剩下那一次就会让你记很久。下面这些是从实际故障里总结出来的,每条都对应真实发生过的场景。

5.1 磁盘"删了不释放"的三种真相

第一种:文件被进程持有。前面提过,rm之后 inode 还被进程占着,df看不到变化。用lsof +L1定位,找到进程后重启它。常见持有者是日志采集组件、被删除但没退出的容器进程、以及某些不规范的 agent。

第二种:容器可写层没有随容器删除而释放。有些运行时版本在容器删除后,可写层的目录还在,需要手动清理或者等运行时 GC。表现是crictl ps -a里已经看不到这个容器了,但du统计/var/lib/containerd还是很大。解决办法是重启容器运行时(systemctl restart containerd),代价是节点上的容器会全部重建。

第三种:文件系统层面的碎片或者保留块。ext4 默认给 root 保留 5% 的空间,df报的 available 已经扣掉了这部分。tune2fs -m 1 /dev/sdX可以把保留比例降到 1%,在数据盘上通常安全,但系统盘不建议改,否则 root 出问题时可能连日志都写不进去。

这三种情况的现象很像,都是"明明删了但空间没回来",区分的关键就是lsof +L1有没有输出、du和df的差值有多大。

5.2 常见问题速查表

现象可能原因快速验证处理方式
df -h显示空间已释放,du统计仍很大目录被挂载覆盖mount | grep <dir>卸载后重新统计
清理后空间不降文件被进程持有lsof +L1重启持有进程
Pod 频繁被驱逐但磁盘还有空间kubelet 监控的 imagefs 与 nodefs 不是同一分区crictl imagefsinfo对比df调整阈值或分区规划
日志采集出现断档用rm删了正在采集的日志检查采集组件日志改用truncate,采集端重配
inode 耗尽但容量正常小文件过多(日志、缓存)df -i清理小文件,调整轮转
节点重启后容器全部消失清理时误删了/var/lib/kubelet下活跃目录对比 API Server Pod 列表按 UID 差异精确清理,不要整目录删
镜像 GC 后 Pod 拉不到镜像镜像被其他节点依赖,本地 GC 误删kubectl describe pod看拉取错误配置私有仓库或保留关键 tag

避坑清单,五条,都是我实际踩过的:

  1. 不要整目录rm -rf /var/lib/kubelet/pods/*。节点上正在运行的 Pod 目录混在里面,删了会导致容器异常,表现是容器还在但 kubelet 找不到它,最终触发重建。必须按 UID 差异精确删除。

  2. 不要在 Kubelet 运行中删除/var/lib/containerd下的内容。运行时会持有大量文件句柄,强删会导致运行时状态不一致。要么用运行时命令,要么停服务再清。

  3. 不要用find / -name "*.log" -delete这种命令。会命中的路径远超你想象,包括应用自己管理的日志、数据库的 WAL 文件。范围一定要限定在/var/log/pods和/var/log/containers下面。

  4. 清理前先cordon节点并确认没有新的 Pod 调度过来。尤其是 DaemonSet 类的 Pod,删了目录之后可能被重建到同一节点,边清边写会让统计失真。

  5. 每次清理动作都要留记录。不只是"我删了什么",还要记"删之前的水位、删之后的水位、用了哪条命令"。下次再出问题时,这份记录能帮你快速判断是该清哪一类,而不是从头再排查一遍。

最后分享一个我觉得最有用的习惯:把节点的磁盘趋势图拉出来看斜率,而不是只看绝对值。70% 但一天涨 5% 的节点,比 85% 但一周涨 1% 的节点危险得多。前者说明有一个明确的增长源在持续写,后者可能只是一次性的大镜像没清。盯着斜率做容量规划,比盯着阈值做救火要省心得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 23:50:18

2026年软件测试趋势:AI与自动化测试核心能力解析

1. 2026年软件测试面试趋势与核心能力要求2026年的软件测试领域正在经历一场由AI技术驱动的深刻变革。根据我最近参与的几场大厂技术评审和行业交流会&#xff0c;测试工程师的岗位要求已经发生了显著变化。传统的功能测试岗位比例正在缩减&#xff0c;而自动化测试、性能工程和…

作者头像 李华
网站建设 2026/10/27 23:50:01

纯CPU零样本语音克隆:LuxTTS与Rust实战指南

1. 项目缘起&#xff1a;为什么要在本地 CPU 上折腾语音克隆1.1 一个真实的需求场景事情的起因很简单。我手上有一个用 Rust 写的桌面小工具&#xff0c;基于 Slint 做界面&#xff0c;功能是帮人整理会议纪要。用了一段时间之后&#xff0c;我越来越觉得那个默认的提示音和机械…

作者头像 李华
网站建设 2026/10/27 23:48:29

CentOS7.9下MySQL8.0密码重置与安全配置指南

1. CentOS7.9环境下MySQL8.0密码重置全攻略 MySQL作为最流行的开源关系型数据库&#xff0c;在日常运维中密码管理是基础但关键的操作。不同于早期版本&#xff0c;MySQL8.0在身份验证机制和密码策略上做了重大调整&#xff0c;这导致很多从5.7升级过来的管理员在密码重置时会遇…

作者头像 李华
网站建设 2026/10/27 23:48:17

城市数字化转型:现状、挑战与关键技术解析

1. 城市数字化转型的现状与挑战2025年的城市全域数字化转型&#xff0c;正在从单点突破走向系统重构。过去五年间&#xff0c;我们看到北上广深等一线城市的"城市大脑"项目已初步实现交通、安防等垂直领域的数字化&#xff0c;但区县层级的数字化渗透率仍不足30%。这…

作者头像 李华
网站建设 2026/10/27 23:45:58

YOLO26与DLGPE模块:多尺度目标检测的创新突破

1. 项目概述&#xff1a;YOLO26与DLGPE模块的创新价值在计算机视觉领域&#xff0c;目标检测算法的演进从未停歇。YOLO系列作为单阶段检测器的代表&#xff0c;其最新迭代版本YOLO26通过引入DLGPE&#xff08;Dynamic Local-Global Parallel Encoder&#xff09;动态局部-全局并…

作者头像 李华
网站建设 2026/10/27 23:45:31

Agent Harness设计中的关键权衡:从抽象层到安全边界的落地实践

做 agent 开发这几年&#xff0c;我见过太多项目把精力都放在模型选型和 prompt 调优上&#xff0c;结果真正让项目卡死的&#xff0c;往往是那一层看起来不起眼的 Harness。很多人第一次听到“agent Harness”这个词时会愣一下&#xff1a;它不是模型&#xff0c;不是 agent 本…

作者头像 李华