09 | 资源隔离:构建容器为什么需要Namespace?
什么是Namespace
下面是Namespace的维基百科定义
Namespace 是 Linux 内核的一项功能,该功能对内核资源进行分区,以使一组进程看到一组资源,而另一组进程看到另一组资源。Namespace 的工作方式通过为一组资源和进程设置相同的 Namespace 而起作用,但是这些 Namespace 引用了不同的资源。资源可能存在于多个 Namespace 中。这些资源可以是进程 ID、主机名、用户 ID、文件名、与网络访问相关的名称和进程间通信。
-
为一组资源和进程设置相同的Namespace
-
Namespace引用了不同的资源
Docker 利用 Linux 内核的 Namespace 特性,实现了每个容器的资源相互隔离,从而保证容器内部只能访问到自己 Namespace 的资源。
最新的 Linux 5.6 内核中提供了 8 种类型的 Namespace:
Namespce 名称 | 作用 |
---|---|
Mount(mnt) | 隔离挂载点2.4.19 |
Process ID (pid) | 隔离进程 ID2.6.24 |
Network (net) | 隔离网络设备,端口号等2.6.29 |
Interprocess Communication (ipc) | 隔离 System V IPC 和 POSIX message queues 2.6.19 |
UTS Namespace(uts) | 隔离主机名和域名2.6.19 |
User Namespace (user) | 隔离用户和用户组3.8 |
Control group (cgroup) Namespace | 隔离 Cgroups 根目录4.6 Time Namespace |
虽然 Linux 内核提供了8种 Namespace,但是最新版本的 Docker 只使用了其中的前6 种,分别为Mount Namespace、PID Namespace、Net Namespace、IPC Namespace、UTS Namespace、User Namespace。
下面,我们详细了解下 Docker 使用的 6 种 Namespace的作用分别是什么。
各种Namespace的作用
(1)Mount Namespace
Mount Namespace 是 Linux 内核实现的第一个 Namespace,从内核的 2.4.19 版本开始加入。它可以用来隔离不同的进程或进程组看到的挂载点。通俗地说,就是可以实现在不同的进程中看到不同的挂载目录。使用 Mount Namespace 可以实现容器内只能看到自己的挂载信息,在容器内的挂载操作不会影响主机的挂载目录。
下面我们通过一个实例来演示下 Mount Namespace。在演示之前,我们先来认识一个命令行工具 unshare。unshare是 util-linux 工具包中的一个工具,CentOS 7 系统默认已经集成了该工具,使用 unshare 命令可以实现创建并访问不同类型的 Namespace。
首先我们使用以下命令创建一个 bash 进程并且新建一个 Mount Namespace:
$ sudo unshare --mount --fork /bin/bash
[root@centos7 centos]#
执行完上述命令后,这时我们已经在主机上创建了一个新的 Mount Namespace,并且当前命令行窗口加入了新创建的 Mount Namespace。下面我通过一个例子来验证下,在独立的 Mount Namespace