返回列表 发布新帖
查看: 18|回复: 0

cgroups与命名空间:解锁容器隔离核心原理

988

主题

0

回帖

833

积分

高级会员

积分
833
发表于 2026-6-25 08:55:01 | 查看全部 |阅读模式
很多人聊容器,总把镜像、编排、镜像仓库这些显眼的词挂在嘴边,但真正支撑起“像虚拟机一样隔离、却又比它轻”的底层功夫,其实是两块:cgroups 和命名空间。理解这俩,能帮你判断一堆看似花哨的功能到底靠不靠谱,也能解释为什么有时容器会“漏水”。

先说命名空间(namespaces)。它的作用是“看见的世界不一样”:不同容器看到的进程列表不一样(PID namespace)、主机名和域名解析不一样(UTS)、网络设备与路由表不一样(NET)、挂载点和根文件系统不一样(MNT)、用户和权限映射不一样(USER)、还包括 IPC 等。简单讲,它让每个容器以为自己是“宇宙中心”。有趣的点在于 USER namespace:在容器里你是 root,外面可能只是个普通用户,通过 UID/GID 映射实现“内高外低”,这在跑无特权容器和提升安全性上特别关键。但

也埋了不少坑:不完善的映射、宿主机文件权限配合不当,可能导致容器里看似“有权”,实际写不进去,或者反过来误触宿主机敏感目录。再比如 MNT namespace 里 bind mount 太随意,把宿主的 /var/run/docker.sock 暴露进去,等于递给容器一把“主机遥控器”。

cgroups 解决的是“能用多少”的问题。v1 时代一堆子系统各管一摊,细粒度但配置零散;v2 统一层级后,限制与统计关系更清晰,也更容易做服务质量(QoS)。CPU 的 shares、quota/period 决定谁先吃饱;内存的 memory.max、memory.high 避免

杀死宿主也不至于把节点拖死;IO 的 io.max、io.weight 让“吵闹”的容器别把磁盘打成风扇。很多人只配了 memory.max 却忽略 memory.high,结果内核来不及回收直接 OOM;合理的做法是先设定 high 做软顶、配合 oom_score_adj 和优雅退出钩子,把“挤牙膏”的过程留给业务自己处理。

把 namespaces 和 cgroups 拼起来,才是“像一台小机子”的错觉:前者改视角,后者控资源。错觉为什么会破?一是越权边界:capabilities 没收紧、privileged 一开,等于

把钥匙全给了;二是逃逸面:宿主内核是共享的,内核漏洞、容器逃逸利用 eBPF/挂载点/设备节点都可能直接打到宿主;三是噪声外溢:cgroups 配得松,邻居的抖动就会穿墙影响你,尤其是 IO 抢占和 LLC 缓存抖动。

工程上我更关心三件事。第一,最小权限原则:把 privileged 当核按钮,默认关;按需收紧 capabilities(比如去掉 CAP_SYS_ADMIN、CAP_NET_RAW),配合 seccomp drop 一些危险 syscalls,再用 AppArmor/SELinux 做第二道网

墙。第二,资源治理要成体系:统一上 cgroup v2,把 CPU、内存、IO 都写进同一层级,别让 sidecar 和主容器跑到不同树上;内存用 memory.high 兜住回收节奏,配合 PSI 指标做拥塞反馈,CPU 用 quota+burst 控峰值、shares 保相对公平,IO 则结合 io.max 限绝对带宽、io.weight 做相对分配,关键路径磁盘再配合 blkio 控制队列深度。第三,观测与调试要落地:没有观测,治理都是拍脑袋
回复 转播

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表