Mount Namespace 通过为每个容器维护独立挂载树实现文件系统视图隔离,同路径可指向不同内容;默认 private 模式下挂载操作互不影响,需显式配置 shared 才能跨空间同步;常结合 pivot_root 构建干净 rootfs,并依赖 findmnt 和 mountinfo 调试传播行为。

Linux 容器通过 Mount Namespace 实现挂载点隔离,核心不是复制文件,而是为每个容器维护一套独立的挂载树(mount tree),让相同路径在不同容器中指向不同内容。
Mount Namespace 是隔离的基础
当容器启动时(如用 docker run 或 unshare --mount),内核会为其创建新的 Mount Namespace。该命名空间初始继承宿主机的挂载状态,但后续所有 mount、umount 操作仅作用于本命名空间内的挂载树,不影响其他容器或宿主机——前提是挂载传播类型未被设为 shared。
- 默认模式是
private:各命名空间挂载行为完全独立 - 若需跨容器同步(如共享卷),需显式执行
mount --make-shared或--make-rslave -
unshare(CLONE_NEWNS)不清空挂载点,只是让原挂载在当前视图中不可见
配合 pivot_root 构建干净根文件系统
单纯隔离挂载视图还不够,容器还需一个专属的 rootfs。常见做法是在新 Mount Namespace 中调用 pivot_root,把容器镜像解压后的目录切换为新的根目录(/),再卸载旧根,从而彻底切断对宿主机根文件系统的可见性。
- Docker 和 Podman 启动时自动完成这一流程
- 手动调试可用
findmnt查看当前挂载树,确认无意外暴露的宿主机路径(如 /proc、/sys) - 推荐使用
--read-only启动,再通过--tmpfs或-v显式开放必要可写路径
必须协同 User Namespace 才能真正限制访问
Mount Namespace 只控制“看不看得见”,不控制“能不能改”。如果容器内 UID 0 直接对应宿主机 root,即使挂载点被隔离,仍可能通过 mount --bind 等方式绕过限制。
- 启用 User Namespace(Docker 默认开启,Podman 也默认启用),将容器内 root 映射为宿主机上的普通 UID(如 100000)
- 该映射依赖
/etc/subuid和/etc/subgid预分配子 ID 范围 - 结合只读挂载、禁止挂载 /proc/sys 等敏感路径,才能形成完整防护链
验证与调试关键命令
进入容器后,可通过以下命令确认隔离是否生效:
-
findmnt:查看当前挂载树结构,检查是否有非预期绑定 -
cat /proc/self/mountinfo:获取详细挂载信息,包括传播类型(shared/slave/private) -
ls -l /proc/1/ns/mnt:对比不同进程的 mount ns inode,确认是否属于同一命名空间


















