Docker网络背后的原理探究

转子:https://www.cnblogs.com/bakari/p/8971772.html

Docker默认的网络环境下,单台主机上的Docker容器可以通过docker0网桥直接通信,而不同主机上的Docker容器之间只能通过在主机上做端口映射进行通信。这种端口映射方式对很多集群应用来说极不方便。如果能让Docker容器之间直接使用自己的IP地址进行通信,会解决很多问题。按实现原理可分别直接路由方式、桥接方式(如pipework)、Overlay隧道方式(如flannelovs+gre)等。

在单主机环境下有四种网络模式:

主要看两种:Nat网络和Host网络模式

在Nat网络模式下,是一些私网,容器不能直接跨主机通信!

Host模式下容器公用主机的网络!

 

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

通过前面两篇文章,我们知道了容器的单主机网络和多主机网络,对于这么多网络方案,我们看到对 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 中。

 

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 等。

总结

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

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

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Docker网络原理可以分为四种工作方式:桥接网络、主机网络、容器网络和无网络模式。其中,桥接网络是默认的网络模式,Docker守护程序将容器连接到docker0网络,除非使用--network选项指定其他网络模式。主机网络模式允许容器与主机共享网络栈,容器可以直接访问主机的网络资源。容器网络模式则是在容器内部创建一个虚拟网络,容器之间可以通过虚拟网络进行通信。无网络模式是指将容器与任何网络隔离,容器之间无法通信也无法访问外部网络。 此外,在Docker的1.8版本中引入了一个称为overlay的新网络模式,它是在1.7版本中对网络部分进行了重构后加入的。这个overlay网络模式可以实现在多个主机上的容器之间进行通信,提供了更高级的网络功能。总的来说,Docker网络原理涵盖了不同的网络模式,可以根据实际需求选择合适的网络配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Docker网络详解——原理篇](https://blog.csdn.net/meltsnow/article/details/94490994)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值