从 Docker 到 runC:容器底层原理详解
目录
1. Docker 与 runC 的关系
2. Docker 的核心组件
3. runC 的核心功能
4. 实战示例:从 Docker 到 runC
4.1 示例场景:运行一个简单容器
4.2 Docker 底层调用 runC 的流程
4.3 查看 runC 的调用
4.4 直接调用 runC 创建容器
4.5 验证容器的隔离性
5. runC 的核心代码解析
5.1 创建命名空间
5.2 设置 Cgroups
5.3 挂载文件系统
6. Docker 与 runC 的协作流程图
7. 总结
1. Docker 与 runC 的关系
Docker 是一个容器化平台,其核心功能是通过容器运行时(Container Runtime)来创建和管理容器。runC 是 Docker 默认使用的底层容器运行时,它实现了 Open Container Initiative (OCI) 标准,负责与 Linux 内核交互,完成容器的创建、启动和销毁。
Docker 与 runC 的协作流程:
- Docker 客户端(CLI)向 Docker 守护进程(
dockerd
)发送指令(如docker run
)。 dockerd
将指令转化为容器配置(JSON 格式),并调用 containerd(Docker 的容器管理服务)。- containerd 通过 containerd-shim 调用 runC,由 runC 负责创建容器的命名空间(Namespaces)、控制组(Cgroups)和文件系统挂载。
- 容器启动后,
containerd-shim
与容器保持通信,确保容器生命周期的管理。
2. Docker 的核心组件
Docker 的架构由多个组件组成,以下是关键部分:
组件 | 作用 |
---|---|
Docker CLI | 用户交互接口,用于执行 docker run 等命令。 |
Dockerd | Docker 守护进程,处理 Docker CLI 的请求,管理容器生命周期。 |
Containerd | 容器管理服务,负责与 runC 交互,管理容器的创建、运行和销毁。 |
runC | 容器运行时,负责与 Linux 内核交互,实现容器的隔离和资源限制。 |
libcontainer | Docker 自研的容器管理库(已逐步被 containerd 替代)。 |
3. runC 的核心功能
runC 是一个轻量级的容器运行时,支持以下核心功能:
- Namespaces 隔离:通过 Linux 的命名空间(PID、Mount、UTS、IPC、Network、User)实现容器的隔离。
- Cgroups 资源限制:通过 Linux 的控制组(CPU、内存、磁盘 I/O)限制容器资源使用。
- 文件系统挂载:挂载容器的根文件系统(RootFS),通常基于 UnionFS(如 AUFS、OverlayFS)。
4. 实战示例:从 Docker 到 runC
以下是一个完整的示例,演示如何通过 Docker 创建一个容器,并分析 runC 的底层行为。