容器——Docker 实现的基本原理

Docker 实现原理

Docker 的实现依赖于三大核心技术:NamespaceCgroupAUFS。这些技术共同支撑了 Docker 的隔离性、资源管理和镜像分层机制。

  • Namespace:用于实现资源的隔离,使每个容器拥有独立的进程、网络、文件系统等视图,从而在操作系统层面实现容器之间的隔离。
  • Cgroup:用于限制和分配容器的资源(如 CPU、内存、磁盘 I/O 等),确保容器不会过度占用主机资源。
  • 联合文件系统:用于实现容器的分层镜像和写时复制(Copy-on-Write)机制,使容器可以高效地共享基础镜像并独立修改文件。

请添加图片描述

Namespace

Namespace 用于实现资源的隔离,使每个容器拥有独立的进程、网络、文件系统等视图,从而在操作系统层面实现容器之间的隔离。

1. PID Namespace(进程命名空间)

  • 作用:隔离进程 ID(PID),使得每个容器内的进程拥有独立的 PID 空间。
  • 特点
    • 每个容器内的进程 PID 从 1 开始,类似于主机上的 /sbin/init 进程。
    • 容器内的进程只能看到同一命名空间或子命名空间中的进程。
    • /proc 文件系统只显示当前命名空间中的进程。
    • 父命名空间可以看到子命名空间中的进程,但 PID 可能不同。
  • 应用场景:实现进程隔离,避免容器内的进程影响主机或其他容器。

2. Net Namespace(网络命名空间)

  • 作用:隔离网络设备、IP 地址、路由表等网络资源。
  • 特点
    • 每个容器拥有独立的网络设备(如虚拟网卡)、IP 地址和路由表。
    • /proc/net 目录只显示当前命名空间的网络信息。
    • Docker 默认使用 veth 方式将容器的虚拟网卡连接到主机的 docker bridge
  • 应用场景:实现网络隔离,使每个容器拥有独立的网络栈。

3. IPC Namespace(进程间通信命名空间)

  • 作用:隔离进程间通信(IPC)资源,如信号量、消息队列和共享内存。
  • 特点
    • 每个 IPC 资源有一个唯一的 32 位 ID。
    • 容器内的进程只能访问同一命名空间中的 IPC 资源。
  • 应用场景:避免容器间的进程间通信干扰。

4. Mnt Namespace(挂载命名空间)

  • 作用:隔离文件系统挂载点,使每个容器拥有独立的文件系统视图。
  • 特点
    • 类似于 chroot,但更强大。
    • 每个容器只能看到自己命名空间中的挂载点。
    • /proc/mounts 只显示当前命名空间的挂载信息。
  • 应用场景:实现文件系统隔离,使容器拥有独立的文件目录结构。

5. UTS Namespace(主机名和域名命名空间)

  • 作用:隔离主机名和域名。
  • 特点
    • 每个容器可以拥有独立的主机名和域名。
    • 使容器在网络上被视为独立节点。
  • 应用场景:实现主机名和域名的隔离,使容器在网络中独立标识。

6. User Namespace(用户命名空间)

  • 作用:隔离用户和用户组 ID。
  • 特点
    • 容器内的用户和用户组 ID 可以与主机不同。
    • 容器内的进程可以以容器内部的用户身份运行,而非主机用户。
  • 应用场景:实现用户权限隔离,增强安全性。

7. Cgroup Namespace(Cgroup 命名空间)

  • 作用:隔离 cgroup 视图。
  • 特点
    • 它让容器内的进程只能看到自己的 cgroup 层次结构,而看不到其他容器或宿主机的 cgroup 信息。
  • 应用场景
    • 防止信息泄露:容器进程无法看到其他容器或宿主机的 cgroup 信息。
    • 简化容器迁移:容器可以在不同宿主机间迁移,而不需要担心 cgroup 配置的冲突。
    • 限制资源使用:容器进程无法获取宿主机的 cgroup 访问权限,只能管理自己的 cgroup。

Cgroup

Cgroup(Control Groups)是 Linux 内核的一个特性,用于对进程组的物理资源(如 CPU、内存、磁盘 I/O 等)进行细粒度的控制和监控。

