概述:Docker 的控制组(Control groups,简称 cgroups)是 Linux 内核的一个功能,用于限制、控制和审计进程组所使用的物理资源。在 Docker 中,cgroups 用于确保容器只能使用分配给它们的资源,从而提供隔离性并防止某个容器占用过多宿主机的资源。
以下是 Docker 中使用 cgroups 实现资源控制的详细底层原理:
1. CPU 控制
- CPU 配额:通过 cgroups 的 CPU 控制器,可以限制容器可以使用的 CPU 时间。例如,如果一个容器被限制为使用 50% 的 CPU,那么它最多只能使用一个具有两个 CPU 核心的服务器上的一个核心。
- CPU 周期:可以为容器设置 CPU 周期(cpu.cfs_period_us)和 CPU 配额(cpu.cfs_quota_us),这两个参数共同工作来限制容器在给定时间段内能使用的 CPU 时间。
2. 内存控制
- 内存限制:cgroups 允许对容器可以使用的内存量进行限制。如果容器试图使用超过其配额的内存量,系统将开始回收页面,可能还会触发 OOM Killer(Out of Memory Killer)杀死该容器。
- 内存报告:cgroups 提供了内存使用的实时报告,包括当前使用的内存量、可用内存量等。
3. 磁盘 I/O 控制
- 读写速度限制:虽然 cgroups 本身不直接支持磁盘 I/O 限制,但可以通过配置块设备上的 I/O 调度器来实现磁盘访问的限制。
4. 网络带宽控制
- 网络带宽限制:利用 cgroups 中的网络控制器(net_cls),可以限制容器的网络带宽使用。这可以通过将网络流量分类并使用流量控制器(如 tc)来实现。
5. 设备访问控制
- 设备白名单:cgroups 可以与 udev 规则结合使用,以控制哪些容器可以访问特定的设备。
6. 审计和报告
- 资源使用跟踪:cgroups 提供了一种机制来跟踪和报告每个 cgroup 的资源使用情况,这对于管理和调试非常有帮助。
7. 层次化控制结构
- 层次结构:cgroups 采用层次化的控制结构,可以轻松地组织和管理一组进程的资源访问。
- 继承:新创建的子进程默认会继承父进程的 cgroup。
通过 cgroups,Docker 能够有效地管理和隔离容器的资源使用,确保容器运行时的性能稳定且可预测,同时防止单个容器影响整个系统的稳定性。