在云计算架构设计中,最复杂且最重要的组件就是网络,Docker作为云计算追捧的新宠儿也不会例外,尤其是当使用Docker容器构建分布式服务时,通信和网络变得非常重要。


开篇之前,先给读者分享下笔者对容器知识总结:容器技术架构、网络和生态详解,内容涉及容器技术的方方面面,感兴趣的读者可通文末“阅读原文”过了解详情。


第1章 容器演进和关键技术介绍4

第2章 为什么是Docker引领主流13

第3章 详谈Docker的生态系统34

  • 3.1 Docker的生态系统导图35

  • 3.2 Docker的挑战者Rocket37

第4章 详解Docker AUFS技术38

第5章 Docker技术架构详细分析44

  • 5.1 Docker关键技术回顾44

  • 5.2 Docker实现持续部署45

  • 5.3 Docker总架构图46

  • 5.3.1 Docker Client模块48

  • 5.3.2 Docker Daemon模块49

  • 5.3.3 Docker Server子模块50

  • 5.3.4 Engine子模块52

  • 5.3.5 Job任务子模块52

  • 5.3.6 Docker Registry模块53

  • 5.3.7 Graph模块53

  • 5.3.8 Driver模块54

  • 5.3.9 Libcontainer模块58

  • 5.3.10 Docker container模块60

第6章 容器定义存储(CDS)技术分析61

第7章 Portworx容器定义存储(CDS)详解70

  • 7.1 Portworx架构和原理71

  • 7.2 存储控制面72

  • 7.3 数据面访问73

  • 7.4 生命周期管理74

  • 7.5 Portworx应用场景75

第8章 Diamanti容器融合存储基础架构78

  • 8.1 容器的内建基础架构79

  • 8.2 容器与其网络互联80

  • 8.3 容器的存储持久化81

  • 8.4 简化容器管理81

  • 8.5 集成流行的容器开源架构82

  • 8.6 Diamanti产品特点83

第9章 Docker原生网络和实现原理84

第10章 Openstack如何实现与容器对接88

第11章 Docker网络技术方案详解94

  • 11.1 Libnetwork方案介绍95

  • 11.2 Pipework方案介绍97

  • 11.3 Socketplane方案介绍98

  • 11.4 Weave方案介绍99

  • 11.5 Flannel方案介绍100

  • 11.6 Tinc方案介绍101

第12章 细说Docker发展和生态102

  • 12.1 Docker发展历程102

  • 12.2 Docker的推动者103

  • 12.3 Docker镜像仓库103

  • 12.4 Docker的生态环境104

  • 12.5 Docker的优势104

  • 12.6 Docker的跨平台特性106

  • 12.7 Docker容器云106

  • 12.8 Docker改名Moby浅析107


