1. 两者的区别是什么?

首先,Docker 和虚拟机(Virtual Machine, VM)都是用来实现隔离资源管理的技术,主要目的是让不同的应用程序能够运行在相互独立的环境中,互不干扰。但它们的实现方式、性能和使用场景有很大的区别。

我们用独立的房子和公寓大楼来类比着理解 Docker 和虚拟机的区别:

  • 虚拟机: 可以把虚拟机比作一套完整的“独立房子”:

    • 每个虚拟机都像一栋完整的房子,带有自己的地基(操作系统内核)、墙(硬件模拟)和房间(运行的应用程序)。
    • 每次需要新的虚拟机,就需要重新盖一套完整的房子(安装新的操作系统和硬件模拟),耗时耗力,且占用资源大。
  • Docker: Docker 更像是住在一栋“公寓大楼”里的租户:

    • 公寓楼(宿主机的操作系统和硬件)已经盖好了,Docker 容器只需要一个隔间(容器)就可以住人,不需要重新建地基(操作系统)。
    • 所有租户(容器)共用这栋公寓楼的公共设施(宿主机内核和资源),但互相独立,各自的生活(程序运行)互不干扰。

根据以上场景,Docker 和虚拟机的区别就比较明显了。下面是他们的核心区别:

特点虚拟机Docker(容器)
运行环境每个虚拟机都有自己的操作系统容器共用宿主机的操作系统内核
启动速度启动一个完整的虚拟机需要数十秒到几分钟启动一个容器通常只需几秒
资源消耗资源占用高,需要模拟完整硬件和操作系统资源占用低,直接运行在宿主机上
隔离性隔离较强,虚拟机之间完全独立隔离性强,但共用内核(通过内核隔离实现)
性能性能损耗较大,因为需要硬件虚拟化性能接近宿主机(因为是直接运行在宿主机上)
镜像大小镜像较大(包含完整操作系统)镜像较小(只包含应用程序及其依赖)
技术复杂度配置复杂,需要安装虚拟机管理程序(如 VMware、VirtualBox)配置简单,直接运行 Docker 容器

2. Docker 是如何实现隔离的?

Docker 的隔离主要通过以下两种技术实现:

  1. 内核级隔离: 利用 Linux 的 Namespace(命名空间)技术。
  2. 资源控制: 利用 Linux 的 Cgroups(控制组)技术。

这两种技术结合起来,让容器之间看起来像是“独立的操作系统”,但实际上它们共用同一个宿主机内核。

2.1 Namespace:命名空间(实现环境隔离)

  • Namespace 是什么? Namespace 是 Linux 内核的一种技术,用于隔离容器的系统资源。通过 Namespace,Docker 可以让每个容器看到的系统资源(如进程、网络、文件系统等)看起来像是独立的。
  • Namespace 的主要作用:
    • 隔离资源: 不同容器只能看到自己的资源,互相看不到。
    • 独立运行: 每个容器都有自己的文件系统、网络、进程列表等,像是运行在独立的系统中。
  • Namespace 的具体分类: Docker 利用了以下几种 Namespace 技术:
    1. PID Namespace(进程隔离)
      • 每个容器都有自己的进程空间。
      • 容器内的进程看不到宿主机和其他容器的进程。
    2. Network Namespace(网络隔离)
      • 每个容器都有自己的网络接口、IP 地址和路由表。
      • 容器之间的网络隔离由 Network Namespace 实现。
    3. Mount Namespace(文件系统隔离)
      • 每个容器可以拥有自己的文件系统挂载点。
      • 容器内看不到宿主机的文件,除非显式挂载共享目录。
    4. UTS Namespace(主机名隔离)
      • 每个容器可以有自己的主机名和域名。
    5. IPC Namespace(进程间通信隔离)
      • 容器之间的共享内存和信号量是隔离的。
    6. User Namespace(用户隔离)
      • 容器内的用户和宿主机的用户可以映射,从而提供更好的安全性。

2.2 Cgroups:控制组(实现资源限制)

  • Cgroups 是什么? Cgroups(Control Groups)是 Linux 的一种机制,用于限制和管理容器的资源使用,包括 CPU、内存、磁盘 IO 和网络带宽
  • Cgroups 的作用:
    1. 限制资源: 限制每个容器最多可以使用的 CPU、内存等资源,防止某个容器消耗过多资源而影响其他容器或宿主机。
    2. 优先级分配: 为容器设置资源的优先级。
    3. 资源统计: 监控容器的资源使用情况。
    4. 隔离资源: 每个容器只能使用分配给它的资源。
  • Cgroups 就像“用电闸”控制每个家庭的电量。每个家庭(容器)分配了一定的用电量(资源),如果超出配额,就会断电(资源耗尽)。

2.3 UnionFS:文件系统隔离

Docker 使用了 UnionFS(联合文件系统) 来管理容器的文件。

  • UnionFS 可以将多个层叠加成一个统一的文件系统。
  • Docker 的镜像分为多层结构,每一层只存储变化的部分(增量存储)。
  • 作用:
    1. 不同容器可以共享同一套基础镜像,节省磁盘空间。
    2. 容器之间的文件系统互相独立,修改不会影响其他容器。

3. Docker 的工作流程

启动容器的过程:

  1. Docker 从镜像中创建一个文件系统(UnionFS)。
  2. Docker 使用 Namespace 技术,为容器创建独立的网络、进程和文件系统空间。
  3. Docker 使用 Cgroups 限制容器的资源(CPU、内存等)。
  4. 容器启动后,用户可以像操作一个独立的虚拟机一样操作容器。