Docker根分区告警?LVM在线扩容实战与避坑指南

1. 磁盘告警背后的真相:为什么容器环境总先撑爆根分区

凌晨两点,监控面板上那台跑了十几个容器的宿主机突然飘红,/dev/mapper/centos-root使用率冲到 98%,Docker 日志写入直接卡死,几个业务容器开始反复重启。这种场景我遇到过不止一次,几乎成了容器化部署的"月经贴"。很多人第一反应是"磁盘不够就加盘",但真正的问题往往不在容量本身,而在于根分区被 Docker 的数据目录、镜像层、容器日志和临时文件共同蚕食,而/dev/mapper/centos-root恰恰是 CentOS 默认 LVM 布局里最容易被忽视的那块逻辑卷。

先把概念理清楚。/dev/mapper/centos-root不是一块物理磁盘,它是 LVM(Logical Volume Manager,逻辑卷管理)体系下centos卷组里的一个逻辑卷,通常挂载在/根目录。CentOS 7 及更早版本默认安装时,会把大部分剩余空间划给root逻辑卷,而/home往往只分到很小一块。Docker 默认把数据放在/var/lib/docker,这个路径就在根分区下面,于是镜像、容器可写层、日志、卷数据全部堆在centos-root上。镜像拉得越多、容器跑得越久、日志不清理,根分区就越危险。

这篇文章面向的是已经在生产或测试环境跑 Docker、并且遇到根分区告警的运维和开发人员,也适合刚接触 LVM 想搞清楚扩容逻辑的新手。我会从 LVM 的底层结构讲起,把"为什么能在线扩容""扩容前必须确认什么""具体命令怎么敲""踩过哪些坑"全部摊开讲。你不需要停机重装系统,也不需要把数据搬来搬去,只要卷组里还有空闲空间,扩容就是几条命令的事。但如果卷组也满了,那就得先解决物理层的问题,这部分我也会讲清楚。

需要提前说明的是,扩容本身是在线操作,LVM 和 XFS 文件系统都支持在线扩展,不需要卸载分区、不需要重启。但"在线"不等于"无风险",操作前该做的备份、该确认的挂载点、该检查的文件系统类型,一个都不能省。下面我按实际排查和操作的顺序,把整个流程拆开讲。

2. LVM 三层结构拆解:扩容到底扩的是哪一层

2.1 物理卷、卷组、逻辑卷的关系

要搞懂扩容,先得把 LVM 的三层结构吃透。我用一个生活化的类比:物理卷(PV)像一块块砖头,卷组(VG)像把这些砖头垒成的一面墙,逻辑卷(LV)像从这面墙上切出来的一块块区域。你可以往墙里加砖头(加物理卷),也可以把某块区域切大一点(扩逻辑卷),只要墙上还有没被切走的面积。

对应到命令层面:

  • PV(Physical Volume):物理卷,通常是/dev/sda3、/dev/sdb1这样的分区,或者整块盘。用pvs、pvdisplay查看。
  • VG(Volume Group):卷组,把多个 PV 聚合成一个资源池。用vgs、vgdisplay查看,重点看VFree(剩余空闲空间)。
  • LV(Logical Volume):逻辑卷,从 VG 里划分出来的实际使用单元,/dev/mapper/centos-root就是其中一个。用lvs、lvdisplay查看。

扩容的本质就一句话:从 VG 的空闲空间里再切一块给 LV,然后让文件系统识别到这块新空间。所以第一步永远是确认 VG 有没有空闲空间。如果VFree是 0,那再怎么敲lvextend都没用,得先加物理卷或者清理空间。

2.2 为什么 CentOS 默认布局容易出问题

CentOS 7 的默认分区方案里,/根分区通常拿到 50G 左右,剩下的空间可能分给/home或者干脆没分配。而 Docker 一上来就把/var/lib/docker放在根分区下,一个中等规模的镜像动辄几百 MB 到几个 GB,跑上十几个容器,日志再一累积,50G 很快见底。更麻烦的是,很多人装系统时选了"自动分区",LVM 结构是自动生成的,自己都不清楚 VG 里还剩多少空间。

我见过最典型的情况是:vgs一看,VFree还有 200G,但根分区就是满了。这种最好办,直接扩 LV 就行。另一种情况是VFree为 0,但物理机上还有未分配的磁盘或未使用的分区,那就得先pvcreate再vgextend,把新空间加进 VG,然后再扩 LV。还有一种最被动的:物理盘本身就没空间了,那只能加新硬盘或者迁移数据,这属于另一个层面的问题。

2.3 扩容前必须确认的四件事

