让我们在一个舒缓的 BGM 中开始今日话题 Docker Namespaces
随着现在云原生蓬勃发展,Docker 成为每个技术伙伴必须要掌握的一项技能,当然小白手套也不例外,有天小白手套想,为什么每次容器运行起来,不管我在当前容器内怎么修改,对于同样运行在宿主机的其他容器毫无影响,同时,我也看不到其他容器中的内容,它究竟是怎么做到的,本章让我们跟随小白手套走进 NameSpace 的世界。
参考维基百科对 Namespaces 的定义
大致意思是:
用大白话翻译过可以这样理解:
Linux 命名空间是 2002 年 2.4.19 内核开始,主要针对挂载命名空间的类型,从 2006 年开始持续至今。
Linux 内核 5.6 开始 支持 8 种命名空间
命名空间 | 隔离资源 |
---|---|
Mount (mnt) | 隔离挂载点 |
Process ID (pid) | 隔离进程 |
Network (net) | 隔离网络 |
Inter-process Communication (ipc) | 隔离进程与商业版 Unix System V |
UTS | 隔离主机名和域名 |
User ID (user) | 隔离用户 |
Control group (cgroup) Namespace | 隔离CPU、内存等 |
Time Namespace | 隔离系统时间 |
华为工程师瑞翔提出 syslog namespace,并没有合并到 linux 内核
unshare
命令是 Linux 中的一个命令行工具,用于在新的命名空间中执行命令。它允许你将进程从当前的命名空间中分离出来,使得它在一个新的、隔离的环境中运行。
unshare
命令的基本用法:
cssCopy code
unshare [options] [command [args...]]
options
: 是一些控制命名空间的选项。command
: 是在新的命名空间中执行的命令。args...
: 是命令的参数。一些常见的选项包括:
-m
或 --mount[=mount_options]
:创建新的挂载命名空间。-u
或 --uts[=utsname]
:创建新的 UTS 命名空间,用于修改系统主机名。-n
或 --net[=hostname]
:创建新的网络命名空间。-i
或 --ipc
:创建新的 IPC 命名空间。
Mount Namespace
创建后,当前挂载命名空间中的挂载将复制到新命名空间,但随后创建的挂载点不会在命名空间之间传播(使用共享子树,可以在命名空间之间传播挂载点)。
我们的操作
mount namespace
,并且访问创建好的 mount namespaceunshare --mount --fork /bin/bash
mkdir -p /maomao/mount
mount -t tmpfs -o size=10m tmpfs /maomao/mount
df -h
ls -l /proc/self/ns/
可以看到已经成功挂载,关注 namespace mount id
df -h
ls -l /proc/self/ns/
可以看到,宿主机是不存在 maomao/mount 这个挂载目录的,并且 mnt id 也是不一致的
Process ID Namespace
不同 Process ID Namespace 中 PID 号是可以相同的
在 PID 命名空间中创建的第一个进程被分配进程 ID 号 1,并接受与正常init进程相同的大部分特殊处理,最值得注意的是命名空间内的孤立进程附加到它。这也意味着终止此 PID 1 进程将立即终止其 PID 命名空间中的所有进程及其任何后代.
unshare --pid --fork --mount-proc /bin/bash
Network Namespace
- 网络命名空间虚拟化网络堆栈。创建时,网络命名空间仅包含一个环回接口。
- 每个命名空间都有一组私有IP 地址、自己的路由表、套接字列表、连接跟踪表、防火墙和其他网络相关资源。
unshare --net --fork /bin/bash
Inter-process Communication Namespace
PC 命名空间将进程与 SysV 样式的进程间通信隔离。这可以防止不同 IPC 命名空间中的进程使用 SHM 系列函数等在两个进程之间建立一系列共享内存。相反,每个进程将能够对共享内存区域使用相同的标识符,并生成两个这样的不同区域。
unshare --ipc --fork /bin/bash
UTS Namespace
允许单个系统对于不同的进程看起来具有不同的主机名
unshare --uts --fork /bin/bash
User ID Namespace
为了促进管理操作的权限隔离,每个命名空间类型都被视为由基于创建时活动用户命名空间的用户命名空间拥有。在适当的用户命名空间中具有管理权限的用户将被允许在其他命名空间类型中执行管理操作。
如果进程具有更改网络接口的 IP 地址的管理权限,则只要其自己的用户命名空间与拥有该网络命名空间的用户命名空间相同(或其祖先),它就可以这样做。因此,初始用户命名空间对系统中的所有命名空间类型具有管理控制权。
非 root 权限就可以创建 user namespace
unshare --user -r /bin/bash
尽情享受技术带来的乐趣吧,祝你好运。
参考文献: