amend gitignore

This commit is contained in:
2026-07-23 15:23:47 +08:00
parent 6f34caf845
commit 3d62194fec
19 changed files with 875 additions and 597 deletions
+134
View File
@@ -0,0 +1,134 @@
# 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