Docker命名空间
阅读原文时间:2023年07月09日阅读:3

命名空间( namespace )是 Linux 内核的一个强大特性,为容器虚拟化的实现带来极大便利,利用这 特性,每个容器都可以拥有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统环境中一样 命名 间机制保证了容器之间彼此互不影响。

在操作系统中,包括内核、文件系统、网络、进程号( Process ID, PID )、用户号( UserID, UID 进程间通信( Inter Process Communication, IPC )等资源,所有的资源都是应用进程直接共享的 要想实现虚拟化,除了要实现对内存、 CPU 、网络 IO 、硬盘 IO 、存储空间等的限制外,还要实现文件系统、网络、 PID UID IPC 等的相互隔离 前者相对容易实现一些,后者则需要宿主主机系统的深入支持。

随着 Linux 系统对于命名空间功能的逐步完善,现在已经可以实现这些需求,让进程在彼此隔离的命名空间中运行 虽然这些进程仍在共用同 个内核和某些运行时环境(runtime ,例如一些系统命令和系统库),但是彼此是不可见的,并且认为自己是独占系统的

Docker 容器每次启动时候,通过调用 func setNamespaces(daemon *Daemon, s *specs. Spec, c *container.Container) error 方法来完成对各个命名 间的配置

进程命名空间

Linux 通过进程命名 理进程号,对于同 进程(同 task struct ),在不同的命名空间中,看到的进程号不相同 个进程命名 间有一套 自己的进程号管理方法 进程命名空间是一个父子关系的结构,子空间中的进程对于父 间是可见的 fork 出的 个进程,在父命名空间和子命名空间将分别对应不同的进程号 例如,查看 Docker 服务主进程( dockerd )的进程号是 3393 ,它作为父进程启动了 docker containerd 进程,进程号为 3398,

代码如下所示:

$ ps - ef lgrep docker
root 3393 1 0 Jan18 ? 00 43 02 /usr/bin/dockerd - H fd : // -H tcp://
127 . 0 . 0 . 1 : 2375 -H unix:///var/run/docker.sock
root 3398 3393 0 Jan18 ? 00 : 34 : 31 docker containerd config /var/ru口/
docker /conta nerd/conta nerd toml

新建一个 Ubuntu 容器,执行 sleep 命令 此时 docker containerd 进程作为父进程,会为每个容器启动一个 docker containerd shim 程,作为该容器内所有进程的根进程

$ docker ru --name test d ubuntu :l6 . 04 sleep 9999
$ ps -ef lgrep docker
root 21535 3398 0 06 : 57 ? 00 : 00 : 00 docker-containerd-shim

从宿主机上查看新建容器的进程的父进程 ,正是 docker-containerd shim 进程:

$ ps -e f lgrep sleep
root 21569 21535 0 06 : 57 ? 00 : 00 : 00 sleep 9999

而在容器内的进程空 间中 则把 docker containerd-shim 进程作为 号根进程(类似宿主系统 号根进程 idle), while 进程的进程号则变为 (类似宿主系统中 号初始化进程/sbin/init 容器内只能看到 docker containerd iim 程往下的子进程空间,而无法获知宿主机上的进程信息:

$ docker exec -it 3a bash c ’ ps ef ’
UID PID PPID C STIME TTY TI ME CMD
root 1 0 0 06 : 57 ? 00 : 00 : 00 sleep 9999

IPC 命名空间

容器中的进程交互还是采用了 Linux 常见的进程间交互方法( Interprocess Communication, IPC ),包括信号 、消息队列和共 内存等方式PID 命名 间和 IPC 命名空间可以组合起来使用,同 IPC 命名 间内的进程可以彼此可见,允许进行交互;不同 间的进程则无法交互

网络命名空间

有了进程命名空间后,不同命名空间中的进 17-2 宿主机与容器内进程空间的关系 程号可以相互隔离,但是网络端口还是共享本地

系统的端口

通过网络命名空间,可以 现网络隔离。一个网络命名空间为进程提供了一个完全独立的网络协议校的视图 包括网络设备接口 1Pv4 1Pv6 协议械 IP路由 表、 防火墙规则 sockets 等, 这样 容器的网络就能隔离开来

Docker 采用虚拟网络设备(Virtual Network Device, VND )的方式,将不同命名 间的网络设备连接到一起,默认情况下, Docker 在宿 机上创建多个虚机网桥(如 认的网桥 dockerO)容器中的虚拟网卡通过网桥进行连接。

使用 docker network ls 令可以查看 当前系统中的网桥:

$ docker network ls
NETWORK ID NAME DRIVER SCOPE
337120b7e82e lO_ default bridge local
7b0bc9cdc8a0 bridge bridge local
8f57993d438b host host local
6d9342f43ffc none null local

使用 brctl 工具(需要 bridge utils 工具包 ,还可以 到连 到网桥 拟网口的信息 默认分配一个网桥上的虚拟网口, 并将 dockerO IP 地址设 默认的网关, 容器发起的网络流 通过宿主机的 iptab es 规则进行转发

$ brctl show

挂载命名空间

类似于 cbro 挂载 Mount MNT 空间可以将一个进 的根文件系 限制到

个特定的目录下

挂载命名 间允许不同命名空 间的进程 到的 位于宿主机中不同路 ,每

个命名 间中的进程所看到的文件目 彼此是隔离的 例如, 同命名空间中的进程, 都认为自己独占了 个完 的根文件系统( rootfs 际上,不同命名空间中的文件彼此不受任何影响,同时也无法 响宿主机文件系统中的 他路径

UTS 命名空间

UTS (UNIX T im e -sh aring System 命名 间允许 容器 有独立的主机 和域 ,从而可以虚拟出一个有独 主机 和网络空间的环境 就跟网 台独 的主机一样

如果没有于动指定主机名称 Docker 器的主机名就是返回的容器 ID 的前 节前缀,否则为指定的用户名:

$docker run - -name testl -d ubuntu : l6 . 04 /bin/sh -c ”while t rue ; do echo h e llo
worl d ; sl eep l ; done "
alb7bdc9609ad52c6ca7cd39dl69d55ae32f8523lee22da063la20c94d7aa8db
$docker [contai ner] inspect -f {{ ". Config . Hostname ” }} testl
alb7bdc9609a
$ docker run --hostname test2 --name test2 -d ubuntu: 16 . 04 /bin/sh c ” while
true ; do echo hello world; sleep l; done ”
140573f8582584d8e 331368288a96a8838f4a7ed0ff7ee50824f8lbc0459677a
$docker [contai ner] inspect -f {{ .Config.Hostn ne ” }} test2
test2

用户命名空间

每个容器可以有不同的用户和组 id 也就是说 可以在 器内使用特定的内部用户执行程序,而非本地系统上存在的用户

每个容器内部都可以有 高权限的 root 帐号,但跟宿主主机不在一个命名 通过使用隔离的用户命名 可以提高安全 ,避 容器内的进程获取 外的权限;同时通过使用不同用户也可以进一步在容器内控制权限

例如,下面的命令在容器内创建了 test 用户,只有普通权限,无法访问更高权限的资源:

$ docker run --rm --it ubuntu :l6 . 04 bash
root@6da1370b22a0: /# cat /pro c/1/enviro
PATH=/usr/local/sbin : /usr/local/bin: /usr/sbin: /usr/bin : /sb工口: lb nHOSTNAME=6dal37
Ob22a0TERM=xtermHOME=/root
root@6da1370b22a0 : /# useradd ms /bin/bash test
root@6da13 70b22a0 : /# su test
test@6da1370b22a0 : /$ cat /proc/1/environ
cat: /proc/1/environ: Pe ssion denied