登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux mount namespace 修改挂载时怎么避免影响宿主

来源:17golang原创

时间:2026-09-08 06:48:35 127浏览 收藏

在 Linux 上用 mount namespace 做临时挂载,最容易踩的坑是以为“有了 --mount 就天然不会影响宿主”。真正决定 mountumount 是否外溢的是挂载传播属性。稳妥做法是:创建独立的 mount namespace,进入后把根挂载树递归设为 private,再只操作专用目录;PID namespace 和 network namespace 可以一起创建,但它们不会替代挂载隔离。

可复用的判断是:先用 unshare --mount --propagation private 建立边界,再用 /proc/self/mountinfo 看有没有 shared:master: 标记。没有传播关系的挂载操作才不会回到宿主的挂载视图。
要点速览
  • mount namespace 隔离的是进程看到的挂载列表,不是磁盘本身。
  • shared 会传播事件,private 不进不出,slave 只接收上游事件。
  • PID 和网络 namespace 是独立维度,是否影响宿主挂载要回到 mount propagation 检查。

先分清三种 namespace 的边界

mount namespace 给进程一份独立的挂载视图;使用 cloneunshare 创建时,初始挂载列表通常是原视图的副本。之后的挂载修改默认只在自己的命名空间可见,但 shared subtree 会改变这个默认行为。

PID namespace 解决进程编号和进程树隔离,network namespace 解决网卡、路由和端口空间隔离。把它们同时打开,只能说明进程运行环境更完整,不能说明挂载已经变成 private。

Linux mount namespace、PID namespace 与 network namespace 的隔离边界关系图
图1:mount namespace 负责挂载视图,PID 与 network namespace 分别负责进程树和网络资源;三者是并列边界。

创建隔离挂载并关闭事件传播

在测试机或具备必要能力的受控进程中,可以从一个干净 shell 开始:

# 创建新的挂载、PID、网络命名空间,并在新环境中启动 shell
sudo unshare --mount --pid --net --fork --mount-proc sh

# 递归切断当前挂载树的传播关系,避免 mount/umount 回到宿主
mount --make-rprivate /

# 只在命名空间内准备实验目录和临时文件系统
mkdir -p /run/ns-lab
mount -t tmpfs -o size=64M ns-lab /run/ns-lab
findmnt /run/ns-lab

--mount-proc 只是为新 PID namespace 准备匹配的 proc 视图;它不是 mount 隔离的替代品。--make-rprivate /r 表示递归处理,适合避免某个父挂载仍是 shared、导致子挂载事件外溢。

Linux private mount propagation 下宿主挂载树与命名空间专用目录的静态边界关系图
图2:把根挂载树设为 private 后,专用目录中的 tmpfs 只属于隔离视图,宿主只保留自己的挂载关系。

用 mountinfo 判断边界是否真的生效

不要只看 mount 的简略输出,检查当前进程的 mountinfo 更直接:

# 查看挂载点及传播标签;shared/master 出现在可选字段中
awk '{print $5, $6, $7, $8}' /proc/self/mountinfo | sed -n '1,12p'

# 只检查是否仍存在共享或主从传播标记
grep -E ' shared:[0-9]+| master:[0-9]+' /proc/self/mountinfo || true

没有匹配结果通常说明当前视图里没有 shared 或 master 标记;若仍看到它们,先找出对应的父挂载点,再对明确范围执行 mount --make-rprivate。不要把“命令成功”当成“宿主安全”,挂载点层级和传播属性才是证据。

常见问题

mount namespace 会复制数据吗?

不会。它主要复制挂载视图和关系,底层文件系统、块设备和目录数据仍可能是同一份,写入风险仍需单独控制。

为什么只用 --mount 仍可能看到宿主变化?

因为新视图可能保留 shared subtree 的传播关系。创建后显式执行递归 private,并检查 mountinfo。

slave 和 private 该怎么选?

完全不希望挂载事件进出时选 private;需要接收上游挂载、但不把自己的事件传回去时才考虑 slave。

小结:隔离挂载的落点是传播属性,不是 namespace 参数数量。把操作限定在专用目录,配合 mount --make-rprivate 和 mountinfo 复查,才能把“看起来隔离”变成可检查的边界。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>