从零开始入门 K8s | 理解 CNI 和 CNI 插件

0.png

做者 | 溪恒 阿里巴巴高级技术专家api

本文整理自《CNCF x Alibaba 云原生技术公开课》第 26 讲,点击直达课程页面安全

关注“阿里巴巴云原生”公众号,回复关键词“入门”,便可下载从零入门 K8s 系列文章 PPT。网络

导读:网络架构是 K8s 中较为复杂的方面之一。K8s 网络模型自己对某些特定的网络功能有着必定的要求,所以,业界已经有了很多的网络方案来知足特定的环境和要求。CNI 意为容器网络的 API 接口,为了让用户在容器建立或销毁时都可以更容易地配置容器网络。在本文中,做者将带领你们理解典型网络插件地工做原理、掌握 CNI 插件的使用。架构

1、CNI 是什么

首先咱们介绍一下什么是 CNI,它的全称是 Container Network Interface,即容器网络的 API 接口。app

它是 K8s 中标准的一个调用网络实现的接口。Kubelet 经过这个标准的 API 来调用不一样的网络插件以实现不一样的网络配置方式,实现了这个接口的就是 CNI 插件,它实现了一系列的 CNI API 接口。常见的 CNI 插件包括 Calico、flannel、Terway、Weave Net 以及 Contiv。负载均衡

2、Kubernetes 中如何使用 CNI

K8s 经过 CNI 配置文件来决定使用什么 CNI。less

基本的使用方法为:机器学习

  1. 首先在每一个结点上配置 CNI 配置文件(/etc/cni/net.d/xxnet.conf),其中 xxnet.conf 是某一个网络配置文件的名称;
  2. 安装 CNI 配置文件中所对应的二进制插件;
  3. 在这个节点上建立 Pod 以后,Kubelet 就会根据 CNI 配置文件执行前两步所安装的 CNI 插件;
  4. 上步执行完以后,Pod 的网络就配置完成了。

具体的流程以下图所示:ide

1.png

在集群里面建立一个 Pod 的时候,首先会经过 apiserver 将 Pod 的配置写入。apiserver 的一些管控组件(好比 Scheduler)会调度到某个具体的节点上去。Kubelet 监听到这个 Pod 的建立以后,会在本地进行一些建立的操做。当执行到建立网络这一步骤时,它首先会读取刚才咱们所说的配置目录中的配置文件,配置文件里面会声明所使用的是哪个插件,而后去执行具体的 CNI 插件的二进制文件,再由 CNI 插件进入 Pod 的网络空间去配置 Pod 的网络。配置完成以后,Kuberlet 也就完成了整个 Pod 的建立过程,这个 Pod 就在线了。微服务

你们可能会以为上述流程有不少步(好比要对 CNI 配置文件进行配置、安装二进制插件等等),看起来比较复杂。

但若是咱们只是做为一个用户去使用 CNI 插件的话就比较简单,由于不少 CNI 插件都已提供了一键安装的能力。以咱们经常使用的 Flannel 为例,以下图所示:只须要咱们使用 kubectl apply Flannel 的一个 Deploying 模板,它就能自动地将配置、二进制文件安装到每个节点上去。

2.png

安装完以后,整个集群的 CNI 插件就安装完成了。

所以,若是咱们只是去使用 CNI 插件的话,那么其实不少 CNI 插件已经提供了一键安装的脚本,无需你们关心 Kubernetes 内部是如何配置的以及如何调用 API 的。

3、哪一个 CNI 插件适合我

社区有不少的 CNI 插件,好比 Calico, flannel, Terway 等等。那么在一个真正具体的生产环境中,咱们要选择哪个 CNI 插件呢?<br /> <br />这就要从 CNI 的几种实现模式提及。咱们须要根据不一样的场景选择不一样的实现模式,再去选择对应的具体某一个插件。

一般来讲,CNI 插件能够分为三种:Overlay、路由及 Underlay。

3.png

  • Overlay 模式的典型特征是容器独立于主机的 IP 段,这个 IP 段进行跨主机网络通讯时是经过在主机之间建立隧道的方式,将整个容器网段的包全都封装成底层的物理网络中主机之间的包。该方式的好处在于它不依赖于底层网络;

  • 路由模式中主机和容器也分属不一样的网段,它与 Overlay 模式的主要区别在于它的跨主机通讯是经过路由打通,无需在不一样主机之间作一个隧道封包。但路由打通就须要部分依赖于底层网络,好比说要求底层网络有二层可达的一个能力;

  • Underlay 模式中容器和宿主机位于同一层网络,二者拥有相同的地位。容器之间网络的打通主要依靠于底层网络。所以该模式是强依赖于底层能力的。

了解了以上三种经常使用的实现模式以后,再根据本身的环境、需求判断可由哪种模式进行实现,再在对应的模式中去找 CNI 插件。不过社区中有那么多插件,它们又都属于哪一种模式?如何进行选择呢?怎么挑选适合本身的呢?咱们能够从如下 3 个方面来考虑。

