挂载命名空间与传播方式
一句话总结
/proc/self/mountinfo包含“整个可视化安装树的这个过程”,其中包含mount甚至还写着不显示命令的传播方式(propagation)。
为什么需要这个?
一旦开始使用容器,安装就会突然变得困难。主机粘贴的卷没有显示在容器中,或者在容器中粘贴的东西流向了主机,或者删除了容器但安装仍然存在。这些现象全部用安装命名空间和传播方式来解释。
怎么行动
读mountinfo
36 25 0:31 / /sys/fs/cgroup rw,nosuid,nodev,noexec shared:9 - cgroup2 cgroup2 rw
[1][2][3] [4] [5] [6] [7] [8] [9] [10] [11]
| 领域 | 意义 |
|---|---|
| 1 | 安装ID |
| 2 | 母机安装ID |
| 3 | major:minor 设备编号 |
| 4 | 原始文件中的根目录 — 绑定安装时,这里是/不是去 |
| 5 | 挂载分店 |
| 6 | 安装选项 |
| 7 | 选择字段 — 传播方式 (shared:,master:,propagate_from:,没有的话是private) |
| 8 | 分隔符- |
| 9~11 | 文件系统类型、源、上位选项 |
**第4个字段是识别绑定安装的关键。**如果粘贴了同一设备的子目录,那么在那里/相反,将那个子路径写下来。
传播方式四种
| 方式 | mountinfo显示 | 行动 |
|---|---|---|
| private | (无显示) | 此安装的变更不会传播到任何地方 |
| shared | shared:N |
双向传播。在这里粘上的话,对方的眼睛也能看到,反面也是一样的。 |
| slave | master:N |
单向。虽然接受大师的变化,但不会发送我的变化。 |
| unbindable | unbindable |
不能成为绑定安装的原件 |
容器运行时附加卷时rslave我rprivate使用它的理由就在这里。如果在容器中不小心粘上的安装程序被改成主机,就会很麻烦,相反,主机粘上的东西很多时候需要显示出来。
tmpfs
是内存上的文件系统。重新启动后就会消失。
tmpfs /var/cache/app tmpfs size=256M,mode=1777,noexec,nosuid,nodev 0 0
size=必须指定**。**如果没有的话,默认值是物理内存的一半,如果有人写大文件,整个系统都会受到内存压力。- tmpfs可以**通过交换出去。**如果想要真正的RAM磁盘的话
ramfs但是,ramfs没有大小限制,更危险。 mode=1777是sticky bit。/tmp大家都这样使用,但不能删除别人的文件。
systemd的.mount设备
也可以用设备文件来定义挂载,而不是fstab。设备名称必须是用双引号括起来的挂载点路径。
# /etc/systemd/system/var-cache-app.mount
[Unit]
Description=Application cache (tmpfs)
[Mount]
What=tmpfs
Where=/var/cache/app
Type=tmpfs
Options=size=256M,mode=1777,noexec,nosuid,nodev
[Install]
WantedBy=local-fs.target
/var/cache/app→var-cache-app.mount. 除掉前面的斜杠,其余的斜杠改成连字符。如果名字与路径不匹配,systemd会拒绝该设备。systemd-escape --path /var/cache/app可以得到准确的名字。
安装消失或看不到时
绑定挂载和tmpfs看起来很简单,但是因为传播和命名空间,预期和 有不同的行动情况。
**在集装箱里看不到以后粘上的安装。**在主机上/mnt/data在
即使安装了新磁盘,也不会出现在已经绑定该路径的容器中。
传播方式是private因为之后的安装不会被传递。在Kubernetes中
mountPropagation: HostToContainer使用它的理由就是这个。
findmnt -o TARGET,SOURCE,PROPAGATION /mnt/data
tmpfs会使用内存。df虽然从文件系统来看是,但实际上是RAM,
在容器中,该内存包含在cgroup限制内。/tmp把放在tmpfs上
使用大文件会死于OOM。一定要确定大小。
tmpfs /tmp tmpfs size=512M,mode=1777,nosuid,nodev 0 0
**如果不挂载到空目录中,原来的内容会被遮蔽。那些文件消失了。 不是,而是在下面铺开占据空间。**要取回的话,要拆下支架。 在别的地方绑定后看。
mkdir /mnt/under && mount --bind / /mnt/under
ls /mnt/under/mnt/data # 가려진 원래 내용
umount不能去的的时候看看是谁在用。
lsof +f -- /mnt/data
fuser -vm /mnt/data
umount -l /mnt/data # 마지막 수단: 이름만 떼고 나중에 정리한다
-l(lazy)在打开的文件关闭之前实际上是粘着的,所以磁盘
在物理上拔掉的情况下是不安全的。
绑定安装的选项需要绑定两次。mount --bind -o ro是
在Linux上不能变成只读模式。粘贴后必须重新安装。
mount --bind /src /dst
mount -o remount,ro,bind /dst
在现场相遇的样子
**删除容器后,仍然有安装。**在广播方式为shared的情况下,如果容器创建安装,就会泄漏到主机命名空间。即使容器死亡,该安装也会留在主机上,抓住磁盘。findmnt需要通过搜索手动整理。
没有确定tmpfs大小,就会出现OOM。size=在没有创建的tmpfs上堆积了日志,内存都被用完了。很容易忘记不是磁盘而是内存的事实。
下次实习要做的事情
/proc/self/mountinfo直接解析,将挂载树和传输方式制成表格,编写绑定挂载和tmpfs的fstab行,.mount将单元文件改成准确的名称。