tnblog
首页
视频
资源
登录

Kubernetes Calico VPP软协议栈

6475人阅读 2022/11/24 14:05 总访问:3464961 评论:0 收藏:0 手机
分类: 容器编排

Kubernetes Calico VPP软协议栈

VPP简介


VPP(Vector Packet Processor)是一个高性能、开源的用户空间网络数据平面,用C语言编写,在 fd.io 旗下开发。它支持许多标准网络功能(L2、L3路由、NAT、封装),并且可以使用插件轻松扩展。VPP数据平面使用插件来有效地实现Kubernetes服务负载平衡和Calico策略。

简单来说,它就是个跑在用户空间的TCP/IP协议栈,不需要进入内核。那么它的实现就如下图所示:

安装VPP

安装前提


首先我们需要一个空白的集群环境,也就是相当执行kubeadm init后没有安装CNI的其他插件。
第二就是内核版本需要很高。

HugePages概述


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


通过以下hugepages配置可能使VPP能够使用更高效的驱动程序:
至少512 x 2MB hugepage可用(grep hugepages_Free/proc/meminfo
加载vfio_pci(centos上的vfio_pci)或uio_pci_generic内核模块。例如:

  1. echo "vfio-pci" > /etc/modules-load.d/95-vpp.conf
  2. modprobe vfio-pci
  3. echo "vm.nr_hugepages = 512" >> /etc/sysctl.conf
  4. # 生效
  5. sysctl -p
  6. # 重新启动kubelet以将更改考虑在内
  7. # 根据kubelet的安装方式,您可能需要使用不同的命令
  8. systemctl restart kubelet

安装Calico与配置VPP


安装Calico与VPP

  1. kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.5/manifests/tigera-operator.yaml
  2. kubectl apply -f https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.24.0/yaml/calico/installation-default.yaml


然后我们等待一下Pod的安装。

安装VPP数据平面组件


首先获取VPP数据平面资源的适当yaml清单:

  1. # 如果设置了hugepages
  2. curl -o calico-vpp.yaml https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.24.0/yaml/generated/calico-vpp.yaml
  3. # 没有设置,或不确定使用
  4. curl -o calico-vpp.yaml https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.24.0/yaml/generated/calico-vpp-nohuge.yaml


这里我们选者后者的下载。
VPP快的原因除了不走内核,还有就是CPU是专用的。
vpp_dataplane_interface是vpp将使用的主要接口。它必须是Linux接口的名称,并使用地址进行配置。此接口上配置的地址必须是Kubernetes中的节点地址。

  1. # 查看我们的网络接口
  2. ifconfig
  3. # 查看虚拟网口的速度
  4. ethtool ens33
  5. vim calico-vpp
  6. # 修改vpp_dataplane_interface: ens33


我们知道VPP可以进行各种各样的包数据进行处理,但是它发出去的时候是通过uplink_interface进行发出去的,vpp_uplink_driver这个参数可以设置具体应该设置什么来快速处理包发出去。举例:dpdk。
这里我们就选默认的即可(模式是af_packet : 使用af_packet套接字驱动接口(未优化,但在任何地方都有效))。
更多请参考:


接下来我们还需要设置Kubernetes中Service的网段也就是service_prefix参数。(可通过如下命令进行查看)

  1. kubectl cluster-info dump | grep -m 1 service-cluster-ip-range


最后Apply一下,完成VPP的安装。

  1. kubectl apply -f calico-vpp.yaml

物理网卡变了?


我们通过ethtool ens33查询发现它的速度从千兆网速度变成了10MB/s,并且物理网卡变成了一个TAP设备。
到这里你可能会问了为什么会这样?


由于我们VPP是用户态的,所以通过TAP/TUN来连接处理数据包。
更多大家可以参考我以往的文章:http://tnblog.net/hb/article/details/7233#TAP%E4%B8%8ETUN%E8%AE%BE%E5%A4%87

简单来讲就是一端连在我们的协议栈一端连接在我们的IP层。


那既然这样包都出不去,我们的ens33物理端口被谁拿走了呢?
答案是被VPP拿走了。我们可以安装calicovpctl来进行查看。

安装calivpctl


calivpctl是vpp容器映像附带的一个助手bash脚本。它可以通过以下方法安装到主机上,并有助于收集日志和调试安装了VPP数据平面的正在运行的集群。

  1. curl https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.24.0/test/scripts/vppdev.sh \
  2. | tee /usr/bin/calivppctl
  3. chmod +x /usr/bin/calivppctl

VPP处理过程


然后我们进入到VPP中。

  1. calivppctl
  2. # 这里的bpf1是通过查看安装好的VPP控制Pod的后缀名称获取到的
  3. calivppctl vppctl bpf1


我们知道VPP是用户态的协议栈,内核协议栈能够处理的它同样能够处理,所以我们把它ens33的主机网卡拿走了我们同样可以处理。不然拿走了我们的ssh就连接不上主机了。
这里我们来查看一下接口处理情况。

  1. show interfaces


我们还可以通过查看物理网卡对接的情况来看。
host-ens33就是对接的我们的物理网卡ens33,并且连物理mac地址都没有变化。

  1. show hardware-interfaces


再来我们在查看接口中有ipip0和ipip1,那么是不是有tunnl呢?
通过查看网卡并没有发现tunnel相关的网卡。
我们可以通过查看Tunnl的方式来查看相关信息。

  1. show ipip tunnel


我们发现这里写好了从源ip地址和目标地址,意思就是现在ipip由vpp来进行处理。


在来我们这里有tap0设备,它是一个vpp的tap文件但这把它当成一个网卡,那么其他pod的另一端在哪儿呢?
我们首先尝试创建几个pod。

  1. kubectl apply -f cni.yaml
  2. # 运行起来后查看pod的接口
  3. kubectl get pod
  4. kubectl exec -it cni-kpfnz -- bash
  5. ifconfig
  6. ip tuntap list


可以看到这个eth0它是没有mac地址的,卧槽为什么没有地址啊?因为它是点对点(P-t-P)的设备一个tun设备,就像两头直接连着线的所以不需要MAC地址,就IP地址就可以了。
我们在VPP中也是可以找到的,我们可以看到有很多tun设备就是它们连接的vpp这一端。

  1. show interfaces
  2. show interfaces address


刚刚我们连接的容器就是tun5的10.244.11.75

所以整个创建的流程是这样:
当在主机上调度Pod时,kubelet服务将为新Pod创建网络名称空间,然后使用CNI请求Calico在此名称空间中配置接口。Calico将首先计算主机的IP配置(地址和路由),然后将其传递给VPP代理。然后,VPP将在所需的容器名称空间中创建tun接口,并使用所需的地址和路由对其进行配置。这使得所有的集装箱流量都通过VPP。


我们可以看到路由表都是直接走eth0,然后交给VPP协议栈处理,看看其他的tun对应的ip在哪儿。

  1. # 一个pod中ping
  2. ping xxxxx
  3. # vpp中抓包
  4. pcap trace rx tx max 30000 intfc any
  5. pcap trace off


这里抓的包在calico vpp的 pod里面,所以我们可以复制拿出来,当然也可以从节点中直接获取到。

  1. find / -name rxtx.pcap


然后直接拿下来进行分析,我们发现它直接实现了ipip。

Vxlan模式能否实现?


首先我们改成Vxlan的配置。


然后我们在来看看接口。

  1. calivppctl
  2. calivppctl vppctl bpf1
  3. show interfaces


我们发现IPIP的没了,现在是vxlan的tunnel。

  1. show vxlan tunnel


我们发现源ip,目的ip,源端口4789,目标端口4789,vni为4096。
接下来我们再抓个包看看。


虽然有相关vxlan信息但是解不开数据。
当我们向外发包的时候,它会修改外部Mac地址为VPP的MAC地址,可以通过show tap来进行查看。

总结


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

net core 使用 EF Code First

下面这些内容很老了看这篇:https://www.tnblog.net/aojiancc2/article/details/5365 项目使用多层,把数据库访问...

cAPS.net 保存base64位格式的图片

publicvoidUpload() { //取出图片对应的base64位字符 stringimgBase=Request["imgBase"]; //c#里边的base6...

Quartz.net实例动态改变周期调度。misfire、Cron

Quartz:Java编写的开源的任务调度作业框架 类似Timer之类定时执行的功能,但是更强大Quartz.NET:是把Quartz转成C# NuGet...

.net Windows服务发布、安装、卸载、监听脚本。服务调试

一、脚本 为方便不用每次都去写安装卸载的脚本1.安装脚本@echooff @echo开始安装【服务】 %SystemRoot%\Microsoft.NET\Fr...

c、VB.net中全角半角转换方法

///<summary> ///转全角的函数(SBCcase) ///</summary> ///<paramname="input">任意字符串...

.net mvc分部页,.net core分部页

.net分部页的三种方式第一种:@Html.Partial("_分部页")第二种:@{ Html.RenderPartial("分部页");}...

C.net 配合小程序实现经过第三方服务器中转文件

某些时候,微信小程序前段上传文件的时候需要经过第三方服务器再将文件上传到客户的服务器;操作如下:1:(小程序内向中端服...

.net实现QQ邮箱发送邮件功能

1、微软已经帮我们封装好了发送邮件的类MailMessage,MailMessage类构造一些邮件信息,然后通过SmtpClient进行邮件发送。Mai...

StackExchange.Redis操作redis(net core支持)

官方git开源地址https://github.com/StackExchange/StackExchange.Redis官方文档在docs里边都是官方的文档通过nuget命令下...

windows 自带的netsh进行端口映射

使用netsh 把本地任意ip的25566端口 映射到192.168.81.234的25565端口netshinterfaceportproxyaddv4tov4listenaddress=0.0....

确保.net程序始终以管理员身份运行

usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; ...

ASP.net Timer细节处理

Timer的用法:1:本人称之为计时器,是asp.net官方的一种。用法即是计时所用 2:关于计时有很多中方式,本人学识有限,暂...

.net core 使用session

tip:net core 2.2后可以直接启用session了,不用在自己添加一次session依赖,本身就添加了使用nuget添加引用Microsoft.AspN...

通俗易懂,什么是.net?什么是.net Framework?什么是.net core?

朋友圈@蓝羽 看到一篇文章写的太详细太通俗了,搬过来细细看完,保证你对.NET有个新的认识理解原文地址:https://www.cnblo...

asp.net core2.0 依赖注入 AddTransient与AddScoped的区别

asp.net core主要提供了三种依赖注入的方式其中AddTransient与AddSingleton比较好区别AddTransient瞬时模式:每次都获取一...
这一世以无限游戏为使命!
排名
2
文章
633
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术