Docker 网络初识之bridge模式

none模式的好处是可以静态配置IP地址,也就是我们可以自己手工去配置IP,不用DHCP去分配,none模式有自己的网络模块,默认是没有指定IP地址需要人工去指定,bridge模式用的是最多的模式,该模式下会为每个容器分配其IP地址

eth0是宿主机的IP地址10.10.101.105,docker0相当于二层的交换机,docker1或者docker2叫做容器(虚拟机),多个容器的网络连接到交换机上(docker0相当于二层的交换机),从而能够实现容器和容器之间是可以访问的,因为在二层网络里面,docker0能够自动学习局域网的mac地址,并将请求转发到对应的网口。交换机是在一个网段当中,二层交换机只有一个网络

 默认的网段是172.17.0.1网段

[root@www my_wordpress]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:b4ff:fe35:f546  prefixlen 64  scopeid 0x20<link>
        ether 02:42:b4:35:f5:46  txqueuelen 0  (Ethernet)
        RX packets 27705  bytes 27905546 (26.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 38270  bytes 339811508 (324.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

#docker0是一张网卡也是一个交换机,docker0是什么网段,那么容器dhcp分配到的iP就是什么网段
ip加掩码来判断是否在一个网络内部 判断交换机和容器

#在同一个网段只能docker之间的通信不需要路由(网关),docker1容器和docker2容器通信只在交换机里面通信,不需要路由,可以找到对方的mac(通过ARP广播找到对方ip),容器和宿主机通信就需要走路由

启动docker引擎就会在宿主机上面添加docker0,docker0即使网卡也是网桥,所以有两重身份。创建容器会创建一对虚拟网卡设备叫veth pair

 

(1)首先宿主机上创建一对虚拟网卡veth pair设备,veth设备总是成对出现的,组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来,veth设备常用来连接两个网络设备。一对虚拟网卡veth pair设备

[root@localhost ~]# docker run -itd centos7-ssh 
47e140d183836ab7293c35e1c7ed0b67339c45f03b34a82aa3057607e547f97e
[root@localhost ~]# ifconfig
vethaa94037: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::bce0:bdff:fe06:4d24  prefixlen 64  scopeid 0x20<link>
        ether be:e0:bd:06:4d:24  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 578 (578.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

你会发现启动一个容器就多了一个网卡,这个网卡是放在宿主机上面,eth0是放在容器里面。

 

(2)Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0,然后将另一端放在宿主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。

创建一个容器,创建容器的时候会创建两个网卡,一个网卡放在容器里面,命名为eth0,一个放在宿主机命名为veth。veth是一种技术相当于网线的两端,那么宿主机上的docker0就可以和容器里面的eth0进行通信了,veth在宿主机,eth0在容器当中

创建多个容器就会产生多个veth网卡,创建10个容器就会多出10个veth*网卡,要将veth看作类似和网口一样的,相当于dcoker0交换机的一个网口

[root@www my_wordpress]#  yum install bridge* -y
[root@www my_wordpress]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-aa9c38324b49		8000.0242b444614d	no		veth200ffc6
							veth8575b7b
docker0		8000.0242b435f546	no		
[root@www my_wordpress]# ifconfig | grep veth
veth200ffc6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
veth8575b7b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

#可以看到网桥交换机有2个网卡,因为我启动了2个容器,brctl可以帮助你看到哪些设备是连接到交换机上面的
[root@www my_wordpress]# docker ps | grep -i up | wc -l
2

这个主要是实现容器和宿主机的通信的,将veth加入网桥交换机docker0,主要是容器就可以在一个网段里面了,就在一个二层交换机上面了,在二层交换机上面容器就可以互相访问了。

 

(3)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。

 

(4)此时容器IP与宿主机能够通信,宿主机也可以访问容器中的IP地址,在Bridge模式下,连在同一网桥上的容器之间可以相互通信,同时容器也可以访问外网,但是其他物理机不能访问docker容器IP,需要通过NAT将容器IP的port映射为宿主机的IP和port。

[root@localhost ~]# docker run -itd centos7-ssh
3e1dbc9ea196401b36842812cb3dfb9ddd351fe986c680a9c097a58912191093
[root@localhost ~]# ifconfig
vethc42c5bc: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::9c6d:b1ff:feeb:1984  prefixlen 64  scopeid 0x20<link>
        ether 9e:6d:b1:eb:19:84  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 578 (578.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

#可以看到vethc42c5bc网卡 9e:6d:b1:eb:19:84和 eth0网卡02:42:ac:11:00:02  MAC地址是不一样的
[root@localhost ~]# docker exec -it 3e1dbc9ea196 /bin/bash
[root@3e1dbc9ea196 ansible]# 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 8  bytes 648 (648.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


#docker0的ip地址为容器的网关
[root@f49833e1e876 ansible]# 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

容器可以访问外网,但是其他的物理机不能访问docker容器的IP的,如果外面物理机想要访问容器想要run -itd -p端口号  这相当于做了地址转换DNAT。

外网是不能之间访问容器IP的,因为容器IP是内网IP,只有宿主机是相通的,veth是不需要IP的,可以将其看作接口,看作交换机上面的接口,数据可以从一端进来,可以从一端出去。

为什么要将容器的网关设置为docker0的IP地址呢,这样做的目的是容器要上网,先将数据发送给docker0网卡,通过它去上网,docker0网卡虽然和外网不通,但是和ens33网卡是相通的,通过转发ens33来上网。

容器的网关地址为docker0的IP地址主要是为了将数据发个docker0,容器不能之间将数据发给物理网卡,因为容器在一个网段,宿主机又在另外一个网段,压根不通,docker0通过ens33将数据转发出去的

docker0相对于宿主机来说是另外一块网卡,ens33相对于连接着网线,但是docker0没有连接网线,只要ens33能够上网,其他网卡就可以通过ens33将数据转发出去,docker0是通过docker引擎创建的,不上外网不需要经过ens33转发。

外网要访问容器要在宿主机做DNAT映射 端口映射-p选项,如果不做端口映射外网是访问不了容器的。

 

[root@localhost ~]# 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:55ff:feda:5064  prefixlen 64  scopeid 0x20<link>
        ether 02:42:55:da:50:64  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5  bytes 438 (438.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.179.2   0.0.0.0         UG    100    0        0 ens33


[root@localhost ~]# docker exec -it b358705e0274 /bin/bash
[root@b358705e0274 ansible]# yum install traceroute -y
[root@b358705e0274 ansible]# 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

[root@b358705e0274 ansible]# traceroute www.baidu.com
traceroute to www.baidu.com (180.101.49.11), 30 hops max, 60 byte packets
 1  gateway (172.17.0.1)  0.032 ms  0.012 ms  0.012 ms
 2  192.168.179.2 (192.168.179.2)  0.169 ms  0.073 ms  0.088 ms
#可以看到是先发给docker0网卡,然后通过ens33上网

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/107943622