CNI -- 容器网络接口(the Container Network Interface)
什么是 CNI?
CNI(Container Network Interface,容器网络接口)是 云原生计算基金会 的一个项目,它由编写插件的规范和库组成,用于配置 Linux 容器中的网络接口,以及一些支持的插件。CNI 只关注容器的网络连接,以及在容器被删除时删除分配的资源。由于这种关注点,CNI 的支持范围很广,规范的实现也很简单。
除了 规范 之外,这个资源库还包含了用于 将 CNI 集成到应用程序中的库 的 Go 源代码,以及用于执行 CNI 插件的 命令行工具示例。另一个包含参考插件的单独的资源库和用于制作新插件的模板。
模板代码可以直接为现有的容器网络项目创建 CNI 插件。CNI 也是一个很好的框架,可以从头开始创建一个新的容器网络项目。
以下是 CNI 维护者在 KubeCon/CloudNativeCon 2019 上举办的两场会议的录音。
为什么要开发 CNI?
Linux 上的应用容器是一个快速发展的领域,而在这个领域中,网络问题并没有得到很好的解决,因为它与环境高度相关。我们相信,许多容器运行时和编排器都会寻求解决同样的问题,即使网络层可插拔。
为了避免重复,我们认为在网络插件和容器执行之间定义一个公共接口是很谨慎的:因此我们提出了这个规范,以及 Go 的库和一组插件。
谁在使用 CNI?
容器运行时
- rkt -- 容器引擎
- Kubernetes -- 一个简化容器操作的系统
- OpenShift -- 带有附加企业特性的 Kubernetes
- Cloud Foundry -- 云应用平台
- Apache Mesos -- 一个分布式系统内核
- Amazon ECS -- 高度可扩展的高性能容器管理服务
- Singularity -- 为 HPC、EPC 和 AI 优化的容器平台
- OpenSVC -- 传统和容器化应用栈的编排器
第三方插件
- Project Calico -- 第三层虚拟网络
- Weave -- 一个多主机的Docker网络
- Contiv Networking -- 针对各种用例的策略网络
- SR-IOV
- Cilium -- 容器的 BPF 和 XDP
- Infoblox -- 容器的企业 IP 地址管理
- Multus -- 一个多插件
- Romana -- 支持 Kubernetes 网络策略的第3层 CNI 插件
- CNI-Genie -- 通用 CNI 网络插件
- Nuage CNI -- 支持网络策略 kubernetes 的 Nuage Networks SDN 插件
- Silk -- 为 Cloud Foundry 设计的 CNI 插件
- Linen -- 一个 CNI 插件,设计用于 Open vSwitch 的覆盖网络,并适合 SDN/OpenFlow 网络环境。
- Vhostuser -- Dataplane 网络插件 -- 支持 OVS-DPDK 和 VPP。
- Amazon ECS CNI Plugins -- CNI 插件的集合,用于配置具有亚马逊 EC2 弹性网络接口(ENI)的容器。
- Bonding CNI -- 解决故障转移和高可用性网络的链接聚合插件。
- ovn-kubernetes -- 基于 Open vSwitch(OVS)和 Open Virtual Networking(OVN)的容器网络插件,支持 Linux 和 Windows。
- Juniper Contrail / TungstenFabric -- 提供叠加式 SDN 解决方案,提供多云网络、混合云网络、同时支持叠加-下层网络(overlay-underlay)、网络策略执行、网络隔离、服务链和灵活的负载均衡。
- Knitter -- 一个支持 Kubernetes 多网络的 CNI 插件。
- DANM -- 符合 CNI 的网络解决方案,适用于在 Kubernetes 上运行的 TelCo 工作负载。
- VMware NSX -- CNI 插件,可实现 NSX L2/L3 自动联网和 L4/L7 负载均衡;在 pod、节点和集群级别的网络隔离;以及 Kubernetes 集群的零信任安全策略。
- cni-route-override -- 一个覆盖路由信息的元 CNI 插件。
- Terway -- 基于阿里巴巴云 VPC/ECS 网络产品的 CNI 插件合集。
- Cisco ACI CNI -- 用于内部(on-prem)和云容器网络,具有一致的策略和安全模型。
- Kube-OVN -- 基于 OVN/OVS 的 CNI 插件,提供子网、静态 IP、ACL、QoS 等高级功能。
- Project Antrea -- 一个 Open vSwitch k8s CNI。
- OVN4NFV-K8S-Plugin -- 基于 OVN 的 CNI 控制器插件,提供基于云计算的原生服务功能链(SFC)、多 OVN 叠加网络。
CNI 团队还在一个单独的资源库中维护了一些 核心插件。
为 CNI 做贡献
我们欢迎大家的贡献,包括 错误报告、代码和文档的改进。如果您打算对代码或文档做出贡献,请阅读 CONTRIBUTING.md。也请参见本 README 中的联系部分。
如何使用 CNI?
使用要求
CNI 规范是语言无关的。要使用这个仓库中的 Go 语言库,你需要一个最新版本的 Go。你可以在 .travis.yaml 中找到我们的 自动测试 所覆盖的 Go 版本。
参考插件
CNI 项目维护了一套实现 CNI 规范的 参考插件。注意:参考插件曾经在这个版本库中,但从2017年5月开始,已经被拆分到一个单独的版本库中。
运行插件
构建并安装好参考插件后,可以使用 scripts/ 目录下的 priv-net-run.sh 和 docker-run.sh 脚本来行使插件。
注意 --priv-net-run.sh 依赖于 jq。
首先创建一个 netconf 文件来描述网络。
$ mkdir -p /etc/cni/net.d $ cat >/etc/cni/net.d/10-mynet.conf <<EOF { "cniVersion": "0.2.0", "name": "mynet", "type": "bridge", "bridge": "cni0", "isGateway": true, "ipMasq": true, "ipam": { "type": "host-local", "subnet": "10.22.0.0/16", "routes": [ { "dst": "0.0.0.0/0" } ] } } EOF $ cat >/etc/cni/net.d/99-loopback.conf <<EOF { "cniVersion": "0.2.0", "name": "lo", "type": "loopback" } EOF
目录 /etc/cni/net.d 是脚本寻找 net 配置的默认位置。
接下来,构建插件。
$ cd $GOPATH/src/github.com/containernetworking/plugins $ ./build_linux.sh # or build_windows.sh
最后,在已经加入 mynet 网络的私有网络命名空间中执行一个命令(本例中的 ifconfig)。
$ CNI_PATH=$GOPATH/src/github.com/containernetworking/plugins/bin $ cd $GOPATH/src/github.com/containernetworking/cni/scripts $ sudo CNI_PATH=$CNI_PATH ./priv-net-run.sh ifconfig eth0 Link encap:Ethernet HWaddr f2:c2:6f:54:b8:2b inet addr:10.22.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::f0c2:6fff:fe54:b82b/64 Scope:Link UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:1 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:1 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:90 (90.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
环境变量 CNI_PATH 告诉脚本和库在哪里寻找插件可执行文件。
使用 CNI 插件设置的网络命名空间运行一个 Docker 容器。
使用上一节的说明来定义 netconf 并构建插件。接下来,docker-run.sh 脚本包装 docker run,以便在进入容器之前执行插件。
$ CNI_PATH=$GOPATH/src/github.com/containernetworking/plugins/bin $ cd $GOPATH/src/github.com/containernetworking/cni/scripts $ sudo CNI_PATH=$CNI_PATH ./docker-run.sh --rm busybox:latest ifconfig eth0 Link encap:Ethernet HWaddr fa:60:70:aa:07:d1 inet addr:10.22.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::f860:70ff:feaa:7d1/64 Scope:Link UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:1 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:1 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:90 (90.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
CNI 未来可能做什么?
CNI 目前由于其简单的模型和 API,覆盖了网络配置的广泛需求。然而,在未来CNI可能会想向其他方向发展。
对现有网络配置进行动态更新
网络带宽和防火墙规则的动态策略
如果对这些话题感兴趣,请通过邮件列表或 IRC 联系团队,在社区里找一些志同道合的人一起提出建议。
二进制文件在哪里?
插件移到了一个单独的 repo:https://github.com/containernetworking/plugins,那里发布的版本包括二进制文件和校验和。
在发布 0.7.0 之前,cni 版本还包括一个 cnitool 二进制文件;由于这是一个开发者工具,我们建议您自己构建。
联系我们
关于 CNI 的任何问题,请通过以下方式联系我们。
电子邮件:cni-dev
IRC: freenode.net 上的 #containernetworking 频道。
Slack: CNCF slack 上的 #cni。注意:之前的 CNI Slack (con containernetworking.slack.com) 已被取消。
如果您有安全问题要报告,请私下向 MAINTAINERS 文件中列出的电子邮件地址报告。
(The first version translated by vz on 2020.09.24)