首页
视频
资源
登录
原
Kubernetes Calico VPP软协议栈
4414
人阅读
2022/11/24 14:05
总访问:
2654798
评论:
0
收藏:
0
手机
分类:
容器编排
![](https://img.tnblog.net/arcimg/hb/334b158ccce44e23ad2d5d76762f6c57.png) >#Kubernetes Calico VPP软协议栈 [TOC] ## VPP简介 tn2>VPP(Vector Packet Processor)是一个高性能、开源的用户空间网络数据平面,用C语言编写,在 fd.io 旗下开发。它支持许多标准网络功能(L2、L3路由、NAT、封装),并且可以使用插件轻松扩展。VPP数据平面使用插件来有效地实现Kubernetes服务负载平衡和Calico策略。 tn>简单来说,它就是个跑在用户空间的TCP/IP协议栈,不需要进入内核。那么它的实现就如下图所示: ![](https://img.tnblog.net/arcimg/hb/7c1c2cf0a9b14a1dadd376b61422cd94.png) ## 安装VPP ### 安装前提 tn2>首先我们需要一个空白的集群环境,也就是相当执行`kubeadm init`后没有安装CNI的其他插件。 第二就是内核版本需要很高。 ### HugePages概述 tn2>HugePages是集成到Linux内核2.6中的一项特性。启用HugePages使操作系统可以支持的内存页大于默认值(通常为4 KB)。使用非常大的页面大小可以通过减少访问page table entries所需的系统资源量来提高系统性能。HugePages对32位和64位配置都很有用。HugePage大小从2 MB到256 MB不等,具体取决于内核版本和硬件架构。对于Oracle数据库,使用HugePages可以减少page states的操作系统维护,并提高转换后备缓冲区(Translation Lookaside Buffer ,TLB)命中率。 更多请参考:https://www.cnblogs.com/plluoye/p/10836322.html ### 配置HugePages tn2>通过以下hugepages配置可能使VPP能够使用更高效的驱动程序: 至少512 x 2MB hugepage可用(`grep hugepages_Free/proc/meminfo`) 加载`vfio_pci`(centos上的`vfio_pci`)或`uio_pci_generic`内核模块。例如: ```bash echo "vfio-pci" > /etc/modules-load.d/95-vpp.conf modprobe vfio-pci echo "vm.nr_hugepages = 512" >> /etc/sysctl.conf # 生效 sysctl -p # 重新启动kubelet以将更改考虑在内 # 根据kubelet的安装方式,您可能需要使用不同的命令 systemctl restart kubelet ``` ### 安装Calico与配置VPP tn2>安装Calico与VPP ```bash kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.5/manifests/tigera-operator.yaml kubectl apply -f https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.24.0/yaml/calico/installation-default.yaml ``` ![](https://img.tnblog.net/arcimg/hb/952417790f464bd3a2f270b20b1c1013.png) tn2>然后我们等待一下Pod的安装。 ### 安装VPP数据平面组件 tn2>首先获取VPP数据平面资源的适当yaml清单: ```bash # 如果设置了hugepages curl -o calico-vpp.yaml https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.24.0/yaml/generated/calico-vpp.yaml # 没有设置,或不确定使用 curl -o calico-vpp.yaml https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.24.0/yaml/generated/calico-vpp-nohuge.yaml ``` tn2>这里我们选者后者的下载。 VPP快的原因除了不走内核,还有就是CPU是专用的。 `vpp_dataplane_interface`是vpp将使用的主要接口。它必须是Linux接口的名称,并使用地址进行配置。此接口上配置的地址必须是Kubernetes中的节点地址。 ```bash # 查看我们的网络接口 ifconfig # 查看虚拟网口的速度 ethtool ens33 vim calico-vpp # 修改vpp_dataplane_interface: ens33 ``` ![](https://img.tnblog.net/arcimg/hb/112c1f83155749fe8ccae4a4ff5a75a1.png) ![](https://img.tnblog.net/arcimg/hb/ee951fcaa5414e119a1fca2f655e69f5.png) ![](https://img.tnblog.net/arcimg/hb/2160d519f35347f382e64a1a0f8beb60.png) tn2>我们知道VPP可以进行各种各样的包数据进行处理,但是它发出去的时候是通过uplink_interface进行发出去的,`vpp_uplink_driver`这个参数可以设置具体应该设置什么来快速处理包发出去。举例:dpdk。 这里我们就选默认的即可(模式是`af_packet` : 使用af_packet套接字驱动接口(未优化,但在任何地方都有效))。 更多请参考: ![](https://img.tnblog.net/arcimg/hb/59bab95b0a914578b268efda2072381b.png) tn2>接下来我们还需要设置Kubernetes中Service的网段也就是`service_prefix`参数。(可通过如下命令进行查看) ```bash kubectl cluster-info dump | grep -m 1 service-cluster-ip-range ``` ![](https://img.tnblog.net/arcimg/hb/df61ed77228d4857a7ffae557141a5ca.png) tn2>最后Apply一下,完成VPP的安装。 ```bash kubectl apply -f calico-vpp.yaml ``` ### 物理网卡变了? tn2>我们通过`ethtool ens33`查询发现它的速度从千兆网速度变成了`10MB/s`,并且物理网卡变成了一个TAP设备。 到这里你可能会问了为什么会这样? ![](https://img.tnblog.net/arcimg/hb/9398b28ebada424abdd607693c176915.png) ![](https://img.tnblog.net/arcimg/hb/307a113b12324f74a232ca25558117a8.png) tn2>由于我们VPP是用户态的,所以通过`TAP/TUN`来连接处理数据包。 更多大家可以参考我以往的文章:http://tnblog.net/hb/article/details/7233#TAP%E4%B8%8ETUN%E8%AE%BE%E5%A4%87 tn>简单来讲就是一端连在我们的协议栈一端连接在我们的IP层。 ![](https://img.tnblog.net/arcimg/hb/994f2c0e5f64433f8e2124433acc72d0.png) tn2>那既然这样包都出不去,我们的ens33物理端口被谁拿走了呢? 答案是被VPP拿走了。我们可以安装`calicovpctl`来进行查看。 ### 安装calivpctl tn2>calivpctl是vpp容器映像附带的一个助手bash脚本。它可以通过以下方法安装到主机上,并有助于收集日志和调试安装了VPP数据平面的正在运行的集群。 ```bash curl https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.24.0/test/scripts/vppdev.sh \ | tee /usr/bin/calivppctl chmod +x /usr/bin/calivppctl ``` ### VPP处理过程 tn2>然后我们进入到VPP中。 ```bash calivppctl # 这里的bpf1是通过查看安装好的VPP控制Pod的后缀名称获取到的 calivppctl vppctl bpf1 ``` ![](https://img.tnblog.net/arcimg/hb/33d6f51c391d4bf1b2c19aa1c51e750d.png) tn2>我们知道VPP是用户态的协议栈,内核协议栈能够处理的它同样能够处理,所以我们把它ens33的主机网卡拿走了我们同样可以处理。不然拿走了我们的ssh就连接不上主机了。 这里我们来查看一下接口处理情况。 ```bash show interfaces ``` ![](https://img.tnblog.net/arcimg/hb/3be79ee7290d4cf0937ccc3f7d64cc34.png) tn2>我们还可以通过查看物理网卡对接的情况来看。 `host-ens33`就是对接的我们的物理网卡ens33,并且连物理mac地址都没有变化。 ```bash show hardware-interfaces ``` ![](https://img.tnblog.net/arcimg/hb/7d078aeeeb0c4e7cae1e7c1421ac84c8.png) tn2>再来我们在查看接口中有ipip0和ipip1,那么是不是有tunnl呢? 通过查看网卡并没有发现tunnel相关的网卡。 我们可以通过查看Tunnl的方式来查看相关信息。 ```bash show ipip tunnel ``` ![](https://img.tnblog.net/arcimg/hb/c2c7446bcad444dd9998ba2b40306eac.png) tn2>我们发现这里写好了从源ip地址和目标地址,意思就是现在ipip由vpp来进行处理。 ![](https://img.tnblog.net/arcimg/hb/54e78b15bbe94c9c90d24b82e5c2bf4d.png) tn2>在来我们这里有tap0设备,它是一个vpp的tap文件但这把它当成一个网卡,那么其他pod的另一端在哪儿呢? 我们首先尝试创建几个pod。 ```bash kubectl apply -f cni.yaml # 运行起来后查看pod的接口 kubectl get pod kubectl exec -it cni-kpfnz -- bash ifconfig ip tuntap list ``` ![](https://img.tnblog.net/arcimg/hb/2fd311c850a4412fbb979ff0b0cf73a3.png) tn2>可以看到这个eth0它是没有mac地址的,卧槽为什么没有地址啊?因为它是点对点(`P-t-P`)的设备一个tun设备,就像两头直接连着线的所以不需要MAC地址,就IP地址就可以了。 我们在VPP中也是可以找到的,我们可以看到有很多`tun`设备就是它们连接的vpp这一端。 ```bash show interfaces show interfaces address ``` ![](https://img.tnblog.net/arcimg/hb/9a22c159237946458a1f7f20c28438d3.png) tn2>刚刚我们连接的容器就是tun5的`10.244.11.75`。 tn>所以整个创建的流程是这样: 当在主机上调度Pod时,kubelet服务将为新Pod创建网络名称空间,然后使用CNI请求Calico在此名称空间中配置接口。Calico将首先计算主机的IP配置(地址和路由),然后将其传递给VPP代理。然后,VPP将在所需的容器名称空间中创建tun接口,并使用所需的地址和路由对其进行配置。这使得所有的集装箱流量都通过VPP。 ![](https://img.tnblog.net/arcimg/hb/143d7ab7657c45658fedf2cebb8f834b.png) tn2>我们可以看到路由表都是直接走eth0,然后交给VPP协议栈处理,看看其他的tun对应的ip在哪儿。 ```bash # 一个pod中ping ping xxxxx # vpp中抓包 pcap trace rx tx max 30000 intfc any pcap trace off ``` ![](https://img.tnblog.net/arcimg/hb/4069e5bcfcbe4f96b7aeedb5bc23aa1b.png) tn2>这里抓的包在calico vpp的 pod里面,所以我们可以复制拿出来,当然也可以从节点中直接获取到。 ```bash find / -name rxtx.pcap ``` ![](https://img.tnblog.net/arcimg/hb/1bf0ac5627bc4307a9d34ca51139f25f.png) tn2>然后直接拿下来进行分析,我们发现它直接实现了ipip。 ![](https://img.tnblog.net/arcimg/hb/8d2767d2fe58463384856f09f819b584.png) ### Vxlan模式能否实现? tn2>首先我们改成Vxlan的配置。 ![](https://img.tnblog.net/arcimg/hb/acbbb78ae78c4195878f5d3df653c1b6.png) tn2>然后我们在来看看接口。 ```bash calivppctl calivppctl vppctl bpf1 show interfaces ``` tn2>我们发现IPIP的没了,现在是vxlan的tunnel。 ![](https://img.tnblog.net/arcimg/hb/3d41ea14b0e54ab18770940dc77c966d.png) ```bash show vxlan tunnel ``` ![](https://img.tnblog.net/arcimg/hb/eed3325d59174780b72b67febecbee77.png) tn2>我们发现源ip,目的ip,源端口4789,目标端口4789,vni为4096。 接下来我们再抓个包看看。 ![](https://img.tnblog.net/arcimg/hb/4df36ce751474c94ab3b608433e93921.png) tn2>虽然有相关vxlan信息但是解不开数据。 当我们向外发包的时候,它会修改外部Mac地址为VPP的MAC地址,可以通过`show tap`来进行查看。 ## 总结 ![](https://img.tnblog.net/arcimg/hb/e51914cf0cd949d7894b8e4611d500b5.png)
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
👈{{preArticle.title}}
👉{{nextArticle.title}}
评价
{{titleitem}}
{{titleitem}}
{{item.content}}
{{titleitem}}
{{titleitem}}
{{item.content}}
尘叶心繁
这一世以无限游戏为使命!
博主信息
排名
6
文章
6
粉丝
16
评论
8
文章类别
.net后台框架
171篇
linux
17篇
linux中cve
1篇
windows中cve
0篇
资源分享
10篇
Win32
3篇
前端
28篇
传说中的c
4篇
Xamarin
9篇
docker
15篇
容器编排
101篇
grpc
4篇
Go
15篇
yaml模板
1篇
理论
2篇
更多
Sqlserver
4篇
云产品
39篇
git
3篇
Unity
1篇
考证
2篇
RabbitMq
23篇
Harbor
1篇
Ansible
8篇
Jenkins
17篇
Vue
1篇
Ids4
18篇
istio
1篇
架构
2篇
网络
7篇
windbg
4篇
AI
18篇
threejs
2篇
人物
1篇
嵌入式
4篇
python
13篇
HuggingFace
8篇
pytorch
9篇
opencv
6篇
Halcon
5篇
最新文章
最新评价
{{item.articleTitle}}
{{item.blogName}}
:
{{item.content}}
关于我们
ICP备案 :
渝ICP备18016597号-1
网站信息:
2018-2024
TNBLOG.NET
技术交流:
群号656732739
联系我们:
contact@tnblog.net
欢迎加群
欢迎加群交流技术