Docker-网络实现

265 阅读4分钟
  • 前面我们介绍了Docker的Namespace和cgroups技术,利用这二项技术可以实现Docker容器的隔离和资源限制,但是此时的容器是没有办法与外界通信的,也就是不能被外部访问到,也无法与外部通信

1:容器网络发展史

  • Docker从1.7版本开始,就将网络和存储从Docker中以插件的形式剥离出来了,并且为其定义了标准,Docker定义的网络模型标准称为CNM(Container Network Model)

2:CNM

  • CNM是Docker发布的容器网络标准,CNM抽象了容器的网络接口,使得只要满足CNM接口的网络方案都可以接入到Docker容器网络,更好的满足用户网络模型多样化的需求
  • CNM定义的网络标准包含三个重要元素
    • 沙箱:沙箱代表一系列网络堆栈配置,其中包含路由信息,网络接口等网络资源的管理,沙箱的实现通常是Linux的Net Namespace,但也可以通过其它技术实现,比如FreeBSD jail等
    • 接入点:接入点将沙箱连接到网络当中,代表容器的网络接口,接入点的实现通常是Linux的veth设备对
    • 网络:网络是一组可以互相通信的接入点,它将多接入点组成一个子网,并且多个接入点之间可以互相通信

3:Libnetwork

  • 为了更好的构建容器网络标准,Docker团队把网络功能从Docker中剥离出来,成为独立的项目libnetwork,它通过插件的形式为Docker提供网络功能。Libnetwork是开源的,使用Golang编写,它完全遵循CNM规范,是CNM的官方实现

4:Libnetwork的工作流程

  • 第一步:Docker通过调用libnetwork.New函数来创建NetworkController实例,NetworkController实例是一个接口类型,提供各种接口
  • 第二步:通过调用NewNetwork函数创建指定名称和类型的Network,其中Network也是接口类型
  • 第三步:通过调用CreateEndpoint来创建接入点,在CreateEndpoint函数中为容器分配ip和网卡接口。
  • 第四步:调用NewSandbox来创建容器沙箱,主要是初始化Namespace的相关资源
  • 第五步:调用Endpoint的Join函数将沙箱和网络接入点关联起来,此时容器就加入了Docker网络并具备了网络访问能力

5:Libnetwork常见网络模式

  • null空网络模式
    • 有时候我们需要处理一些保密数据,处于安全考虑,我们需要一个隔离的网络环境执行一些纯计算的任务,null空网络模型可以使我们容器不会联网,处于一个相对较安全的环境,确保我们数据不会被他人窃取
  • bridge桥接模式
    • Docker的bridge网络是启动容器默认的网络模式,使用bridge网络可以实现容器与容器的互通,可以从一个容器通过ip访问另一个容器。同时使用bridge网络可以实现主机与容器的互通
  • host主机网络模式
    • 容器内的网络并不是希望永远是跟主机隔离的,有些基础业务需要创建或更新主机的网络配置,我们的程序必须以主机网络模式运行才能修改主机网络。host主机网络模式通常适用于想要使用主机网络,但是又不想把运行环境直接安装到主机上的场景
  • container网络模式
    • container网络模式允许一个容器共享另一个容器的网络命名空间,当二个容器需要共享网络,但是其它资源仍然需要隔离时就可以使用container网络模式,例如我们开发一个http服务,但是又想使用nginx的一些特性,让nginx代理外部的请求然后转发给自己的业务,这时我们使用 container网络模式将自己开发的服务和 nginx 服务部署到同一个网络命名空间中。