Docker 资源隔离

技术实现

Docker 是使用 Linux 的 Namespace 技术实现各种资源隔离的。
Namespace 是 Linux 内核的一项功能,该功能对内核资源进行分区,以使一组进程看到一组资源,而另一组进程看到另一组资源。Namespace 的工作方式通过为一组资源和进程设置相同的 Namespace 而起作用,但是这些 Namespace 引用了不同的资源。资源可能存在于多个 Namespace 中。这些资源可以是进程 ID、主机名、用户 ID、文件名、与网络访问相关的名称和进程间通信。


Namespace 类型

在最新的 Linux 5.6 内核中,提供了 8 种类型的 Namespace,但最新版本的 Docker 只使用了其中的前 6 种类型,如下表所示:

Namespace 名称简称作用内核版本
Mountmnt隔离挂载点2.4.19
Process IDpid隔离进程ID2.6.24
Networknet隔离网络设备、端口号等2.6.29
Interprocess Communicationipc隔离信息量、消息队列和共享内存2.6.19
UTSuts隔离主机名和域名2.6.19
Useruser隔离用户和用户组3.8
Control groupcgroup隔离 Cgroups 根目录4.6
Timetime隔离系统时间5.6

Namespace 各类型作用

通过使用 unshare 命令可以实现创建并访问不同类型的 Namespace,模拟 Dokcer 资源隔离的效果。以下只针对 Docker 使用的前 6 种类型来分析它们各自的作用:

##### Mount Namespace:实现在不同的进程中看到不同的挂载目录
### 通过unshare命令创建一个bash进程,作为窗口1
$ unshare --mount --fork /bin/bash
[root@centos7 ~]# mkdir /tmp/tmpfs
[root@centos7 ~]# mount -t tmpfs -o size=20m tmpfs /tmp/tmpfs
[root@centos7 ~]# df -h /tmp/tmpfs
Filesystem      Size  Used Avail Use% Mounted on
tmpfs            20M     0   20M   0% /tmp/tmpfs

### 打开一个新的命令行窗口,作为窗口2验证
[root@centos7 ~]# df -h /tmp/tmpfs
df: /tmp/tmpfs: No such file or directory

--------------------------------------------------------------------------------------------------
##### PID Namespace:实现每个容器的主进程为1号进程,而容器内的进程在主机上却拥有不同的PID
### 在当前命令行窗口加入了新创建的 PID Namespace,从而看不到主机上其他进程信息
$ unshare --pid --fork --mount-proc /bin/bash
[root@centos7 ~]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0 115544  2004 pts/0    S    10:57   0:00 bash
root        10  0.0  0.0 155444  1764 pts/0    R+   10:59   0:00 ps aux

--------------------------------------------------------------------------------------------------
##### UTS Namespace:实现在容器内的主机名称为任意自定义的主机名
### 在当前命令行窗口加入了新创建的 UTS Namespace,作为窗口1
$ unshare --uts --fork /bin/bash
[root@centos7 ~]# hostname -b utsdocker && hostname
utsdocker

### 打开一个新的命令行窗口,作为窗口2验证
[root@centos7 ~]# hostname
centos7

--------------------------------------------------------------------------------------------------
##### IPC Namespace:实现在容器内的不同空间下的进程间不能通信
### 在当前命令行窗口加入了新创建的 IPC Namespace,作为窗口1
$ unshare --ipc --fork /bin/bash

## 创建系统间通信队列
[root@centos7 centos]# ipcmk -Q
Message queue id: 0

## 查看系统间通信队列列表
[root@centos7 ~]# ipcs -q
------ Message Queues --------
key          msqid      owner      perms      used-bytes   messages
0x73682a32   0          root       644        0            0

### 打开一个新的命令行窗口,作为窗口2验证
[root@centos7 ~]# ipcs -q
------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

--------------------------------------------------------------------------------------------------
##### User Namespace:实现进程在容器内拥有root权限,而在主机上却只是普通用户
### unshare命令报错无效参数,需要修改系统允许创建 User Namespace 的数量
$ echo 65535 > /proc/sys/user/max_user_namespace

### 在当前命令行窗口加入了新创建的 User Namespace
$ unshare --user -r /bin/bash
[root@centos7 ~]# id
uid=0(root) gid=0(root) groups=0(root),65534(nfsnobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

### 虽然已是root用户,但执行重启失败,说明并不能获取到主机的root权限
[root@centos7 ~]# reboot
Failed to open /dev/initctl: Permission denied
Failed to talk to init daemon.

--------------------------------------------------------------------------------------------------
##### Net Namespace:实现每个进程拥有自己独立的IP地址、端口和网卡信息
### 在当前命令行窗口加入了新创建的 Net Namespace,作为窗口1
$ unshare --net --fork /bin/bash
[root@centos7 ~]# 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

### 打开一个新的命令行窗口,作为窗口2验证
[root@centos7 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:11:b0:14:01:0c brd ff:ff:ff:ff:ff:ff
    inet 172.25.168.11/24 brd 172.25.168.255 scope global dynamic eth0
       valid_lft 86063337sec preferred_lft 86063337sec
    inet6 fe80::11:b0ff:fe14:10c/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:82:8d:a0:df brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:82ff:fe8d:a0df/64 scope link
       valid_lft forever preferred_lft forever
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值