跨主机容器通信 ############## * https://www.cnblogs.com/kevingrace/p/6590319.html .. note:: host 网络驱动程序仅适用于 Linux 主机,在 Docker Desktop for Mac、Docker Desktop for Windows 或 Docker EE for Windows Server 上不受支持。 早期的跨主机通信方案 ==================== 1. 容器使用host模式:: 容器直接使用宿主机的网络,这样天生就可以支持跨主机通信。 虽然可以解决跨主机通信问题,但这种方式应用场景很有限,容易出现端口冲突,也无法做到隔离网络环境 一个容器崩溃很可能引起整个宿主机的崩溃 2. 端口绑定:: 通过绑定容器端口到宿主机端口 跨主机通信时,使用主机IP+端口的方式访问容器中的服务 显而易见,这种方式仅能支持网络栈的四层及以上的应用 并且容器与宿主机紧耦合很难灵活的处理,可扩展性不佳 3. docker外定制容器网络:: 在容器通过docker创建完成后,然后再通过修改容器的网络命名空间来定义容器网络 典型的就是很久以前的pipework,容器以none模式创建, pipework通过进入容器的网络命名空间为容器重新配置网络 这样容器网络可以是静态IP、vxlan网络等各种方式,非常灵活 容器启动的一段时间内会没有IP,明显无法在大规模场景下使用,只能在实验室中测试使用 4. 第三方SDN定义容器网络:: 使用Open vSwitch或Flannel等第三方SDN工具,为容器构建可以跨主机通信的网络环境。 这些方案要求各个主机上的docker0网桥的cidr不同 以避免出现IP冲突的问题限制了容器在宿主机上的可获取IP范围 并且在容器需要对集群外提供服务时,需要比较复杂的配置,对部署实施人员的网络技能要求比较高 .. note:: 上面这些方案有各种各样的缺陷,同时也因为跨主机通信的迫切需求,docker 1.9版本时,官方提出了基于vxlan的overlay网络实现,原生支持容器的跨主机通信。同时,还支持通过libnetwork的plugin机制扩展各种第三方实现,从而以不同的方式实现跨主机通信。 流行的方案 ========== 1. 基于隧道的overlay网络:: 按隧道类型来说,不同的公司或者组织有不同的实现方案。 a. docker原生的overlay网络就是基于vxlan隧道实现的。 b. ovn则需要通过geneve或者stt隧道来实现的。 c. flannel最新版本也开始默认基于vxlan实现overlay网络。 2. 基于包封装的overlay网络:: 基于UDP封装等数据包包装方式,在docker集群上实现跨主机网络。 典型实现方案有Weave、Flannel的早期版本。 3. 基于三层实现SDN网络:: 基于三层协议和路由,直接在三层上实现跨主机网络,并且通过iptables实现网络的安全隔离。 典型的方案为 Calico。 同时对不支持三层路由的环境,Calico还提供了基于IP封装的跨主机网络实现 操作命令 ======== Docker通过使用Linux桥接提供容器之间的通信,docker0桥接接口的目的就是方便Docker管理。当Docker daemon启动时需要做以下操作:: -> 如果docker0不存在则创建 -> 搜索一个与当前路由不冲突的ip段 -> 在确定的范围中选择 ip -> 绑定ip到 docker0 列出当前主机网桥:: [root@localhost ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.02426f15541e no vethe833b02 查看当前 docker0 ip:: [root@localhost ~]# ifconfig docker0: flags=4163 mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0 inet6 fe80::42:6fff:fe15:541e prefixlen 64 scopeid 0x20 ether 02:42:6f:15:54:1e txqueuelen 0 (Ethernet) RX packets 120315 bytes 828868638 (790.4 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 132565 bytes 100884398 (96.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ................ 在容器运行时,每个容器都会分配一个特定的虚拟机口并桥接到docker0。每个容器都会配置同docker0 ip相同网段的专用ip 地址,docker0的IP地址被用于所有容器的默认网关:: // 一般启动的容器中ip默认是172.17.0.1/24网段 [root@linux-node2 ~]# docker run -t -i --name my-test centos /bin/bash [root@c5217f7bd44c /]# [root@linux-node2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c5217f7bd44c centos "/bin/bash" 10 seconds ago Up 10 seconds my-test [root@linux-node2 ~]# docker inspect c5217f7bd44c|grep IPAddress "SecondaryIPAddresses": null, "IPAddress": "172.17.0.2", "IPAddress": "172.17.0.2", 注意:宿主机的ip路由转发功能一定要打开,否则所创建的容器无法联网:: [root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward 1 [root@localhost ~]# [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e64eade06d1 docker.io/centos "/bin/bash" 10 seconds Up 9 seconds my-centos [root@localhost ~]# docker run -itd --net=none --name=container1 docker.io/centos 5e5bdbc4d9977e6bcfa40e0a9c3be10806323c9bf5a60569775903d345869b09 [root@localhost ~]# docker attach container1 [root@5e5bdbc4d997 /]# ping www.baidu.com PING www.a.shifen.com (61.135.169.121) 56(84) bytes of data. 64 bytes from 61.135.169.121 (61.135.169.121): icmp_seq=1 ttl=53 time=2.09 ms 64 bytes from 61.135.169.121 (61.135.169.121): icmp_seq=2 ttl=53 time=2.09 ms 关闭ip路由转发功能,容器即不能联网 [root@localhost ~]# echo 0 > /proc/sys/net/ipv4/ip_forward [root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward 0 [root@5e5bdbc4d997 /]# ping www.baidu.com //ping不通~