Docker—基础之Linux Namespace(Docker – Basic Linux namespace)

Docker

网络名称空间概念:为了支持网络协议栈的多个实例,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,然后转发容器通信。

Docker通过namespace及cgroup等来提供容器的资源隔离与安全保障等,下面来看是怎么实现的。

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

Concept of network namespace: in order to support multiple instances of network protocol stack, Linux isolates independent protocol stacks into different network namespaces through network namespace. Network stacks in different network namespaces are completely isolated and cannot communicate with each other. Through the isolation of network resources, multiple different network environments can be virtualized on a host.

Docker makes use of the characteristics of network namespace to realize the network isolation between different containers. All kinds of network stacks in docker container are automatically created and configured by docker daemon at startup.

Vet equipment:

Because the network namespace represents an independent protocol stack, they are completely isolated and cannot communicate with each other.

Veth device pair, note: here is the device pair, that is, it appears in pairs; One of its functions is to break through the barriers between invisible protocol stacks. It is like a pipe connecting two different network namespaces to realize communication.

In the docker container, Veth is an important bridge connecting the container and the host,

Bridge:

Similar to the principle of layer-2 switch, it uses MAC address addressing. If it exists in the MAC table, it will be forwarded, and vice versa.

The Linux kernel bridges through several network bridging devices. This virtual device can bind several Ethernet interface devices to bridge them. This bridge is different from other devices. The most obvious feature is that it can have an IP address.

Docker network type:

 – host

– container mode (container shared network namespace)

 – none

 – bridge

In bridge mode, docker startup will create a virtual bridge docker0, and then assign a subnet to docker0. For each container created by docker0, a virtual Ethernet device (Veth device pair) will be created. One end is associated with docker0 and the other end is associated with eth0 inside the container. Then, an address of the container will be assigned in the network segment where docker0 is located.

In the same host, different containers can bridge direct communication through docker0. Different hosts need to map the host port. The host network card forwards docker0, and then forwards container communication.

Docker provides container resource isolation and security through namespace and CGroup. Let’s see how to implement it.

When docker is started, it will run as a daemon in 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

Viewing the daemon relationship through 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)