TT Lab
开始
学习 学习路径 课程

LFCS — Linux 基金会认证系统管理员

扩容发生在两个层次 — LVM、fstab、swap、NFS、autofs

在 TT Lab 中继续学习

一句话总结

存储是分层的。块设备之上是 LVM,其上是文件系统,再上是挂载,每一层只知道自己下面的一层。所以扩大 LV 后文件系统并不知道,修改 fstab 后内核并不知道,修改 /etc/exports 后 NFS 服务器也不知道。本模块的实验,就是一项项亲手把这些“不知道”告诉它们的练习。

为什么需要它

上一个模块(lfcs-storage)在 Pod 中运行。那里既用不了 mount,也用不了 pvcreate,阅读材料自己也写明“建议在可以使用虚拟机或回环设备的环境中另行练习”。LFCS 的 Storage 领域占 20%,而这部分全都只停留在概念说明上。

本模块在 Ubuntu 24.04 VM 中运行。你是 root,systemd 是 PID 1,所以一切都是真实可用的。只是没有空磁盘。平台挂载的暂存磁盘已经被 cloud-init 格式化为 ext4 并完成绑定。因此第一步是 losetup。losetup(8) 是用来操作回环设备的工具,回环设备能让普通文件看起来像块设备;在没有磁盘的情况下试验 LVM、RAID 和文件系统,实际工作中恰好就是这样做的。Ubuntu 云镜像里 snap 已经从 /dev/loop0 开始占用了若干个,所以写死编号就会遇到“设备忙”。用 losetup -f --show 获取空闲的设备,之后用 losetup -j <파일> 找回。

工作原理

LVM 分为三层。 按 lvm(8) 的术语,PV(physical volume)是写入了 LVM 标签的块设备,VG(volume group)是汇集 PV 的池,LV(logical volume)是从该池中切出的块设备。VG 以区段(extent,默认 4MiB)为单位管理空间,所以 lvcreate -L 600M 会占用 150 个区段。增加磁盘,就是在 pvcreate 之后用 vgextend 把它加入 VG,LV 随后再扩大。不必重新划分分区,正是使用 LVM 的原因。

层 创建命令 扩大命令 查看命令
PV pvcreate — pvs
VG vgcreate vgextend vgs
LV lvcreate lvextend lvs
文件系统 mkfs.ext4 resize2fs df

考试最常追问的位置就是最后两行。lvextend(8) 只是扩大 LV 这个块设备,它上面的 ext4 并不知道自己坐在一个 900MiB 的设备上。lvs 显示 900M 而 df 毫无变化,说的就是这种状态。resize2fs(8) 负责调整文件系统层,而 ext4 可以在挂载状态下(在线)扩大。lvextend -r 是一次性处理这两层的选项。

fstab 中写 UUID,而不是设备名。 fstab(5) 的第一个字段是设备,但 /dev/sdb1 或 /dev/loop3 这样的名称可能随启动顺序变化。写在文件系统里的 UUID 则不会变。用 blkid 读取,以 UUID=… 的形式写入,六个字段(设备、挂载点、类型、选项、dump、pass)用空格分隔。修改之后还要再做两件事。systemd 会把 fstab 翻译成 .mount 单元,所以要执行 systemctl daemon-reload,并且用 mount -a 当场确认那一行确实能工作。只要 findmnt --verify 输出哪怕一个 [E],下次启动就会进入 emergency shell。

交换文件的权限必须是 600。 mkswap(8) 会对权限过宽的文件给出“insecure permissions”警告。交换空间里存放的是内存的副本,所以不能让其他用户读取。顺序是创建、chmod 600、mkswap、swapon,fstab 中挂载点的位置写 none,类型写 swap。

NFS 服务器不知道文件被修改了。 exports(5) 的格式是 디렉터리 클라이언트(옵션)(占位符依次为目录、客户端、选项),如果在客户端与左括号之间加了空格,这些选项就会应用于所有人,而不是那个客户端——这是 man 手册明确警告的陷阱。修改文件之后,用 exportfs(8) 的 -ra 通知服务器,再用 exportfs -v 查看是否真的导出了。NFSv4 只用 2049 一个端口,所以像本实验这样,在同一个 VM 内就能挂载 127.0.0.1:/srv/share。

autofs 在访问时才挂载。 auto.master(5) 的主映射文件决定“哪个目录之下使用哪个映射文件”,autofs(5) 的映射文件决定“键、选项、源”。Ubuntu 的 /etc/auto.master 末尾有 +dir:/etc/auto.master.d,所以该目录中的 *.autofs 文件会被当作主映射文件读取。写好映射文件后必须重启守护进程,而 ls /nfs/share 就是触发挂载的条件。有一点会让人意外:如果服务器就是本机,autofs 不会使用 NFS,而是以 bind 挂载。auto.master(5) 把 nobind 选项解释为“阻止对本地 NFS 文件系统使用 bind 挂载”,这句话说明了默认行为。

在现场相遇的样子

“磁盘扩大了,为什么空间没变”这个问题,在云上也每周都会出现。扩大卷(云控制台)、扩大分区或 LV、扩大文件系统,是三层各自的事,在控制台修改容量的人只做了第一层。登录节点,自上而下依次用 lsblk 查看设备是否变大、用 lvs 查看 LV 是否变大、用 df 查看文件系统是否变大,就能一眼看出卡在了哪一层。

Kubernetes 的 ReadWriteMany 卷通常是 NFS。Pod 因 mount.nfs: access denied by server 而停住时,要检查服务器端 /etc/exports 的客户端范围是否包含节点 IP,以及 exportfs -v 中是否真有那一项。文件里有,但没有执行 exportfs -ra 的情况比想象的要多。

磁盘性能问题用 iostat(1) 和 vmstat(8) 来区分。两者的第一次采样都是开机以来的累计平均值,必须丢弃;iostat -x 的 %util 和 await 说明磁盘是否繁忙,vmstat 的 si 和 so 两列说明是否正在使用交换空间。

下一项实验要做什么

两个回环设备 → PV → VG vg_lfcs → LV lv_data(ext4)→ 挂载到 /srv/data 并写入 UUID 形式的 fstab 行 → 在线扩展 → 256MiB 交换文件 → 仅向 127.0.0.1 以 NFS 导出 /srv/share 并挂载 → 用 autofs 挂载同一个共享 → iostat、vmstat 指标和汇总文件。评分器不只检查文件,还会用 vgs、lvs、findmnt、swapon --show、exportfs -v 查看系统当前的状态。所以不要停留在“修改了文件”,而要做到“守护进程已经知道”。