Core(核心)

  • 定义:Core 是 cgroup 的核心功能,即分层组织进程。
  • 特点
    • 每个 cgroup 可以包含子 cgroup,形成一个层次结构(树)。
    • 这种层次结构允许对进程进行分组管理。
  • 作用
    • 提供了一种灵活的方式来组织和管理进程。
    • 比如,你可以将所有数据库进程放在一个 cgroup 中,而将所有 Web 服务器进程放在另一个 cgroup 中。

Hierarchy(层级结构)

  • 定义:hierarchy 是 cgroup 的组织形式,可以理解为一棵树,树的每个节点是一个 cgroup(进程组)。
  • 特点
    • 每棵树可以关联零到多个子系统(subsystem)。
    • 一棵树中包含系统中的所有进程,但每个进程只能属于树中的一个节点(cgroup)。
    • 系统中可以有多棵树,每棵树关联不同的子系统。
    • 一个进程可以属于多棵树,但每棵树关联的子系统不同。
  • 作用
    • 将进程分组,并对这些组进行资源管理。
    • 通过关联不同的子系统,实现对不同资源的控制(如 CPU、内存等)。

Controller(控制器)或 SubSystem(子系统)

  • 定义:控制器(Controller)和子系统(Subsystem)在 cgroup 的上下文中其实是同一个概念,只是叫法不同。它们都指的是 cgroup 中负责管理特定类型资源的模块。
  • 特点
    • 控制器负责管理特定类型的系统资源,不同的控制器可以控制不同的资源。
    • 例如:
      • cpu 控制器:控制进程的 CPU 时间分配。
      • memory 控制器:控制进程的内存使用。
      • blkio 控制器:控制块设备 I/O(如硬盘)的带宽和 IOPS。
      • net_cls 控制器:控制网络流量的分类和质量服务。
      • freezer 控制器:暂停和恢复 cgroup 任务。
      • device 控制器:允许或拒绝 cgroup 任务对设备的访问。
  • 作用
    • 每个 cgroup 都有一个 cgroup.controllers 文件,其中列出了所有可供该 cgroup 启用的控制器。
    • 这意味着你可以为不同的 cgroup 启用不同的控制器组合,以实现对不同资源的控制。

联合文件系统 UnionFS

1. 什么是联合文件系统 UnionFS?

联合文件系统可以将多个目录(称为分支)挂载到同一个虚拟文件系统下。每个分支可以有不同的权限,比如:

  • 只读(readonly):不能修改。
  • 读写(readwrite):可以修改。
  • 白名单(whiteout-able):可以删除或隐藏文件。

核心思想是 分层存储,通过将多个只读层和一个可写层叠加在一起,形成一个完整的文件系统视图。

2. 联合文件系统在 Docker 中的作用

Docker 使用联合文件系统来实现容器的 镜像分层写时复制(Copy-on-Write) 机制。

(1) 镜像分层
  • Docker 镜像是由多个 只读层(readonly layers) 组成的,每一层包含文件系统的一部分。
  • 例如:
    • 基础镜像(Base Image)包含操作系统的核心文件(如 /bin/lib 等)。
    • 上层镜像包含应用程序及其依赖。
  • 这些只读层通过联合文件系统叠加在一起,形成一个完整的文件系统视图。
(2) 容器层
  • 当 Docker 启动一个容器时,会在镜像的最上层添加一个 可写层(writable layer)
  • 所有对文件系统的修改(如创建、修改、删除文件)都发生在可写层中,而不会影响底层的只读镜像。
  • 这种机制称为 写时复制(Copy-on-Write)
(3) 镜像共享
  • 多个容器可以共享同一个基础镜像,但每个容器有自己的可写层。
  • 这样可以节省存储空间,因为基础镜像只需要存储一次。

3. 联合文件系统的优势

  • 节省存储空间:多个容器可以共享同一个基础镜像,避免了重复存储。
  • 快速部署:由于镜像分层,启动容器时只需要加载可写层,而不需要复制整个文件系统。
  • 内存更省:多个容器共享同一个基础镜像,操作系统可以将这些文件缓存到内存中。
  • 升级更方便:如果需要更新基础镜像,只需要更新底层的只读层,而不需要修改每个容器。
  • 灵活的文件修改:所有对文件系统的修改都发生在可写层中,不会影响底层的只读镜像。

Docker 容器的启动过程

