Docker—基础之Linux Namespace

Docker

Docker通过namespace及cgroup等来提供容器的资源隔离与安全保障等

网络名称空间概念:为了支持网络协议栈的多个实例,linux在网络栈通过网络名称空间将独立的协议栈隔离到不同的网络名称空间。处于不同网络名称空间的网络栈是完全隔离的,彼此之间无法通信。通过对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环境。

Docker正是利用网络名称空间特性,实现不同容器之间的网络隔离。Docker容器中各类网络栈都是Docker Daemon在启动时自动创建和配置的。

Veth设备:

由于网络名称空间代表一个独立的协议栈,所以他们是完全隔离的,彼此无法通信。

Veth设备对,注意:这里说的是设备对,即是成对出现的;其中一个作用就是打通了相互看不到的协议栈之间的壁垒,它像一条管子,将两个不同的网络名称空间连接起来实现通信。

在docker容器中,veth是连接容器与宿主机通信的重要桥梁,

网桥:

类似于二层交换机原理,利用MAC地址寻址,如果在MAC表存在,则转发,反之广播。

linux内核通过若干个网络桥接设备实现桥接,这个虚拟设备可以绑定若干个以太网接口设备,从而将它们桥接起来,这个网桥与其他的设备不同,最明显特性是它可以有一个IP地址。

Docker网络类型:

 - host

 - container模式(容器共享网络名称空间)  

 - none

 - bridge

在bridge模式下,Docker启动会创建一个虚拟网桥Docker0,然后给Docker0分配一个子网。由Docker0创建的每一个容器,都会创建一个虚拟以太网设备(Veth设备对),一端关联Docker0,一端关联容器内部eth0,然后在Docker0所在的网段分配容器一个地址。

在同一台主机,不同容器之间通过即可Docker0桥接直接通信,不同主机需要映射宿主机端口,由宿主机网卡转发Docker0,然后转发容器通信。

 

查看宿主机网卡

