pinns 是 cri-o 默认的轻量级容器用户命名空间初始化工具,专为解决 unshare 在嵌套 user namespace、uid/gid 映射传递及与 runc 协作时序上的缺陷而设计。

pinns 是什么,为什么 CRI-O 会用它而不是直接调用 unshare
pinns 是 CRI-O 默认使用的轻量级容器命名空间初始化工具,专为用户命名空间(userns)隔离设计。它不替代 unshare,而是补足其在多层级 user namespace 场景下的缺陷:比如嵌套 user namespace 创建、uid/gid 映射传递、以及与 runc 的协作时机控制。
常见错误现象是手动替换 pinns 为 unshare --user --map-root-user 后,容器启动失败并报 operation not permitted —— 这是因为 unshare 没有处理 CRI-O 要求的「先建 user ns、再进新 ns、最后 exec runc」这一精确时序。
-
pinns会在 fork 出子进程后立刻 drop capabilities,再进入新 user namespace,避免 capability 污染 - 它读取 CRI-O 传入的
--uid-map和--gid-map参数,生成符合内核要求的映射格式,unshare不支持原生解析这些参数 - 当启用
userns-remap且 host 用户被映射到非 0 uid 时,pinns会自动跳过 setuid/setgid 调用,而unshare可能因权限不足卡死
如何确认 pinns 正在生效,以及它是否真在用 user namespace
最直接的办法是进容器查 /proc/self/status 中的 Uid: 和 Gid: 行,并比对 /proc/self/ns/user 的 inode —— 如果 uid 显示非 0 但进程能访问 /etc/passwd,说明 user namespace 已启用且 pinns 成功完成了映射。
验证步骤:
- 启动一个带
securityContext.runAsUser: 1001的 Pod,确保 CRI-O 配置了userns_mode = "auto" - 进容器执行
cat /proc/self/status | grep -E "Uid|Gid",输出应类似Uid: 1001 1001 1001 1001 - 执行
ls -l /proc/self/ns/user,若显示user:[4026532728]这类非默认编号,说明已进入独立 user namespace - 检查 CRI-O 日志:
journalctl -u crio | grep pinns,应看到类似execing pinns with args [... --uid-map 0:1001:1 ...]
启用 user namespace 后,哪些操作会突然失败
不是所有系统调用都能跨 user namespace 无缝工作。典型失效点集中在需要内核级权限或全局资源访问的地方:
- 挂载 tmpfs 或 overlayfs 时,若未显式指定
uid=/gid=,内核可能拒绝创建,因为当前 user namespace 没有对 host rootfs 的写权限 -
sethostname()失败并报EPERM:即使容器里是 root,user namespace 中的 root 并不等价于 host root,无法修改 UTS namespace - 使用
memfd_create()+seccomp组合时,某些 seccomp 规则因 capability 检查逻辑变化而误判,需额外添加CAP_SYS_ADMIN到 bounding set - SELinux 标签继承异常:如果 host 使用
kernel.sched_autogroup_enabled=1,user namespace 内进程可能无法正确继承 context,需在 pod annotation 中显式设container.apparmor.security.beta.kubernetes.io/pod: runtime/default
pinns 的配置项和兼容性边界
CRI-O 不直接暴露 pinns 参数,所有控制都通过 /etc/crio/crio.conf 中的 [crio.runtime] 段落完成。关键配置只有两个:
-
userns_mode = "auto":CRI-O 自动为每个容器分配独立 user namespace,pinns接收映射规则并执行 -
userns_mode = "host":完全绕过pinns,此时runc直接运行,无 user namespace 隔离
注意:CRI-O v1.26+ 要求内核 ≥ 5.12 才能稳定支持嵌套 user namespace + pinns;低于该版本时,若开启 userns_mode = "auto",pinns 可能静默降级为 host 模式,且日志中仅提示 falling back to host userns,容易被忽略。










