阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Docker的网络-Container network interface(CNI)与Container network model(CNM)

129次阅读
没有评论

共计 3354 个字符,预计需要花费 9 分钟才能阅读完成。

Overview

目前围绕着 docker 的网络,目前有两种比较主流的声音,docker 主导的 Container network model(CNM)和社区主导的 Container network interface(CNI)。本文就针对两者模型进行分别介绍。

Container Networking Interface

概述

Container Networking Interface(CNI)提供了一种 linux 的应用容器的插件化网络解决方案。最初是由 rkt Networking Proposal 发展而来。也就是说,CNI 本身并不完全针对 docker 的容器,而是提供一种普适的容器网络解决方案。因此他的模型只涉及两个概念:

  • 容器(container) : 容器是拥有独立 linux 网络命名空间的独立单元。比如 rkt/docker 创建出来的容器。

这里很关键的是容器需要拥有自己的 linux 网络命名空间。这也是加入网络的必要条件。

  • 网络 (network): 网络指代了可以相互联系的一组实体。这些实体拥有各自独立唯一的 ip。这些实体可以是容器,是物理机,或者其他网络设备(比如路由器) 等。

接口及实现

CNI 的接口设计的非常简洁,只有两个接口 ADD/DELETE。

以 ADD 接口为例

Add container to network

参数主要包括:

  • Version. CNI 版本号
  • Container ID. 这是一个可选的参数,提供容器的 id
  • Network namespace path. 容器的命名空间的路径,比如 /proc/[pid]/ns/net。
  • Network configuration. 这是一个 json 的文档,具体可以参看 network-configuration
  • Extra arguments. 其他参数
  • Name of the interface inside the container. 容器内的网卡名

返回值:

  • IPs assigned to the interface. ipv4 或者 ipv6 地址
  • DNS information. DNS 相关信息

调用实现

CNI 的调用方式是通过一个可执行文件进行的。这里以 calico 为例,说明 CNI 插件的调用方式。

首先,calico 进行插件注册

mkdir -p /etc/cni/net.d
$ cat >/etc/cni/net.d/10-calico.conf <<EOF
{"name": "calico-k8s-network",
    "type": "calico",
    "etcd_authority": "<ETCD_IP>:<ETCD_PORT>",
    "log_level": "info",
    "ipam": {
        "type": "calico-ipam"
    },
    "policy": {
        "type": "k8s"
    }
}
EOF

k8s 的 DefaultCNIDir 是 /opt/cni/bin。因为注册的typecalico,所以 k8s 会从 /opt/cni/bin 中搜索一个 calico 的可执行文件,然后进行执行。

执行的时候传递参数有两种方式,一种是通过环境变量进行传递,比如上文中的 VersionContainer ID 等;另外一种是通过执行 calico 作为执行的参数传进去,这个主要就是 Network configuration 的部分,通过 json 将其打包传入。

同样判断是否执行成功,是通过执行文件的返回值获取的。0 为成功,1 为版本版本不匹配,2 为存在不符合的字段。如果执行成功,返回值将通过 stdout 返回。

Container Network Model

概述

相较于 CNI,CNM 是 docker 公司力推的网络模型。其主要模型如下图:

Docker 的网络 -Container network interface(CNI)与 Container network model(CNM)

Sandbox

Sandbox 包含了一个容器的网络栈。包括了管理容器的网卡,路由表以及 DNS 设置。一种 Sandbox 的实现是通过 linux 的网络命名空间,一个 FreeBSD Jail 或者其他类似的概念。一个 Sandbox 可以包含多个 endpoints。

Endpoint

一个 endpoint 将 Sandbox 连接到 network 上。一个 endpoint 的实现可以通过 veth pair,Open vSwitch internal port 或者其他的方式。一个 endpoint 只能属于一个 network,也只能属于一个 sandbox。

Network

一个 network 是一组可以相互通信的 endpoints 组成。一个 network 的实现可以是 linux bridge,vlan 或者其他方式。一个网络中可以包含很多个 endpoints。

接口

CNM 的接口相较于 CNI 模型,较为复杂。其提供了 remote plugin 的方式,进行插件化开发。remote plugin 相较与 CNI 的命令行,更加友好一些,是通过 http 请求进行的。remote plugin 监听一个指定的端口,docker daemon 直接通过这个端口与 remote plugin 进行交互。

鉴于 CNM 的接口较多,这里就不一一展开解释了。这里主要介绍下在进行 docker 的操作中,docker daemon 是如何同 CNM 插件繁盛交互。

调用过程

Create Network

这一系列调用发生在使用 docker network create 的过程中。

  1. /IpamDriver.RequestPool: 创建 subnetpool 用于分配 IP
  2. /IpamDriver.RequestAddress: 为 gateway 获取 IP
  3. /NetworkDriver.CreateNetwork: 创建 neutron network 和 subnet

Create Container

这一系列调用发生在使用 docker run,创建一个 contain 的过程中。当然,也可以通过docker network connect 触发。

  1. /IpamDriver.RequestAddress: 为容器获取 IP
  2. /NetworkDriver.CreateEndpoint: 创建 neutron port
  3. /NetworkDriver.Join: 为容器和 port 绑定
  4. /NetworkDriver.ProgramExternalConnectivity:
  5. /NetworkDriver.EndpointOperInfo

Delete Container

这一系列调用发生在使用 docker delete,删除一个 contain 的过程中。当然,也可以通过docker network disconnect 触发。

  1. /NetworkDriver.RevokeExternalConnectivity
  2. /NetworkDriver.Leave: 容器和 port 解绑
  3. /NetworkDriver.DeleteEndpoint
  4. /IpamDriver.ReleaseAddress: 删除 port 并释放 IP

Delete Network

这一系列调用发生在使用 docker network delete 的过程中。

  1. /NetworkDriver.DeleteNetwork: 删除 network
  2. /IpamDriver.ReleaseAddress: 释放 gateway 的 IP
  3. /IpamDriver.ReleasePool: 删除 subnetpool

CNI 与 CNM 的转化

CNI 和 CNM 并非是完全不可调和的两个模型。二者可以进行转化。比如 calico 项目就是直接支持两种接口模型。

从模型中来看,CNI 中的 container 应与 CNM 的 sandbox 概念一致,CNI 中的 network 与 CNM 中的 network 一致。在 CNI 中,CNM 中的 endpoint 被隐含在了 ADD/DELETE 的操作中。CNI 接口更加简洁,把更多的工作托管给了容器的管理者和网络的管理者。从这个角度来说,CNI 的 ADD/DELETE 接口其实只是实现了 docker network connectdocker network disconnect两个命令。

kubernetes/contrib 项目提供了一种从 CNI 向 CNM 转化的过程。其中原理很简单,就是直接通过 shell 脚本执行了 docker network connectdocker network disconnect命令,来实现从 CNI 到 CNM 的转化。

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-10/147496.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计3354字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中