Linux的namespace和cgroups简介

简介: 本文介绍了Linux的Namespace技术和cgroups,解释了它们如何帮助实现容器的隔离和资源限制。

作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.Linux Namespace技术

  Namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在核内,各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核。  

  各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间,网络空间,进程空间等,目前主要通过以下技术实现容器运行空间的相互隔离。

1>.MNT Namespace

  每个容器都要有独立的根文件系统用户空间,以实现在容器里面启动服务并且使用容器的运行环境,即一个宿主机是ubuntu的服务器,可以在里面启动一个centos运行环境的容器并且在里面启动一个Nginx服务,此Nginx运行时使用的运行环境就是centos系统目录的运行环境,但是在容器里面不能访问宿主机的资源,宿主机是使用了chroot技术把容器锁定到一个指的运行目录里面。

2>.IPC Namespace

  一个容器内的进程间通信,允许一个容器内的不同进程的(内存,缓存等)数据访问,但是不能跨容器访问其他容器的数据 。

3>.UTS Namespace

  UTS namespace(UNIX Timesharing System 包含了运行内核的名称、版本底层体系结构类型等信息)用于系统标识,其中包含了hostname和域名domainname,它使得一个容器拥有属于自己hostname标识,这个主机名标识独立于宿主机系统和其上的他容器 。

4>.PID Namespace

  Linux系统中,有一个PID为1的进程(init/systemd)是其他所有进程的父,那么 在每个容器内也要有一个父进程来管理其下属的子进程,那么多个容器的进程通的PID namespace进程隔离(比如PID编号重复、器内的主进程与回收子进程等)。

root@docker101:~# docker images                          #查看现有的镜像
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              c7460dfcab50        2 days ago          126MB
centos              latest              0f3e07c0138f        3 months ago        220MB
root@docker101:~# 
root@docker101:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
968e7ecc39f2        centos              "/bin/bash"         3 hours ago         Up 3 hours                              keen_meitner
root@docker101:~# 
root@docker101:~# docker run -d -it nginx                  #基于nginx镜像运行一个容器
44edd3477c0d7380ab23dc23f00055b7a17eecd483a666c47e11fac6786a2f3e
root@docker101:~# 
root@docker101:~# docker ps                                #查看正在运行的容器
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
44edd3477c0d        nginx               "nginx -g 'daemon of…"   4 seconds ago       Up 2 seconds        80/tcp              stupefied_driscoll
968e7ecc39f2        centos              "/bin/bash"              3 hours ago         Up 3 hours                              keen_meitner
root@docker101:~# 
root@docker101:~# ps -ef | grep docker                     #我们现在宿主机上查看所有docker相关的容器,我们通过目录前缀就可以判断出PID为"7183"的进程是咱们刚刚启动的"nginx"容器。
root       6171      1  0 08:18 ?        00:00:11 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root       6553   4451  0 08:24 ?        00:00:02 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/968e7ecc39f277a3d3f98b658f8f496de622edccfa4ef45d8ec64c46f5012d4c -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root       7831   4451  0 11:27 ?        00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/44edd3477c0d7380ab23dc23f00055b7a17eecd483a666c47e11fac6786a2f3e -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root       7923   6955  0 11:27 pts/1    00:00:00 grep --color=auto docker
root@docker101:~# 
root@docker101:~# ps -ef | grep 4451
root       4451      1  0 08:03 ?        00:01:40 /usr/bin/containerd
root       6553   4451  0 08:24 ?        00:00:02 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/968e7ecc39f277a3d3f98b658f8f496de622edccfa4ef45d8ec64c46f5012d4c -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root       7831   4451  0 11:27 ?        00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/44edd3477c0d7380ab23dc23f00055b7a17eecd483a666c47e11fac6786a2f3e -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root       8136   6955  0 11:43 pts/1    00:00:00 grep --color=auto 4451
root@docker101:~# 
root@docker101:~# ps -ef | grep 7831                       #查看nginx容器的进程信息。
root       7831   4451  0 11:27 ?        00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/44edd3477c0d7380ab23dc23f00055b7a17eecd483a666c47e11fac6786a2f3e -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root       7862   7831  0 11:27 pts/0    00:00:00 nginx: master process nginx -g daemon off;
root       7925   6955  0 11:29 pts/1    00:00:00 grep --color=auto 7831
root@docker101:~# 
root@docker101:~# pstree -p 7831                           #很明显,在宿主机上"7831"运行的是"nginx"容器,而该容器中运行了nginx的主进程(pid为7862)和工作进程(pid为7904)
containerd-shim(7831)─┬─nginx(7862)───nginx(7904)
                      ├─{containerd-shim}(7832)
                      ├─{containerd-shim}(7833)
                      ├─{containerd-shim}(7834)
                      ├─{containerd-shim}(7835)
                      ├─{containerd-shim}(7836)
                      ├─{containerd-shim}(7837)
                      ├─{containerd-shim}(7838)
                      ├─{containerd-shim}(7840)
                      ├─{containerd-shim}(7892)
                      └─{containerd-shim}(8110)