4.png

1. 环境限制

不一样环境中所支持的底层能力是不一样的。

  • 虚拟化环境(例如 OpenStack)中的网络限制较多,好比不容许机器之间直接经过二层协议访问,必需要带有 IP 地址这种三层的才能去作转发,限制某一个机器只能使用某些 IP 等。在这种被作了强限制的底层网络中,只能去选择 Overlay 的插件,常见的有 Flannel-vxlan, Calico-ipip, Weave 等等;

  • 物理机环境中底层网络的限制较少,好比说咱们在同一个交换机下面直接作一个二层的通讯。对于这种集群环境,咱们能够选择 Underlay 或者路由模式的插件。Underlay 意味着咱们能够直接在一个物理机上插多个网卡或者是在一些网卡上作硬件虚拟化;路由模式就是依赖于 Linux 的路由协议作一个打通。这样就避免了像 vxlan 的封包方式致使的性能下降。这种环境下咱们可选的插件包括 clico-bgp, flannel-hostgw, sriov 等等;

  • 公有云环境也是虚拟化,所以底层限制也会较多。但每一个公有云都会考虑适配容器,提高容器的性能,所以每家公有云可能都提供了一些 API 去配置一些额外的网卡或者路由这种能力。在公有云上,咱们要尽可能选择公有云厂商提供的 CNI 插件以达到兼容性和性能上的最优。好比 Aliyun 就提供了一个高性能的 Terway 插件。

环境限制考虑完以后,咱们心中应该都有一些选择了,知道哪些能用、哪些不能用。在这个基础上,咱们再去考虑功能上的需求。

2. 功能需求

 

  • 首先是安全需求;

K8s 支持 NetworkPolicy,就是说咱们能够经过 NetworkPolicy 的一些规则去支持“Pod 之间是否能够访问”这类策略。但不是每一个 CNI 插件都支持 NetworkPolicy 的声明,若是你们有这个需求,能够选择支持 NetworkPolicy 的一些插件,好比 Calico, Weave 等等。

  • 第二个是是否须要集群外的资源与集群内的资源互联互通;

你们的应用最初都是在虚拟机或者物理机上,容器化以后,应用没法一下就完成迁移,所以就须要传统的虚拟机或者物理机能跟容器的 IP 地址互通。为了实现这种互通,就须要二者之间有一些打通的方式或者直接位于同一层。此时能够选择 Underlay 的网络,好比 sriov 这种就是 Pod 和之前的虚拟机或者物理机在同一层。咱们也可使用 calico-bgp,此时它们虽然不在同一网段,但能够经过它去跟原有的路由器作一些 BGP 路由的一个发布,这样也能够打通虚拟机与容器。

  • 最后考虑的就是 K8s 的服务发现与负载均衡的能力

K8s 的服务发现与负载均衡就是咱们前面所介绍的 K8s 的 Service,但并非全部的 CNI 插件都能实现这两种能力。好比不少 Underlay 模式的插件,在 Pod 中的网卡是直接用的 Underlay 的硬件,或者经过硬件虚拟化插到容器中的,这个时候它的流量没法走到宿主机所在的命名空间,所以也没法应用 kube-proxy 在宿主机配置的规则。

这种状况下,插件就没法访问到 K8s 的服务发现。所以你们若是须要服务发现与负载均衡,在选择 Underlay 的插件时就须要注意它们是否支持这两种能力。

通过功能需求的过滤以后,能选的插件就不多了。通过环境限制和功能需求的过滤以后,若是还剩下 三、4 种插件,能够再来考虑性能需求。

3. 性能需求

咱们能够从 Pod 的建立速度和 Pod 的网络性能来衡量不一样插件的性能。

  • Pod 的建立速度

当咱们建立一组 Pod 时,好比业务高峰来了,须要紧急扩容,这时好比说咱们扩容了 1000 个 Pod,就须要 CNI 插件建立并配置 1000 个网络资源。Overlay 和路由模式在这种状况下的建立速度是很快的,由于它是在机器里面又作了虚拟化,因此只须要调用内核接口就能够完成这些操做。但对于 Underlay 模式,因为须要建立一些底层的网络资源,因此整个 Pod 的建立速度相对会慢一些。所以对于常常须要紧急扩容或者建立大批量的 Pod 这些场景,咱们应该尽可能选择 Overlay 或者路由模式的网络插件。

  • Pod 的网络性能

主要表如今两个 Pod 之间的网络转发、网络带宽、PPS 延迟等这些性能指标上。Overlay 模式的性能较差,由于它在节点上又作了一层虚拟化,还须要去封包,封包又会带来一些包头的损失、CPU 的消耗等,若是你们对网络性能的要求比较高,好比说机器学习、大数据这些场景就不适合使用 Overlay 模式。这种情形下咱们一般选择 Underlay 或者路由模式的 CNI 插件。

相信你们经过这三步的挑选以后都能找到适合本身的网络插件。

