Kubernetes — CNI 网络插件规范
目录
文章目录
- 目录
- CNI
- CNI 规范
- CNI Plugin
- Main 插件
- Bridge 插件
- HOST-DEVICE
- MACVLAN
- 第三方网络插件
- CNI 使用的 I/O 接口虚拟化
CNI
Kubernetes 本身并没有实现自己的容器网络,而是借助 CNI 标准,通过插件化的方式来集成各种网络插件,实现集群内部网络相互通信。
CNI(Container Network Interface,容器网络的 API 接口),是 Google 和 CoreOS 联合定制的网络标准,它是在 RKT 网络提议的基础上发展起来的,综合考虑了灵活性、扩展性、IP 分配、多网卡等因素。Kubernetes 网络的发展方向是希望通过 Plugin 的方式来集成不同的网络方案, CNI 就是这一努力的结果。
CNI 旨在为容器平台提供网络的标准化,为解决容器网络连接和容器销毁时的资源释放,提供了一套框架。所以 CNI 可以支持大量不同的网络模式,并且容易实现。不同的容器平台(e.g. Kubernetes、Mesos 和 RKT)能够通过相同的接口调用不同的网络组件。
CNI 规范
CNI 规范的几点原则:
- CNI Plugin 负责连接容器(Linux network namespace)。
- CNI 的网络定义以 JSON 的格式存储。
- 有关网络的配置通过 stdin(Linux 标准输入)的方式传递给 CNI Plugin,其他的参数通过 ENV(环境变量)的方式传递。
- CNI 插件是以 exec(可执行文件)的方式实现的。
CNI 规范定义的核心接口:
- ADD:将容器添加到网络;
- DEL:从网络中删除一个容器;
- CHECK:检查容器的网络是否符合预期等;
- etc…
CNI 对饭定义了两个组件,包括:
- Container Management System
- Network Plugin:CNI 接收到的具体请求都是由 Plugin 来完成的,例如:创建容器网络空间(network namespace)、把网络接口(interface)放到对应的网络空间、给网络接口分配 IP 等。
CNI Plugin
从 Network Plugin 实现的功能可以把 CNI Plugin 分为 5 类:
Main 插件:创建具体的网络设备。有以下类型:
2. bridge:网桥设备,连接 Container 和 Host;
3. ipvlan:为容器增加 ipvlan 网卡;
4. loopback:回环设备;
5. macvlan:为容器创建一个 MAC 地址;
6. ptp:创建一对 Veth Pair;
7. vlan:分配一个 vlan 设备;
8. host-device:将已存在的设备移入容器内。IPAM 插件:负责分配 IP 地址。有以下类型:
- dhcp:容器向 DHCP 服务器发起请求,给 Pod 发放或回收 IP 地址;
- host-local:使用预先配置的 IP 地址段来进行分配;
- static:为容器分配一个静态 IPv4/IPv6 地址,主要用于 Debug 场景。
META 插件:其他功能的插件。有以下类型
- tuning:通过 sysctl 调整网络设备参数;
- portmap:通过 iptables 配置端口映射;
- bandwidth:使用 Token Bucket Filter 来限流;
- sbr:为网卡设置 source based routing;
- firewall:通过 iptables 给容器网络的进出流量进行限制。
Windows 插件:专门用于 Windows 平台的 CNI 插件。
- win-bridge
- win-overlay 网络插件。
第三方网络插件:第三方开源的网络插件众多,每个组件都有各自的优点及适应的场景,难以形成统一的标准组件,常用有 Flannel、Calico、Cilium、OVN 网络插件。
大部分的 CN I插件功能设计上遵守功能职责单一原则,比如:
- Bridge 插件负责网桥的相关配置;
- Firewall 插件负责防火墙相关配置;
- Portmap 插件负责端口映射相关配置。
因此,当网络设置比较复杂时,通常通过调用多个插件来完成。CNI 通过链式调(NetworkConfigList)用多个插件,将多个插件组合起来按顺序调用。
例如:Flannel CNI 插件配置 POD 网络时的链式调用。
Main 插件
Bridge 插件
- 下载源码:
cd cni/
curl -O -L https://github.com/containernetworking/cni/releases/download/v0.4.0/cni-amd64-v0.4.0.tgz
tar -xzvf cni-amd64-v0.4.0.tgz
- 创建 Network Namespace:
ip netns add 1234567890
- 新增 CNI Bridge Plugin 的配置文件:
cat > mybridge.conf <<"EOF"
{"cniVersion": "0.2.0", # CNI 规范的版本"name": "mybridge", # 网络的名字"type": "bridge", # 使用 CNI 的 Bridge Plugin"bridge": "cni_bridge0","isGateway": true, # 如果是 true,为网桥分配 IP 地址,以便连接到它的容器可以将其作为网关。"ipMasq": true, # 在插件支持的情况下,设置 IP 伪装。"hairpinMode":true, # 让网络设备能够让数据包从一个端口发进来一个端口发出去。"ipam": {"type": "host-local", # IPAM 可执行文件的名字。"subnet": "10.15.20.0/24", # 要分配给容器的子网。"routes": [ # 子网路由。{ "dst": "0.0.0.0/0" },{ "dst": "1.1.1.1/32", "gw":"10.15.20.1"}]}
}
EOF
- 将 Pod Network 加入到 Network Namespace 中:
$ cd cni
$ CNI_COMMAND=ADD
$ CNI_CONTAINERID=1234567890
$ CNI_NETNS=/var/run/netns/1234567890
$ CNI_IFNAME=eth12
$ CNI_PATH=`pwd`
$ .cni/bin/bridge < mybridge.conf
2020/03/02 22:14:57 Error retriving last reserved ip: Failed to retrieve last reserved ip: open /var/lib/cni/networks/mybridge/last_reserved_ip: no such file or directory
{"ip4": {"ip": "10.15.20.2/24","gateway": "10.15.20.1","routes": [{"dst": "0.0.0.0/0"},{"dst": "1.1.1.1/32","gw": "10.15.20.1"}]},"dns": {}
}
- 查看 Network Namespace 的网络配置:
$ ip netns exec 1234567890 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: eth12@if1137099: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/ether 0a:58:0a:0f:14:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 10.15.20.2/24 scope global eth12valid_lft forever preferred_lft foreverinet6 fe80::34da:9fff:febe:f332/64 scope linkvalid_lft forever preferred_lft forever$ ip netns exec 1234567890 route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.15.20.1 0.0.0.0 UG 0 0 0 eth12
1.1.1.1 10.15.20.1 255.255.255.255 UGH 0 0 0 eth12
10.15.20.0 0.0.0.0 255.255.255.0 U 0 0 0 eth12$ ip netns exec 1234567890 ifconfig
eth12: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 10.15.20.2 netmask 255.255.255.0 broadcast 0.0.0.0inet6 fe80::34da:9fff:febe:f332 prefixlen 64 scopeid 0x20<link>ether 0a:58:0a:0f:14:02 txqueuelen 0 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 9 bytes 738 (738.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
HOST-DEVICE
host-device CNI 的作用就是把 Physical Network Interface 直接交给 Pod 使用。
实现很简单,做了 2 件事情:
- 收到 ADD 命令时,bin/host-device 根据命令参数,将网卡移入到指定的 Network Namespace。
- 收到 DEL 命令时,bin/host-device 根据命令参数,将网卡从指定的 Network Namespace 移出到 Root Namespace。
原理也比较简单,使用下述指令就可以做到,将 dev “移动” 到指定的 Network Namespace 中:
$ ip a
...
3: ens8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000link/ether 52:54:00:5e:1f:f5 brd ff:ff:ff:ff:ff:ff$ ip netns add test$ ip link set dev ens8 netns test$ ip netns exec test ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000link/ipip 0.0.0.0 brd 0.0.0.0
3: ens8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000link/ether 52:54:00:5e:1f:f5 brd ff:ff:ff:ff:ff:ff
- 新增 host-device CNI 的配置文件:
cat > myhost-device.conf <<"EOF"
{"cniVersion": "0.3.1","type": "host-device","device": "ens8","name": "host"
}
EOF
- 使用 host-device CNI 将 host-device 加到 Network Namespace 中:
export CNI_COMMAND=ADD
export CNI_NETNS=/var/run/netns/test
export CNI_IFNAME=eth0
export CNI_ARGS
export CNI_PATH=/opt/cni/bin
export CNI_CONTAINERID="aaa" $ /opt/cni/bin/host-device < myhost-device.conf$ ip netns exec test ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000link/ipip 0.0.0.0 brd 0.0.0.0
3: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000link/ether 52:54:00:5e:1f:f5 brd ff:ff:ff:ff:ff:ff
MACVLAN
MACVLAN 是 Linux Kernel 比较新的特性,允许在主机的一个网络接口上配置多个虚拟的网络接口,这些网络 interface 有自己独立的 MAC 地址,也可以配置上 IP 地址进行通信。macvlan 下的虚拟机或者容器网络和主机在同一个网段中,共享同一个广播域。macvlan 和 bridge 比较相似,但因为它省去了 bridge 的存在,所以配置和调试起来比较简单,而且效率也相对高。除此之外,macvlan 自身也完美支持 VLAN。
基于 Linux Kernel MACVLAN feature,将 VNI 子接口交给 Pod 使用,作为 Pod Network Namespace 的一个 Interface。
- 下载 CNI:https://github.com/containernetworking/plugins/releases
- 把 CNI 的 binary 放置到每个 Node 的 /opt/cni/bin/。
- 为每个 Node 配置 kubelet:
$ vi /etc/kubernetes/kubelet
...
KUBELET_ARGS="--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
- MACVLAN CNI 的配置文件:
{"name": "macvlannet","type": "macvlan","master": "ens33","mode": "vepa","isGateway": true,"ipMasq": false,"ipam": {"type": "host-local","subnet": "192.168.166.0/24","rangeStart": "192.168.166.21","rangeEnd": "192.168.166.29","gateway": "192.168.166.2","routes": [{ "dst": "0.0.0.0/0" }]}
}
第三方网络插件
CNI 第三方网络插件通常有 3 种实现模式:
- Overlay:靠隧道打通,不依赖底层网络;
- Underlay:靠底层网络打通,强依赖底层网络;
- 路由:靠路由打通,部分依赖底层网络;
常见的第三方网络插件:
Calico(性能好、灵活性最强,目前的企业级主流):是一个基于 BGP 路由协议的纯 L3 的数据中心网络方案(不需要 Overlay),提供简单,可扩展的网络。除了可扩展的网络, Calico 还提供策略隔离。
Flannel(最成熟、最简单的选择):基于 Linux TUN/TAP,使用 UDP 封装 IP 数据包的方式来创建 Overlay 网络,并借助 etcd 来维护网络资源的分配情况,是一种简单易用的 Overlay 网络方案。
Weave:支持多主机容器网络,可以跨越不同的云网络配置。独有的功能,是对整个网络的简单加密,会增加网络开销。
Cilium:是一个开源软件,基于 Linux Kernel BPF 技术,可以在 Linux Kernel 内部动态地插入具有安全性、可见性的网络控制逻辑。
kopeio-networking:是专为 Kubernetes 而设计的网络方案,充分利用了 Kubernetes API,因此更简单,更可靠。
kube-router:也是专为 Kubernetes 打造的专用网络解决方案,旨在提供操作简单性和性能。
CNI 插件项目 Forks 数量比较:
CNI 插件项目 10Gbit 网络下的 CPU 消耗比较:
CNI 使用的 I/O 接口虚拟化
根据 CNI 插件不同的实现方式,也会使用到不同的 I/O 接口虚拟化技术。
Veth-Pair:创建一个 Veth-Pair 对,两端分别接入到 Host root namespace(Linux Bridge / Open vSwitch)和 Container network namespace。Container 内发出的网络数据包,通过 vSwitch 进入到 Host OS Kernel Network Stack。
Multi-Plexing(多路复用):使用一个 MACVLAN / IPVLAN 中间网络设备,虚拟出多个 Virtual NIC 接入到 Container,根据 MAC/IP 地址来区分数据报文如何转发到具体的容器。
Hardware switching(硬件交换):SR-IOV 内部实现了一个 Hardware Switch,通过 VFs 的方式接入到每个 Pods。
Kubernetes — CNI 网络插件规范相关推荐
- kubelet配置cni插件_Kubernetes CNI网络插件
CNI 容器网络接口,就是在网络解决方案由网络插件提供,这些插件配置容器网络则通过CNI定义的接口来完成,也就是CNI定义的是容器运行环境与网络插件之间的接口规范.这个接口只关心容器的网络连接,在创建 ...
- k8s - 如何变更CNI网络插件IP池?
作者:justmine 头条号:大数据与云原生 微信公众号:大数据与云原生 创作不易,在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处. 为了方便阅读,微信公众号已按分类排版,后续的文 ...
- cni k8s 插件安装_k8s的CNI网络插件-flannel
k8s设计了网络模型,但是把实现交给了网络插件,而CNI网络插件实现的最主要的功能就是POD跨宿主机资源互相访问 flannel安装: hdss7-21和hdss7-22 两个几点操作:wget ht ...
- 阿里云容器服务cni网络插件terway非官方网络性能测试
作者:张荣滨,酷划在线后端架构师,关注微服务治理,容器化技术,Service Mesh等技术领域 terway网络性能测试 酷划在线成立于2014年,是国内激励广告行业的领军者.酷划致力于打造一个用户 ...
- kubernetes系列之二十:Kubernetes Calico网络插件
一.前言 Calico作为Kubernetes的CNI插件可以支持underlay和overlay模式的网络互联:在BGP信息的交互方式上也同时支持中心服务方式和grid mesh方式:但是Calic ...
- kubelet配置cni插件_kubernetes网络插件对比分析(flannel、calico、weave)
本文将在介绍技术原理和相应术语的基础上,再集中探索与详细对比目前最流行的CNI插件: Flannel Calico Weave 介绍 网络架构是Kubernetes中较为复杂.让很多用户头疼的方面之一 ...
- Kubemetes网络插件cni
因为项目中需要使用k8s部署swagger服务,然后在kubectl create这一步出现了如下报错,找不到网络插件 failed to find plugin "loopback&quo ...
- Kubernetes网络插件对比分析(Flannel、Calico、Weave)
文章目录 Kubernetes网络插件对比分析(Flannel.Calico.Weave) 1.Flannel 2.Calico 3.Weave 结语 Kubernetes网络插件对比分析(Flann ...
- 云原生|kubernetes|网络插件flannel二进制部署和calico的yaml清单部署总结版
前言: 前面写了一些关于calico的文章,但感觉好像是浅尝辄止,分散在了几篇文章内,并且很多地方还是没有说的太清楚云原生|kubernetes|kubernetes的网络插件calico和flann ...
最新文章
- HashMap 详解七
- django 数据库迁移注意事项
- AB1601中使用定时器来进行延时的弊端
- Linux下的/bin、/sbin、/usr/bin、/usr/sbin目录
- UVa140 - Bandwidth
- 作死!研究生用实验室里的烧杯冲咖啡,喝完就进了医院抢救
- PS卸载不彻底,ADMUI3删除不掉怎么办
- Python代码实现信息轰炸
- HTML5网页中的链接
- 安装Ctex后Texstudio编译出现 LateX Error: Unknown graphics extension: .eps.解决办法
- 滴滴android wear,滴滴货运app下载_滴滴货运apk最新安卓版下载v5.4.0_3DM手游
- 在matlab上利用fft进行信号频谱分析_使用示波器进行信号频谱分析(FFT)的设置教学...
- 以运力平台的方式切入自动驾驶会是一条捷径吗?
- 以太坊 solidity在线实时编译器
- unity3d:ugui 长按按钮
- MatLab中多项式
- 爱思助手更新后无法连接服务器,《爱思助手》操作失败解决办法(图文)
- 【SQL】Sql Server SQL语句学习
- android判断银行卡号格式不正确,android银行卡号验证算法 android银行卡号验证算法详解...
- 动态规划之股票买卖系列问题