在敲任何命令之前,我习惯先做四项检查,这几步能避免 90% 的翻车:

  1. 确认挂载点和文件系统类型:df -Th看/dev/mapper/centos-root挂在哪、是什么文件系统。CentOS 7 默认是 XFS,CentOS 6 是 ext4,两者扩容命令不同。
  2. 确认 VG 剩余空间:vgs看VFree,这是能不能直接扩的关键。
  3. 确认是否有快照:如果这个 LV 上有 LVM 快照,扩容前要特别小心,快照空间不足会导致快照失效。
  4. 确认备份:虽然在线扩容很成熟,但涉及分区操作,重要数据该备份还是得备份。我一般会至少确认数据库已经做了逻辑备份。

提示:XFS 文件系统只能扩大不能缩小,这是它和 ext4 最大的区别。如果你扩错了想缩回去,XFS 是做不到的,只能备份数据重建。所以扩容前想清楚要加多少,宁可一次加够,别反复折腾。

3. 实操全流程:从告警到扩容完成的每一步

3.1 现场诊断:先看清楚磁盘到底怎么分的

登录机器第一件事不是急着敲扩容命令,而是把现状摸清楚。我通常按这个顺序来:

# 看各分区使用率和文件系统类型 df -Th # 看 LVM 逻辑卷、卷组、物理卷的概况 lvs vgs pvs # 看块设备整体情况 lsblk

df -Th的输出里,你会看到类似这样一行:

/dev/mapper/centos-root xfs 50G 48G 2.1G 96% /

这说明根分区是 XFS,总共 50G,已经用了 48G。接着vgs的输出:

VG #PV #LV #SN Attr VSize VFree centos 1 3 0 wz--n- 299.00g 200.00g

这里VFree有 200G,说明卷组里还有大量空闲空间,直接扩 LV 就行。如果VFree是 0,那就要看pvs和lsblk,确认有没有未使用的磁盘或分区可以加进来。

我特别建议用lsblk看一眼整体结构,它能直观显示磁盘、分区、LVM 的层级关系:

sda 8:0 0 300G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 299G 0 part ├─centos-root 253:0 0 50G 0 lvm / ├─centos-swap 253:1 0 4G 0 lvm [SWAP] └─centos-home 253:2 0 45G 0 lvm /home

看到这个结构,心里就有数了:sda2是 LVM 的物理卷,centos卷组建立在它上面,root、swap、home是三个逻辑卷。如果home用不上,甚至可以考虑从home缩容再扩给root,但 XFS 不支持缩容,这条路对 XFS 走不通,只能靠 VG 空闲空间或加新盘。

3.2 情况一:VG 有空闲空间,直接扩 LV

这是最省事的情况。假设我要把根分区从 50G 扩到 100G,也就是增加 50G。命令分两步:先扩逻辑卷,再扩文件系统。

# 第一步:扩展逻辑卷,增加 50G lvextend -L +50G /dev/mapper/centos-root # 第二步:扩展 XFS 文件系统,让它占满整个逻辑卷 xfs_growfs /

如果是 ext4 文件系统,第二步换成:

resize2fs /dev/mapper/centos-root

这里有个细节值得说清楚:lvextend的-L +50G表示"在现有基础上增加 50G",而-L 100G表示"扩展到总共 100G"。这两个写法差别很大,用错了要么扩不够要么报错。我一般用+的写法,因为不用去记当前容量,直接说加多少更直观。

xfs_growfs后面跟的是挂载点,不是设备路径。这一点很多人会搞混,写成xfs_growfs /dev/mapper/centos-root会报错。而resize2fs后面跟的是设备路径。这是 XFS 和 ext4 在扩容命令上的一个关键区别,记牢了能少踩坑。

执行完再df -Th看一眼,根分区应该已经变成 100G 了。整个过程几秒钟,业务无感知。

3.3 情况二:VG 没空间,先加物理卷再扩

如果vgs显示VFree为 0,但机器上还有未使用的磁盘(比如/dev/sdb)或者未分配的分区,那就得先把新空间加进 VG。假设/dev/sdb是一块全新的 500G 磁盘:

# 第一步:把新磁盘创建为物理卷 pvcreate /dev/sdb # 第二步:把新物理卷加入 centos 卷组 vgextend centos /dev/sdb # 第三步:确认卷组空间已增加 vgs # 第四步:扩展逻辑卷 lvextend -L +200G /dev/mapper/centos-root # 第五步:扩展文件系统 xfs_growfs /

