上回说到,docker自带的网桥br0,在跨宿主机通讯时,默认充当了VXLAN的VTEP,因此,会造成较大的互通开销。
如果期望两个宿主机上在同一子网内的容器能够不通过VXLAN隧道互访,我们就需要利用linux自带的linux bridge了。
首先,我们创建网桥br0:
点击ubuntu桌面右上角的工具栏的网络图标,选择Edit Connections..
点击Add,选择Bridge类型:
将连接改名为br0,点击“Add”:
选择Ethernet,并在Ethernet选项卡的Device选择ens33并保存:
记得把STP关掉,避免麻烦:
在IPv4设置中,打开DHCP:
很快,我们看见,br0 获取到IP地址了!
行百里者半九十,我们才刚刚成功一半。
如图,br0这个虚拟交换机的上行口,已经被设定为ens33,它本身也获取到了172.16.1.0/24网段的IP地址。
而原来ens33网卡,不再拥有IP地址。
我们需要做的是,把各个容器绑定到这个虚拟交换机的接口上。这就需要让dockerd守护进程绑定br0作为bridge网络,而不是使用默认的docker0。
我们注意到,通过dockerd –help查看命令行选项,发现dockerd有一个 –bridge选项,可以修改默认桥接网络:
注意要打开Linux自带的IPv4转发选项:
#sysctl -w net.ipv4.ip_forward=1
并且在/etc/sysctl.conf中修改net.ipv4.ip_forward参数,改为1。
我们停止docker服务,并增加参数 –b br0启动docker服务:
运行容器ubuntu:
(由于原生ubuntu的容器镜像不含ip/ifconfig/ping等命令,我重新制作了一个含有网络常用工具的image)
可以看到,这个容器获取的是和宿主机网段一致的172.16.1.0/24的IP地址,但IP地址却从该子网的第一个IP地址开始分配。这是因为docker默认使用自带的DHCP服务。
我们可以给它手动指定一个IP:
让我们到容器里跑的ubuntu里面再去看看IP地址:
可见,容器ubuntu_101已经获取到了我们赋予的地址 172.16.1.143。
如图:
我们在其他主机上也如法将容器连接到br0网桥:
再从host A上的ubuntu容器,对host B和host B上的容器发起ping:
看,两个宿主机上的容器,通过Linux Bridge直接互通了!
我们再从同一子网外的计算机发起ping:
这样,在子网外也可以访问容器了!
果然是“一桥飞架南北,天堑变通途”!
进一步地,我们还可以通过反向代理或DNAT网关,让容器对互联网发布业务。
不过,大家也看到,在docker中,网络的设置是非常繁琐的,需要操作一系列容易出错的Linux命令。
好在,kubernetes的出现,弥补了docker很多方面的不足,在网络层面也给出了更多的选择——
敬请期待下期。