目录

文章目录

  • 目录
  • 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 规范的几点原则:

  1. CNI Plugin 负责连接容器(Linux network namespace)。
  2. CNI 的网络定义以 JSON 的格式存储。
  3. 有关网络的配置通过 stdin(Linux 标准输入)的方式传递给 CNI Plugin,其他的参数通过 ENV(环境变量)的方式传递。
  4. CNI 插件是以 exec(可执行文件)的方式实现的。

CNI 规范定义的核心接口:

  1. ADD:将容器添加到网络;
  2. DEL:从网络中删除一个容器;
  3. CHECK:检查容器的网络是否符合预期等;
  4. etc…

CNI 对饭定义了两个组件,包括:

  1. Container Management System
  2. Network Plugin:CNI 接收到的具体请求都是由 Plugin 来完成的,例如:创建容器网络空间(network namespace)、把网络接口(interface)放到对应的网络空间、给网络接口分配 IP 等。

CNI Plugin

从 Network Plugin 实现的功能可以把 CNI Plugin 分为 5 类:

  1. Main 插件:创建具体的网络设备。有以下类型:
    2. bridge:网桥设备,连接 Container 和 Host;
    3. ipvlan:为容器增加 ipvlan 网卡;
    4. loopback:回环设备;
    5. macvlan:为容器创建一个 MAC 地址;
    6. ptp:创建一对 Veth Pair;
    7. vlan:分配一个 vlan 设备;
    8. host-device:将已存在的设备移入容器内。

  2. IPAM 插件:负责分配 IP 地址。有以下类型:

    1. dhcp:容器向 DHCP 服务器发起请求,给 Pod 发放或回收 IP 地址;
    2. host-local:使用预先配置的 IP 地址段来进行分配;
    3. static:为容器分配一个静态 IPv4/IPv6 地址,主要用于 Debug 场景。
  3. META 插件:其他功能的插件。有以下类型

    1. tuning:通过 sysctl 调整网络设备参数;
    2. portmap:通过 iptables 配置端口映射;
    3. bandwidth:使用 Token Bucket Filter 来限流;
    4. sbr:为网卡设置 source based routing;
    5. firewall:通过 iptables 给容器网络的进出流量进行限制。
  4. Windows 插件:专门用于 Windows 平台的 CNI 插件。

    1. win-bridge
    2. win-overlay 网络插件。
  5. 第三方网络插件:第三方开源的网络插件众多,每个组件都有各自的优点及适应的场景,难以形成统一的标准组件,常用有 Flannel、Calico、Cilium、OVN 网络插件。

大部分的 CN I插件功能设计上遵守功能职责单一原则,比如:

  • Bridge 插件负责网桥的相关配置;
  • Firewall 插件负责防火墙相关配置;
  • Portmap 插件负责端口映射相关配置。

因此,当网络设置比较复杂时,通常通过调用多个插件来完成。CNI 通过链式调(NetworkConfigList)用多个插件,将多个插件组合起来按顺序调用。

例如:Flannel CNI 插件配置 POD 网络时的链式调用。

Main 插件

Bridge 插件

  1. 下载源码:
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
  1. 创建 Network Namespace:
ip netns add 1234567890
  1. 新增 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
  1. 将 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": {}
}
  1. 查看 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 件事情:

  1. 收到 ADD 命令时,bin/host-device 根据命令参数,将网卡移入到指定的 Network Namespace。
  2. 收到 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。

  1. 下载 CNI:https://github.com/containernetworking/plugins/releases
  2. 把 CNI 的 binary 放置到每个 Node 的 /opt/cni/bin/。
  3. 为每个 Node 配置 kubelet:
$ vi /etc/kubernetes/kubelet
...
KUBELET_ARGS="--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
  1. 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 种实现模式:

  1. Overlay:靠隧道打通,不依赖底层网络;
  2. Underlay:靠底层网络打通,强依赖底层网络;
  3. 路由:靠路由打通,部分依赖底层网络;

常见的第三方网络插件:

  • 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 接口虚拟化技术。

  1. Veth-Pair:创建一个 Veth-Pair 对,两端分别接入到 Host root namespace(Linux Bridge / Open vSwitch)和 Container network namespace。Container 内发出的网络数据包,通过 vSwitch 进入到 Host OS Kernel Network Stack。

  2. Multi-Plexing(多路复用):使用一个 MACVLAN / IPVLAN 中间网络设备,虚拟出多个 Virtual NIC 接入到 Container,根据 MAC/IP 地址来区分数据报文如何转发到具体的容器。

  3. Hardware switching(硬件交换):SR-IOV 内部实现了一个 Hardware Switch,通过 VFs 的方式接入到每个 Pods。

