本文转载自51CTO博客:“深入浅出”来解读Docker网络核心原理

前言

 之前笔者写了有些关于dokcer的各种相关技术的文章,唯独Docker网络这一块没有具体的来分享。后期笔者会陆续更新Docker集群以及Docker高级实践的文章,所以在此之前必须要和大家一起来解读一下Docker网络原理。

 就好比中国武术一样:学招数,会的只是一时的方法;练内功,才是受益终生长久之计。认真看下去你会有收获的,我们一起来把docker的内功修练好。

“深入浅出”来解读Docker网络核心原理

 在深入Docker内部的网络原理之前,我们先从一个用户的角度来直观感受一下Docker的网络架构和基本操作是怎么样的。

Docker网络架构

 Docker在1.9版本中(现在都1.17了)引入了一整套docker network子命令和跨主机网络支持。这允许用户可以根据他们应用的拓扑结构创建虚拟网络并将容器接入其所对应的网络。

 其实,早在Docker1.7版本中,网络部分代码就已经被抽离并单独成为了Docker的网络库,即libnetwork。在此之后,容器的网络模式也被抽像变成了统一接口的驱动。

 为了标准化网络的驱动开发步骤和支持多种网络驱动,Docker公司在libnetwork中使用了CNM(Container Network Model)。CNM定义了构建容器虚拟化网络的模型。同时还提供了可以用于开发多种网络驱动的标准化接口和组件。

 libnetwork和Docker daemon及各个网络驱动的关系可以通过下面的图进行形象的表示。

“深入浅出”来解读Docker网络核心原理

  如上图所示,Docker daemon通过调用libnetwork对外提供的API完成网络的创建和管理等功能。libnetwrok中则使用了CNM来完成网络功能的提供。而CNM中主要有沙盒(sandbox)、端点(endpoint)、网络(network)这3种组件。

  libnetwork中内置的5种驱动则为libnetwork提供了不同类型的网络服务。接下来分别对CNM中的3个核心组件和libnetwork5种内置驱动进行介绍。

CNM核心组件

1、沙盒(sandbox)
 一个沙盒也包含了一个容器网络栈的信息。沙盒可以对容器的接口、路由和DNS设置等进行管理。沙盒的实现可以是Linux netwrok namespace、FreeBSD jail或者类似的机制。一个沙盒可以有多个端点和多个网络。

2、端点(endpoint)
 一个端点可以加入一个沙盒和一个网络。端点的实现可以是veth pair、Open vSwitch内部端口或者相似的设备。一个端点只可以属于一个网络并且只属于一个沙盒。

3、网络(network)
 一个网络是一组可以直接互相联通的端点。网络的实现可以是Linux bridge、VLAN等。一个网络可以包含多个端点

libnetwork内置驱动

libnetwork共有5种内置驱动:bridge驱动、host驱动、overlay驱动、remote驱动、null驱动。

1、bridge驱动
 此驱动为Docker的默认设置驱动,使用这个驱动的时候,libnetwork将创建出来的Docker容器连接到Docker网桥上。作为最常规的模式,bridge模式已经可以满足Docker容器最基本的使用需求了。然而其与外界通信使用NAT,增加了通信的复杂性,在复杂场景下使用会有诸多限制。

2、host驱动
 使用这种驱动的时候,libnetwork将不为Docker容器创建网络协议栈,即不会创建独立的network namespace。Docker容器中的进程处于宿主机的网络环境中,相当于Docker容器和宿主机共同用一个network namespace,使用宿主机的网卡、IP和端口等信息。

 但是,容器其他方面,如文件系统、进程列表等还是和宿主机隔离的。host模式很好地解决了容器与外界通信的地址转换问题,可以直接使用宿主机的IP进行通信,不存在虚拟化网络带来的额外性能负担。但是host驱动也降低了容器与容器之间、容器与宿主机之间网络层面的隔离性,引起网络资源的竞争与冲突。
 因此可以认为host驱动适用于对于容器集群规模不大的场景。

3、overlay驱动
 此驱动采用IETE标准的VXLAN方式,并且是VXLAN中被普遍认为最适合大规模的云计算虚拟化环境的SDN controller模式。在使用过程中,需要一个额外的配置存储服务,例如Consul、etcd和zookeeper。还需要在启动Docker daemon的时候额外添加参数来指定所使用的配置存储服务地址。

4、remote驱动
 这个驱动实际上并未做真正的网络服务实现,而是调用了用户自行实现的网络驱动插件,使libnetwork实现了驱动的可插件化,更好地满足了用户的多种需求。用户只需要根据libnetwork提供的协议标准,实现其所要求的各个接口并向Docker daemon进行注册。

5、null驱动
 使用这种驱动的时候,Docker容器拥有自己的network namespace,但是并不为Docker容器进行任何网络配置。也就是说,这个Docker容器除了network namespace自带的loopback网卡名,没有其他任何网卡、IP、路由等信息,需要用户为Docker容器添加网卡、配置IP等。
 这种模式如果不进行特定的配置是无法正常使用的,但是优点也非常明显,它给了用户最大的自由度来自定义容器的网络环境。

完整内容请访问: “深入浅出”来解读Docker网络核心原理
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