1. 典型的 Linux 启动过程

  • BootFS(Boot File System)
    • 包含 bootloader 和内核(kernel)。
    • 系统启动时,BIOS/UEFI 加载 bootloader(如 GRUB)。
    • bootloader 加载内核到内存中。
    • 内核初始化硬件并加载必要的驱动。
    • 内核加载完成后,BootFS 会被卸载,内存使用权交给内核。
  • RootFS(Root File System)
    • 包含操作系统的核心文件,如 /bin/lib/etc/dev 等。
    • 内核挂载 RootFS 为只读(readonly),并进行文件系统检查。
    • 检查完成后,RootFS 被切换为读写(readwrite),供用户使用。
    • 系统启动初始化进程(如 systemd 或 init),加载服务并进入用户空间。

2. Docker 容器的启动过程

请添加图片描述

  • BootFS
    • Docker 镜像的最底层是 BootFS,包含 bootloader 和内核。
    • Docker 容器启动时,会加载 BootFS 中的内核。
    • 内核初始化后,BootFS 会被卸载。
    • 注意:Docker 容器通常共享宿主机的内核,因此 BootFS 在容器中并不常用。
  • RootFS
    • RootFS 包含操作系统的核心文件,如 /bin/lib/etc/dev 等。
    • Docker 镜像的 RootFS 是只读(readonly)的,由多个镜像层(layers)组成。
    • 容器启动时,Docker 会在 RootFS 之上加载一个可写层(容器层)。
    • 容器的文件系统视图是 RootFS(只读)和容器层(可写)的联合挂载。
  • 容器层
    • 容器层是容器运行时唯一的可写层,所有对文件系统的修改都发生在这里。
    • 容器启动后,用户可以在容器层中创建、修改或删除文件。
    • 这些修改不会影响底层的只读镜像,从而实现容器的隔离性和可移植性。
  • 后续操作
    • 容器启动后,Docker 会执行容器中的入口点(Entrypoint)或命令(CMD)。
    • 容器进程运行在容器层中,用户可以通过命令行或应用程序与容器交互。

3. Docker 容器与典型 Linux 启动过程的区别

特性典型 Linux 启动过程Docker 容器启动过程
BootFS包含 bootloader 和内核,启动后卸载。通常共享宿主机的内核,BootFS 不常用。
RootFS挂载为只读,检查后切换为读写。由多个只读镜像层组成,容器层为可写。
文件系统完整的文件系统,包含所有目录和文件。联合文件系统,只读镜像层 + 可写容器层。
内核使用自己的内核。通常共享宿主机的内核。
隔离性无隔离,直接运行在物理机或虚拟机上。通过命名空间和控制组实现隔离。

Docker 使用的不同的存储驱动

Docker 在不同的时期和环境下使用了不同的存储驱动(Storage Driver),包括 AUFS、OverlayFS、Device Mapper 等。具体使用哪个存储驱动取决于以下因素:

  • 操作系统:不同的 Linux 发行版支持不同的存储驱动。
  • 内核版本:某些存储驱动需要特定的内核版本支持。
  • 用户配置:用户可以通过 Docker 配置文件手动指定存储驱动。

1. AUFS

  • 使用时期:Docker 早期版本(如 Docker 1.0 到 Docker 1.12)。
  • 支持环境:Ubuntu 和 Debian 等支持 AUFS 的 Linux 发行版。
  • 特点
    • 性能较好,尤其是在处理大量小文件时。
    • 未合并到 Linux 内核主线,需要额外补丁支持。
  • 现状:由于未合并到内核主线,AUFS 逐渐被 OverlayFS 取代。

2. OverlayFS

  • 使用时期:Docker 1.4 及以后版本。
  • 支持环境:Linux 内核 3.18 及以上版本。
  • 特点
    • 高性能,稳定性高。
    • 已合并到 Linux 内核主线,无需额外补丁。
  • 现状:OverlayFS 是 Docker 的默认存储驱动,广泛应用于现代 Linux 发行版。

3. Device Mapper

  • 使用时期:Docker 早期版本(如 Docker 1.0 到 Docker 1.12)。
  • 支持环境:CentOS、RHEL 等不支持 AUFS 的 Linux 发行版。
  • 特点
    • 基于块设备的存储驱动,适合企业级环境。
    • 配置复杂,性能较 AUFS 和 OverlayFS 稍差。
  • 现状:逐渐被 OverlayFS 取代,但在某些特定场景下仍在使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值