挂载根的磁盘空间太小,这次咱们一次性解决
只要跑过Linux服务器的人,基本都被“挂载根”的分区容量告警折磨过。df -h一敲,红字跳出来,根分区使用率冲到95%以上,紧接着就是服务无响应、日志写不进去、SSH卡到怀疑人生。这篇文章不是科普,是我把过去几年处理根分区爆满问题的所有经验整理出来,从诊断到清理再到扩容,直接给你一套能落地的方案,适合刚接触Linux的新手,也适合被生产环境磁盘问题搞到头大的运维同行。
先说清楚根分区为什么会这么容易满。根分区是所有系统文件的起点,/usr、/var、/home、/tmp全挂在它下面,系统日志、软件包缓存、容器镜像、数据库文件,只要规划时没做好隔离,所有数据都会往里面堆。而且很多人在安装系统时习惯用“使用整个磁盘”的默认选项,或者手工分区时只给根分区留了二三十GB,等跑起来才发现根本不够用。更被动的是根分区通常位于磁盘靠前的位置,想直接扩大小区必须处理前后物理块的问题,不像数据分区一样说改就改。
我见过太多因为这个细节翻车的例子。最典型的是某台CentOS服务器,根分区用了LVM,逻辑卷明明还有几十GB空闲,但物理卷所在磁盘已经满了,非LVM场景则直接卡在“前面有空闲空间但后面被其他分区占着”的尴尬局面。这篇文章会把这些场景全部拆开讲,每一招怎么用、为什么这么用、踩过什么样的坑,都写清楚,你按顺序做完基本能恢复可用状态。
1. 动手之前,先搞清楚根分区里到底堆了什么东西
很多人的第一反应是“直接删文件”,但删什么、能不能删、删了之后会不会引发其他问题,这些问题没想明白就动手,反而容易把系统搞挂。在做任何清理或扩容操作之前,先花几分钟把根目录下的空间分布摸清楚,这才是省时间的关键。
1.1 根文件系统的基本盘:核心目录与常见占用大户
根文件系统也就是挂载根这一层,所有目录都从/开始。理解里面的目录结构是诊断空间去向的前提,不同目录的用途完全不一样,占用增长的原因也各不相同。
/usr:系统软件的主体目录。所有通过yum、apt、dnf安装的软件包基本都在这里,依赖库、二进制文件、系统工具全集中在此。这个目录的体量通常在几个GB到十几个GB之间。/var:一块“变动的”数据集合地。日志(/var/log)、缓存(/var/cache)、邮件(/var/spool)都在这里。这台机器如果跑着数据库或Web服务,数据库文件放/var/lib/mysql之类路径时,增长最快的就是它。/home:普通用户的数据目录。如果运行的是个人开发机,代码工程、虚拟环境、下载文件全在这;如果是生产服务器,这一般是独立分区,但如果规划不合理也会挤占根分区。/tmp:临时文件目录,很多应用程序没有及时清理的临时文件会长期滞留,重启后部分内容会保留。/boot:内核与引导文件。多次系统升级后,旧内核如果一直没清理,这个分区也会悄悄满。
占用大户随应用场景变化很大,跑着数据库的机器,膨胀点通常在/var/lib/mysql;长时间不重启的服务器,膨胀点在/var/log/journal;喜欢用Docker或Podman的环境,镜像和容器层会把/var/lib/docker撑到几十甚至上百GB。线上服务器频繁更新软件包时,/var/cache/yum或/var/cache/apt也会积攒大量缓存文件,这些都是清理排查时的首要对象。
1.2 为什么根分区总是不经意就满了:从历次踩坑看规划失误
回顾几次典型的根分区爆满事故,原因都集中在几个方面。第一个是安装系统时没有精细化分区,直接选择自动分区。这种情况系统往往只分配很小的空间给根分区,后续想调整时发现邻居分区没有预留空间,只能看着剩余磁盘发愁。第二个是服务器跑着跑着业务升级,数据库目录、日志目录、应用生成的临时数据以前都直接写在根分区下,没有做目录挂载隔离,空间就开始悄悄被吃光。第三个是应用日志轮转策略失效,日志文件无限增长,/var/log目录占用从一个平时只有几百MB的目录膨胀成几十GB的大户。
还有一类比较隐蔽的情况是:根分区本身用的是LVM,你有多余的物理卷空间可以扩容,但是卷组的可用空间检查不及时,或者用户在不知情的情况下给其他逻辑卷分配了空间,导致根逻辑卷想扩却扩不出去。这类问题只靠“删文件”解决不了,必须走扩容路线。
提醒一句:排查根分区占用时,先看
df -hT确认挂载点对应的文件系统类型和设备,再看挂载关系,确认是否存在某些大目录因为挂载了其他磁盘而并不占用根分区的情况。没有挂载的大目录才是真正需要关注的占用点。
1.3 诊断定位基本功:从df到du再到ncdu的三步走
诊断过程有一套比较固定的思路,我每次处理都按这个流程走,基本不会漏掉关键信息。
第一步,用df -hT确认整体情况和文件系统类型。df展示的是整个文件系统的容量使用情况,重点看挂载点为/的行。如果这行使用率超过80%,就该警觉了;超过90%,后续操作要尽快进行。-T参数会显示文件系统类型,LVM逻辑卷、ext4、xfs、btrfs类型不同,后面扩容方案也完全不同。
# 查看根分区挂载情况,确认文件系统类型 df -hT # 查看inode使用情况,inode耗尽也会导致无法写入文件 df -i第二步,用du逐层深入定位大目录。du统计的是目录的实际占用量,比df更细。先从根目录开始,筛出占用最大的目录,然后逐层进入,一层层逼近问题源头。
# 统计根目录下第一层目录的大小,sort排序后看前10名 du -x -h --max-depth=1 / | sort -rh | head -10-x参数表示不跨越文件系统边界,这个特别重要。如果系统里挂着其他磁盘,不加-x会让du把其他分区的内容也统计进来,干扰判断。得到第一层结果后,再进入占用最大的目录,用同样的命令继续往下追。
# 假设 /var 最大,继续查看 /var 下的详情 du -x -h --max-depth=1 /var | sort -rh | head -10第三步,如果环境允许,用ncdu做交互式排查。ncdu可以在一个终端界面里快速浏览目录和文件大小,按d键删除不需要的文件,按n按文件名排序,按s按大小排序。处理大量文件时,效率比一条条敲du高很多。
# 安装 ncdu apt install ncdu # Ubuntu/Debian yum install ncdu # CentOS/RHEL # 扫描根目录 ncdu / -x还有一个经验上的细节:du在遍历大型目录时耗时会比较久,但如果文件数特别多,这个等待是值得的。找准大目录才能精准下手,否则在错误的地方反复折腾只会浪费时间。
2. 先别急着扩容,这些空间是可以安全释放的
在考虑扩容之前,先做一轮彻底的清理往往就能释放出可观的容量。很多人一看到磁盘满就想着扩容,但实际上系统里堆了大量根本不用的缓存、过期日志和临时文件,清理完直接就能恢复健康状态。
2.1 包管理器缓存清理:安全释放最容易忽略的一块
主流Linux发行版的包管理器都会在安装或升级软件时留下缓存。Ubuntu/Debian系缓存放在/var/cache/apt/archives,CentOS/RHEL系缓存放在/var/cache/yum或/var/cache/dnf。跑了一段时间的机器,这个目录攒下好几个GB并不稀奇。
# Ubuntu/Debian 系统清理 apt 缓存 apt clean # 只清理过期的软件包缓存 apt autoclean # 移除不再需要的依赖包 apt autoremoveCentOS/RHEL系的操作:
# 清理 yum 缓存(旧版本) yum clean all # 清理 dnf 缓存(新版本) dnf clean all # 清理过期的内核头文件和开发包 yum autoremoveapt clean会把所有下载的软件包删掉,好处是空间回收彻底,代价是下次安装软件要重新下载。autoclean只删掉版本过期的包,更保守一点。一般推荐先autoclean再autoremove,把不需要的依赖一并清掉。
清理完成后看下效果:
df -h /这里顺便提一个很多新手不知道的知识点:固件更新等系统级改动也会在/var/cache留下备份文件,这些备份文件如果确认当前运行状态正常,也可以手动清理。但这点要谨慎——对于服务器系统,建议至少保留最近一份可用状态。
2.2 日志文件与journal日志的处理策略
日志是另一个“看不见的膨胀大户”。特别是使用systemd的现代发行版,系统日志统一由journald管理,默认情况下日志会占用/var/log/journal目录,而且不会自动缩减容积。
journalctl命令可以快速确认日志占用了多少空间:
# 查看journal日志占用磁盘空间 journalctl --disk-usage如果输出显示占用好几个GB,可以用以下命令进行清理:
# 清理journal日志,只保留最近2天 journalctl --vacuum-time=2d # 限制journal日志文件总大小不超过200M journalctl --vacuum-size=200M这些命令会立即释放/var/log/journal目录占用的空间。但如果想彻底防止日志再次无限增长,需要修改journald的配置文件。编辑/etc/systemd/journald.conf:
[Journal] # 限制日志最大占用空间 SystemMaxUse=500M # 单文件最大大小 SystemMaxFileSize=50M # 日志文件最多保留数量 MaxRetentionSec=7day修改后重启journald服务:
systemctl restart systemd-journald这里有一个细节容易忽略:修改journald配置之前,要把原有日志先清理一次,否则重启后它会尝试先压缩旧日志,可能会短暂占用额外磁盘空间。我的习惯是:先做journalctl --vacuum-size,再改配置,最后重启服务。
对于传统的文本日志,比如应用输出的/var/log/nginx/access.log、/var/log/messages等,用logrotate做转轮切割。确认配置在/etc/logrotate.d/目录下按需调整即可,常见错误是logrotate配置了但没设置compress选项,导致切割后的旧日志还是很大:
# 查看logrotate是否正常运行 cat /var/lib/logrotate/status如果发现日志轮转没生效,直接手动执行一次:
logrotate -f /etc/logrotate.conf清理日志的底线是不要直接删正在被进程写入的文件。因为进程会一直持有文件句柄,即使你删掉了文件,空间也不会释放,直到服务重启。正确做法是通过logrotate或journalctl来管理。
2.3 这些“冗余文件”也能安全清掉,但有一个底线
系统运行过程中还会产生各种临时文件和缓存,这些也可以放心清:
/var/tmp:系统重启后不会自动清理的临时文件。长时间运行的机器,这里会堆积很多老旧文件。/tmp:部分进程异常退出时留下的临时文件。但注意有些进程还在使用,删除前最好用lsof +L1查一下。/var/cache/man:man命令的索引缓存,删掉后下次使用man时会重新生成。/root/.cache:root用户的缓存目录,某些命令和工具会往这里写数据。- 旧内核:每次系统升级都会保留上一版内核,
/boot空间紧张的机器可以考虑删除旧内核。但删除前务必保留至少两个可用内核。
清理旧内核时要特别注意:不要手动强删/boot下的vmlinuz等文件,正确方法是使用系统的包管理器。Ubuntu/Debian系可以自动清理:
# 查看当前内核版本 uname -r # 列出所有已安装的内核 dpkg --list | grep linux-imageCentOS/RHEL系用包管理器删除旧内核后,再更新一下grub引导配置:
# 查看已安装的内核包 rpm -qa | grep kernel # 删除指定版本的旧内核 yum remove kernel-旧版本号 # 更新引导配置 grub2-mkconfig -o /boot/grub2/grub.cfg底线是:别把正在使用的内核删掉,也别把所有旧内核一次清空。万一新内核有问题,旧内核至少还能拉你一把。
2.4 容器与镜像占用:Docker环境下的隐藏空间黑洞
如果机器上装了Docker,/var/lib/docker很可能是一个巨大的空间消耗点。镜像层、多层缓存、停止状态的容器、没用的网络和挂载卷,全都堆在里面。
# 查看Docker磁盘占用概览 docker system df这个命令会清楚列出镜像、容器、本地卷、构建缓存分别用了多少空间。清理操作也很成熟:
# 清理所有停止的容器、未被使用的网络、悬空镜像和构建缓存 docker system prune -a --volumes对于个人开发机,这么清理一般没问题。但对于生产环境,要慎重处理--volumes参数,因为会连没有容器引用的数据卷一并删除——如果你的容器数据是用普通volume而不是绑定挂载方式存储的,那可能直接导致数据丢失。
更稳妥的方式是分层清理:
# 只清理悬空镜像(没有标签且没被容器引用的镜像) docker image prune # 只清理构建缓存 docker builder prune清理结束后再跑一遍df -h /,通常能释放不少空间。我在一台跑了十几个容器的机器上清出过40多GB,数据量相当可观。
2.5 清理操作汇总:一句代码、一条命令、一个安全注意事项
把常见的“直接删”操作整理成一个速查表,方便实际操作时对照:
| 目标 | 查看占用 | 清理命令 | 注意事项 |
|---|---|---|---|
| apt缓存 | du -sh /var/cache/apt | apt clean/apt autoclean | 清掉后下次装软件要重新下载 |
| yum/dnf缓存 | du -sh /var/cache/yum | yum clean all/dnf clean all | 对线上环境影响不大 |
| journal日志 | journalctl --disk-usage | journalctl --vacuum-size=200M | 建议改配置文件限制上限 |
| Docker镜像 | docker system df | docker image prune -a | 别乱加--volumes |
| 旧内核 | rpm -qa | grep kernel | yum remove 旧内核包 | 保留当前和最近一两版 |
| 临时文件 | du -sh /tmp | find /tmp -type f -atime +30 -delete | 确认没有进程引用 |
| 软件日志 | du -sh /var/log | logrotate轮转 | 别手动删正在写的日志 |
清理完再跑一遍df -hT,确认根分区负载降下来了。如果降到80%以下,日常使用问题不大;如果还是很高,那就必须走扩容路线了。
3. 真正的大招:给挂载根做“扩容”
清理只能缓解短期问题,如果业务增长把根分区塞满,扩容才是治本方案。扩容方案根据文件系统类型和磁盘状况分成几条路线,下面把每种情况都讲透。
3.1 分区规划检查:判断能否在线扩,还是需要新增磁盘
扩容之前要先判断现有环境属于什么情况。用lsblk -f看当前磁盘的分区结构,用vgs和lvs看LVM情况:
# 查看所有块设备与文件系统 lsblk -f # 查看逻辑卷与卷组状态(LVM场景) vgs lvs常见场景分为三类:
- 根分区在LVM卷组上,且卷组还有空闲空间,或者物理磁盘上还有未划分的空间可以加入卷组——这是最理想的情况,可以直接在线扩容。
- 根分区是传统物理分区(ext4或xfs),没有使用LVM,且分区后面紧跟着其他分区——这种情况不能直接在线扩容,需要更复杂的操作(或者用新磁盘方案)。
- 当前磁盘已经完全没空间了,或者虚拟机可以加一块新磁盘——优先走新增磁盘并迁移目录的路线。
在开始任何扩容操作前,务必备份关键数据。千万别嫌麻烦,生产环境扩容时断电、操作失误导致分区表损坏的教训我都见过,备份之后再动手才能安心。
3.2 LVM在线扩容实操:从pvcreate到resize2fs的完整流程
LVM是在线扩容的首选方案。假设当前根逻辑卷/dev/ubuntu-vg/ubuntu-lv快满了,而物理卷所在的磁盘还有未分配的空间。流程分为四个步骤:创建物理卷、扩展卷组、扩展逻辑卷、扩容文件系统。
第一步,如果新磁盘或未分区空间需要初始化,先创建物理卷。假设新磁盘是/dev/sdb:
# 创建物理卷 pvcreate /dev/sdb # 查看物理卷 pvs如果原物理卷所在磁盘还有未分配空间,需要先扩展物理卷。比较典型的场景是虚拟机扩容了虚拟磁盘,但分区表还没将新增空间纳入。这时先调整分区:
# 用 parted 或 fdisk 将剩余空间创建为新分区 parted /dev/sda (parted) print free (parted) mkpart primary ext4 结束扇区位置 100% (parted) quit # 创建物理卷(或扩展已有物理卷) pvcreate /dev/sda2 # 如果新分区 # 或者扩展原有物理卷,例如 /dev/sda1 pvresize /dev/sda1第二步,将物理卷加入卷组:
# 将新物理卷加入已有卷组。卷组名用 vgs 查询 vgextend ubuntu-vg /dev/sdb # 或者对该卷组重新扫描,PV大小变化后更新卷组 vgscan vgdisplay第三步,扩展逻辑卷。例如把根逻辑卷/dev/ubuntu-vg/ubuntu-lv扩展到占用卷组所有剩余空间:
# 将逻辑卷扩展到全部空闲空间 lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv # 或者扩展指定大小,例如增加20G lvextend -L +20G /dev/ubuntu-vg/ubuntu-lv第四步,最关键的一步——同步文件系统大小。很多人忘了这一步,导致逻辑卷扩大了,但文件系统还是原大小,df -h没变化。
# ext4 文件系统使用 resize2fs resize2fs /dev/ubuntu-vg/ubuntu-lv # xfs 文件系统使用 xfs_growfs,挂载点作为参数 xfs_growfs /扩展完成后验证:
df -hT / lvdisplay提醒:xfs文件系统不支持缩小,所以扩容前必须确认逻辑卷的目标大小,别扩过头了。ext4在未挂载时支持缩小,但也极不建议在生产环境做缩小操作。
3.3 非LVM物理分区的扩容技巧:ext4和xfs各有什么限制
如果根分区没用LVM,情况会麻烦一些。传统分区方案要扩容,核心难点在于根分区后面的空间是否可用。
一种可行方案是使用GParted Live CD或SystemRescue盘启动系统,离线调整分区。操作时要先把根分区收缩或者利用相邻空闲空间,流程比较繁琐,但确实可行。步骤如下:
- 备份重要数据。
- 从Live USB启动系统,不要在目标系统运行时操作。
- 在GParted界面中,先删除根分区后面紧挨着的独立分区(或者先将其缩小),腾出连续空闲空间。
- 将根分区拖拽扩大,应用操作。
- 重启系统后,进入系统再对文件系统做一次扩容。
但这个方案有一个很大的限制:如果根分区后面紧挨着/boot分区或者swap分区,那么需要先把这些分区移开,整个操作复杂度翻倍。物理机上这么操作还存在断电风险,一旦中途断电,分区表损坏的概率会明显增加。
相比折腾物理分区,我更推荐下面这个新磁盘挂载方案,步子更稳、风险更小。
3.4 新增磁盘并挂载到指定目录:把“大目录”巧妙移出去
当原磁盘空间确实已经无法扩展时,最稳妥的做法是挂载一块新磁盘,把占用大的目录迁移过去。比如数据库中某个数据目录或/var/lib/docker这类无限增长的目录,直接把它迁到新磁盘上。
假设新磁盘是/dev/sdb,需要格式化并挂载到新目录,然后迁移数据:
# 1. 格式化新磁盘为 ext4(或 xfs) mkfs.ext4 /dev/sdb # 2. 创建临时挂载点,挂载新磁盘 mkdir -p /mnt/newdisk mount /dev/sdb /mnt/newdisk # 3. 通过 rsync 同步原目录数据到新磁盘 rsync -avxHAX --numeric-ids /var/lib/docker/ /mnt/newdisk/ # 4. 确认数据完整后,重命名原目录 mv /var/lib/docker /var/lib/docker.bak # 5. 创建原目录路径,把新磁盘挂上去 mkdir -p /var/lib/docker mount /dev/sdb /var/lib/docker # 6. 写入 /etc/fstab 实现开机自动挂载 blkid /dev/sdb把blkid查出的UUID写入/etc/fstab:
UUID=xxxxxx /var/lib/docker ext4 defaults 0 2完成后重启或先reload systemd验证挂载配置无误:
mount -a确认无误后,原来备份的目录可以删除:
rm -rf /var/lib/docker.bak这套方案的好处是:不动原分区表,不影响系统引导,迁移过程相对可控。缺点是需要短暂停掉相关服务,因为在迁移过程中写数据会产生不一致。具体操作时,最好在迁移前先停掉Docker服务或其他依赖该目录的服务,迁移完成后重新启动即可。
3.5 虚拟机场景的磁盘扩展细节:VMware与VirtualBox怎么处理
如果跑在虚拟机上,扩容的原生做法是在宿主机上先扩展虚拟磁盘。扩展完后,虚拟机内部需要让系统识别到新增空间。
VMware场景:编辑虚拟机设置,扩展硬盘大小,然后进入虚拟机内部执行以下操作:
# 让内核重新读取分区表 partprobe # 如果磁盘已经有分区,扩容分区 # 以 /dev/sda 为例,用 fdisk 交互式调整主分区大小 fdisk /dev/sdaVirtualBox场景:同样在虚拟机设置中扩展VDI/VHD大小,然后内部重读分区表。如果系统无法识别扩容后的空间,可能需要关机重启,让虚拟机重新扫描磁盘。
在VMware虚拟机中,如果原来的根分区就是LVM,流程更直接:扩展了虚拟磁盘后,直接用pvresize /dev/sda扩展物理卷,然后lvextend+resize2fs搞定,这样分区表不用动,风险小得多。
# 扩展物理卷到最大空间 pvresize /dev/sda # 查看卷组可用空间 vgdisplay # 扩展逻辑卷和文件系统 lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv resize2fs /dev/ubuntu-vg/ubuntu-lv4. 实战中的高频坑位与排查诀窍
清理和扩容操作看起来简单,但实际上处处有坑。把这几年来遇到过的典型问题和处理心得整理在这里,希望能帮你少走弯路。
4.1 高频问题速查表
| 现象 | 原因 | 解决办法 |
|---|---|---|
df -h显示已满,但du统计不到大文件 | 文件被进程删除但未释放句柄 | lsof | grep deleted找出进程,重启服务或kill进程 |
| inode已满但磁盘空间还有 | 小文件数量过多 | df -i确认,清理大量零碎小文件(如缓存目录) |
扩容后df -h没变化 | 文件系统没有同步扩容 | 执行resize2fs或xfs_growfs |
lvextend提示卷组空间不足 | 卷组没有空闲空间可分配 | 用pvcreate+vgextend加入新物理卷 |
| 删了日志文件但空间没释放 | 进程还在写被删文件的句柄 | systemctl restart rsyslog或相关服务 |
| 根分区外还有空闲磁盘但无法在线扩 | 非LVM且分区相邻空间被占 | 走新磁盘挂载迁移目录方案 |
| Docker清理后空间还是大 | 挂载卷中存了有效数据未清理 | docker system df -v查看具体卷占用 |
补充一下第一个问题:文件被进程删除后但进程未退出,文件占用的空间不会释放。用lsof | grep deleted找出这些进程也是运维排查中的常用招数。判段后,能重启服务就重启服务,不能重启的评估业务影响后再kill。
4.2 排查技巧与个人心得
第一个心得:任何清理操作前,先看df -i。很多运维只看容量,结果删了半天发现是inode耗尽导致的无法写入。一个小细节:即使在同一个分区,inode满了和容量满了处理思路完全不同。/var/spool/postfix/maildrop这类目录经常因为大量小文件耗尽inode,这种问题用大而化之的“删文件”方式不一定解决问题,得找到具体的目录精准清理。
第二个心得:删除文件时用rm还是其他方式?如果你删的是超过几GB的大文件,推荐的顺序是先用truncate把文件“截断”,再删除。比如:
# 先将日志文件大小截断为0,让进程继续写入不中断 truncate -s 0 /var/log/nginx/access.log # 确认路径删除或交由logrotate处理 rm /var/log/nginx/access.log直接rm在文件被进程占用时会导致空间不释放,截断则不会出现“删除后df没变”的情况。这个细节在处理正在写入的日志时非常实用。
第三个心得:在虚拟机里扩容根分区前,先做一次快照。VMware、VirtualBox都支持在线或离线快照,操作失误时能一键还原。我接触过不少人在生产环境扩容失败后,因为没有快照只能整机重装,那感觉实在难受。
第四个心得:扩容后务必检查挂载配置是否正确。/etc/fstab写错UUID会导致重启后系统挂载失败,直接进入emergency模式。一个通用做法是:写入/etc/fstab后用mount -a验证,再执行reboot前顺手确认:
# 检查fstab语法 findmnt --verify --verbose这条命令会逐行验证fstab配置的有效性,绝大多数配置错误都能提前暴露。
4.3 容器环境特殊排查:Docker根目录迁移细节
Docker环境遇到根分区空间不足时,除了清理,也可以把Docker的数据目录整体迁移到大磁盘。修改Docker daemon配置:
{ "data-root": "/data/docker" }保存后重启Docker:
systemctl restart docker但要注意顺序:最好先停掉Docker,把原目录整个移动过去,再改配置启动。顺序反了,Docker启动时会发现目录中数据缺失,反而会重新初始化。
还有一个容易出问题的点:新数据目录的SELinux标签或权限。一台启用SELinux的CentOS机器上迁移过Docker目录,忘了处理标签,结果容器全都启动失败。解决办法是:
# 给新数据目录打上容器运行时需要的SELinux标签 semanage fcontext -a -t container_var_lib_t "/data/docker(/.*)?" restorecon -Rv /data/docker不强求大家立刻理解SELinux的底层原理,但迁移数据目录后检查SELinux上下文这一步骤千万别省。
写在最后的几条实操建议
操作之前,先确认当前系统的文件系统类型再选方案:LVM走lvextend加resize2fs或xfs_growfs,非LVM优先考虑新增磁盘迁移目录。从时间成本上看,新增磁盘迁移大目录通常比动分区表快得多,风险也更低。
清理日志和缓存时,把“日志轮转是否正常”作为一个运维检查点定期过一遍。很多根分区爆满的机器,根源就是日志轮转失效没被发现。给journald设置SystemMaxUse,给应用日志配好logrotate的rotate、compress、maxsize参数,这类问题就会自动消解。
最后再分享一个小技巧:每次做磁盘清理前,把清理前的空间使用率记下来,清理后对比确认释放效果,顺便记录一下多轮数据。长期坚持下来,你能摸清这台机器磁盘增长的真实规律,后续规划会更从容。
我个人实际用下来觉得最顺手的一套组合是:df -hT查总览 +du -x --max-depth=1定位大目录 +ncdu交互式整理,三步下来一般就能判断问题出在哪。如果你按照这篇文章的步骤操作完,根分区还是告急,那就要认真考虑新增磁盘并调整目录挂载结构了。只要前期诊断做得足够细,处理方案的选择就会很清晰,这也正是处理这类问题时最值钱的经验。