4、如何开发本身的 CNI 插件

有时社区的插件没法知足本身的需求,好比在阿里云上只能使用 vxlan 这种 Overlay 的插件,而 Overlay 插件的性能相对较差,没法知足阿里云上的一些业务需求,因此阿里云上开发了一个 Terway 的插件。

若是咱们本身的环境比较特殊,在社区里面又找不到合适的网络插件,此时能够开发一个本身的 CNI 插件。

CNI 插件的实现一般包含两个部分:

  1. 一个二进制的 CNI 插件去配置 Pod 网卡和 IP 地址。这一步配置完成以后至关于给 Pod 上插上了一条网线,就是说它已经有本身的 IP、有本身的网卡了;

  2. 一个 Daemon 进程去管理 Pod 之间的网络打通。这一步至关于说将 Pod 真正连上网络,让 Pod 之间可以互相通讯。

给 Pod 插上网线

那么如何实现第一步,给 Pod 插上网线呢?一般是这样一个步骤:

5.png

1. 给 Pod 准备一个网卡

一般咱们会用一个 "veth" 这种虚拟网卡,一端放到 Pod 的网络空间,一端放到主机的网络空间,这样就实现了 Pod 与主机这两个命名空间的打通。

2. 给 Pod 分配 IP 地址

这个 IP 地址有一个要求,咱们在以前介绍网络的时候也有提到,就是说这个 IP 地址在集群里须要是惟一的。如何保障集群里面给 Pod 分配的是个惟一的 IP 地址呢?

通常来讲咱们在建立整个集群的时候会指定 Pod 的一个大网段,按照每一个节点去分配一个 Node 网段。好比说上图右侧建立的是一个 172.16 的网段,咱们再按照每一个节点去分配一个 /24 的段,这样就能保障每一个节点上的地址是互不冲突的。而后每一个 Pod 再从一个具体的节点上的网段中再去顺序分配具体的 IP 地址,好比 Pod1 分配到了 172.16.0.1,Pod2 分配到了 172.16.0.2,这样就实现了在节点里面 IP 地址分配的不冲突,而且不一样的 Node 又分属不一样的网段,所以不会冲突。

这样就给 Pod 分配了集群里面一个惟一的 IP 地址。

3. 配置 Pod 的 IP 和路由

  • 第一步,将分配到的 IP 地址配置给 Pod 的虚拟网卡;
  • 第二步,在 Pod 的网卡上配置集群网段的路由,令访问的流量都走到对应的 Pod 网卡上去,而且也会配置默认路由的网段到这个网卡上,也就是说走公网的流量也会走到这个网卡上进行路由;
  • 最后在宿主机上配置到 Pod 的 IP 地址的路由,指向到宿主机对端 veth1 这个虚拟网卡上。这样实现的是从 Pod 可以到宿主机上进行路由出去的,同时也实现了在宿主机上访问到 Pod 的 IP 地址也能路由到对应的 Pod 的网卡所对应的对端上去。

给 Pod 连上网络

刚才咱们是给 Pod 插上网线,也就是给它配了 IP 地址以及路由表。那怎么打通 Pod 之间的通讯呢?也就是让每个 Pod 的 IP 地址在集群里面都能被访问到。

通常咱们是在 CNI Daemon 进程中去作这些网络打通的事情。一般来讲是这样一个步骤:

  • 首先 CNI 在每一个节点上运行的 Daemon 进程会学习到集群全部 Pod 的 IP 地址及其所在节点信息。学习的方式一般是经过监听 K8s APIServer,拿到现有 Pod 的 IP 地址以及节点,而且新的节点和新的 Pod 的建立的时候也能通知到每一个 Daemon;

  • 拿到 Pod 以及 Node 的相关信息以后,再去配置网络进行打通。

    • 首先 Daemon 会建立到整个集群全部节点的通道。这里的通道是个抽象概念,具体实现通常是经过 Overlay 隧道、阿里云上的 VPC 路由表、或者是本身机房里的 BGP 路由完成的;

    • 第二步是将全部 Pod 的 IP 地址跟上一步建立的通道关联起来。关联也是个抽象概念,具体的实现一般是经过 Linux 路由、fdb 转发表或者OVS 流表等完成的。Linux 路由能够设定某一个 IP 地址路由到哪一个节点上去。fdb 转发表是 forwarding database 的缩写,就是把某个 Pod 的 IP 转发到某一个节点的隧道端点上去(Overlay 网络)。OVS 流表是由 Open vSwitch 实现的,它能够把 Pod 的 IP 转发到对应的节点上。

6、本文总结

本文的主要内容就到此为止了,这里为你们简单总结一下:

  1. 在咱们本身的环境中搭建一个 K8s 集群,应当如何选择最适合本身的网络插件?
  2. 当社区网络插件不能知足时,如何开发本身的网络插件?

2群直播海报.png

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,作最懂云原生开发者的技术圈。”

相关文章
相关标签/搜索