root@docker101:~#

宿主机上查看PID信息

root@docker101:~# docker ps                      #我们可以看到基于nginx镜像的容器处于正常运行状态。
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
44edd3477c0d        nginx               "nginx -g 'daemon of…"   28 minutes ago      Up 28 minutes       80/tcp              stupefied_driscoll
968e7ecc39f2        centos              "/bin/bash"              4 hours ago         Up 4 hours                              keen_meitner
root@docker101:~# 
root@docker101:~# 
root@docker101:~# docker exec -it 44edd3477c0d bash
root@44edd3477c0d:/# 
root@44edd3477c0d:/# cat /etc/issue                 #查看当前nginx的镜像在哪个操作系统开发的,我们看到的信息是在Debian系统开发的,这很正常。
Debian GNU/Linux 10 n l

root@44edd3477c0d:/# 
root@44edd3477c0d:/# uname -a                     #很显然,容器除了有自己的主机名,内核版本使用的是宿主机ubuntu的。
Linux 44edd3477c0d 4.15.0-74-generic #84-Ubuntu SMP Thu Dec 19 08:06:28 UTC 2019 x86_64 GNU/Linux
root@44edd3477c0d:/# 
root@44edd3477c0d:/# apt-get update                          #必须先更新软件源,否则无法执行下面的安装命令。
root@44edd3477c0d:/# 
root@44edd3477c0d:/# apt-get -y install net-tools           #Debian系统安装网络工具
root@44edd3477c0d:/# 
root@44edd3477c0d:/# apt-get -y install curl                  #Debian系统安装curl命令
root@44edd3477c0d:/# 
root@44edd3477c0d:/# apt-get -y install procps             #Debian系统安装top命令
root@44edd3477c0d:/# 
root@44edd3477c0d:/# apt-get -y install iputils-ping         #Debian系统安装ping命令
root@44edd3477c0d:/# 
root@44edd3477c0d:/# top                         #不难发现,使用top命令我们可以看到PID为1的进程竟然是Nginx的主进程。
top - 12:09:29 up  6:27,  0 users,  load average: 0.00, 0.00, 0.00
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3921.8 total,   2027.7 free,    359.8 used,   1534.2 buff/cache
MiB Swap:   8192.0 total,   8192.0 free,      0.0 used.   3312.7 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                                                                                                
     1 root      20   0   10632   5468   4760 S   0.0   0.1   0:00.30 nginx                                                                                                                                                                                                  
     7 nginx     20   0   11120   2564   1436 S   0.0   0.1   0:00.00 nginx                                                                                                                                                                                                  
    37 root      20   0    3988   3284   2784 S   0.0   0.1   0:00.32 bash                                                                                                                                                                                                   
  2968 root      20   0    8024   3132   2664 R   0.0   0.1   0:00.00 top                                                                                                                                                                                                    
