摘要:本文将描述以下内容框架模的实现原理框架模型下的网络模型如上所示。的一种典型实现是。将这些加入到,即实现了多个的互通。注意三种接口都有其对应的实现如接口的实现为。而插件型的是运行在上,通过通道与之间进行通信。
简介
Libnetwork是从docker1.6开始,逐渐将docker项目中的网络部分抽离出来形成的Lib,作用是为其他应用程序(如docker engine)提供一套抽象的容器网络模型,该模型也被称为Container Network Model,简称CNM。本文将描述以下内容
CNM框架模
Libnetwork的实现原理
plugin demo
CNM 框架
CNM模型下的docker网络模型如上所示。它由Sandbox, Endpoint, Network 三种组件组成。注意,该模型只是规定了三种组件各自的作用,他们都有各自的具体实现方式。
Sandbox: Sandbox包含了一个Container的网络相关的配置,如网卡Interface,路由表等。Sandbox在Linux上的典型实现是Network namespace。在Linux系统上的docker环境中,Container,Network namespace,Sandbox 这三者是绑定在一起的。一个Sandbox可以包含多个Endpoint,这些Endpoint 可以来自多个Network
Endpoint: Sandbox加入Network的方式是通过Endpoint完成的。Endpoint的典型实现方式是veth pair,每个Endpoint 都是由某个Network创建,创建后,它就归属于该Network,同时,Endpoint还可以加入(Join)一个Sandbox,加入后,相当于该Sandbox也加入了此Network。
Network:Network的一种典型实现是Linux bridge。一个Network可以创建多个Endpoint。将这些Endpoint加入到Sandbox,即实现了多个Sandbox的互通。
总结起来:如果要想两个Container之间可以直接通信,那么最简单的办法就是由一个Network创建两个Endpoint,分别加入这两个Container对应的Sandbox。
注意: 不同Network之间默认的隔离性是docker通过设置iptables完成的,通过改变iptables的设置,可以使得两个Network互通。
Libnetwork 实现 核心对象LibNetwork是CNM框架的实现,Network、Sandbox、Endpoint三种接口描述了前面的三种组件,三种接口分别在network.go 、sandbox.go 、 endpoint.go实现
三个接口需要实现的方法的关系如上图所示。注意:三种接口都有其对应的实现(如Network接口的实现为network)。
NetworkController 为 docker engine提供创建Network的API,比如我们在使用命令 docker network create 创建网络时,都是通过controller创建。
除此之外NetworkController接口的实现结构controller还维护了一张Driver的注册表(Registry),它记录了所有支持的Driver
Driver 每个Network都有对应的底层Driver,这些Driver负责在主机上真正实现需要网络功能(如创建Veth设备)。Driver有两种类型:1. 内置型(如Bridge Host None) 2. 插件型。
无论是哪种类型,其工作方式都类似,docker engine发送请求,Libnetwork做一些框架性的动作,然后将请求传给Driver做一些特异性的动作。两者的差别在于,内置性的Driver是内置在Libnetwork内部,它们也就是docker原生支持的网络类型。而插件型的Driver是运行在Host上,通过socket通道与Libnetwork之间进行通信。
在 controller.go 中的 New() 是创建controller的入口。
func New(cfgOptions ...config.Option) (NetworkContriller, error) { c := controller{ id: stringid.GenerateRandomID(); sandboxes: sandboxTable{}, ..... } drvRegistry, err := drvregistry.New(......) for _, i := range getInitizers(c.cfg.Daemon.Experimental){ drvRegistry.AddDriver(i.ntype,i.fn, dcfg) } c.drvRegistry = drvRegistry }
可以看到,首先是创建controller,此外 它还创建了drvRegistry记录注册的Driver,并将 getInitizers() 的返回内置型的 Driver 添加到 drvRegistry 上。
func getInitializers(experimental bool) []initialize { return []initializer { {bridge.Init, "bridge"}, {host.Init, "host"}, {macvlan.Init, "macvlan"}, {null.Init, "null"}, {remote.Init, "remote"}, {overlay.Init, "overlay"}, ...... } }
getInitizers() 包含的内置型Driver如上图所示,其中的每一项的Init()方法会被调用
创建网络
创建 network 的入口NewNetwork()同样在controller.go中,它首先创建一个通用的 network 结构,进而解析出 其Driver 类型,然后调用特定 Driver 的 CreateNetwork() 方法。注意,如果是该网络的类型不在 drvRegistry 上,则 Libnetwork 会尝试从 Plugin 路径 (/var/run/docker/plugins) 寻找 plugin-name.sock .之后,向该 socket 发送创建网络的 request
以 bridge 为例,其最后会调用到 drivers/bridge/bridge.go 的 createNetwork() 方法,该方法中,使用netlink提供的接口建立了 bridge net device
容器加入在使用 docker run 启动容器时可以通过指定 -net 参数将容器连接到特定的网络。入口是 docker 项目中的 container_operations.go 的 connectToNetwork() 方法
图中左侧部分是属于 docker engine ,中间部分属于 Libnetwork , 右侧部分属于 Driver 。可以它首先创建Endpoint,创建 Sandbox 和 Endpoint,然后将 Endpoint 加入该 Sandbox 。
Plugin Demo将 docker 原生 Bridge 网络的功能插件化,制作名为 myPlugin 的网络插件,效果和原生的 Bridge 一样.
Code
root@sb:/home/yc# ls -l /run/docker/plugins/ total 0 srw-rw---- 1 root root 0 8月 26 14:41 myplugin.sock root@sb:/home/yc# docker network create --driver myplugin mynet 460db416c6f90fb16c499c5fd56b5e984d6472a113f5d8ed3f8633174159aa53 root@sb:/home/yc# docker network ls NETWORK ID NAME DRIVER SCOPE 6f5763ae335d bridge bridge local 71d355df68ec host host local 460db416c6f9 mynet myplugin local 91360b8a5fe4 none null local docker run -tid --net=mynet busybox 617a314c4f69f835ab1a4e5cf9ce211a55e4651be4fa47e4ebd849c34c192e9d root@sb:/home/yc# docker network inspect mynet [ { "Name": "mynet", "Id": "460db416c6f90fb16c499c5fd56b5e984d6472a113f5d8ed3f8633174159aa53", "Created": "2018-08-26T14:42:51.998760172+08:00", "Scope": "local", "Driver": "myplugin", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "617a314c4f69f835ab1a4e5cf9ce211a55e4651be4fa47e4ebd849c34c192e9d": { "Name": "gallant_wozniak", "EndpointID": "90ce305bea6a2054ee953f6fcebd0d23c94058026ac594d686f4d731464d45d8", "MacAddress": "", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/27531.html
摘要:网络结构上图为的网络模型,大体上可分为和两个组件其中运行在每台宿主机上主要负责与交互实现插件逻辑配置底层进程实现具体的网络功能组件是与交互的核心逻辑以常用的为例该逻辑即是实现框架下所规定的种种接口实现与的消息交互关于和请查看与框架与实现同 Contiv网络结构 showImg(https://segmentfault.com/img/remote/1460000017001034?w=...
摘要:网络主要是单机网络和多主机通信模式。下面分别介绍一下的各个网络模式。设计的网络模型。是以对定义的元数据。用户可以通过定义这样的元数据来自定义和驱动的行为。 前言 理解docker,主要从namesapce,cgroups,联合文件,运行时(runC),网络几个方面。接下来我们会花一些时间,分别介绍。 docker系列--namespace解读 docker系列--cgroups解读 ...
摘要:网络主要是单机网络和多主机通信模式。下面分别介绍一下的各个网络模式。设计的网络模型。是以对定义的元数据。用户可以通过定义这样的元数据来自定义和驱动的行为。 前言 理解docker,主要从namesapce,cgroups,联合文件,运行时(runC),网络几个方面。接下来我们会花一些时间,分别介绍。 docker系列--namespace解读 docker系列--cgroups解读 ...
摘要:网络主要是单机网络和多主机通信模式。下面分别介绍一下的各个网络模式。设计的网络模型。是以对定义的元数据。用户可以通过定义这样的元数据来自定义和驱动的行为。 前言 理解docker,主要从namesapce,cgroups,联合文件,运行时(runC),网络几个方面。接下来我们会花一些时间,分别介绍。 docker系列--namespace解读 docker系列--cgroups解读 ...
阅读 2176·2021-11-24 09:38
阅读 3240·2021-11-08 13:27
阅读 3081·2021-09-10 10:51
阅读 3141·2019-08-29 12:20
阅读 661·2019-08-28 18:28
阅读 3458·2019-08-26 11:53
阅读 2703·2019-08-26 11:46
阅读 1514·2019-08-26 10:56