接下来,我们将从Docker原生网络架构出发,讨论目前活跃的多种针对Docker提出的网络优化方案。

 

      Docker的网络是基于Linux的网络命名空间和虚拟网络设备(特别是veth pair)来实现。在Docker中,网络接口默认都是虚拟的接口,可以充分发挥数据在不同Docker间或Docker与宿主机转发效率。这是因为Linux通过在内核中通过数据复制实现虚拟接口之间的数据转发,即发送接口的发送缓存中的数据包将被直接复制到接收接口的接收缓存中,而无需通过外部物理网络设备进行交换。

 

      Docker容器创建网络时,会在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通,形成一对虚拟网络接口,这样的一对接口叫做veth pair。



 

     当Docker进程启动之后,它会配置一个叫docker0的虚拟网桥在宿主机上。这个网桥接口允许Docker去分配虚拟的子网给即将启动的容器。这个网桥在容器内的网络和宿主机网络之间将作为网络接口的主节点呈现。


      当Docker容器启动后,创建一对虚拟接口,分别放到本地主机和新容器的命名空间中。本地宿主机一端的虚拟接口连接到默认的docker0网桥或指定网桥上,并具有一个以veth开头的唯一名字。容器一端的虚拟接口将放到新创建的容器中,并修改名字作为eth0,这个接口只在容器的命名空间可见。

      从网桥可用地址段中,分配一个网桥子网内的IP地址给容器的eth0。这个IP地址嵌在容器内网络中,用于提供容器网络到宿主机docker0网桥上的一个通道。并配置默认路由网关为docker0网卡的内部接口docker0的IP地址。Docker会自动配置iptables规则和配置NAT,便于连通宿主机上的docker0网桥。完成这些操作之后,容器就可以使用它所能看到的eth0虚拟网卡,来连接其他容器和访问外部网络。

 

      Docker提供了一种容器间通信机制叫做Docker links。如果一个新容器链接到一个已有容器,新容器将会通过环境变量获得已有容器的链接信息。通过提供给信任容器有关已有容器的链接信息,实现容器间的通信。



  

    同一宿主机上的容器可以相互通信并提供服务给相邻容器,而不需要额外的配置(端口暴露或发布),宿主系统会简单将路由请求从docker0传到目的地。


      容器可以暴露它们的端口给宿主机,用于接收外部请求流量。暴露出的端口可以通过特定端口或由Docker来随机选择一个高位空闲端口映射到宿主机上。暴露端口意味着Docker将呈现该端口是暴露容器所使用,这可以被用于服务发现和links(新容器将会设置环境变量来对应原容器暴露的端口)。


      容器可以发布它们的端口给宿主机,端口发布将映射端口到宿主接口,使得它可以与外界交互。暴露出的端口可选择映射宿主机上一个指定端口,或者Docker可以自动的随机选择一个高位空闲端口。

 

      Libcontainer也需要重点关注下,它是Docker中用于容器管理模块(创建容器、实现容器生命周期管理),它基于Go语言实现,通过管理Namespaces、Cgroups以及文件系统来进行容器控制。在Docker中,对容器管理的模块为Execdriver,目前Docker支持的容器管理方式有两种,一种就是最初支持的LXC方式,另一种称为Native的Libcontainer进行容器管理。


 

     Docker起初是采用LXC的开源容器管理引擎。把LXC复杂的容器创建与使用方式简化为Docker自己的一套命令体系。后来Docker将底层实现都抽象化到Libcontainer的接口。这样可以实现跨平台能力,无论是使用了Namespace、Cgroups技术或是使用Systemd等其他方案,只要实现了Libcontainer定义的一组标准接口,Docker都可以运行。


      Docker原生网络模型在保证端口映射、链接正确的情况下,可实现同一宿主机上容器间的通信和宿主机之间的通信。

但针对安全或者特殊功能要求特殊的网络环境,Docker这个原生的网络功能就会受限制。于是许多项目致力于扩展Docker网络生态。下面我们重点介绍下这些基于Docker网络优化的6个项目及方案。


Libnetwork方案介绍


      Libnetwork是Docker公司正在开发的新的网络底层架构,由libcontainer和Docker Engine中的网络相关的代码合并而成。Libnetwork的目标是引入了容器网络模型(CNM),并为应用程序提供一致的编程API接口以及网络抽象。CNM得到了网络方面的合作伙伴Cisco、IBM、Joyent、Microsoft、Rancher、VMware和Weave的支持,使Libnetwork发展为一个跨平台的容器网络管理工具。


      Libnetwork的容器网络模型包含了三个重要概念,Network Sandbox,Endpoint和Network。



 

     网络沙盒Network Sandbox承载Docker容器中一个网络配置的隔离、独立运行环境。Endpoint用于在某个网络上进行网络通讯的接口,一个Endpoint只能加入一个network Sandbox,同时,多个Endpoint也可以在一个网络沙盒中共存。


Network就是一个唯一的、可识别的endpoint组,组内endpoint可以相互通讯。不同网络组内的endpoint不能通信。可以创建两个完全隔离的Frontend network和Backend network。

Pipework方案介绍


      Pipework是由Docker开发者通过Shell开发,作为一个权宜之计来简化Docker网络配置流程,这个项目使得高级网络配置变得容易,能够自动完成一些网络功能配置,但功能有限。



 

     Pipework首先会检查是否存在br0网桥,若不存在,就自己创建。若"ovs"开头,就会创建OpenVswitch网桥,以"br"开头,创建Linux网桥。创建veth pair设备,用于为容器提供网卡并连接到br0网桥。


      使用Docker inspect找到容器在主机中的pid,然后通过PID将容器的网络命名空间链接到/var/run/netns/目录下。这么做的目的是,方便在主机上使用ip netns命令配置容器的网络。将之前创建的veth pair设备分别加入容器和网桥中(在容器中默认为eth1)。


      最后会配置新网卡eth1的IP。若指定为网关地址,那么pipework会改变默认路由eth0和docker0为该IP,容器通往外网的流量会经由新配置的eth1出去。

 