root@44edd3477c0d:/# 
root@44edd3477c0d:/# ps -ef | grep nginx
root          1      0  0 11:27 pts/0    00:00:00 nginx: master process nginx -g daemon off;
nginx         7      1  0 11:27 pts/0    00:00:00 nginx: worker process
root       2973     37  0 12:11 pts/1    00:00:00 grep nginx
root@44edd3477c0d:/# 
root@44edd3477c0d:/# netstat -untalp          #可以看到nginx进程监听了80端口
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro 
root@44edd3477c0d:/# 
root@44edd3477c0d:/# curl -I 127.0.0.1         #nginx的服务也是可以正常范围的
HTTP/1.1 200 OK
Server: nginx/1.17.7
Date: Sun, 12 Jan 2020 12:17:40 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 24 Dec 2019 13:07:53 GMT
Connection: keep-alive
ETag: "5e020da9-264"
Accept-Ranges: bytes

root@44edd3477c0d:/# 
root@44edd3477c0d:/# pstree -p 1
nginx(1)---nginx(7)
root@44edd3477c0d:/# 
root@44edd3477c0d:/# nginx -s reload                #我们可以对nginx进行重新加载,并不会让当前容器结束运行。
2020/01/12 12:12:22 [notice] 2975#2975: signal process started
root@44edd3477c0d:/# 
root@44edd3477c0d:/# ps -ef | grep nginx
root          1      0  0 11:27 pts/0    00:00:00 nginx: master process nginx -g daemon off;
nginx      2976      1  0 12:12 pts/0    00:00:00 nginx: worker process
root       2978     37  0 12:12 pts/1    00:00:00 grep nginx
root@44edd3477c0d:/# 
root@44edd3477c0d:/# 
root@44edd3477c0d:/# pstree -p 1
nginx(1)---nginx(2976)
root@44edd3477c0d:/# 
root@44edd3477c0d:/# nginx -s stop                #如果我们将nginx容器中的nginx进程给停掉后,发现该容器也会跟着停止使用了。
2020/01/12 12:14:15 [notice] 2983#2983: signal process started
root@44edd3477c0d:/# root@docker101:~# 
root@docker101:~# 
root@docker101:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
968e7ecc39f2        centos              "/bin/bash"         4 hours ago         Up 4 hours                              keen_meitner
root@docker101:~# 
root@docker101:~# docker ps -a                  #可以看到当前nginx容器是退出状态的。
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
44edd3477c0d        nginx               "nginx -g 'daemon of…"   47 minutes ago      Exited (0) 11 seconds ago                       stupefied_driscoll
968e7ecc39f2        centos              "/bin/bash"              4 hours ago         Up 4 hours                                      keen_meitner
root@docker101:~# 
root@docker101:~# docker start 44edd3477c0d          #当然,咱们也可以再次将该容器启动
44edd3477c0d
root@docker101:~# 
root@docker101:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
44edd3477c0d        nginx               "nginx -g 'daemon of…"   48 minutes ago      Up 2 seconds        80/tcp              stupefied_driscoll
968e7ecc39f2        centos              "/bin/bash"              4 hours ago         Up 4 hours                              keen_meitner
root@docker101:~# 
root@docker101:~#

查看容器中的PID相关信息

5>.Net Namespace

  每一个容器都类似于虚拟机一样有自己的网卡,监听端口,TCP/IP协议栈等,Docker使用network namespace启动一个vethX接口,这样你的容器将拥有它自己的桥接ip地址,通常是docker0,而docker0实质就是Linux的虚拟网桥,网桥是在OSI七层模型的数据链路网络设备,通过mac地址对网络进行划分,并且在不同网络直接传递数据。

