XingfenD f21cbe0574 Add comments to all source and header files
- include/container.h: document struct fields and constants
- src/main.c: explain argument parsing, clone flow, parent/child roles
- src/mount.c: describe 6-step mount isolation process
- src/cgroup.c: explain cgroup data structures and resource setup/cleanup
- src/capabilities.c: document capability drop (bounding + inheritable)
- src/seccomp.c: explain each seccomp rule's security purpose
- src/userns.c: describe parent-child sync and uid_map/gid_map format
- src/hostname.c: document tarot card random naming scheme
2026-07-23 15:48:33 +08:00
2026-07-23 15:23:47 +08:00
2026-07-23 15:23:47 +08:00
2026-07-23 15:23:47 +08:00
2026-07-23 15:23:47 +08:00

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

S
Description
No description provided
Readme
69 KiB
Languages
C 94.5%
Shell 4.1%
Makefile 1.4%