这里有个容易忽略的点:pvcreate会清空磁盘上的分区表和文件系统签名。如果/dev/sdb上还有数据,这一步会直接毁掉。所以执行前一定要用lsblk和blkid确认这块盘是干净的、没有挂载、没有重要数据。我见过有人把数据盘误当成新盘pvcreate,结果数据全没了,这种事故完全可以在操作前用一条blkid /dev/sdb避免。

另外,如果新空间是磁盘上的一个未使用分区(比如/dev/sdb1),那pvcreate的对象就是/dev/sdb1,而不是整块盘。用fdisk -l或parted -l能看清楚分区情况。

3.4 情况三:物理盘也满了,只能加盘或迁移

最被动的情况是物理磁盘本身没有剩余空间,也没有空闲分区。这时候有几条路:

  • 加新硬盘:物理机加盘,或者云主机挂载新云盘,然后按 3.3 的流程pvcreate+vgextend+lvextend。
  • 迁移 Docker 数据目录:把/var/lib/docker迁到一块独立的大盘上,从根分区卸载压力。这个方案治本,但需要停 Docker 服务,操作步骤多。
  • 清理空间:docker system prune -a清理无用镜像和容器,清理日志文件,这是应急手段,不解决根本问题。

我个人的经验是,生产环境最好一开始就把 Docker 数据目录规划到独立分区或独立盘上,别让它和根分区抢空间。如果已经混在一起了,扩容之后也建议做一次数据目录迁移,把根分区彻底解放出来。

4. 避坑指南:扩容过程中最容易翻车的几个点

4.1 文件系统类型判断错误

这是新手最常犯的错。CentOS 7 默认 XFS,但如果你装系统时手动选了 ext4,或者从 CentOS 6 升级上来,文件系统可能是 ext4。用错命令的后果是:xfs_growfs对 ext4 报错,resize2fs对 XFS 也报错,虽然不会损坏数据,但会让人一脸懵。

判断方法很简单,df -Th的输出里有一列就是文件系统类型,或者用blkid /dev/mapper/centos-root看TYPE字段。XFS 用xfs_growfs 挂载点,ext4 用resize2fs 设备路径,记住这个对应关系就不会错。

4.2 扩容命令参数写反

lvextend -L +50G和lvextend -L 50G是两回事。前者是增加 50G,后者是扩展到 50G。如果当前已经是 50G,你敲-L 50G,它会提示"New size matches existing size",什么都不做。如果当前是 80G,你敲-L 50G,它会报错说不能缩小。所以加空间一律用+,这是最稳妥的写法。

还有一个参数是-l(小写 L),它按扩展块(extent)数量来算,不是按容量。除非你很清楚 PE(Physical Extent)的大小,否则别用-l,用-L按容量算最直观。

4.3 忘记扩文件系统

lvextend只是把逻辑卷这个"容器"变大了,里面的文件系统还是原来的大小。很多人敲完lvextend一看df -Th没变化,就以为扩容失败了。其实还差最后一步xfs_growfs或resize2fs。这两步是配套的,缺一不可。

我习惯把这两条命令写成一个组合,执行完立刻df -Th验证。如果df显示容量没变,先检查文件系统类型对不对,再检查命令有没有报错。

4.4 快照和精简卷的坑

如果 LV 上存在 LVM 快照,扩容主卷之前要确认快照的 COW(Copy-On-Write)空间是否足够。主卷扩容后,如果快照空间不足,快照会失效(变成Invalid状态),虽然不影响主卷数据,但快照就没用了。

另外,如果用的是精简置备(thin provisioning)的逻辑卷,扩容命令略有不同,要用lvextend配合-L并确保 thin pool 有足够空间。普通线性卷没这个问题,但精简卷在容器和虚拟化环境里越来越常见,值得留意。

4.5 常见问题速查表

现象可能原因排查与解决
lvextend报 "insufficient free space"VG 没有空闲空间vgs确认 VFree,为 0 则先pvcreate+vgextend
df -Th扩容后容量没变忘记扩文件系统XFS 执行xfs_growfs /,ext4 执行resize2fs
xfs_growfs报 "not a mounted XFS"参数写成了设备路径改成挂载点,如xfs_growfs /
resize2fs报 "Bad magic number"文件系统不是 ext 系列用df -Th确认类型,XFS 改用xfs_growfs
pvcreate后数据丢失误对数据盘操作操作前blkid确认盘是空的,有数据先备份
扩容后根分区还是满Docker 日志或镜像占用docker system df看占用,清理无用镜像和日志

5. 扩容之后的收尾:让根分区不再反复告警

扩容只是止血,真正要解决的是"为什么根分区会满"。我一般会在扩容后做几件事,把隐患掐掉。

