背景

Docker容器之间是通过namespace互相隔离的,每个容器都有自己独立的用户空间环境,那么docker是如何支持容器间或容器和宿主机间通信呢?

docker 网络设计

基于docker容器的轻量高效动态可移植等特性,docker网络在设计时也具有以下特性,该特性也方便更好的支持微服务,提供高效的连接和安全的隔离。

  • 可移植性
    在利用独特的网络特性的同时,还保证在各种网络环境中的最大可移植性
  • 服务发现
    及时发现和扩展服务,提供dns动态解析
  • 负载均衡
    随着服务的启动和扩展,提供服务负载均衡功能
  • 安全
    对网络中的容器进行隔离和访问控制
  • 性能
    减少延迟和最大化带宽的同时提供高级网络服务,方便更好的支持微服务
  • 可扩展性
    方便在多个主机之间扩展应用程序

CNM

Docker网络架构核心是建立在称为 容器网络模型(Container Network Model,简称CNM)的一组接口上,只要符合这个模型的网络接口就能被用于容器之间通信,而通信的过程和细节可以完全由网络接口来实现。
CNM的理念是在各种基础网络架构之间提供应用程序可移植性。
docker基础整理(3)-- 网络介绍_网络介绍
CNM的三个高级结构,和基础网络结构无关,在基础网络之上,方便应用程序可移植性:
Sandbox:包含容器的网络堆栈的配置。包括相应的网卡配置、路由表、DNS配置等。沙箱是伴随容器的生命周期的,可以看成是容器的网络环境;
Endpoint:Endpoint将Sandbox连接到网络,具体表现为容器中eth0,eth1这些虚拟网卡;
Network:连通两个或多个Endpoint,指的是一个能够相互通信的容器网络,提供容器互相访问的通道。 网络的实现可以是Linux网桥,VLAN等。

docker 网络驱动

CNM提供了网络驱动程序接口,Docker的网络驱动程序提供了使网络正常工作的实际实现。它们是可插拔的,因此可以轻松使用和互换不同的驱动程序,以支持不同的应用场景。
Docker支持的网络驱动较多,根据不同应用场景可分为:
docker自带驱动:

  • 宿主机内部容器通信:bridge,host,container和none;
  • 跨主机容器通信:macvlan,overlay;

第三方驱动:

  • 大规模集群跨主机容器通信: flannel、pipework、weave 和 calico。

CNM还提供另一种驱动程序,IPAM驱动程序,区别于网络驱动程序,支持手动分配ip地址。

其他技术支撑

网络命名空间:是用于隔离容器网络资源(IP、网卡、路由等)。网络名称空间可确保同一主机上的两个容器无法相互通信,甚至不能与主机本身进行通信,除非配置为通过Docker网络进行通信。通常,CNM网络驱动程序为每个容器实现单独的名称空间。但是,容器可以共享相同的网络名称空间,甚至可以是主机的网络名称空间的一部分。
由于一个容器网络最多存放在一个网络命名空间中且互相隔离,所以通过 veth pair 在不同的网络命名空间中创建通道,负责不同网络命名空间的通信。
veth pair:用于不同network namespace间进行通信。veth是全双工链接,在每个名称空间中都有一个接口,充当两个网络名称空间之间的连接线,负责将一个 network namespace 数据发往另一个 network namespace 的 veth。
如当容器连接到Docker网络时,veth的一端放置在容器内部(通常视为ethX接口),而另一端连接到Docker网络(vethxxx)。
iptables:负责包过滤,端口映射和负载均衡。

宿主机内部容器通信

bridge

docker默认网络类型,默认网桥为docker0(172.17.0.1/16),容器间通过docker0通信。
docker bridge和linux bridge不同,后者是Linux桥接器的更高级别的实现。docker bridge本质是nat桥。
docker基础整理(3)-- 网络介绍_Docker_02可以看到创建的容器默认会创建一个eth0虚拟网卡创建一对虚拟接口,即veth pair,分别放到宿主机和容器中;
docker基础整理(3)-- 网络介绍_Docker_03
docker基础整理(3)-- 网络介绍_网络介绍_04
默认bridge和自定义bridge:
自定义的网桥和默认网桥类似,但用户定义的网桥网络优于默认网桥网络:
自定义的网桥优势:优势对比
自定义bridge:

docker network create --subnet=10.10.0.0/16 --gateway=10.10.0.1 --driver bridge mybridge10 #创建自定义bridge
docker run -it --name 10_b1 --net mybridge10 busybox sh # 关联容器
docker network connect mybridge10 b1	# 将b1 加入mybridge10网络
docker network disconnect mybridge10 b1	# 断开mybridge10网络和b1的连接

创建mybridge10网络和处于mybridge10网络的10_b1容器:
docker基础整理(3)-- 网络介绍_Docker_05
docker基础整理(3)-- 网络介绍_Docker_06
可以看到宿主机新增了自定义br桥和10_b1容器对应的接口:
docker基础整理(3)-- 网络介绍_Docker_07
将b1 加入mybridge10网络:
docker基础整理(3)-- 网络介绍_网络介绍_08
自定义网桥会自动dns解析:
docker基础整理(3)-- 网络介绍_Docker_09

host

和宿主机共享网络,仅共享network namespace,其他namespace隔离。该容器创建时不会分配自己的IP地址,使用主机ip地址,其开通的服务端口可直接通过主机ip:端口访问。

docker run -it --name b2 --net host  busybox

可以看到下面容器读取到的ip信息和tcp信息直接是宿主机的ip信息和tcp信息
docker基础整理(3)-- 网络介绍_网络介绍_10
宿主机ip和tcp信息
docker基础整理(3)-- 网络介绍_Docker_11
访问容器8080端口服务:
docker基础整理(3)-- 网络介绍_Docker_12

none

容器有自己的网络堆栈和网络命名空间,但不分配接口,仅存在lo接口,适合不需要通过网络通信的容器。什么情况下容器要禁用网络呢???
docker基础整理(3)-- 网络介绍_网络介绍_13

container

容器c1共享之前的容器b1网络,网络环境相同,仅通过端口区分服务,两容器用同一端口即会冲突。

 docker run -it --name c1 --rm --net container:b1 busybox sh

容器c1:
docker基础整理(3)-- 网络介绍_Docker_14
docker基础整理(3)-- 网络介绍_Docker_15

跨主机容器通信

端口映射

-P|p指定一个docker主机端口给容器中的端口做映射,可以实现跨主机通信。不适合容器间互相通信,手动映射有点麻烦。

docker run -d --name mynginx -p 8080:80  nginx

docker基础整理(3)-- 网络介绍_Docker_16

macvlan

macvlan 本身是 linux kernel 模块,允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP。
macvlan 的最大优点是性能极好,相比其他驱动,macvlan 不需要创建 Linux bridge,而是直接通过以太接口连接到物理网络。由于么有物理机测试,so只做介绍,具体我也不了解。

overlay(swarm network)

跨节点容器网络互联,比较通用的是使用 overlay 网络。
overlay涉及到三个网络: overlay ingress bridge
其他:overlay_sbox lb_overlay

docker network create   --driver overlay   --ingress   --subnet=10.11.0.0/16   --gateway=10.11.0.1   --opt com.docker.network.driver.mtu=1200   myingress11
docker service create --name hostname --publish target=8000,published=8080 --network myingress11 --replicas=3 xlbubble/hostname:1.0

注意:自定义overlay与默认overlay的区别:默认没有服务发现,dns解析。

集群内部通信-- flannel

这里仅介绍flannel。
flannel安装:https://blog.51cto.com/13941177/2299470
暂时先这样吧

博客参考和扩展

  • 网络:https://success.docker.com/article/networking
  • overlay详解:https://www.jianshu.com/p/c83a9173459f