Socketplane方案介绍


      Socketplane是SND创业公司,目前已经被Docker公司收购,其实现方式是在原有的Docker命令上做了一层封装,通过拦截并修改Docker Client发送给Docker engine的命令来实现网络安全和维护的目前。



 

     Socketplane依赖于OpenvSwitch和Consul。Socketplane作为虚拟交换机实现底层网络通信,Consul实现消息同步和服务发现。SocketPlane在 Socket 层面提供了一个网络的抽象层,对开发者屏蔽VLANs, VXLANs, Tunnels 或TEPs等概念,实现和OpenvSwitch集成,支持多网络和分布式 IP 地址管理,通过可管理的方式去解决各种网络问题。

 

Weave方案介绍


      Weave方案包含两大组件,用户态Shell脚本和Weave虚拟路由容器。Weave虚拟路由容器需要在每个宿主机上布置,把不同宿主机的route容器连接起来。



 

     不同主机间的网络通信依赖于Weave虚拟route,通过route拦截所有普通容器的IP请求,以UDP数据包发送到其他宿主机上的普通容器,实现跨主机的多个容器扁平网络。但是Weave解决了不同主机网络间通信问题。

 

Flannel方案介绍 


      Flannel原名为Rudder,是由CoreOS团队开发,这个项目被开发的初衷是为每一个宿主系统提供一个共享、完整的网络子网,配合Google kubernetes使用,但在其他场景下也被用来简化端口映射和网络管理的复杂性。




      Flannel和OpenvSwitch设计思路基本一致,在Docker在宿主机上创建一个网桥时,通过采用Flannel自己的网桥替代它。其差别在于Flannel通信是用软的UDP来包装IP数据包,而OpenvSwitch用的是采用SDN思想。Flannel网络配置是写入到etcd集群中,Flannel进程一般运行在三台主机上,Docker启动时,运行的Docker从主机所属的完整子网网段中动态分配IP。

 

Tinc方案介绍


      Tinc是一个轻量的***软件,也是一个开源的***解决方案,它采用隧道和加密实现。Tinc是一个健壮的解决方案,它能够使私有网络对任何应用透明。



 

     关于Tinc方案介绍的资料并不多,主要借助***技术实现数据网络安全传输,由于采用了“虚拟专用网”技术,即用户实际上并不存在一个独立专用的网络,也能保证Docker间数据安全传输。


      Docker容器本身具备对内或对外提供服务是原生网络模型和能力,如通过虚拟接口的配置、子网、NAT表管理和iptables等,但是还需要一些网络项目支持,提供了更高级的网络配置和安全控制。


©著作权归作者所有:来自51CTO博客作者mob604756fca9f3的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Gartner:政府CIO将在2018年增加云、网络安全和分析方面的支出
  2. 创建你的第一个Docker应用
  3. 互联网企业网络信息安全实践
  4. 虚拟网络:OpenFlow,与OpenStack集成,边缘虚拟网络
  5. (设计模式)迭代器 > 本篇文章由一文多发平台[ArtiPub](https://gi
  6. Docker是不是遇上麻烦了?
  7. 计算机网络中的交换技术
  8. Java岗 面试考点精讲(网络篇03期)
  9. 【完整版21章】深度学习经典网络架构实战系列

随机推荐

  1. 使用Android Studio与ArcGIS Android SDK
  2. Android技术内幕
  3. Android热修复(2):AndFix热修复框架的使用
  4. android仿网易云音乐、即时通讯、bilibil
  5. [转]android:layout_gravity 和 android:
  6. Android(安卓)-- StateMachine瑙f瀽
  7. Android 多线程之几个基本问题
  8. Android通知栏微技巧,8.0系统中通知栏的适
  9. Andriod应用开发--第二章作业1--习题答案
  10. Android(安卓)由android:process引发LMK