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

存储与挂载

读懂挂载树并做设计

在 TT Lab 中继续学习

目标

直接读取 /proc/self/mountinfo,掌握挂载树和传播方式,并用 fstab 和 systemd 单元两种形式写出绑定挂载和 tmpfs。

为什么重要

在容器时代,挂载之所以变难,是因为挂载命名空间和传播方式。在主机上挂载的卷在容器里看不到,或者容器已经删除了,挂载却还在、仍占着磁盘,这些现象全都出在这里。而这些信息不在 mount 命令的输出中,只存在于 /proc/self/mountinfo 的可选字段里。会读这个文件与不会读,差别很大。

本实验在 Ubuntu 24.04 VM 中运行。所以会用 systemctl start 把第 7 步中写的 .mount 单元真的挂载一次——你会通过亲身被拒绝,而不是死记规则,明白单元名称与路径只要有一个字符不同,systemd 就会拒绝。以前是在 Pod 中运行的,没有 mount 权限,只做到读取和设计为止。

步骤

  1. 创建目录 /root/mnt,从 /proc/self/mountinfo 的每一行中提取 마운트지점 타입 옵션(占位符依次为挂载点、类型、选项)三个值,用空格分隔后保存到 /root/mnt/parsed.txt。至少要有 5 行,并且必须包含 /proc。
  2. 用 findmnt 按 타깃,소스,타입(列依次为目标、源、类型)的格式输出当前挂载,并保存到 /root/mnt/findmnt.txt。
  3. 只挑出类型为 tmpfs 的挂载,保存到 /root/mnt/tmpfs.txt。至少要有 1 行。
  4. 判定每个挂载的传播方式,按 마운트지점 <shared|slave|private>(占位符为挂载点)的格式保存到 /root/mnt/propagation.txt。至少要有 5 行。
  5. 在 /root/mnt/bind.fstab 中,用一行写出下面的绑定挂载行。源 /srv/data,目标 /var/www/data,类型 none,选项中包含 bind 和 ro,dump 为 0,pass 为 0。
  6. 在 /root/mnt/tmpfs.fstab 中,用一行写出下面的 tmpfs 行。挂载点 /var/cache/app,类型 tmpfs,选项中必须同时包含 size=256M、mode=1777、noexec、nosuid、nodev,dump 为 0,pass 为 0。
  7. 把与第 6 步相同的内容,也写成 systemd 单元。文件名必须是对挂载点转义后的准确名称,并放在 /root/mnt/ 之下。必须有 [Unit]、[Mount]、[Install] 三个节,而且 [Mount] 中必须有 What、Where、Type、Options 四个键。
  8. 把 /root/mnt/design.txt 写成下面这 4 行。 MOUNTS=<1번 파일의 줄 수> / TMPFS=<3번 파일의 줄 수> / BIND_TARGET=/var/www/data / UNIT=<7번에서 만든 파일 이름(경로 제외)>(第 1 项、第 2 项和第 4 项的占位符依次为第 1 步文件的行数、第 3 步文件的行数、第 7 步中所创建文件的名称,不含路径)

参考

解析 mountinfo

创建目录 /root/mnt,从 /proc/self/mountinfo 的每一行中提取 마운트지점 타입 옵션(占位符依次为挂载点、类型、选项)三个值,用空格分隔后保存到 /root/mnt/parsed.txt。至少要有 5 行,并且必须包含 /proc。

字段分隔符是空格,中间有数量可变的可选字段。一个连字符就是它的边界。

用 findmnt 查看

用 findmnt 按 타깃,소스,타입(列依次为目标、源、类型)的格式输出当前挂载,并保存到 /root/mnt/findmnt.txt。

findmnt 是读取 /proc 的工具,所以无需特权就能工作。有指定输出格式的选项。

只挑出 tmpfs 挂载

只挑出类型为 tmpfs 的挂载,保存到 /root/mnt/tmpfs.txt。至少要有 1 行。

请只过滤出类型为 tmpfs 的。留意一下有 size 选项的和没有的。

制作传播方式表

判定每个挂载的传播方式,按 마운트지점 <shared|slave|private>(占位符为挂载点)的格式保存到 /root/mnt/propagation.txt。至少要有 5 行。

如果可选字段中有 shared: 或 master:,分别是 shared 和 slave。什么都没有就是 private。

绑定挂载的 fstab 行

在 /root/mnt/bind.fstab 中,用一行写出下面的绑定挂载行。源 /srv/data,目标 /var/www/data,类型 none,选项中包含 bind 和 ro,dump 为 0,pass 为 0。

绑定挂载的类型字段是 none,选项中要有 bind。也可以同时指定只读。

tmpfs 的 fstab 行

在 /root/mnt/tmpfs.fstab 中,用一行写出下面的 tmpfs 行。挂载点 /var/cache/app,类型 tmpfs,选项中必须同时包含 size=256M、mode=1777、noexec、nosuid、nodev,dump 为 0,pass 为 0。

设备的位置写 tmpfs。必须指定大小,并同时加入三个安全选项。

.mount 单元文件

把与第 6 步相同的内容,也写成 systemd 单元。文件名必须是对挂载点转义后的准确名称,并放在 /root/mnt/ 之下。必须有 [Unit]、[Mount]、[Install] 三个节,而且 [Mount] 中必须有 What、Where、Type、Options 四个键。

单元名称必须是对挂载点路径转义后的结果。用 systemd-escape 可以得到准确的名称。

挂载设计文档

把 /root/mnt/design.txt 写成下面这 4 行。 MOUNTS=<1번 파일의 줄 수> / TMPFS=<3번 파일의 줄 수> / BIND_TARGET=/var/www/data / UNIT=<7번에서 만든 파일 이름(경로 제외)>(第 1 项、第 2 项和第 4 项的占位符依次为第 1 步文件的行数、第 3 步文件的行数、第 7 步中所创建文件的名称,不含路径)

值从前面步骤中创建的文件里取即可。数量按行数统计就足够了。