Docker容器网络

Docker容器的网络驱动有很多种方式,当安装docker engine后,docker会在每一个engine上面生成一个3种网络,通过命令可以看到是bridge,host和none,而docker官方推荐用户使用自己的自定义网络,所以在使用容器的时候最好使用自定义的网络,默认docker使用自带的bridge网络,bridge网络下的docker容器相互之间可以通信但无法解析彼此的容器名称。如果需通过容器名称通信,则官方允许使用旧版本的--link参数。

一.常见的主机内部容器网络模式

  • 默认网络模式---bridge
  • 无网络模式---none
  • 宿主网络模式---host
  • 容器共享模式---container
  • 自定义

1.bridge网络模式;bridge模式是docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将并将一个主机上的docker容器连接到一个虚拟网桥上。docker在启动时会创建一个虚拟网桥docker0,默认地址为 172.17.0.1/16, 容器启动后都会被桥接到docker0上,并自动分配到一个IP地址。
思考:
同一个bridge的网络中,容器是以相同的vethXXX可以达到网络互通的结果,如果是外界想同docker通信呢?其实道理也是一样的,容器发出去的数据包经过docker0网桥流向eth0,eth0在将数据包转发给与之相通的外部主机,于是容器就能和其他主机进行通讯了。当然如果这个地址不是其他主机节点而是公网地址,只要eth0能到达,容器都能与之通讯。

2.none网络模式;docker容器拥有自己的Network Namespace,但并不为docker容器进行任何网络配置。也就是说,这个docker容器没有网卡、IP、路由等信息。需要使用者为docker容器添加网卡、配置IP等。

3.host网络模式;如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

4.container网络模;这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的已有容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

5.自定义模式

docker network create -d bridge leo_zhou 
#新建一个bridge模式的leo_zhou网络
docker run -d --name bb-1 --network leo_zhou busybox
#新建bb-1的容器并加入leo_zhou网络
docker run -d --name bb-2 --network leo_zhou busybox
#新建bb-2的容器并加入leo_zhou网络
docker network create -d bridge leo_zhou_2 --subnet=172.30.0.0/16
#新建一个bridge模式的leo_zhou_2网络并且规则IP范围
docker run -itd --name bb-3 --network=leo_zhou_2  --ip 172.30.0.7 busybox
#新建bb-3的容器并加入leo_zhou_2网络并且规定了具体的IP地址

 测试结果
①leo_zhou和leo_zhou_2之间的容器不能相互通信。
②leo_zhou相同网络下可以相互通信,但如果想通过容器名称通信就需要--link参数。
③如果相同主机不同网络之间想进行通信可以使用connect命令把容器加入到网络中取。

docker network connect network-name container-name

二.跨主机之间的容器通信
Docker默认的网络环境下,单台主机上的docker容器最终都可以通过docker0网桥直接通信,而不同主机上的docker容器之间只能又该怎么进行通信呢?现实中最简单暴力的方式是使用端口映射,把docker的服务端口映射到宿主机node上进行端口访问,这种端口映射方式对很多集群应用来说极不方便,如果能让docker容器之间直接使用自己的IP地址进行通信,会解决很多问题。按实现原理可分别直接路由方式、桥接方式(如pipework)、Overlay隧道方式(如flannel、ovs+gre)等,虽然这些方案在实现细节上存在很多差异,但其思路无非分为两种: 二层VLAN网络和Overlay网络简单来说,二层VLAN网络解决跨主机通信的思路是把原先的网络架构改造为互通的大二层网络,通过特定网络设备直接路由,实现容器点到点的之间通信。这种方案在传输效率上比Overlay网络占优,然而它也存在一些固有的问题。这种方法需要二层网络设备支持,通用性和灵活性不如后者。由于通常交换机可用的VLAN数量都在4000个左右,这会对容器集群规模造成限制,远远不能满足公有云或大型私有云的部署需求; 大型数据中心部署VLAN,会导致任何一个VLAN的广播数据会在整个数据中心内泛滥,大量消耗网络带宽,带来维护的困难。相比之下,Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。其中Flannel是一种基于overlay网络的跨主机容器网络解决方案,即将TCP数据包封装在另一种网络包里面进行路由转发和通信,Flannel是CoreOS开发,专门用于docker多机互联的一个工具,让集群中的不同节点主机创建的容器都具有全集群唯一的虚拟ip地址。
flannel+etcd方案是典型应用(以后有实际的操作后,再补充)

总结
bridge网络模式实现方式是docker0网桥+veth实现通信,而host、container模式都是"共享"方式实现,host网络模式是容器共享宿主机Network Namespace,continer网络模式是容器共享已存在的容器的Network Namespace,none模式则是网络封闭状态。每一个网络模式都是有用处的,bridge模式适合进行项目之间的网络隔离;host可以作为公用的共享;而container可以作为两个关系紧密的项目的载体,例如web和db,共用一个网络。

原文地址:https://www.cnblogs.com/zhouzhifei/p/11607467.html