关于 containers-internals
面向 Agent 的 Linux 容器内部机制指南,涵盖隔离、资源控制、存储与安全。适用于容器调试、定制运行时和加固工作负载,并结合命令与代码示例说明实践方法。
主要功能
- 01Linux 命名空间与进程隔离
- 02cgroups v2 资源限制
- 03overlayfs 与 OCI 运行时
- 04seccomp、能力与逃逸防护
- 05容器故障排查示例
适用场景
- 01分析容器 OOM 或 CPU 限流
- 02编写沙箱工作负载的 seccomp 配置
- 03无需 Docker 构建精简容器
- 04调查容器逃逸风险
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill containers-internals安装后在 Claude Code 中输入/containers-internals确认已加载。
详细介绍
容器内部原理
目的
指导 Agent 了解 Linux 容器内部原理:命名空间(clone、unshare、nsenter)、cgroups v2 资源限制、overlayfs 存储、runc 和 OCI 运行时规范、seccomp-bpf 过滤、用于降权的 Linux capabilities,以及容器逃逸缓解措施。
适用场景
- 了解 Docker/Podman 如何在底层隔离进程
- 调试容器资源限制(OOM、CPU 限流)
- 为沙盒工作负载编写自定义 seccomp 配置文件
- 不使用 Docker 构建精简容器
- 调查容器逃逸漏洞
- 为 Kubernetes Pod 调整 cgroups v2
工作流
1. 命名空间
# List namespaces for a process
ls -la /proc/self/ns/
readlink /proc/self/ns/pid
readlink /proc/1234/ns/net
# Enter container namespaces
nsenter -t <pid> -m -u -i -n -p bash
# Unshare namespaces (manual container)
unshare --fork --mount-proc --pid --net --uts --ipc bash
| 命名空间 | 隔离内容 |
|---|---|
CLONE_NEWNS(挂载) | 挂载点、文件系统根目录 |
CLONE_NEWPID | 进程 ID |
CLONE_NEWNET | 网络栈 |
CLONE_NEWUTS | 主机名 |
CLONE_NEWIPC | SysV IPC、POSIX 消息队列 |
CLONE_NEWUSER | UID/GID 映射 |
CLONE_NEWCGROUP | cgroup 根视图 |
// clone() with namespaces
#define _GNU_SOURCE
#include <sched.h>
int container_init(void *arg) {
sethostname("container", 9);
mount("proc", "/proc", "proc", 0, NULL);
execv("/bin/sh", (char *[]){"/bin/sh", NULL});
return 1;
}
int stack[1024 * 1024];
clone(container_init, stack + sizeof(stack)/sizeof(int),
CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD, NULL);
2. cgroups v2
# Unified hierarchy (cgroup v2)
mount -t cgroup2 none /sys/fs/cgroup
# Create cgroup and set limits
mkdir /sys/fs/cgroup/mycontainer
echo $$ > /sys/fs/cgroup/mycontainer/cgroup.procs
# Memory limit 256MB
echo 256M > /sys/fs/cgroup/mycontainer/memory.max
# CPU weight (relative to siblings, default 100)
echo 50 > /sys/fs/cgroup/mycontainer/cpu.weight
# IO weight
echo default 100 > /sys/fs/cgroup/mycontainer/io.weight
# Check current cgroup
cat /proc/self/cgroup
# OOM events
cat /sys/fs/cgroup/mycontainer/memory.events
3. overlayfs
overlayfs layers
├── lowerdir (read-only image layers)
├── upperdir (container writes)
├── workdir (internal bookkeeping)
└── merged (mount point seen by container)
mount -t overlay overlay \
-o lowerdir=lower1:lower2,upperdir=upper,workdir=work \
merged
# Docker stores layers in /var/lib/docker/overlay2/
写时复制:从 lower 读取,写入 upper。
4. runc 和 OCI 规范
# Generate default OCI config
mkdir -p mycontainer/rootfs
runc spec
# Edit config.json — namespaces, mounts, process args
# Run container
sudo runc run mycontainer
# List
runc list
config.json 关键部分:
{
"ociVersion": "1.0.2",
"process": {
"args": ["/bin/sh"],
"capabilities": { "bounding": ["CAP_NET_BIND_SERVICE"] }
},
"linux": {
"namespaces": [
{"type": "pid"}, {"type": "network"}, {"type": "mount"}
],
"seccomp": { ... },
"resources": {
"memory": { "limit": 268435456 }
}
},
"root": { "path": "rootfs", "readonly": false }
}
5. seccomp-bpf
// libseccomp example — block mount
#include <seccomp.h>
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mount), 0);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(pivot_root), 0);
seccomp_load(ctx);
# Docker default seccomp profile (JSON)
# https://github.com/moby/moby/blob/master/profiles/seccomp/default.json
# Audit blocked syscalls
# kernel: seccomp log via auditd
ausearch -m SECCOMP
| 操作 | 效果 |
|---|---|
SCMP_ACT_KILL | 终止进程 |
SCMP_ACT_ERRNO(n) | 返回错误 |
SCMP_ACT_TRACE | 通知跟踪器 |
SCMP_ACT_ALLOW | 允许系统调用 |
6. Linux capabilities
# Drop all caps except needed
capsh --drop=all --add=net_bind_service -- -c '/app/server'
# File capabilities
setcap cap_net_bind_service+ep /usr/bin/myserver
getcap /usr/bin/myserver
在容器中:Docker 默认会移除 CAP_SYS_ADMIN、CAP_NET_RAW 等。使用非 root 用户运行,并将权限边界集设为最小。
7. 用户命名空间无 root 模式
# Rootless podman/docker maps root in container to unprivileged UID on host
cat /proc/self/uid_map
# 0 1000 1
# container UID 0 → host UID 1000
无 root 模式的限制:无法挂载大多数文件系统,也没有 CAP_SYS_ADMIN。
8. 逃逸缓解措施
Defense layers
├── User namespace (rootless)
├── seccomp (block dangerous syscalls)
├── AppArmor/SELinux (MAC)
├── Capabilities drop (--cap-drop=ALL)
├── Read-only rootfs
├── no-new-privileges
└── Seccomp + Landlock for filesystem
docker run --read-only --cap-drop=ALL --security-opt=no-new-privileges \
--security-opt seccomp=default.json myimage
已知逃逸途径:挂载 docker.sock、特权模式、内核 CVE、/proc 信息泄漏。
常见问题
| 症状 | 原因 | 解决方法 |
|---|---|---|
| 容器被 OOMKilled | 超出 memory.max 限制 | 提高限制或修复内存泄漏 |
| CPU 被限流 | cpu.max 配额过低 | 调整 cpu.max 或权重 |
| 容器内权限被拒绝 | capability 已被移除 | 添加特定 capability 或修复应用 |
| 启动时被 seccomp 终止 | 配置文件缺少系统调用 | 使用 strace 查找;允许该系统调用 |
| overlay 挂载失败 | workdir 非空 | 清理 workdir;检查权限 |
| 无 root 模式挂载失败 | 用户命名空间限制 | 使用来自主机的卷挂载 |
相关技能
skills/virtualization/qemu-kvm— VM 隔离与容器隔离skills/security/kernel-security— SELinux、AppArmor、seccomp 深入介绍skills/observability/ebpf— 跟踪容器系统调用skills/runtimes/binary-hardening— 生产环境中的 seccomp 和 capabilitiesskills/kernel/kernel-internals— 内核中的 cgroups 和命名空间skills/profilers/strace-ltrace— 用于调整 seccomp 的系统调用跟踪
评论
支持 Markdown