root@docker101:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
44edd3477c0d        nginx               "nginx -g 'daemon of…"   About an hour ago   Up 16 minutes       80/tcp              stupefied_driscoll
968e7ecc39f2        centos              "/bin/bash"              4 hours ago         Up 4 hours                              keen_meitner
root@docker101:~# 
root@docker101:~# docker exec -it 44edd3477c0d bash
root@44edd3477c0d:/# 
root@44edd3477c0d:/# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 13  bytes 1006 (1006.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 44  bytes 4822 (4.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 44  bytes 4822 (4.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@44edd3477c0d:/# 
root@44edd3477c0d:/# exit 
exit
root@docker101:~# 
root@docker101:~# docker exec -it 968e7ecc39f2 bash
[root@968e7ecc39f2 /]# 
[root@968e7ecc39f2 /]# yum -y install net-tools
[root@968e7ecc39f2 /]# 
[root@968e7ecc39f2 /]# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 3708  bytes 15399326 (14.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3356  bytes 185759 (181.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@968e7ecc39f2 /]# 
[root@968e7ecc39f2 /]# ping 172.17.0.3            #很显然,同一个宿主机的不同容器默认是可以相互通信的。
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.101 ms
bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.042 ms
bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.108 ms
bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.052 ms
bytes from 172.17.0.3: icmp_seq=5 ttl=64 time=0.112 ms
^C
--- 172.17.0.3 ping statistics ---
packets transmitted, 5 received, 0% packet loss, time 83ms
rtt min/avg/max/mdev = 0.042/0.083/0.112/0.029 ms
[root@968e7ecc39f2 /]# 
[root@968e7ecc39f2 /]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0
[root@968e7ecc39f2 /]# 
[root@968e7ecc39f2 /]#

同一个宿主机的不同容器默认是可以相互通信的

