1.默认的传统网桥通信方式
docker的通信使用的是传统的linux网桥,他会在主机上虚机出来一个名为docker0的接口,执行docker0:
2.docker0网桥连接方式
网络配置过程如下:
a. 在宿主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
b. 在容器启动时,Docker引擎将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在宿主机中,以veth***这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
c. docker启动一个容器时会根据docker0的网段划分容器的IP,docker0是每个container的网关,容器的ip都将会是172.17网段。
3.自定义虚拟网桥
// 新增网桥br0
# brctl addbr br0
# ifconfig br0 172.17.0.0/24 up
// 修改docker启动配置文件(centos下,docker启动配置文件路径是/etc/sysconfig/docker),添加DOCKER_OPTS值,使docker启用新添加的网桥br0
# vim /etc/sysconfig/docker
DOCKER_OPTS="-b=br0"
// 修改docker守护进程配置文件,添加EnvironmentFile绝对路径与启动项$DOCKER_OPTS,其中“ - ”代表ignore error
# vim /usr/lib/systemd/system/docker.service
EnvironmentFile=-/etc/sysconfig/docker
ExecStart=/usr/bin/dockerd $DOCKER_OPTS
// 重启所有守护进程。重新装载所有守护进程的unit文件,然后重新生成依赖关系树
# systemctl daemon-reload
# service docker restart
// 查看容器IP,验证其更改为br0网段
# docker run -it --name test2 centos /bin/bash
cID# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 1188 bytes 7830677 (7.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1073 bytes 73229 (71.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
4.使用ovs网桥(通过ovs-docker命令配置)
1)创建ovs网桥,并设置ip为192.168.1.250/24,并在后续容器网络中作为其默认网关
[root@vm1 ~]# ovs-vsctl add-br br0
[root@vm1 ~]# ovs-vsctl show
Bridge br0
Port br0
Interface br0
type: internal
[root@vm1 ~]# ifconfig br0 192.168.1.250/24
[root@vm1 ~]# ifconfig br0
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.250 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::c0b6:92ff:fe4d:7649 prefixlen 64 scopeid 0x20<link>
ether c2:b6:92:4d:76:49 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 8 overruns 0 frame 0
TX packets 6 bytes 508 (508.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2)启动无网络docker
[root@vm1 ~]# docker run -d --name con1 --net=none busybox top
[root@vm1 ~]# docker exec -it con1 ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
3)此时利用ovs-docker 设置此容器ip地址为192.168.1.2/24,需要保证与ovs网桥同一个网段,并且设置ovs网桥地址为容器默认网关为192.168.1.250
[root@vm1 ~]# ovs-docker add-port br0 eth0 con1 --ipaddress=192.168.1.2/24 --gateway=192.168.1.250
[root@vm1 ~]# docker exec -it con1 ifconfig
e
eth0 Link encap:Ethernet HWaddr 56:39:36:6A:B0:61
inet addr:192.168.1.2 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:7 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:578 (578.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
[root@vm1 ~]# docker exec -it con1 route -n
K
Kernel IP routing table
D
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.250 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
[root@vm1 ~]# ovs-vsctl show
c152c245-2f6c-478c-9c07-2e4a3c7a2403
Bridge br0
Port veth0
Interface veth0
Port 7506959a37594_l
Interface 7506959a37594_l
Port br0
Interface br0
type: internal
5.ovs-docker的原理(其实容器的网络就相当于一个ns)
1)同上步骤1)创建ovs网桥br0
2)创建一个network namespace ns1
[root@vm1 ~]# ip netns add ns1
创建一对veth pair (veth0 和 veth1)
[root@vm1 ~]# ip link add veth0 type veth peer name veth1
// 将veth0加入到br0中
[root@vm1 ~]# ip link set veth0 up
[root@vm1 ~]# ovs-vsctl add-port br0 veth0
[root@vm1 ~]# ovs-vsctl show
c152c245-2f6c-478c-9c07-2e4a3c7a2403
Bridge "br0"
Port "veth0"
Interface "veth0"
Port "br0"
Interface "br0"
type: internal
ovs_version: "2.5.1"
[root@vm1 ~]#
// 将veth1加入到ns1中
[root@vm1 ~]# ip link set veth1 netns ns1
// 设置veth1 ip 与br0是同一个网络
[root@vm1 ~]# ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth1
[root@vm1 ~]# ip netns exec ns1 ip link set veth1 up
[root@vm1 ~]# ip netns exec ns1 ip link set lo up
// 在ns1中ping br0成功
[root@vm1 ~]# ip netns exec ns1 ping -c 1 192.168.1.250
PING 192.168.1.250 (192.168.1.250) 56(84) bytes of data.
64 bytes from 192.168.1.250: icmp_seq=1 ttl=64 time=0.392 ms
--- 192.168.1.250 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
r
rtt min/avg/max/mdev = 0.392/0.392/0.392/0.000 ms
3)给ns1增加路由
[root@vm1 ~]# ip netns exec ns1 route add default gw 192.168.1.250
[
[root@vm1 ~]# ip netns exec ns1 ping -c 1 172.19.0.12
P
PING 172.19.0.12 (172.19.0.12) 56(84) bytes of data.
64 bytes from 172.19.0.12: icmp_seq=1 ttl=64 time=0.224 ms
--- 172.19.0.12 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.224/0.224/0.224/0.000 ms