第一件事是限制 Docker 日志大小。默认情况下,Docker 容器的日志是无限增长的,一个疯狂打日志的应用几天就能吃掉几十 G。在/etc/docker/daemon.json里加上日志限制:

{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }

这样每个容器最多保留 3 个 100M 的日志文件,总共 300M,不会无限膨胀。改完重启 Docker 生效,注意这只对新创建的容器生效,已有容器需要重建。

第二件事是定期清理无用镜像和容器。docker system df能看清楚镜像、容器、卷、构建缓存各占多少。docker system prune -a能清理所有未使用的资源,但会删掉没在运行的容器和没被引用的镜像,生产环境用之前要确认清楚。我一般用更保守的docker image prune和docker container prune分开清理。

第三件事是把 Docker 数据目录迁到独立盘。如果机器上有独立的数据盘,把/var/lib/docker迁过去是最彻底的方案。步骤是:停 Docker 服务,rsync迁移数据,修改/etc/docker/daemon.json里的>

相关新闻

不登录、不注册,如何免费完整破解所有国际版 Unity?UniHacker 快速上手指南

不登录、不注册,如何免费完整破解所有国际版 Unity?UniHacker 快速上手指南

不登录、不注册,如何免费完整破解所有国际版 Unity?UniHacker 快速上手指南 【免费下载链接】UniHacker 为Windows、MacOS、Linux和Docker修补所有版本的Unity3D和UnityHub 项目地址: https://gitcode.com/GitHub_Trending/un/UniHacker UniHacke…

2026/10/21 1:44:29 阅读更多 →
戴森球计划燃料棒蓝图选型:FactoryBluePrints 的 3 条生产链 + 导入排障指南

戴森球计划燃料棒蓝图选型:FactoryBluePrints 的 3 条生产链 + 导入排障指南

戴森球计划燃料棒蓝图选型:FactoryBluePrints 的 3 条生产链 导入排障指南 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints FactoryBluePrints 是戴森球计划的工…

2026/10/21 1:44:29 阅读更多 →
Switch 游戏如何装进电脑:yuzu 模拟器完整指南

Switch 游戏如何装进电脑:yuzu 模拟器完整指南

Switch 游戏如何装进电脑:yuzu 模拟器完整指南 【免费下载链接】yuzu 任天堂 Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/yu/yuzu yuzu 是一款开源的任天堂 Switch 模拟器,能把 NSP、XCI 等 Switch 游戏文件装进电脑真正跑起来…

2026/10/21 1:44:29 阅读更多 →

最新新闻

Wi-Fi MAC Layer: Scanning, Authentication, Association, and Data Transmission Processes

Wi-Fi MAC Layer: Scanning, Authentication, Association, and Data Transmission Processes

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 2:25:53 阅读更多 →
ROS2笔记1

ROS2笔记1

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 2:25:53 阅读更多 →
26 精武杯手机部分复盘

26 精武杯手机部分复盘

【简要案情】 近期,某市反诈部门接到多名群众报案,均遭遇“投资理财”类电信网络诈骗,指向的犯罪团伙涉案资金巨大、作案链条隐蔽。办案单位迅速成立专案组开展电子数据取证工作。经初查,该犯罪团伙搭建虚假投资平台,通…

2026/10/21 2:25:53 阅读更多 →
PHP安全漏洞修复指南:防SQL注入与XSS

PHP安全漏洞修复指南:防SQL注入与XSS

一、为什么 PHP 项目总被盯上做 PHP 开发这些年,我见过太多项目上线后被黑的情况。说句实话,大部分漏洞并不是什么高深的技术,翻来覆去就是 SQL 注入和 XSS 这两类。很多新手写代码的时候图省事,直接把用户输入拼进 SQL 语句&…

2026/10/21 2:25:53 阅读更多 →
中小企业建数据中台预算不多怎么办?先把这 5 笔成本拆开,别只问报价

中小企业建数据中台预算不多怎么办?先把这 5 笔成本拆开,别只问报价

报价单拿到手,最常见的第一反应是"怎么比我想的贵这么多"。而这个"我想的",通常是拿一套软件的价钱估出来的。 这篇为谁写:中小企业里兼管数据的 IT、被老板一句"我们是不是该上中台,先报个价"问到…

2026/10/21 2:25:53 阅读更多 →
C语言基础笔记 04 指针

C语言基础笔记 04 指针

00 包 目前CLion的最新版本还不支持中文&#xff0c;需要导入#include <stdlib.h> &#xff0c;再在main函数内写system("chcp 65001");才能在代码中用中文stdlib 还可以提供动态内存分布——malloc函数01 使用原因对于函数&#xff0c;在函数外定义的变量&…

2026/10/21 2:24:52 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →