Docker网络模型

5 阅读12分钟

容器与虚拟机对比

“容器和宿主机共享操作系统,而且可以实现资源的动态分配。容器包含应用程序和所依赖的软件包,并且不同容器之间共享内核,这与虚拟机相比大大节省了额外的资源占用。在宿主机操作系统中,不同容器在用户空间以隔离的方式运行着各自的进程。容器与虚拟机对比如图所示。”

“容器的网络方案可以分为三大部分:

·单机的容器间通信;

·跨主机的容器间通信;

·容器与主机间通信。”

docker网络模式

bridge模式

“Docker在安装时会创建一个名为docker0的Linux网桥。bridge模式是Docker默认的网络模式,在不指定--network的情况下,Docker会为每一个容器分配network、namespace、设置IP等,并将Docker容器连接到docker0网桥上。严谨的表述是,创建的容器的veth pair中的一端桥接到docker0上。docker0网桥是普通的Linux网桥,而非OVS网桥”

host模式

“连接到host网络的容器共享Docker host的网络栈,容器的网络配置与host完全一样。host模式下容器将不会获得独立的network namespace,而是和宿主机共用一个network namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。”

container模式

“创建容器时使用--network=container:NAME_or_ID模式,在创建新的容器时指定容器的网络和一个已经存在的容器共享一个network namespace,但是并不为Docker容器进行任何网络配置,这个Docker容器没有网卡、IP、路由等信息,需要手动为Docker容器添加网卡、配置IP等。”

none模式

“这种模式下的Docker容器拥有自己的network namespace,但是并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息,需要我们自己为Docker容器添加网卡、配置IP等。”

docker网络标准

CNM标准

“·Network Sandbox:容器网络栈,包括网卡、路由表、DNS配置等。对应的技术实现有network namespace、FreeBSD Jail(类似于namespace的隔离技术)等。一个Sandbox可能包含来自多个网络(Network)的多个Endpoint;

·Endpoint:Endpoint作为Sandbox接入Network的介质,是Network Sandbox和Backend Network的中间桥梁。对应的技术实现有veth pair设备、tap/tun设备、OVS内部端口等;”

“·Backend Network:一组可以直接相互通信的Endpoint集合。对应的技术实现包括Linux bridge、VLAN等。如读者所见,一个Backend Network可以包含多个Endpoint。除此之外,CNM还需要依赖另外两个关键的对象来完成Docker的网络管理功能,它们分别是:

·Network Controller:对外提供分配及管理网络的APIs,Docker Libnetwork支持多个网络驱动,Network Controller允许绑定特定的驱动到指定的网络;

·Driver:网络驱动对用户而言是不直接交互的,它通过插件式的接入方式,提供最终网络功能的实现。Driver(包括IPAM)负责一个Network的管理,包括资源分配和回收。”

容器网络挑战综述

“原生Docker容器网络的组网模型比较简单,主要是单主机模式,它基于以下几个简单的假定:

·它充分利用与容器相连接的本地Linux网桥;

·每个宿主机都有集群看得见的公共IP地址;

·每个容器都有集群看不见的专有的IP地址;

·通过NAT将容器的专有IP地址绑定到宿主机公共IP地址上;

·iptable用于容器与用户基础网络之间的网络隔离;

·负载均衡系统将服务映射至一组容器IP地址和端口。

相较于虚拟机,容器的诸多特点和以上Docker对网络模型的假定迫使我们必须忘掉一些在传统网络领域的经验,例如SDN。”

容器网络最大的挑战在跨容器通信层面,具体有以下几点:

·虚拟机拥有较强的隔离机制,虚拟网卡与硬件网卡在使用上没有什么区别。由于容器基于网络隔离能力较弱的network namespace,容器网络的设计首要考虑隔离性和安全性;

·出于安全考虑,很多情况下容器会被部署在虚拟机内部,这种嵌套部署对应一个新的组网模型;

·原生Docker容器不解决跨主机通信问题,而大规模的容器部署势必涉及不同主机上的网络通信;

·容器相较虚拟机生命周期更短,重启更加频繁,重启后IP地址将发生变化,需要进行高效的网络地址管理,因此静态的IP地址分配或DHCP(耗费数秒才能生效)将不起作用;

·在创建虚拟机的时候,IP地址的分配是一种静态方式。但是在容器上面,IP地址的分配通常是动态的。在创建容器时,通常我们不知道它的IP是什么,只有真正运行后才能知道[…]”

“·容器相较虚拟机发生迁移的频率更高,且原生的Docker容器不支持热迁移,迁移后的容器面临IP地址漂移,而且经常出现不在同一网段的情况,对应的网络策略的刷新要及时跟上;

·容器的部署数量远大于虚拟机,如果为每个容器分配一个主机网络的IP地址,则可能会导致不够分配;

·大规模跨机部署带来多主机间的ARP洪泛,造成大量的资源浪费;

·大部分的容器网络方案都会使用iptables和NAT,NAT的存在会造成通信两端看不到彼此的真实IP地址,并且iptable和NAT的结合使用限制了可扩展性和性能,这让使用容器的主要优势之一荡然无存;

·大规模部署使用veth设备会影响网络性能,最严重时甚至会比裸机降低50%;

·过多的MAC地址。当MAC地址超过限制时,主机中的物理网络接口卡虽然可以切换到混杂模式,但会导致性能下降,“而且顶级机架(ToR)交换机可支持的MAC地址数量也有上限。”

“针对以上挑战,有一些针对性的解决方案。例如,可以使用Macvlan和IPvlan替代veth,以降低处理veth网络的性能开销。当使用IPvlan驱动时,IPvlan工作在L3,而L3网络不会受到洪泛影响,因此只有主机的物理网卡MAC地址可见,容器MAC地址不会暴露在网络中,从而解决数据中心可见MAC地址过多给ToR交换机带来的影响。”

“消除NAT的第二种方法是把主机变成全面的路由器,甚至是使用BGP的路由器。主机会将前缀路由到主机中的容器,每个容器会使用全球唯一的IP地址。尽管在IPv4地址空间已经耗尽的今天,给每个容器提供一个完全可路由的IPv4地址有些不太实际,但IPv6将使这种主机作为路由器的容器组网技术变得可能,事实上很多公有云都已经支持IPv6。”

Docker的解决方案

“在意识到可扩展、自动化的网络对大规模容器部署的重要性后,Docker公司于2015年3月收购了初创企业SocketPlane,后者的主要业务就是将软件定义网络功能以原生方式添加到Docker中。同年6月,Docker将SocketPlane技术整合至其集群管理项目Swarm中,基于Linux桥接与VXLAN解决容器的跨主机通信问题。

与此同时,Docker将网络管理从Docker Daemon中独立出来形成Libnetwork,该项目从1.9版本开始提供多种网络驱动,并支持跨主机的网络部署等功能,也允许第三方网络管理工具以插件方式替代Docker中内置的网络功能,接口标准便是CNM。”

“随着Docker的兴起,一些专业的容器网络插件,例如flannel、Weave、Calico等也开始与各个容器编排平台进行集成,“那么,一个容器网络插件应该提供什么功能呢?”

“1.你会在基于容器的基础设施上运行哪种类型的应用程序?

这直接影响到网络基础设施的蓝图及如何构建网络基础设施。你的应用程序需要复杂的网络拓扑结构及高级网络服务吗?它们是多租户模式,还是简单的“扁平网络”?”

“2.性能和可扩展性方面的要求是什么?

你在思考这个问题时,要考虑基础设施上应用程序的要求。应当考虑这样的解决方案:在一种完全分布式的架构中提供隔离和网络功能,为应用程序的发展和扩展铺平道路。随着部署的云越来越庞大,网络解决方案应该跨多个物理主机向外扩展,还应该在云编排框架里紧密地整合起来。”

“3.你需要将容器与虚拟机和裸机工作负载互联起来吗?

大多数应用程序需要用容器支持混合工作负载,所以要寻求同时支持两者的解决方案。一致的抽象模型(网络、子网、路由器、接口和浮动IP地址)和一套用于配置和自动化的一致的API,是完成这项工作的方法。”

容器组网方案

隧道方案

“隧道网络也称为overlay网络,有时也被直译为覆盖网络。其实隧道方案不是容器领域新发明的概念,它在IaaS网络中应用得也比较多。overlay网络最大的优点是适用于几乎所有网络基础架构,它唯一的要求是主机之间的IP连接。但overlay网络的问题是随着节点规模的增长,复杂度也会随之增加,而且用到了封包,因此出了网络问题定位起来比较麻烦。”

“使用UDP进行封包的时候性能损失在50%以上,使用VXLAN也会有20%~30%的损耗。”

路由方案

“回过头来想一下,我们为什么要封包?其实它是改包,主要解决的问题是同一个问题,即在容器网络里,主机间不知道对方的目的地址,没有办法把IP包投递到正确的地方。传统的三层网络是用路由来互相访问的,不需要封包。至于路由规则怎么维护?传统的网络解决方案是利用BGP部署一个分布式的路由集群”

“·Calico:源自Tigera,基于BGP的路由方案,支持很细致的ACL控制,对混合云亲和度比较高;”

“Calico的设计灵感源自通过将整个互联网的可扩展IP网络原则压缩到数据中心级别。Calico在每一个计算节点,利用Linux Kernel实现高效的vRouter来负责数据转发,而每个vRouter通过BGP把自己节点上的工作负载的路由信息向整个Calico网络传播。小规模部署可以直接互联,大规模下可通过指定的BGP Route Reflector完成。保证最终所有的容器之间的数据流量都是通过IP路由的方式完成互联的。”

容器网络组网类型

“1.overlay网络

overlay网络是在传统网络上虚拟出一个虚拟网络,承载的底层网络不再需要做任何适配。在容器的世界里,物理网络只承载主机网络通信,虚拟网络只承载容器网络通信。overlay网络的任何协议都要求在发送方对报文进行包头封装,接收方剥离包头。

L2 overlay

传统的二层网络的范围有限,L2 overlay网络是构建在底层物理网络上的L2网络,相较于传统的L2网络,L2 overlay网络是个“大二层”的概念,其中“大”的含义是可以跨越多个数据中心(即容器可以跨L3 underlay进行L2通信),而“二层”指的是通信双方在同一个逻辑的网段内,例如172.17.1.2/16和172.17.2.3/16。

VXLAN就是L2 overlay网络的典型实现,其通过在UDP包中封装原始L2报文,实现了容器的跨主机通信。

“L2 overlay网络容器可在任意宿主机间迁移而不改变其IP地址的特性,使得构建在大二层overlay网络上的容器在动态迁移时具有很高的灵活性。”

L3 overlay

“L3 overlay组网类似L2 overlay,但会在节点上增加一个网关。每个节点上的容器都在同一个子网内,可以直接进行二层通信。跨节点的容器间通信只能走L3,都会经过网关转发,性能相比于L2 overlay较弱。牺牲的性能获得了更高的灵活性,跨节点通信的容器可以存在于不同的网段中,例如192.168.1.0/24和172.17.16.0/24。

flannel的UDP模式采用的就是L3 overlay模型。

L3 overlay网络容器在主机间迁移时可能需要改变其IP地址。”

“2.underlay网络

underlay网络一般理解为底层网络,传统的网络组网就是underlay类型,区别于上文提到的overlay网络。

L2 underlay

L2 underlay网络就是链路层(L2)互通的底层网络。IPvlan L2模式和Macvlan属于L2 underlay类型的网络。

L3 underlay

在L3 underlay组网中,可以选择IPvlan的L3模式,该模式下IPvlan有点像路由器的功能,它在各个虚拟网络和主机网络之间进行不同网络报文的路由转发工作。只要父接口相同,即使虚拟机/容器不在同一个网络,也可以互相ping通对方,因为IPvlan会在中间做报文的转发工作。

IPvlan的L3模式,flannel的host-gw模式和Calico的BGP组网方式都是L3 underlay类型的网络。”