NameSpace是什么?
NameSpace 是 Linux 内核的一项功能,该功能对内核资源进行分区,以使一组进程看到一组资源,而另一组进程看到另一组资源。Namespace 的工作方式通过为一组资源和进程设置相同的 Namespace 而起作用,但是这些 Namespace 引用了不同的资源。资源可能存在于多个 Namespace 中。这些资源可以是进程 ID、主机名、用户 ID、文件名、与网络访问相关的名称和进程间通信。
linux5.8内核中提供以下8种类型namespace
2.4.19
NameSpace名称 | 解释 | 内核版本 |
Mount(mnt) | 隔离挂载点 | 2.4.19 |
Process ID (pid) | 隔离进程ID | 2.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 | 隔离系统时间 | 5.6 |
接下来实操几个namespace
[root@control-plane ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
安装util-linux包,里面有个我们需要的工具unshare,利用这个工具创建不同的namespace
1、Mount(mnt)
执行下列命令就将创建的bash放到了mount空间中
[root@control-plane ~]# unshare --mount --fork /bin/bash
创建目录并挂载
[root@control-plane ~]# mkdir /tmp/mytmp
[root@control-plane ~]# mount -t tmpfs -o size=20m tmps /tmp/mytmp/
查看挂载 ,我这里有很多docker的东西这里我就过滤一下了
[root@control-plane ~]# df -Th|grep -v var
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root xfs 116G 40G 77G 34% /
devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 12K 3.9G 1% /dev/shm
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
tmpfs tmpfs 3.9G 26M 3.8G 1% /run
tmpfs tmpfs 783M 0 783M 0% /run/user/0
/dev/sda1 xfs 1014M 146M 869M 15% /boot
tmps tmpfs 20M 0 20M 0% /tmp/mytmp
这里在打开一个控制台来验证下是否有这个挂载点,这里就可以证明mount空间被隔离了
[root@control-plane ~]# df -Th|grep -v var
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root xfs 116G 40G 77G 34% /
devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 12K 3.9G 1% /dev/shm
tmpfs tmpfs 3.9G 26M 3.8G 1% /run
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda1 xfs 1014M 146M 869M 15% /boot
tmpfs tmpfs 783M 0 783M 0% /run/user/0
mount空间中的mount 号,这里除了mount命名空间的号不一致其它空间均一致
[root@control-plane ~]# ls -l /proc/self/ns
总用量 0
lrwxrwxrwx 1 root root 0 9月 28 15:14 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 9月 28 15:14 mnt -> mnt:[4026532796]
lrwxrwxrwx 1 root root 0 9月 28 15:14 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 9月 28 15:14 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 9月 28 15:14 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 9月 28 15:14 uts -> uts:[4026531838]
本机中的mount号
[root@control-plane ~]# ls -l /proc/self/ns
总用量 0
lrwxrwxrwx 1 root root 0 9月 28 15:14 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 9月 28 15:14 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 9月 28 15:14 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 9月 28 15:14 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 9月 28 15:14 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 9月 28 15:14 uts -> uts:[4026531838]
2、PID namespace
在不同的PID namespace 每个容器进程号从1开始
进入pid空间
[root@control-plane ~]# unshare --pid --fork --mount-proc /bin/bash
查看进程pid空间进程号和主机上的进程对比
[root@control-plane ~]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 115576 2116 pts/0 S 15:23 0:00 /bin/bash
root 13 0.0 0.0 155364 1860 pts/0 R+ 15:24 0:00 ps aux
3、UTS namespace
主要用来隔离主机名
进入UTS空间
[root@control-plane ~]# unshare --uts --fork --mount-proc /bin/bash
配置主机名,设置后并不会影响其它空间中的主机名
[root@control-plane ~]# hostname -b mytest
[root@control-plane ~]# hostname
mytest
4、IPC namespace
主要是隔离进程间通信的,通一个命名空间中的进程可以互相通信
进入ipc空间
[root@control-plane ~]# unshare --ipc --fork /bin/bash
[root@control-plane ~]# ipcs -q
--------- 消息队列 -----------
键 msqid 拥有者 权限 已用字节数 消息
[root@control-plane ~]# ipcmk -Q
消息队列 id:0
[root@control-plane ~]# ipcs -q
--------- 消息队列 -----------
键 msqid 拥有者 权限 已用字节数 消息
0x364fd18a 0 root 644 0 0
5、NET namespace
这里就是隔离网络空间的,在创建个path对就可以和主机通信了
[root@control-plane ~]# unshare --net --fork /bin/bash
[root@control-plane ~]# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6、User namespace
[root@control-plane ~]# unshare --user -r /bin/bash
提示:
CentOS7 默认允许创建的 User Namespace 为 0,如果执行上述命令失败( unshare 命令返回的错误为 unshare: unshare failed: Invalid argument ),需要使用以下命令修改系统允许创建的 User Namespace 数量,命令为:echo 65535 > /proc/sys/user/max_user_namespaces,然后再次尝试创建 User Namespace。
Docker创建容器就利用了这6个namespace进行资源隔离