Files
2026-07-23 15:23:47 +08:00

135 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
## 依赖
```bash
# Alibaba Cloud Linux / RHEL
dnf install -y libseccomp-devel libcap-devel
# Ubuntu / Debian
apt install -y libseccomp-dev libcap-dev
```
## 编译
```bash
make
```
清理:
```bash
make clean
```
## 用法
```
./container-from-scratch -u <uid> -m <rootfs路径> -c <命令>
```
| 参数 | 含义 |
|------|------|
| `-m` | 容器根文件系统目录(rootfs) |
| `-u` | 容器内进程的 UID |
| `-c` | 要执行的命令(必须放最后) |
## 快速开始
### 1. 创建 rootfs
```bash
mkdir -p rootfs
dnf install -y --installroot=$(pwd)/rootfs --releasever=3 bash coreutils procps-ng iproute hostname
```
### 2. 准备 /dev/null
```bash
rm -f rootfs/dev/null
mknod -m 666 rootfs/dev/null c 1 3
```
### 3. 运行容器
```bash
# 交互式 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