前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes CNI网络插件

Kubernetes CNI网络插件

作者头像
shysh95
发布2023-08-23 09:57:06
3650
发布2023-08-23 09:57:06
举报
文章被收录于专栏:shysh95shysh95

网络插件的目的?

通过某种方法,把不同主机上的网络进行连通,从而达到跨主机网络通信的目的。

什么是CNI网桥?

Kubernetes通过一个CNI接口,维护了单独的网桥代替docker0,该网桥就是CNI网桥,默认是cni0。

CNI网络插件的思想是?

Kubernetes在启动Infra容器之后,可以直接调用CNI网络插件,为这个Infra容器的Network Namespace,配置符合预期的网络栈。

kubernetes-cni包的作用是?

在Kubernetes中,有一个步骤是安装kubenetes-cni包,目的是在宿主机上安装CNI插件所需的基础可执行文件,安装完成后可以在/opt/cni/bin目录下看到,如下图:

CNI可执行文件的分类

主要分为三类:

  • Main插件:用来创建具体网络设备的二进制文件,比如:bridge(网桥)、ipvlan、loopback、macvlan、ptp(Veth Pair设备)以及vlan
  • IPAM插件:用来负责分配IP地址,比如:dhcp会向DHCP服务器发起请求,host-local会使用预先配置的IP地址进行分配
  • CNI社区维护的CNI差价:比如:flannel,专门为Flannel项目提供的CNI插件;tunning,通过sysctl调整网络设备参数的二进制文件;portmap通过iptables配置端口映射的二进制文件;bandwidth使用Token Bucket Filter进行限流的二进制文件。

实现一个容器网络方案需要做哪些工作

  1. 实现网络方案本身:比如flanneld里面的主要逻辑,比如创建和配置flannel.1设备,配置宿主机路由,配置ARP和FDB表中的信息
  2. 实现网络方案对应的CNI插件:主要是配置Infra容器里面的网络栈,并把它连接到CNI网桥上。

CNI插件的安装

Flannel的CNI插件默认已经在/opt/cni/bin中,所以无需单独安装,但是如果是其他的网络项目,则需要把其对应的CNI插件可执行文件放在/opt/cni/bi目录下。

网络方案本身的安装

当在宿主机上安装网络方案本身比如flanneld时,flanneld启动时会在每台宿主机上生成它对应的CNI配置文件(ConfigMap),从而告诉Kubernetes这个集群使用Flannel作为容器网络解决方案,CNI配置文件内容如下:

dockershim是什么?

在Kubernetes处理容器网络的逻辑不在kubelet主干代码里执行,会在具体的CRI实现里完成,对于docker来说它的CRI是dockershim。

dockershim会加载CNI配置文件,上面的配置文件中Flannel项目指定了flannel和portmap两个插件,dockershim会对CNI配置文件加载,将列表中的第一个插件也就是flannel设置默认插件。

Kubelet组件在创建Pod时,dockershim会调用Docker API创建并启动Infra容器,紧接着执行一个SetUpPod方法,该方法会为CNI插件准备参数,然后调用CNI插件为Infra容器配置网络。

CNI插件的工作原理

CNI插件在被调用时会接收由dockershim设置的一组CNI环境变量,其中有一个环境变量参数叫做CNI_COMMAND,取值有ADD和DEL两种。

ADD和DEL就是CNI插件唯一要实现的两个方法,ADD的含义是把容器添加到CNI网络中,DEL则是把容器从CNI网络中移除。

CNI ADD操作的参数主要包括:容器里网卡的名字eth0(CNIIFNAME),Pod的Network NameSpace文件路径(CNINETNS),容器的ID(CNICONTAINERID), CNI_AGRS(CRI可以key-value的形式传递自定义信息给网络插件)。

CNI插件在被调用时还需要接收dockershim从CNI配置文件里加载到的默认插件的配置信息。

ADD操作过程

知道了做什么操作,且有了配置信息以后,就可以设置一些网络信息了,其中配置文件中的delegate文件表示Flannel插件不会自己工作,而是会调用delegate指定的CNI内置插件完成,对于Flannel则是指CNI bridge插件。

dockershimp对于Flannel CNI插件的调用只是个过场,但是Flannel CNI插件会对其收到的配置信息进行补充,比如为delegate设置type为bridge, ipam字段设置host-local等,如下:

ipam字段的信息来Flannel在宿主机上生成的配置文件(/run/flannel/subnet.env)

下面Flannel CNI插件会调用CNI bridge插件,在调用插件的时候会传递两个参数,第一个参数还是ADD,第二个参数则是delegate字段的内容,同时Flannel CNI插件会把delegate字段保存在/var/lib/cni/flannel目录下,方便后续DEL进行使用。

CNI Bridge插件对的ADD操作

1. CNI Bridge首先会在宿主机上检查CNI网桥是否存在,如果没有则进行创建:

代码语言:javascript
复制
# 在宿主机上
 
$ ip link add cni0 type bridge
 
$ ip link set cni0 up
 

2. 通过Infra容器的Network Namespace文件进入到Network Namespace中创建一对Veth Pair设备:

代码语言:javascript
复制
#在容器里
 


 
# 创建一对Veth Pair设备。其中一个叫作eth0,另一个叫作vethb4963f3
 
$ ip link add eth0 type veth peer name vethb4963f3
 


 
# 启动eth0设备
 
$ ip link set eth0 up
 


 
# 将Veth Pair设备的另一端(也就是vethb4963f3设备)放到宿主机(也就是Host Namespace)里
 
 ip link set vethb4963f3 netns HOST_NS 


 
# 通过Host Namespace,启动宿主机上的vethb4963f3设备
 
 ip netns exec HOST_NS ip link set vethb4963f3 up 

3. 把宿主机上的vethb4963f3设备插到CNI 网桥上:

代码语言:javascript
复制
# 在宿主机上
 
$ ip link set vethb4963f3 master cni0
 

4. 为vethb4963f3设置HairpinMode模式,默认情况下网桥不允许一个数据包从一个端口进来以后再从相同的端口出去,设置HairpinMode则可以取消这个限制,这样才可以保证集群中的Pod能够通过自己的Service访问自己

5. CNI bridge插件会调用CNI ipam插件,从ipam.subnet规定的网段中为容器分配一个可用的ip地址看,同时为容器设置默认路由,如下:

代码语言:javascript
复制
# 在容器里
 
$ ip addr add 10.244.0.2/24 dev eth0
 
$ ip route add default via 10.244.0.1 dev eth0
 

6. CNI bridge为CNI网桥添加IP地址,如下:

代码语言:javascript
复制
# 在宿主机上
 
$ ip addr add 10.244.0.1/24 dev cni0
 

7. CNI 插件会把容器的IP地址返回给dockershim,然后kubelet会将其添加到Pod的status字段。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员修炼笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档