容器架构与运行时解析
Source: Dev.to
核心概念:操作系统级虚拟化
不同于需要完整客体操作系统、对整套硬件栈进行虚拟化的虚拟机(VM),Docker 使用的是操作系统级虚拟化。这意味着容器直接在宿主 OS 的内核上运行,从而实现快速且轻量的运行方式。
用于隔离的关键 OS 技术
容器通过 Linux 内核内置的两大特性(在 Windows/macOS 上也有对应的镜像或虚拟实现)实现隔离:
命名空间 (Namespaces)
隔离容器对操作系统的视图。每个容器拥有自己独立的资源切片,包括:
- PID Namespace – 容器只能看到自己的进程。
- Net Namespace – 容器拥有自己的网络接口、端口和路由表。
- Mount Namespace – 容器拥有自己的根文件系统(基于镜像层)。
控制组 (cgroups)
限制容器可以消耗的资源量。它们充当资源控制器,允许你对容器的以下资源进行上限设定:
- CPU – 限制处理器时间的百分比。
- Memory – 对内存使用设定硬性上限。
- Block I/O – 控制磁盘的输入/输出。
简而言之:命名空间隔离容器“看到的内容”(视图),而 cgroups 限制容器“使用的资源”(资源)。
引擎:Docker Daemon 与容器运行时
当你执行类似 docker run 的命令时,多个软件组件会协同工作。
A. Docker Daemon (dockerd)
Docker Daemon 是在后台运行的服务器组件,负责繁重的工作,包括:
- 构建镜像。
- 从注册中心(如 Docker Hub)拉取和推送镜像。
- 管理存储(卷)和网络。
- 接收 CLI 发来的指令并将其转交给相应的运行时。
B. 容器运行时
容器运行时是执行容器进程运行与管理的底层组件。它直接与内核的命名空间和 cgroups 交互。
高层运行时(例如 containerd)
管理整个容器生命周期:镜像传输、挂载根文件系统、设置网络以及日志记录。Docker Daemon 使用 containerd 来管理容器。
低层运行时(例如 runc)
真正创建并运行容器进程的可执行文件。它是最终直接调用内核特性(命名空间和 cgroups)以实现隔离的组件。runc 是 OCI Runtime 规范的参考实现。
指令链路
- 你输入
docker run …。 - Docker CLI 将指令发送给 Docker Daemon(
dockerd)。 - Docker Daemon 准备镜像并将请求交给高层运行时(
containerd)。 containerd解析容器配置并交给低层运行时(runc)。runc使用命名空间和 cgroups 在宿主 OS 内核上创建并运行隔离的容器进程。
OCI:开放容器倡议
OCI 为容器技术的核心组件提供标准化规范。
- 镜像规范 – 定义容器镜像的结构、层次和清单等必须满足的格式。
- 运行时规范 – 定义容器运行时(如
runc)的配置与执行方式。
这些标准确保由一种工具(例如 Docker)构建的镜像能够被另一种符合规范的工具(例如 Podman 或 Kubernetes 的 Kubelet)运行,从而提升可移植性并防止厂商锁定。
接下来会讲什么?
掌握这些底层概念至关重要。现在我们已经了解了容器的工作原理以及支撑它们运行的软件。下一篇文章我们将探讨 Docker 使用的文件系统。
谢谢。