Kubernetes网络自学系列 | 打通CNI与Kubernetes:Kubernetes网络驱动
Posted COCOgsta
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes网络自学系列 | 打通CNI与Kubernetes:Kubernetes网络驱动相关的知识,希望对你有一定的参考价值。
素材来源:《Kubernetes网络权威指南》
一边学习一边整理内容,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:Kubernetes网络自学系列 | 汇总_COCOgsta的博客-CSDN博客
3.4 打通CNI与Kubernetes:Kubernetes网络驱动
Kubernetes支持两种网络驱动,分别是Kubenet和CNI,其中:
· CNI plugins:遵守appc/CNI规范,允许自由接入多个符合CNI标准的网络插件;
· Kubenet plugins:基于cbr0的一个单机容器网络方案,同时使用CNI的bridge和host-local插件实现一些功能。
3.4.1 即将完成历史使命:Kubenet
Kubenet是Kubernetes早期原生的网络驱动,提供非常简单和基本的单机容器网络能力。使用Kubelet必须运行--network-plugin=kubenet参数,以开启插件。
Kubenet本身不会实现更高级的功能,如跨节点网络连接或网络策略等,它通常与cloud provider一起使用,配置路由规则实现跨主机的通信能力。随着CNI的广泛使用,Kubenet正在被慢慢弃用。然而,Kubenet也用了一些CNI的功能,例如它基于CNI bridge插件创建名为cbr0的Linux网桥,为每个容器建立一对veth pair并连接到cbr0网桥上。每个Pod通过配置的网段分配到一个IP地址。
Kubenet在bridge插件的基础上拓展了很多功能,包括:
· 使用CNI的host-local IP地址管理插件,为Pod分配IP地址,并定期释放已分配但未使用的IP地址;
· 设置sysctl net.bridge.bridge-nf-call-iptables=1;
· 为Pod的IP配置SNAT(MASQUERADE)规则,允许Pod访问因特网;
· 开启网桥的hairpin和Promisc模式,允许Pod访问它自己所在的Service IP(即通过NAT后再访问Pod);
· HostPort管理及设置端口映射;
· 带宽控制,支持通过kubernetes.io/ingress-bandwidth和kubernetes.io/egress-bandwidth这两个annotations设置Pod网络带宽限制。
除此之外,使用Kubenet插件还需要注意以下几点:
· Kubenet使用了几个标准CNI插件,例如bridge、lo和host-local,其最低的版本为0.2.0。Kubenet默认会在/opt/cni/bin中搜索这些插件的二进制,用户也可以指定network-plugin-dir以支持额外的搜索路径。Kubenet还会去/etc/cni/net.d目录搜索CNI的配置文件,使用找到的第一个匹配的conf文件;
· Kubelet启动时可以添加--non-masquerade-cidr=参数,意思是向该IP段之外的IP地址发送的流量将进行一次SNAT;
· 节点必须被分配到一个IP子网,通过Kubelet的--pod-cidr参数进行配置;
· --allcate-node-cidrs=true --cluster-cidr=参数指定集群和节点的网段。
1. 定制MTU
正确地配置MTU才能获得最佳的网络性能。网络插件通常会尝试推断出合理的MTU,但由于网络拓扑的复杂性,有时程序无法自动推算最优的MTU。例如,适合Docker网桥和IPSEC封装的MTU是不一样的。
Kubenet支持用户使用Kubelet的--network-plugin-mtu参数指定MTU。例如在AWS上,eth0 MTU通常为9001,于是用户可以指定--network-plugin-mtu=9001。如果使用IPSEC,则可以因为封装开销而减少MTU,例如--network-plugin-mtu=8873。
目前,只有Kubenet支持--network-plugin-mtu选项。
2. 带宽控制
Kubenet调用Linux tc实现了一个简单的ingress/egress的带宽控制器。当我们对Pod做了以下配置时:
Kubenet就会自动为这个Pod分别将上传和下载的最高带宽限制为1Mb/s。在很长一段时间内,Pod带宽控制这个功能一直是Kubenet的专利,CNI插件一直不支持,而这也是Kubenet迟迟没有被CNI完全代替的重要原因之一。当集群不需要SDN时,例如单机部署,可能Kubenet是一个不错的选择。
3.4.2 网络生态第一步:CNI
CNI是容器网络的标准化,试图通过JSON描述一个容器网络配置。CNI的原理如图3-10 所示。
图3-10 CNI的原理
从 图3-10 中可 以看 出,CNI 是Kubernetes 与底层网络插件之 间的一个抽象层,为Kubernetes屏蔽了底层网络实现的复杂度,同时解耦了Kubernetes的具体网络插件实现。
CNI主要有两类接口:分别是在创建容器时调用的配置网络接口:
和删除容器时调用的清理网络接口:
不论是配置网络接口还是清理网络接口,都有两个入参,分别是网络配置和runtime配置。网络配置很好理解,runtime配置则主要是容器运行时传入的网络namespace信息。符合CNI标准的默认/第三方网络插件如图3-11所示。
图3-11 符合CNI标准的默认/第三方网络插件
其中,左边是CNI自带插件(其实还有更多),右边是符合CNI标准的第三方插件。CNI-Genie是一个开源的多网络的容器解决方案,后面章节会进行详细介绍。
安装CNI
下面我们举几个CNI网络插件的例子。
host-local&bridge插件
上文的JSON文件是一个host-local+bridge插件组合的例子,在一个JSON文件中,我们定义了一个名为mynet的网络。它是一个bridge模型,而IP地址管理(ipam)使用的是host-local(在本地用一个文件记录已经分配的容器IP地址),且可供分配的容器网段是10.10.0.0/16。
至于在Kubernets中如何使用它们?Kubelet和CNI给出了两个默认的文件系统路径,/etc/cni/net.d用来存储CNI配置文件,/opt/cni/bin目录用来存放CNI插件的二进制文件。在我们这个例子中,至少要提前放好bridge和host-local两个插件的二进制,以及10-mynet.conf配置文件(叫什么名字随意,Kubelet只解析*.conf文件)。主流的网络插件都集成了bridge插件并提供了各自的ipam功能,因此在实际的Kubernets使用过程中,我们不需要操心上面的过 程,也无须做额外配置。
在Kubernetes中使用CNI
与Kubenet类似,Kubelet要使用CNI网络驱动需要配置启动参数--network-plugin=cni。Kubelet从--cni-conf-dir(默认为/etc/cni/net.d)中读取文件,并使用该文件中的CNI配置配置每个Pod网络。如果目录中有多个CNI配置文件,则使用文件名字典序列中的第一个文件。CNI插件二进制文件所放置的目录通过Kubelet的--cni-bin-dir参数配置,默认为/opt/cni/bin。Kubernetes要求标准CNI插件的最低版本为0.2.0。
Kubernetes自己定义一套网络接口,这是面向Pod的API:
一个使用Kubernetes网络API的例子:
下面我们以Pod带宽控制为例,介绍Kubernetes使用CNI插件的流程。
CNI支持Pod的带宽控制是Kubernetes 1.11版本新开发的一个功能。当书写了以下Pod配置时:
Kubernetes会自动为这个Pod分别限制上传和下载的带宽为1Mb/s。注意,我们需要自己在/etc/cni/net.d目录下写一个配置文件,例如my-net.conf:
这个配置文件会告诉Kubelet去调用CNI的默认bandwidth插件,然后根据Pod annotation里带宽的ingress/egress值进行容器上行/下行带宽的限制。当然,CNI插件最后调用的还是Linux tc工具,主机上的tc配置如下所示:
Pod带宽控制的底层技术栈如图3-12所示。不难看出,用户通过Pod的annotations下发带宽限制数值,CNI的bandwidth插件调用Linux流量控制插件tc,在宿主机上应用tc配置。
图3-12 Pod带宽控制的底层技术栈
Pod带宽控制的工作流如图3-13所示。
图3-13 Pod带宽控制的工作流
以上是关于Kubernetes网络自学系列 | 打通CNI与Kubernetes:Kubernetes网络驱动的主要内容,如果未能解决你的问题,请参考以下文章
Kubernetes_CNI_Calico_04_Calico的网络策略NetworkPolicy
Kubernetes网络自学系列 | 终于等到你:Kubernetes网络