我的试验环境说明:centos8.4 + Docker version 20.10.7, build f0df350
参考:
https://www.cnblogs.com/kevingrace/p/6590319.html
https://www.cnblogs.com/bakari/p/9036984.html
Docker单主机容器通信
基于对net namespace的控制,docker可以为在容器创建隔离的网络环境,在隔离的网络环境下,容器具有完全独立的网络栈,与宿主机隔离,也可以使容器共享主机或者其他容器的网络命名空间,基本可以满足开发者在各种场景下的需要。
按docker官方的说法,docker容器的网络有五种模式:
bridge模式,–net=bridge(默认) 这是dokcer网络的默认设置,为容器创建独立的网络命名空间,容器具有独立的网卡等所有单独的网络栈,是最常用的使用方式。在docker run启动容器的时候,如果不加–net参数,就默认采用这种网络模式。安装完docker,系统会自动添加一个供docker使用的网桥docker0,我们创建一个新的容器时,容器通过DHCP获取一个与docker0同网段的IP地址,并默认连接到docker0网桥,以此实现容器与宿主机的网络互通。
host模式,–net=host 这个模式下创建出来的容器,直接使用容器宿主机的网络命名空间。将不拥有自己独立的Network Namespace,即没有独立的网络环境。它使用宿主机的ip和端口。这种模式主要适用于管理员希望以docker方式管理服务器。(实际使用不多)
none模式,–net=none 为容器创建独立网络命名空间,但不为它做任何网络配置,容器中只有lo,用户可以在此基础上,对容器网络做任意定制。这个模式下,dokcer不为容器进行任何网络配置。需要我们自己为容器添加网卡,配置IP。因此,若想使用pipework配置docker容器的ip地址,必须要在none模式下才可以。
其他容器模式(即container模式,join模式),–net=container:NAME_or_ID 与host模式类似,只是容器将与指定的容器共享网络命名空间。这个模式就是指定一个已有的容器,共享该容器的IP和端口。除了网络方面两个容器共享,其他的如文件系统,进程等还是隔离开的。
用户自定义:docker 1.9版本以后新增的特性,允许容器使用第三方的网络实现或者创建单独的bridge网络,提供网络隔离能力。
参考:https://www.coonote.com/docker-note/docker-network-mode.html
最后发现默认的docker0这种bridge和用户自己创建的bridge的网络方案最实用。那么这两种方式有啥区别呢?
Link方式实现本机容器间互联通信
容器互联大体有以下三种方式:
-
基于volume的互联
-
基于link的互联
-
基于网络的互联
一些常用命令:
docker network ls docker network create -d bridge demo-net # 新建虚拟网络 # 用下面的命令创建docker网桥 docker network create br0 -d bridge -o com.docker.network.bridge.name='br0' \ --subnet=172.10.200.0/24 --ip-range=172.10.200.0/24 --gateway=172.10.200.1 # 运行容器 docker run -itd --name centostst --network br0 bmc/opensuse15.2:dev /bin/bash # 第二个例子 docker run -itd --name suse11 --network demo-net opensuse /bin/bash docker run -itd --name suse22 --network demo-net opensuse /bin/bash # 分别进入容器,户型能够ping通 docker exec -it suse11 /bin/bash docker exec -it suse22 /bin/bash # vi /etc/docker/daemon.json 设置所有容器的DNS # 这样容器就可以共享这里的DNS配置,解析域名了。 "dns": [ "223.5.5.5", "8.8.8.8" ] # 单独指定容器DNS docker run -it --rm --dns=223.5.5.5 --dns-search=test.com bmc/opensuse15.2:dev
Docker默认的网桥是docker0。此网桥只会在本机连接所有容器。下面我们借助两台服务器上的docker0网桥来互相通信。
vi /etc/docker/daemon.json { "bip":"172.16.200.1/24" } { "bip":"172.16.201.1/24" }
之后你会发现现在两台机器上的两个容器IP是不会互通的。但是他们能够Ping通主机的内网IP,下面在宿主机上面添加到达对方的路由:
# docker1 route add -net 172.16.201.0/24 gw 10.10.200.172 route del -net 172.16.201.0/24 gw 10.10.200.172 # docker2 route add -net 172.16.200.0/24 gw 10.10.200.142 # 添加权限 --privileged
杯具,最后发现还是不通,看看是哪里出问题了? (这种方式并不是太好,还是用下面的方式吧 O(∩_∩)O哈哈~)
桥接到Docker宿主机实现跨主机Docker容器通信
如果希望Docker跨主机访问,最简单的方式就是将不同主机的docker0 设置为同一网段。
整体网络拓扑结构就是这样(网上借用的示意图,参考即可):
在两台宿主机,安装网桥查询工具
zypper in bridge-utils brctl show PC-A: eth1:10.10.200.142 PC-B: eth1:10.10.200.172
PC-A执行:
# 第一步 vi /etc/docker/daemon.json "bip": "10.10.200.142/24", "fixed-cidr": "10.10.200.16/28" "default-gateway": "192.168.61.1" # 不需要这行 # 第二步 ifconfig eth1 0.0.0.0 # 将物理网卡IP值空 brctl addif docker0 eth1 # 将docker0 桥接到 eth1 上 brctl show systemctl restart docker.service ifconfig # 查看网卡 docker0 Link encap:Ethernet HWaddr 02:42:6A:9E:15:CA inet addr:10.10.200.142 Bcast:10.10.200.255 Mask:255.255.255.0 # 第三步 docker start susexx # 启动容器,查看IP,ping主机试一试
PC-B执行:
# 第一步 vi /etc/docker/daemon.json "bip": "10.10.200.172/24", "fixed-cidr": "10.10.200.32/28" # 第二步 ifconfig eth1 0.0.0.0 # 将物理网卡IP置空 brctl addif docker0 eth1 # 将docker0 桥接到 eth1 上 brctl show systemctl restart docker.service ifconfig # 查看网卡 docker0 Link encap:Ethernet HWaddr 02:42:6A:9E:15:CA inet addr:10.10.200.172 Bcast:10.10.200.255 Mask:255.255.255.0 # 第三步 docker start susexx # 启动容器,查看IP,ping主机试一试
参考:
https://developer.51cto.com/art/202002/609994.htm
https://www.pianshen.com/article/5546389320/
主机重启自动启动br0的绑定
在上面的配置中,如果主机重启,有可能网桥br0上配置的IP地址无法正常访问,这是因为网桥没有和实体网卡绑定。怎么办?
CentOS系统
这个时候在/etc/rc.local
中配置brctl addif br0 eno1
可能报错,重启不生效。给网卡做如下配置:
# brctl addif br0 eno1 # /etc/sysconfig/network-scripts/ifcfg-br0 PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no UUID=f2e0b49a-d9fe-4472-85e4-30ccdfbb254e TYPE=Bridge NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=192.168.xx.xx PREFIX=16 # /etc/sysconfig/network-scripts/ifcfg-eno1 TYPE=Ethernet BOOTPROTO=none ONBOOT=yes DEVICE=eno1 BRIDGE=br0
suse用上面的方法可能不行了,这个时候把绑定命令写入after.local
文件中有效。
# cat /etc/init.d/after.local #!/bin/bash brctl addif br0 em1 brctl addif br1 em2 # systemctl status after-local.service # 启动服务的配置可以参考其它文章。
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