docker 网络
现在的linux内核支持6中名称空间:UTS、User、Mount、IPC、Pid、Net,只要有工具支持这6重名称空间是可以直接操作的。
网络名称空间主要用于协议栈网络设备的隔离,一个设备一般属于一个空间,一块网卡一个名称空间,这样每个名称空间都能配置IP地址与外部进行通讯,对于物理网卡是完全没有问题的。如果名称空间数量超过物理网卡的数量,每一个名称空间内的进程也需要通过网络进行通讯时用纯软件的方式来模拟物理设备的使用。linux内核支持两种设备的模拟,一种是二层设备一种是三成设备的模拟。二层及链路层,物理网卡就是二层设备,能封装物理报文的并在各个设备之间实现转发的设备。
这个功能完全可以利用linux内核对虚拟谁被的支持来创建虚拟网卡接口。这个虚拟网卡设备很独特必须成对出现,模拟一根网线的两头,一头插在主机之上,一头插在交换机之上,就相当于主机连接到了交换机之上了。使用brctl 可以实现。如果有两个名称空间一头留在虚拟名称空间上,一头连接到同一个交换机上,如果两个名称空间的地址配置在同一个网段上这两个名称空间就可以通信了。
在同一个物理机上的两个容器或两个名称空间之间要通信只要在这个主机上建一个虚拟交换机,再建立一对网卡连接到交换机即可。如果有多对这样的容器和交换机可以使用iptables 或打开核心转发作为路由器使用。
路由器是一个三层设备,需要一个单独的名称空间,也就是说需要一个单独的容器来实现。
桥接方式:
如果两台物理机上的容器要通信使用桥接的方式进行通讯,实现的方法是把物理网卡当交换机使用,发送的消息先到达物理网卡并转发,根据目标MAC 来判断是交给那个名称空间的,个名称空间都有一个MAC地址,由于本机的物理网卡被作为交换机所以需要一个虚拟网卡来作为物理机的网卡。各个名称空间连接到物理交换机上。但是这种方法容易产生网络风暴。一般不使用。
NAT方式:
NAT方式效率比较低,也不使用。
Overlay Network 叠加网络:
通过隧道叠加了另一层网络,IP首部再封装一个IP首部。名称空间将消息发送给网桥,网桥将IP报文再封装一个IP首部发送给物理机1,再发送到物理机2,拆报文最终到达 namespace2。
docker网络:
docker默认提供了三种网络docker network ls,bridge,host,none,docker自动创建了一个虚拟交换机叫docker0,可以作为网卡使用也可以作为交换机使用。
启动每一对个容器就会自动创建一对网卡设备,一个在容器内,一个在docker0 桥上。
veth47c0b56: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::6c:acff:fec0:f084 prefixlen 64 scopeid 0x20<link> ether 02:6c:ac:c0:f0:84 txqueuelen 0 (Ethernet) RX packets 67 bytes 190734 (186.2 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 79 bytes 25107 (24.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
使用ifconfig 命令即可看到 vethxxx 开头的网卡设备,并且这些设备被插到docker0 上,这就是一对网卡中的一个,另一半在容器中。使用命令brctl show 可以看到docker0上关联的接口,这个虚拟桥也可以自己创建。如下所示 br-8408f33f5585 为手动创建的虚拟桥,并关联了两个虚拟网卡。
r]# brctl show bridge name bridge id STP enabled interfaces br-8408f33f5585 8000.0242c0a228c1 no veth47c0b56 veth9689b12 docker0 8000.02423ef8d980 no veth5c90ac3 vethdc32b49
桥接式网络:
容器通过桥接通信。创建一个虚拟桥,通过虚拟桥来进行通信。
联盟式网络:
让两个容器有一部分名称空间是隔离的,但使用同一组网络名称空间。
开放式网络:
多个容器共享宿主机的名称空间。
指定创建的网络:
创建docker 时可以选择使用的网络类型,不指定使用的是默认桥接
docker run --network bridge --name nginx -d nginx:latest
查看桥接网络:
docker network inspect bridge