[root@web ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:33ff:fe81:19b5  prefixlen 64  scopeid 0x20<link>
        ether 02:42:33:81:19:b5  txqueuelen 0  (Ethernet)
        RX packets 4408  bytes 255165 (249.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5186  bytes 9931732 (9.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.4.8  netmask 255.255.252.0  broadcast 10.0.7.255
        inet6 fe80::5054:ff:fe56:8b72  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:56:8b:72  txqueuelen 1000  (Ethernet)
        RX packets 7987346  bytes 1205279160 (1.1 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7137417  bytes 1120316658 (1.0 GiB)
        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 1  (Local Loopback)
        RX packets 776  bytes 99408 (97.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 776  bytes 99408 (97.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth99d1f16: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500                  # 连接不同namespace网络
        inet6 fe80::5cd1:2aff:fef9:65d5  prefixlen 64  scopeid 0x20<link>
        ether 5e:d1:2a:f9:65:d5  txqueuelen 0  (Ethernet)
        RX packets 4392  bytes 315581 (308.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5184  bytes 9931552 (9.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 当再启动一个容器,再次查看,可以看到又启动了一个veth设置

vethb50dc70: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::98cb:6cff:fe1b:b147  prefixlen 64  scopeid 0x20<link>
        ether 9a:cb:6c:1b:b1:47  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 648 (648.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

进入容器查看,eth0 就是veth设备,他被命名为eth0,而且分配了IP地址。

[root@ad0c18fcb99c /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:3  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 14314  bytes 44963854 (42.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8786  bytes 588018 (574.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

查看容器网关

]# 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     # 指向docker0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

 

docker启动会在linux以守护进程运行

]# ps -ef | grep docker
root       1128      1  3 May11 ?        02:33:12 /usr/bin/dockerd
root       1262   1128  0 May11 ?        00:37:17 containerd --config /var/run/docker/containerd/containerd.toml --log-level warn
root       2494   1262  0 May11 ?        00:00:20 containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/34e4b348f161a741dbfe734561d5218addb793c74696b7bd10d517a5b6741751 -address /var/run/docker/containerd/containerd.sock -containerd-binary /usr/local/bin/containerd -runtime-root /var/run/docker/runtime-runc

 通过pstree查看进程守护关系

├─dockerd(1128)─┬─containerd(1262)─┬─containerd-shim(2494)─┬─pause(2557)
           │               │                  │                       ├─{containerd-shim}(2517)
           │               │                  │                       ├─{containerd-shim}(2518)
           │               │                  │                       ├─{containerd-shim}(2519)
           │               │                  │                       ├─{containerd-shim}(2520)
           │               │                  │                       ├─{containerd-shim}(2521)
           │               │                  │                       ├─{containerd-shim}(2523)
           │               │                  │                       ├─{containerd-shim}(2524)
           │               │                  │                       └─{containerd-shim}(3789)

查看docker是如何管理容器的

启动容器

docker run -d docker.io/nginx
4892163d8ab1f27f3b5e13fd78c2307e8ceacfb0d6fd464214cb827c76de4d51

pstree查看进程关系

├─dockerd-current(18899)─┬─docker-containe(18908)─┬─docker-containe(16228)─┬─nginx(16247)─┬─nginx(16304)
           │                        │                        │                        │              ├─nginx(16305)
           │                        │                        │                        │              ├─nginx(16306)
           │                        │                        │                        │              └─nginx(16307)

查看进程关系详情

]# ps -ef | grep 18899  # docker进程
root     16383 14276  0 10:48 pts/3    00:00:00 grep --color=auto 18899
root     18899     1  0 May14 ?        00:01:15 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt nativxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json --selinux-enabled --log-driver=journald -ge-driver overlay2
root     18908 18899  0 May14 ?        00:00:37 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2minerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true

[root@web ~]# ps -ef | grep 18908      # 查看dontainerd进程
root     16228 18908  0 10:48 ?        00:00:00 /usr/bin/docker-containerd-shim-current 4892163d8ab1f27f3b5e13fd78c2307e8ceacfb0d6fd464214cb827c76de4d51 /var/run/docker/libcontainerd/480d6fd464214cb827c76de4d51 /usr/libexec/docker/docker-runc-current
root     16412 14276  0 10:49 pts/3    00:00:00 grep --color=auto 18908
root     18908 18899  0 May14 ?        00:00:37 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2minerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true

[root@web ~]# ps -ef | grep 16228      # 可以看到由containerd启动了一个nginx的master进程
root     16228 18908  0 10:48 ?        00:00:00 /usr/bin/docker-containerd-shim-current 4892163d8ab1f27f3b5e13fd78c2307e8ceacfb0d6fd464214cb827c76de4d51 /var/run/docker/libcontainerd/480d6fd464214cb827c76de4d51 /usr/libexec/docker/docker-runc-current
root     16247 16228  0 10:48 ?        00:00:00 nginx: master process nginx -g daemon off;
root     16434 14276  0 10:49 pts/3    00:00:00 grep --color=auto 16228

[root@web ~]# ps -ef | grep 16247      # master启动了4个worker进程
root     16247 16228  0 10:48 ?        00:00:00 nginx: master process nginx -g daemon off;
101      16304 16247  0 10:48 ?        00:00:00 nginx: worker process
101      16305 16247  0 10:48 ?        00:00:00 nginx: worker process
101      16306 16247  0 10:48 ?        00:00:00 nginx: worker process
101      16307 16247  0 10:48 ?        00:00:00 nginx: worker process
root     16465 14276  0 10:49 pts/3    00:00:00 grep --color=auto 16247

进入容器查看

root@4892163d8ab1:/# apt-get update
root@4892163d8ab1:/# apt-get install procps  # 安装ps命令

root@4892163d8ab1:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 02:48 ?        00:00:00 nginx: master process nginx -g daemon off;   # PID为1的进程为nginx主进程
nginx       32     1  0 02:48 ?        00:00:00 nginx: worker process
nginx       33     1  0 02:48 ?        00:00:00 nginx: worker process
nginx       34     1  0 02:48 ?        00:00:00 nginx: worker process
nginx       35     1  0 02:48 ?        00:00:00 nginx: worker process
root        36     0  0 02:58 ?        00:00:00 bash
root       405    36  0 03:08 ?        00:00:00 ps -ef

通过以上结果,由containerd启动了一个nginx的master进程,作为容器进程为1的主进程。

  

posted @ 2022-05-14 20:24  不会跳舞的胖子  阅读(165)  评论(0编辑  收藏  举报