Docker 网络背后的原理探索

Stella981
• 阅读 450

本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复**「1024」**即可领取,欢迎大家关注,二维码文末可以扫。

知其然而不知其所以然,不知也。老古人说得多好,学知识不懂得知识背后的原理,等于白学。

通过前面两篇文章,我们知道了容器的单主机网络和多主机网络,对于这么多网络方案,我们看到对 Docker 的整体网络结构好像没有改动,都是水平扩展的,那 Docker 网络究竟是怎么集成这么多网络方案而不改变自身原有的结构呢?本文就来一探究竟。

Docker 的总体框架

要回答这个问题,得从 Docker 的总体框架说起。

Docker 网络背后的原理探索

容器和虚拟机一样,都是虚拟化的产品,都包括计算虚拟化,存储虚拟化和 IO 虚拟化。容器作为轻量级的进程,不像虚拟机那般复杂,这三块分别靠三个 Driver 来完成的,execdriver 负责计算虚拟化,networkdriver 负责网络虚拟化,graphdriver 负责存储虚拟化。由此可见,Docker 靠 Driver 这种设计思想来支撑起它的基础平台,再往深了挖,它的每个子模块都随处可见这种设计思想,就网络这个子模块来看,也是如此。

Docker 的网络模型

docker engine + libcontainer

期初的 Docker 网络子模块的代码是分散在 docker daemon 和 libcontainer 中的,libcontainer 是一个独立的容器管理包,execdriver 和 networkdriver 都是通过 libcontainer 来实现对容器的具体操作。

随着业务场景越来越复杂,这种内嵌的方式很难针对不同的网络场景进行扩展。后来,Docker 收购了一个做多主机网络解决方案的公司 SocketPlane,然后让那帮人专门来解决这个问题。这就是接下来要介绍的 libnetwork。

libnetwork && CNM

libnetwork 起初的做法很简单,就是将 docker engine 和 libcontainer 中网络相关的代码抽出来,合并成一个单独的库,做成网络抽象层,并对外提供 API。Docker 的愿景就是希望 libnetwork 能够做像 libcontainer 那样,成为一个多平台的容器网络基础包。

后来受一个 GitHub issue ( https://github.com/moby/moby/issues/9983) 的启发,libnetwork 引入容器网络模型(Container Network Model,CNM),该模型进一步对 Docker 的网络结构进行了细分,提出了三个概念:network、sandbox 和 endpoint。

network

network 是一个抽象的概念,你可以把它理解成一个网络的插件,或者是网络的 Driver,比如说单主机网络的 Driver 就有 none、host、bridge,joined container 这四种,多主机网络就有 overlay、macvlan、flannel 这些。network 可以独立出去做,只需调用 Docker 对外提供的 API 就可以作为插件集成到 Docker 网络中使用。

sandbox

sandbox 实现了容器内部的网络栈,它定义容器的虚拟网卡,路由表和 DNS 等配置,其实就是一个标准的 linux network namespace 实现。

endpoint

network 实现了一个第三方的网络栈,sandbox 则实现了容器内部的网络栈,那这两者怎么联系起来呢?答案就是通过 endpoint,endpoint 实现了 veth pair,一个 endpoint 就表示一对 veth pair,一端挂在容器中,另一端挂在 network 中。

Docker 网络背后的原理探索

network、sandbox 和 endpoint 三者之间的关系:

  • 一个 network 可以包含多个 endpoint,自然也就包含多个 sandbox。

  • 一个 sandbox 可以包含多个 endpoint,可以属于多个 network。

  • 一个 endpoint 只可以属于一个 network,并且只属于一个 sandbox。

如上图显示三个容器,每个容器一个 sandbox,除了第二个容器有两个 endpoint 分别接入 network1 和 network2 之外,其余 sandbox 都只有一个 endpoint 分别接入不同的 network。

到此,我们就可以解答文章开篇提到的问题,“不同的网络方案如何集成到 Docker 网络模型中而不改变原有结构?”

答案就是基于 libnetwork CNM,将各个网络模型以插件或 Driver 的形式集成到 Docker 网络中来,与 docker daemon 协同工作,实现容器网络。Docker 原生的 Driver 包括单主机的 none、bridge、joined container 和 多主机的 overlay、macvlan,第三方 Driver 就包括多主机的 flannel、weave、calico 等。

Docker 网络背后的原理探索

总结

  1. libnetwork 基于 CNM 模型将 Docker 网络结构从原生方案中抽离出来,增强了网络扩展性,以至于现在各种网络方案层出不穷,都可以轻松集成到 Docker 中。

  2. network,sandbox,endpoint 三个概念。


我的公众号 「Linux云计算网络」(id: cloud_dev) ,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。

Docker 网络背后的原理探索

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Stella981 Stella981
3年前
Docker 跨主机网络方案分析
本文首发于我的公众号Linux云计算网络(id:cloud\_dev),专注于干货分享,号内有10T书籍和视频资源,后台回复\\「1024」\\即可领取,欢迎大家关注,二维码文末可以扫。上篇文章介绍了容器网络的单主机网络,本文将进一步介绍多主机网络,也就是跨主机的网络。总结下来,多主机网络解决方案包括但不限于以下几种:
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这