root@docker101:~# ifconfig 
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:87ff:febc:3cd8  prefixlen 64  scopeid 0x20<link>
        ether 02:42:87:bc:3c:d8  txqueuelen 0  (Ethernet)
        RX packets 5364  bytes 225742 (225.7 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6098  bytes 28280444 (28.2 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.6.101  netmask 255.255.248.0  broadcast 192.168.7.255
        inet6 fe80::20c:29ff:fe57:8cb7  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:57:8c:b7  txqueuelen 1000  (Ethernet)
        RX packets 179980  bytes 248819555 (248.8 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 37062  bytes 4513196 (4.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 314  bytes 31398 (31.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 314  bytes 31398 (31.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth47b028a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::2ce5:b3ff:fe43:2cc4  prefixlen 64  scopeid 0x20<link>
        ether 2e:e5:b3:43:2c:c4  txqueuelen 0  (Ethernet)
        RX packets 7  bytes 574 (574.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 24  bytes 1832 (1.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vethed7471a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::9cef:51ff:fe7a:fd0c  prefixlen 64  scopeid 0x20<link>
        ether 9e:ef:51:7a:fd:0c  txqueuelen 0  (Ethernet)
        RX packets 3364  bytes 186375 (186.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3719  bytes 15400120 (15.4 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@docker101:~# 
root@docker101:~#

查看宿主机的网卡信息,如上图所示。

root@docker101:~# apt-get -y install bridge-utils                         #安装查看宿主机网桥的命令,安装后才能使用下面的"brctl"命令
root@docker101:~# 
root@docker101:~# brctl show
bridge name    bridge id        STP enabled    interfaces
docker0        8000.024287bc3cd8    no        veth47b028a
                            vethed7471a
root@docker101:~#

查看宿主机的桥接设备

root@docker101:~# iptables -t nat -vnL                        #查看宿主机的iptables规则。
Chain PREROUTING (policy ACCEPT 60 packets, 3937 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   52 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 9 packets, 676 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 68 packets, 5251 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 69 packets, 5335 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 3177 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
root@docker101:~# 
root@docker101:~# iptables  -vnL
Chain INPUT (policy ACCEPT 25019 packets, 126M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
11436   28M DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
11436   28M DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
 6080   28M ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    1    84 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
 5355  225K ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    1    84 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 21954 packets, 3062K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 5355  225K DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
11436   28M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
 5355  225K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
11436   28M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           
root@docker101:~# 
root@docker101:~#

查看宿主机的iptables规则,docker网络通信默认就是基于iptables规则实现的。docker的逻辑网络如下图所示。

6>.User Namespace

  各个容器内可能会出现重名的用户和用户组名称,或重复的用户UID或者GID,那么怎隔离各个容器内的用户空间呢?  
  User Namespace允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的用户UID和GID,只是会用户的作用范围限制在每个容器内,即A容器和B容器可以有相同的用户名称和ID的账户,但是此用户的有效范围仅是当前容器内,不能访问另外一个容器内的文件系统,即相互隔离,互不影响,永不相见 。

root@docker101:~# 
root@docker101:~# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin
jason:x:1000:1000:jason:/home/jason:/bin/bash
root@docker101:~# 
root@docker101:~# 
root@docker101:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
44edd3477c0d        nginx               "nginx -g 'daemon of…"   3 hours ago         Up 2 hours          80/tcp              stupefied_driscoll
968e7ecc39f2        centos              "/bin/bash"              6 hours ago         Up 6 hours                              keen_meitner
root@docker101:~# 
root@docker101:~# docker exec -it 968e7ecc39f2 bash
[root@968e7ecc39f2 /]# 
[root@968e7ecc39f2 /]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
[root@968e7ecc39f2 /]# 
[root@968e7ecc39f2 /]# exit 
exit
root@docker101:~# 
root@docker101:~# docker exec -it 44edd3477c0d bash
root@44edd3477c0d:/# 
root@44edd3477c0d:/# 
root@44edd3477c0d:/# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
nginx:x:101:101:nginx user,,,:/nonexistent:/bin/false
root@44edd3477c0d:/# 
root@44edd3477c0d:/#

每个容器内部都有超级管理员root及其它普通用户,且与其它容器ID相同,但并不会相互影响,因为每个容器内部的用户只作用于其所在的容器,如下图所示。

二.Linux control groups

1>.什么是Linux Cgroups

  一个容器如果不对其做任何资源限制,则宿主机会允许其占用无限大的内存空间,有时候会因为代码bug程序会一直申请内存,直到把宿主机内存占完。  

  为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,比如CPU,内存等,Linux Cgroups的全称是Linux Control Groups,它最主要的作用就是限制一个进程组能够使用的资源上限,包括CPU,内存,磁盘,网络带宽等等。  

  此外,Linux Cgroups还能够对进程优先级设置,以及将进程挂起和恢复等操作。

2>.验证系统Linux Cgroups**

[root@computing121.yinzhengjie.org.cn ~]# cat /etc/redhat-release 
CentOS Linux release 7.2.1511 (Core) 
[root@computing121.yinzhengjie.org.cn ~]# 
[root@computing121.yinzhengjie.org.cn ~]# uname -r
3.10.0-327.el7.x86_64
[root@computing121.yinzhengjie.org.cn ~]# 
[root@computing121.yinzhengjie.org.cn ~]# uname -m
x86_64
[root@computing121.yinzhengjie.org.cn ~]# 
[root@computing121.yinzhengjie.org.cn ~]# cat /boot/config-3.10.0-327.el7.x86_64 | grep -i cgroup
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NETPRIO_CGROUP=m
[root@computing121.yinzhengjie.org.cn ~]# 
[root@computing121.yinzhengjie.org.cn ~]# 
[root@computing121.yinzhengjie.org.cn ~]# cat /boot/config-3.10.0-327.el7.x86_64 | grep -i cgroup | wc -l
13
[root@computing121.yinzhengjie.org.cn ~]# 
[root@computing121.yinzhengjie.org.cn ~]#

CentOS7.2 Cgroups

root@docker101:~# hostname
docker101.yinzhengjie.org.cn
root@docker101:~# 
root@docker101:~# uname -r
4.15.0-74-generic
root@docker101:~# 
root@docker101:~# uname -m
x86_64
root@docker101:~# 
root@docker101:~# uname -a
Linux docker101.yinzhengjie.org.cn 4.15.0-74-generic #84-Ubuntu SMP Thu Dec 19 08:06:28 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
root@docker101:~# 
root@docker101:~# 
root@docker101:~# cat /boot/config-4.15.0-74-generic | grep -i cgroup
CONFIG_CGROUPS=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
root@docker101:~# 
root@docker101:~# 
root@docker101:~# cat /boot/config-4.15.0-74-generic | grep -i cgroup | wc -l
19
root@docker101:~#

Ubuntu18.04 Cgroups

  Cgroups在内核层默认已经开启,从Centos(如上图所示)和Ubuntu(如下图所示)对比结果来看,显然内核较新的ubuntu支持的功能更多。

3>.查看系统cgroups

root@docker101:~# ll /sys/fs/cgroup/
total 0
drwxr-xr-x 15 root root 380 Jan 12 05:41 ./
drwxr-xr-x 10 root root   0 Jan 12 05:41 ../
dr-xr-xr-x  5 root root   0 Jan 12 05:41 blkio/                      #块设备IO限制。
lrwxrwxrwx  1 root root  11 Jan 12 05:41 cpu -> cpu,cpuacct/              #使用调度程序为cgroup任务提供cpu的访问。
lrwxrwxrwx  1 root root  11 Jan 12 05:41 cpuacct -> cpu,cpuacct/            #产生cgroup任务的cpu资源报告。
dr-xr-xr-x  5 root root   0 Jan 12 05:41 cpu,cpuacct/
dr-xr-xr-x  3 root root   0 Jan 12 05:41 cpuset/                      #如果是多核心的cpu,这个子系统会为cgroup任务分配单独的cpu和内存。
dr-xr-xr-x  5 root root   0 Jan 12 05:41 devices/                     #允许或拒绝cgroup任务对设备的访问。
dr-xr-xr-x  3 root root   0 Jan 12 05:41 freezer/                     #暂停和恢复cgroup任务。
dr-xr-xr-x  3 root root   0 Jan 12 05:41 hugetlb/                  
dr-xr-xr-x  5 root root   0 Jan 12 05:41 memory/                      #设置每个cgroup的内存限制以及产生内存资源报告。
lrwxrwxrwx  1 root root  16 Jan 12 05:41 net_cls -> net_cls,net_prio/         #标记每个网络包以及提供cgroup方便是使用。
dr-xr-xr-x  3 root root   0 Jan 12 05:41 net_cls,net_prio/
lrwxrwxrwx  1 root root  16 Jan 12 05:41 net_prio -> net_cls,net_prio/
dr-xr-xr-x  3 root root   0 Jan 12 05:41 perf_event/                   #增加了对每个group的监测跟踪的能力,可以监测属于某个特定的group的所有线程以及运行在特定CPU上的线程。
dr-xr-xr-x  5 root root   0 Jan 12 05:41 pids/
dr-xr-xr-x  2 root root   0 Jan 12 05:41 rdma/
dr-xr-xr-x  6 root root   0 Jan 12 05:41 systemd/
dr-xr-xr-x  5 root root   0 Jan 12 05:41 unified/
root@docker101:~# 
root@docker101:~#
目录
相关文章
|
1月前
|
Unix 关系型数据库 MySQL
Linux 简介
Linux 简介
40 2
Linux 简介
|
5月前
|
缓存 Linux 程序员
老程序员分享:linux下netlink的使用简介
老程序员分享:linux下netlink的使用简介
|
1月前
|
大数据 Linux 开发工具
【Linux】命令简介------迅速掌握Linux命令
【Linux】命令简介------迅速掌握Linux命令
|
3月前
|
Unix Linux Shell
Linux I/O 重定向简介
Linux I/O 重定向简介
36 2
|
3月前
|
Unix Linux Shell
Linux 权限简介
Linux 权限简介
44 1
|
3月前
|
网络协议 Linux 应用服务中间件
Linux 中Namespace技术
【8月更文挑战第1天】Linux 内核里面实现了以下几种不同类型的 namespace。
|
3月前
|
Java Linux 编译器
【Linux】gcc简介+编译过程
【Linux】gcc简介+编译过程
|
3月前
|
存储 运维 监控
运维.Linux下执行定时任务(上:Cron简介与用法解析)
运维.Linux下执行定时任务(上:Cron简介与用法解析)
51 0
|
5月前
|
NoSQL Java Linux
linux 安装 neo4j简介
Neo4j是高性能NoSQL图形数据库,利用图结构存储数据。推荐使用JDK 11配合Neo4j 3.x版本。下载3.5.9版,通过`curl`命令在Linux上获取tar.gz文件,然后解压。配置`neo4j.conf`,调整内存设置,开启远程访问。执行`./bin/neo4j start`启动,通过`http://服务器IP:7474`访问,默认凭据是username: neo4j, password: neo4j,登录后应更改密码。
488 1
|
5月前
|
Linux Unix Ubuntu
01. 【Linux教程】Linux 简介
01. 【Linux教程】Linux 简介
41 3