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

namespace 隔离怎么配置或排查

来源:17golang原创

时间:2026-09-13 07:14:24 197浏览 收藏

Linux 的 namespace 隔离不是一个总开关,而是按资源拆开的边界:mount 隔离挂载视图,UTS 隔离主机名,PID 隔离进程编号,network 隔离网络设备与路由,user 隔离用户和能力映射。排查时最稳的做法是先选准资源,再用 unshare 创建最小环境,最后比较 /proc/self/ns 的标识和实际可见资源。只看到新的 hostname,并不能证明文件系统或网络已经隔离。

要点速览
  • 隔离效果取决于 namespace 类型,不能用一个参数替代所有边界。
  • 创建 PID namespace 通常要配合 --fork,非特权测试优先配合 user namespace 映射。
  • 挂载 namespace 还要关注 propagation;创建新视图不等于宿主挂载事件不会传播。

先把“隔离”拆成可验证的资源边界

一次故障复盘里,最常见的误判是把 namespace 当成轻量虚拟机。它实际包装的是某一类全局资源,其他 namespace 中的进程可能仍能看到未被隔离的部分。先把目标写成资源名,再决定参数,排障会简单很多。

目标常用类型先看什么
挂载点和根目录视图mount/proc/self/mountinfo、传播属性
主机名UTShostnameuname -n
进程编号视图PIDps 是否从 1 开始、是否使用 --fork
用户身份和能力userid、uid/gid 映射和权限
网卡、地址和路由networkip addrip route
Linux namespace 资源边界静态框图,展示 mount、UTS、PID、network、user 与 unshare 的关系
图1:namespace 资源边界静态框图;它说明不同 namespace 控制不同资源视图,不是运行结果截图。

用 unshare 创建一个最小、可回收的测试环境

为了先验证边界,可以从 UTS 和 user namespace 开始,再按需增加 mount 或 PID。下面的命令只展示配置思路,图示是解释性插图,不代表本机已经执行。

# 创建独立的用户映射和 UTS 视图,并启动一个临时 shell
unshare --user --map-root-user --uts sh -c '
  # 只修改新 UTS namespace 内的主机名
  hostname ns-demo
  # 输出当前身份与 hostname,作为边界检查点
  id
  hostname
'

# PID namespace 要让 shell 成为新视图里的第一个子进程
unshare --user --map-root-user --pid --fork sh -c '
  # 观察新 PID 视图,避免把宿主进程列表当成隔离结果
  ps -ef
'

--user --map-root-user 只是在新 user namespace 内建立当前用户到“映射 root”的关系,并不自动给宿主机 root 权限。挂载 namespace 常与 --mount 一起使用;若环境不允许创建它,先记录错误是 EPERM 还是挂载传播导致的可见性问题。

不要只看命令成功,用标识和可见资源双重确认

同一个进程的 namespace 入口会出现在 /proc/self/ns/。括号里的 inode 可作为比较标识:两个 shell 对同一类型 namespace 的数字不同,说明它们不在同一个 namespace;但数字不同仍要结合资源检查,因为 user namespace 和 mount namespace 的权限关系会影响后续操作。

# 输出当前 shell 参与的 namespace 标识,用于和宿主 shell 对照
for ns in mnt uts pid net ipc user; do
  # readlink 会给出类型和 inode,便于发现是否真的换了边界
  printf '%-4s ' "$ns"
  readlink "/proc/self/ns/$ns"
done

# 检查挂载传播字段,避免新 mount 视图的事件回传到不该影响的层
grep -E ' / | /proc | /sys ' /proc/self/mountinfo | head -n 5

验证时建议保存宿主 shell 和隔离 shell 两份输出,重点比较 namespace inode、hostname、PID 视图以及 mountinfo 的传播标记。不要把“能进入 shell”当成成功标准:如果 namespace 类型没选对,进入动作本身并不能说明目标资源已经隔离。

Linux namespace 排查静态框图,关联 /proc/self/ns 标识、mountinfo、hostname、PID 视图和 user 映射
图2:namespace 排查静态框图;用标识、资源视图和权限映射三个分组解释如何判断隔离边界。

四种常见症状对应四条修复线索

  • 创建时报 EPERM:先缩小到 user 或 UTS,再确认内核、容器运行时和当前能力是否允许创建目标类型;不要直接给整台宿主机提权。
  • 新的 mount namespace 仍看见宿主挂载:检查挂载传播属性。Linux 手册说明,unshare 创建 mount namespace 时会处理传播关系;需要保留现状时才考虑 --propagation unchanged,否则应明确设置 private 或 slave。
  • PID namespace 里进程列表不对:确认是否使用 --fork,并记住 PID namespace 的第一个进程承担该视图的 init 角色。
  • nsenter 进入失败:确认目标进程仍在、目标 namespace 文件可读,以及进入者在 user namespace 层级上具备对应权限;临时 namespace 随成员进程退出而消失是正常现象。

恢复时优先退出临时 shell,删除用于持久化 namespace 的 bind mount,再重新创建最小配置。生产环境不要把 namespace 当成完整安全边界;它通常还要和 cgroup、权限控制、seccomp 或容器运行时的策略组合使用。

常见问题

namespace 和容器是一回事吗?

不是。namespace 提供资源视图隔离,容器还需要文件系统、资源控制、能力和安全策略等组合。

为什么只加 --mount 还是能看到很多宿主信息?

mount 只改变挂载视图,hostname、PID、网络和用户身份分别由其他 namespace 控制;要先明确想隐藏的资源。

非 root 用户一定不能用 namespace 吗?

不一定。user namespace 可以建立受限的身份映射,但发行版策略、内核配置和目标 namespace 的权限仍可能拒绝创建。

参考:https://man7.org/linux/man-pages/man7/namespaces.7.htmlhttps://man7.org/linux/man-pages/man1/unshare.1.htmlhttps://man7.org/linux/man-pages/man7/mount_namespaces.7.html

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