用bash实现一个kubernets CNI
Network plugin(Org/CN)
Kubernetes Networking: How to Write Your Own CNI Plug-in with Bash
(github)
很多人想更深入的了解kubernets的网络
- 部署到不同物理节点的Pod如何使用从单个子网分配的IP地址直接相互通信
- Kubernetes服务如何工作
- 如何实现负载平衡
- 如何实施网络策略
- Kubernetes覆盖网络增加了多少开销
本文计划:
- 首先讨论Kubernetes网络模型以及CNI插件如何适配他。
- 然后,尝试编写一个简单的CNI插件,该插件负责实现Kubernetes覆盖网络,以及在Pod中分配和配置网络接口。
- 部署Kubernetes集群并将其配置为使用CNI插件。
- 此过程中,将讨论所有相关网络概念来理解插件如何工作的。
涉及到的基本知识
Kubernetes网络的模型
三个基本要求:
- 所有容器都可以直接相互通信而无需NAT。
- 所有节点都可以在没有NAT的情况下与所有容器通信(反之亦然)。
- 容器所看到的IP与其他人所看到的IP是相同的。
CNI插件
Kubernetes网络模型的另一个问题是它没有单一的标准实现。取而代之的是,首选的实现很大程度上取决于群集的部署环境。因此,Kubernetes团队决定将这种方法外部化,并将将网络模型的实现任务交给CNI插件。
CNI插件负责将网络接口分配给新创建的容器。 Kubernetes首先创建一个没有网络接口的容器,然后调用CNI插件。该插件配置容器网络并返回有关分配的网络接口,IP地址等的信息。Kubernetes发送给CNI插件的参数以及响应的结构必须满足CNI规范,但是插件本身可能会做任何需要做的事情。
配置CNI插件
几个基本设计原则:
Plugins是可执行文件
- 提供基本的命令: ADD, DEL, CHECK and VERSION
- runtime在需要网络操作的时候启动插件
- 通过stdin传入JSON 格式的配置
- 通过stdin传入container-specific的数据
- 通过stdout返回数据。
现在,我们准备开始配置插件。 您应该做的第一件事是创建插件配置。 将以下文件另存为/etc/cni/net.d/10-bash-cni-plugin.conf。
{ "cniVersion": "0.3.1", "name": "mynet", "type": "bash-cni", "network": "10.244.0.0/16", "subnet": "<node-cidr-range>" }
这必须在主节点和辅助节点上都进行。 别忘了将<node-cidr-range>替换为master的10.244.0.0/24和worker的10.244.1.0./24。 将文件放入/etc/cni/net.d/文件夹也很重要。 kubelet使用此文件夹发现CNI插件。
现在,让我们自己创建插件。 插件的可执行文件必须放在/ opt / cni / bin /文件夹中,其名称必须与插件配置(bash-cni)中的type参数完全相同,并且其内容在 这个GiHub。 (将插件放置在正确的文件夹中后,请不要忘记通过运行sudo chmod + x bash-cni使其可执行。)在主虚拟机和辅助虚拟机上均应执行此操作。
Golang example
package skel provides skeleton code for a CNI plugin, In particular, it implements argument parsing and validation. 提供解析环境变量函数getCmdArgsFromEnv, 并提供了一个调用plugin的主入口函数PluginMain, 该函数要求提供ADD,DEL,CHECK和VERSION的回调函数。比如intel的multus plugin提供了cmdAdd来处理ADD操作。
Kubelet 调用plugin
network cni 提供了各种库如(skel/libcin等)用来编写插件以配置Linux容器中的网络接口, 并定了相应的规范。 CNI仅涉及容器的网络连接以及删除容器时删除分配的资源。 由于这种关注,CNI具有广泛的支持,并且该规范易于实现。
kubelet的network package 提供了InitNetworkPlugin 来调用这些plugin。
libcni 提供了网络接口的基本的库。
type CNI interface { AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error) CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error DelNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error GetNetworkListCachedResult(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error) GetNetworkListCachedConfig(net *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error) AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error) ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error) ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error) }
kubelet/app/server.go 在运行的时候,run 会调用 PreInitRuntimeService -> NewDockerService -> InitNetworkPlugin
Kubenets Plugins
more example see github
Main: interface-creating
-
bridge
: Creates a bridge, adds the host and the container to it.ipvlan
: Adds an ipvlan interface in the container.loopback
: Set the state of loopback interface to up.macvlan
: Creates a new MAC address, forwards all traffic to that to the container.ptp
: Creates a veth pair.vlan
: Allocates a vlan device.host-device
: Move an already-existing device into a container.
Windows: windows specific
-
win-bridge
: Creates a bridge, adds the host and the container to it.win-overlay
: Creates an overlay interface to the container.
IPAM: IP address allocation
-
dhcp
: Runs a daemon on the host to make DHCP requests on behalf of the containerhost-local
: Maintains a local database of allocated IPsstatic
: Allocate a static IPv4/IPv6 addresses to container and it's useful in debugging purpose.
Meta: other plugins
-
flannel
: Generates an interface corresponding to a flannel config filetuning
: Tweaks sysctl parameters of an existing interfaceportmap
: An iptables-based portmapping plugin. Maps ports from the host's address space to the container.bandwidth
: Allows bandwidth-limiting through use of traffic control tbf (ingress/egress).sbr
: A plugin that configures source based routing for an interface (from which it is chained).firewall
: A firewall plugin which uses iptables or firewalld to add rules to allow traffic to/from the container.
Sample
The sample plugin provides an example for building your own plugin.
第三方plugin
- Project Calico - a layer 3 virtual network
- Weave - a multi-host Docker network
- Contiv Networking - policy networking for various use cases
- SR-IOV
- Cilium - BPF & XDP for containers (BPF example/ BPF 简史)
- Infoblox - enterprise IP address management for containers
- Multus - a Multi plugin
- Romana - Layer 3 CNI plugin supporting network policy for Kubernetes
- CNI-Genie - generic CNI network plugin
- Nuage CNI - Nuage Networks SDN plugin for network policy kubernetes support
- Silk - a CNI plugin designed for Cloud Foundry
- Linen - a CNI plugin designed for overlay networks with Open vSwitch and fit in SDN/OpenFlow network environment
- Vhostuser - a Dataplane network plugin - Supports OVS-DPDK & VPP
- Amazon ECS CNI Plugins - a collection of CNI Plugins to configure containers with Amazon EC2 elastic network interfaces (ENIs)
- Bonding CNI - a Link aggregating plugin to address failover and high availability network
- ovn-kubernetes - an container network plugin built on Open vSwitch (OVS) and Open Virtual Networking (OVN) with support for both Linux and Windows
- Juniper Contrail / TungstenFabric - Provides overlay SDN solution, delivering multicloud networking, hybrid cloud networking, simultaneous overlay-underlay support, network policy enforcement, network isolation, service chaining and flexible load balancing 官网中文架构介绍(非常不错)website
- Knitter - a CNI plugin supporting multiple networking for Kubernetes
- DANM - a CNI-compliant networking solution for TelCo workloads running on Kubernetes
- VMware NSX – a CNI plugin that enables automated NSX L2/L3 networking and L4/L7 Load Balancing; network isolation at the pod, node, and cluster level; and zero-trust security policy for your Kubernetes cluster.
- cni-route-override - a meta CNI plugin that override route information
- Terway - a collection of CNI Plugins based on alibaba cloud VPC/ECS network product
- Cisco ACI CNI - for on-prem and cloud container networking with consistent policy and security model.
- Kube-OVN - a CNI plugin that bases on OVN/OVS and provides advanced features like subnet, static ip, ACL, QoS, etc.
- Project Antrea - an Open vSwitch k8s CNI
The CNI team also maintains some core plugins in a separate repository.
REF:
CSI
ovn
CRI
BPF/EBPF:
BPF用于很多的抓包程序,在linux中,一般内核自动编译进了af_packet这个驱动,因此只需要在用户态配置一个PACKET的socket,然后将filter配置进内核即可,使用setsockopt的SO_ATTACH_FILTER 命令,这个filter是在用户空间配制的,比如tcpdump应用程序,tcpdump和内核BPF过滤器的关系类似iptables与netfilter的关系,只是Netfilter实现了match/target的复合配合,而BPF的target则只是选择是否要与不要.
Linux内核功能eBPF入门学习(一):BPF、eBPF、BCC等基本概念
linux 下的 包过滤器 BPF
A brief introduction to XDP and eBPF
Linux内核工程导论——网络:Filter(LSF、BPF、eBPF)
BPF简介,以及使用kubectl trace插件为kubernetes集群运行BPF程序
Cilium: Network and Application Security with BPF and XDP (视频)
[译] Cilium:BPF 和 XDP 参考指南(2019) (强烈推荐)
Welcome to Cilium’s documentation! (学习Cilium)
github.com/cilium (github)