Files
container-from-scratch/README.md
T
2026-07-23 15:23:47 +08:00

4.1 KiB
Raw Blame History

Container From Scratch

用纯 C 从零实现一个简易容器运行时,演示 Linux 容器核心原理。

功能

  • Namespace 隔离 — PID、UTS、NET、Mount、IPC、Cgroup、User
  • Cgroup 资源限制 — 内存 1GB、CPU shares、最大 64 进程
  • Capability 权限收窄 — drop 20 个危险 capability
  • Seccomp 系统调用过滤 — 禁止 ptrace、keyctl 等危险 syscall

依赖

# Alibaba Cloud Linux / RHEL
dnf install -y libseccomp-devel libcap-devel

# Ubuntu / Debian
apt install -y libseccomp-dev libcap-dev

编译

make

清理:

make clean

用法

./container-from-scratch -u <uid> -m <rootfs路径> -c <命令>
参数 含义
-m 容器根文件系统目录(rootfs)
-u 容器内进程的 UID
-c 要执行的命令(必须放最后)

快速开始

1. 创建 rootfs

mkdir -p rootfs
dnf install -y --installroot=$(pwd)/rootfs --releasever=3 bash coreutils procps-ng iproute hostname

2. 准备 /dev/null

rm -f rootfs/dev/null
mknod -m 666 rootfs/dev/null c 1 3

3. 运行容器

# 交互式 shell
./container-from-scratch -u 0 -m ./rootfs -c /bin/sh

# 运行测试脚本
./container-from-scratch -u 0 -m ./rootfs -c /test-container.sh

项目结构

container-from-scratch/
├── include/
│   ├── container.h              # 核心定义:child_config 结构体、系统头文件、常量
│   ├── mount.h                  # mounts() — 文件系统隔离
│   ├── cgroup.h                 # resources()、free_resources() — 资源限制
│   ├── capabilities.h           # capabilities() — 权限收窄
│   ├── container_seccomp.h      # syscalls() — 系统调用过滤
│   ├── userns.h                 # userns()、handle_child_uid_map() — 用户命名空间
│   └── hostname.h               # choose_hostname() — 随机主机名
├── src/
│   ├── main.c                   # 主流程:参数解析、clone、waitpid
│   ├── mount.c                  # pivot_root、挂载 /proc、/dev
│   ├── cgroup.c                 # cgroup 目录创建与清理
│   ├── capabilities.c           # prctl + cap_set_flag drop 权限
│   ├── seccomp.c                # seccomp 规则定义与加载
│   ├── userns.c                 # user namespace + UID/GID 映射
│   └── hostname.c               # 塔罗牌随机名生成
├── rootfs/                      # 容器根文件系统
├── test-container.sh            # 容器环境测试脚本
├── Makefile
└── README.md

工作原理

main()
  ├── 解析参数(-m、-u、-c)
  ├── 检查内核版本(>= 4.7)
  ├── choose_hostname()         → 生成随机主机名
  ├── resources()               → 创建 cgroup,写入资源限制
  ├── clone()                   → 创建子进程(6 个 namespace flag)
  │
  ├── [父进程]
  │   ├── handle_child_uid_map() → 写入 uid_map/gid_map
  │   └── waitpid()              → 等待子进程退出
  │
  └── [子进程 — child()]
      ├── sethostname()          → 设置容器主机名(UTS namespace)
      ├── mounts()               → pivot_root + 挂载 /proc、/dev
      ├── userns()               → 创建 user namespace + 切换 UID
      ├── capabilities()         → drop 危险 capability
      ├── syscalls()             → 加载 seccomp 过滤器
      └── execve()               → 执行目标命令

容器核心机制

机制 作用 类比
Namespace 隔离视野(进程、网络、文件系统...) 每个房间有独立的门牌号和家具
Cgroup 限制资源(内存、CPU、进程数) 给每个房间限电限水
Capabilities 细分 root 权限 老板权限拆成"能开保险柜"、"能进机房"
Seccomp 禁止危险系统调用 规定能用螺丝刀,不能用电钻

四者叠加 = 容器隔离。

License

GPLv3