Kubernetes — CNI 网络插件规范相关推荐

  1. kubelet配置cni插件_Kubernetes CNI网络插件

    CNI 容器网络接口,就是在网络解决方案由网络插件提供,这些插件配置容器网络则通过CNI定义的接口来完成,也就是CNI定义的是容器运行环境与网络插件之间的接口规范.这个接口只关心容器的网络连接,在创建 ...

  2. k8s - 如何变更CNI网络插件IP池?

    作者:justmine 头条号:大数据与云原生 微信公众号:大数据与云原生 创作不易,在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处. 为了方便阅读,微信公众号已按分类排版,后续的文 ...

  3. cni k8s 插件安装_k8s的CNI网络插件-flannel

    k8s设计了网络模型,但是把实现交给了网络插件,而CNI网络插件实现的最主要的功能就是POD跨宿主机资源互相访问 flannel安装: hdss7-21和hdss7-22 两个几点操作:wget ht ...

  4. 阿里云容器服务cni网络插件terway非官方网络性能测试

    作者:张荣滨,酷划在线后端架构师,关注微服务治理,容器化技术,Service Mesh等技术领域 terway网络性能测试 酷划在线成立于2014年,是国内激励广告行业的领军者.酷划致力于打造一个用户 ...

  5. kubernetes系列之二十:Kubernetes Calico网络插件

    一.前言 Calico作为Kubernetes的CNI插件可以支持underlay和overlay模式的网络互联:在BGP信息的交互方式上也同时支持中心服务方式和grid mesh方式:但是Calic ...

  6. kubelet配置cni插件_kubernetes网络插件对比分析(flannel、calico、weave)

    本文将在介绍技术原理和相应术语的基础上,再集中探索与详细对比目前最流行的CNI插件: Flannel Calico Weave 介绍 网络架构是Kubernetes中较为复杂.让很多用户头疼的方面之一 ...

  7. Kubemetes网络插件cni

    因为项目中需要使用k8s部署swagger服务,然后在kubectl create这一步出现了如下报错,找不到网络插件 failed to find plugin "loopback&quo ...

  8. Kubernetes网络插件对比分析(Flannel、Calico、Weave)

    文章目录 Kubernetes网络插件对比分析(Flannel.Calico.Weave) 1.Flannel 2.Calico 3.Weave 结语 Kubernetes网络插件对比分析(Flann ...

  9. 云原生|kubernetes|网络插件flannel二进制部署和calico的yaml清单部署总结版

    前言: 前面写了一些关于calico的文章,但感觉好像是浅尝辄止,分散在了几篇文章内,并且很多地方还是没有说的太清楚云原生|kubernetes|kubernetes的网络插件calico和flann ...

最新文章

  1. HashMap 详解七
  2. django 数据库迁移注意事项
  3. AB1601中使用定时器来进行延时的弊端
  4. Linux下的/bin、/sbin、/usr/bin、/usr/sbin目录
  5. UVa140 - Bandwidth
  6. 作死!研究生用实验室里的烧杯冲咖啡,喝完就进了医院抢救
  7. PS卸载不彻底,ADMUI3删除不掉怎么办
  8. Python代码实现信息轰炸
  9. HTML5网页中的链接
  10. 安装Ctex后Texstudio编译出现 LateX Error: Unknown graphics extension: .eps.解决办法
  11. 滴滴android wear,滴滴货运app下载_滴滴货运apk最新安卓版下载v5.4.0_3DM手游
  12. 在matlab上利用fft进行信号频谱分析_使用示波器进行信号频谱分析(FFT)的设置教学...
  13. 以运力平台的方式切入自动驾驶会是一条捷径吗?
  14. 以太坊 solidity在线实时编译器
  15. unity3d:ugui 长按按钮
  16. MatLab中多项式
  17. 爱思助手更新后无法连接服务器,《爱思助手》操作失败解决办法(图文)
  18. 【SQL】Sql Server SQL语句学习
  19. android判断银行卡号格式不正确,android银行卡号验证算法 android银行卡号验证算法详解...
  20. 动态规划之股票买卖系列问题

热门文章

  1. 《电子计算机机房设计规范》(GB50174-93)
  2. VirtualBox命令行VBoxManage创建与管理虚拟机教程
  3. 解决The package java.awt is not accessible问题
  4. i.MX8MP开发板移植驱动,其实可以很简单
  5. springboot生成接口文档
  6. 10大PHP开源网店系统
  7. 设计巴特沃斯滤波器实现高通滤波
  8. YOLOv5的Tricks | 【Trick7】指数移动平均(Exponential Moving Average,EMA)
  9. 根据轨道根数来计算卫星位置
  10. 2021美赛总结及常用网站