专栏首页Tungsten Fabric中文社区TF虚拟网络流量排错:在正确的时刻使用正确的工具
原创

TF虚拟网络流量排错:在正确的时刻使用正确的工具

我们总是希望一切都能如期进行。不过残酷的现实是,大多数时候,总会出现问题。

在排除网络故障时,第一个碰到的问题总是这个——“流量在哪里?”

事情变得有点“复杂”

对于虚拟网络来说,也依然如此!即使是在Tungsten Fabric集群内部,按理说,我们在故障排除环节的第一步,也会进行某种流量嗅探或流量识别。

那么……和传统的物理网络有什么不同呢?从概念上讲,没有什么不同……但是,在实践当中,事情会更复杂一些。我们所说的复杂,并不是指难以理解无从下手。所谓复杂,是指有更多的变数在起作用,但这并不一定意味着故障排除会非常难。相反,从另一个角度来看,这意味着我们可以使用更多的工具来更好地了解网络中发生的事情。

回到Tungsten Fabric集群,或者说是一般的虚拟环境,我们的目标是检查/监控进出某个虚拟机的流量。与传统的物理设备相比,如前所述,环境更加复杂。有了物理设备,就像有了一台一体化设备。但当移动到虚拟环境时,一体化设备就不存在了!你有物理服务器(计算)和连接到DC架构的NIC,你有管理程序,最后,你有虚拟机。虚拟机的流量会经过所有这些层次。在每个层次,都有工具可以用来检查/监控流量。这就是我说的“更复杂的场景”的意思,但也是为什么说,从另一个角度来看,这意味着有很多有用的武器可以满足我们的需求。

因此,了解在每个层面可以使用哪些工具是很重要的。我们必须掌握复杂性,并利用它!

让我们用一个例子来解决这个问题。例如有一个IP为192.168.10.3的虚拟机(VM1),这个虚拟机运行在compute1上。在compute2上,有另一个IP为192.168.10.4的虚拟机(VM2)。让我们从VM1 ping到VM2:

$ ping 192.168.10.4
PING 192.168.10.4 (192.168.10.4): 56 data bytes
64 bytes from 192.168.10.4: seq=0 ttl=64 time=44.812 ms
64 bytes from 192.168.10.4: seq=1 ttl=64 time=32.076 ms
64 bytes from 192.168.10.4: seq=2 ttl=64 time=6.418 ms
^C
--- 192.168.10.4 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 6.418/27.768/44.812 ms
$

Ping成功了!现在,我们要做的是识别和监控这些流量。

三个层次,三套工具

首先,正如之前预想的那样,我们必须掌握复杂性。在处理Tungsten Fabric集群时,我们可以识别3个层次:VNF,hypervisor和vRouter。

现在来看一下整个流程。

在VNF层面,我们拥有VNF提供的所有工具,可能有类似tcpdum的命令,或者如果VNF是一个防火墙,有一些东西可以查看流表内容。由于这个级别取决于厂商/VNF,这里不打算详细介绍。

再来看看vRouter。vRouter是Tungsten Fabric解决方案的核心,它提供并管理计算节点内部的所有虚拟网络。此外,它还提供了一系列不错的工具,可以用来了解集群内的流量是如何流动的。

要访问这套工具,首先要访问vRouter容器,通过连接到计算节点并使用知名的docker命令来实现。

[root@compute1 ~]# docker ps | grep vrouter
c1f441949cb5        hub.juniper.net/contrail/contrail-vrouter-agent:1911.31       "/entrypoint.sh /usr…"   8 days ago          Up 8 days                               vrouter_vrouter-agent_1
4333e1b1cf92        hub.juniper.net/contrail/contrail-nodemgr:1911.31             "/entrypoint.sh /bin…"   8 days ago          Up 8 days                               vrouter_nodemgr_1
[root@compute1 ~]# docker exec -it vrouter_vrouter-agent_1 bash
(vrouter-agent)[root@compute1 /]$

一旦我们进行到这里,就可以开始寻找流量了。

首先,确定VM的虚拟机接口(vif)。通过使用“vif”实用程序,匹配端口IP地址(192.168.10.3)来实现:

(vrouter-agent)[root@compute1 /]$ vif --list | grep -B 1 -A 1 192.168.10.3
vif0/3      OS: tapcae84676-cb NH: 33
            Type:Virtual HWaddr:00:00:5e:00:01:00 IPaddr:192.168.10.3
            Vrf:2 Mcast Vrf:2 Flags:PL3L2DEr QOS:-1 Ref:6

在这里,我们学到了很多有用的东西。

接口属于Vrf 2,这是一种路由表索引。虚拟接口索引是3(vif0/3)。最后,对应的tap接口是tapcae84676-cb。

下一个工具,我们可以使用rt。记住,我们要ping的是地址为192.168.10.4的远程虚拟机。

(vrouter-agent)[root@compute1 /]$ rt --get 192.168.10.4/32 --vrf 2
Match 192.168.10.4/32 in vRouter inet4 table 0/2/unicast

Flags: L=Label Valid, P=Proxy ARP, T=Trap ARP, F=Flood ARP
vRouter inet4 routing table 0/2/unicast
Destination           PPL        Flags        Label         Nexthop    Stitched MAC(Index)
192.168.10.4/32         0           LP         23             20        2:e7:fd:ee:27:78(148824)

上面的输出结果告诉我们流量将被发送到下一跳20。此外,它还说到将使用标签23。这表明,为了到达目的地,流量将不得不离开计算节点,并被封装成一个MPLSoUDP(或MPLSoGRE)包。这个标签就是将要推送的服务标签。

我们来检查下一跳:

(vrouter-agent)[root@compute1 /]$ nh --get 20
Id:20         Type:Tunnel         Fmly: AF_INET  Rid:0  Ref_cnt:6          Vrf:0
              Flags:Valid, MPLSoUDP, Etree Root,
              Oif:0 Len:14 Data:56 68 ac c3 28 02 56 68 ac c3 28 04 08 00
              Sip:192.168.200.3 Dip:192.168.200.4

正如想象的那样,下一跳是一个MPLSoUDP隧道,将流量从compute1(vhost0地址192.168.200.3)发送到compute2(vhost0地址192.168.200.4)。

请注意输出中的“Vrf:0”字段,这告诉我们,流量将通过VRF 0发送出去(如前所述,VM在VRF 2中)。Vrf 0是“fabric network”,连接计算节点和underlay的网络。此外,发送到下一跳20的流量将通过接口0(Oif 0)发送到Vrf 0(如前所述)。Oif 0是连接计算和底层的物理接口接口:

(vrouter-agent)[root@compute1 /]$ vif --get 0
Vrouter Interface Table
vif0/0      OS: ens3f1 (Speed 1000, Duplex 1) NH: 4
            Type:Physical HWaddr:56:68:ac:c3:28:04 IPaddr:0.0.0.0
            Vrf:0 Mcast Vrf:65535 Flags:TcL3L2VpEr QOS:-1 Ref:7
            RX packets:738213  bytes:47096090 errors:0
            TX packets:808295  bytes:42533041 errors:0
            Drops:30

这是vhost0所在的接口。Oif 0会“看到”封装的数据包。

综上所述,我们的虚拟机的流量属于VRF 2,在这个VRF里面,发生了查找(lookup)动作。在那里,通过Oif 0接口(物理接口),流量将被封装成MPLSoUDP数据包,然后发送到另一个计算节点。

下一个有用的工具,是“流(flow)”。vRouter默认是基于流的(可以通过将vmis设置为数据包模式来选择性地禁用每个vmi的流模式)。

让我们根据目的地来匹配流量:

(vrouter-agent)[root@compute1 /]$ flow --match 192.168.10.4
Listing flows matching ([192.168.10.4]:*)

    Index                Source:Port/Destination:Port                      Proto(V)
-----------------------------------------------------------------------------------
   512500518060       192.168.10.3:49409                                  1 (2)
                         192.168.10.4:0
(Gen: 1, K(nh):33, Action:F, Flags:, QOS:-1, S(nh):33,  Stats:4/392,  SPort 54199,
 TTL 0, Sinfo 3.0.0.0)

   518060512500       192.168.10.4:49409                                  1 (2)
                         192.168.10.3:0
(Gen: 1, K(nh):33, Action:F, Flags:, QOS:-1, S(nh):20,  Stats:4/392,  SPort 65513,
 TTL 0, Sinfo 192.168.200.4)

到目前为止,我们只看到了控制面信息:接口索引、路由表、下一跳。

这是第一次确认流量真的在虚拟机之间流动。

我们有2个流,因为每个流都是单向的。

这个输出有这么多信息!流量是流动的,因为Action被设置为F,也就是转发。

我们还知道,流量是ICMP,因为proto等于1。Proto旁边有“(V)”。这代表了VRF id,不出意外的话,它等于2!

最后,看到K(NH)和S(NH):这些是Key和Source(RPF)的下一跳。下一跳20我们已经看到了。此外,我们还看到下一跳33,它指向我们的本地虚拟机(vif 3):

(vrouter-agent)[root@compute1 /]$ nh --get 33 | grep Oif
              EncapFmly:0806 Oif:3 Len:14

我们可以从vRouter内部使用的东西就到这里了。

最后,我们进入到hypervisor层。我所说的“hypervisor层”指的是虚拟机和外界之间的那个中间层。这是虚拟机接口与物理网卡连接的地方。在这个层面我们能做的主要是嗅探流量。

先退出vRouter容器。

当使用vif时,我们能够定位到与该端口相关的tap接口“tapcae84676-cb”。

可以使用标准的tcpdump:

[root@compute1 ~]# tcpdump -i tapcae84676-cb -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tapcae84676-cb, link-type EN10MB (Ethernet), capture size 262144 bytes
09:24:55.082119 IP 192.168.10.3 > 192.168.10.4: ICMP echo request, id 49409, seq 688, length 64
09:24:55.107621 IP 192.168.10.4 > 192.168.10.3: ICMP echo reply, id 49409, seq 688, length 64
09:24:56.082344 IP 192.168.10.3 > 192.168.10.4: ICMP echo request, id 49409, seq 689, length 64
09:24:56.092153 IP 192.168.10.4 > 192.168.10.3: ICMP echo reply, id 49409, seq 689, length 64
^C
4 packets captured
10 packets received by filter
0 packets dropped by kernel

是的,这里就是我们的流量。

其次,可以直接在物理接口上嗅探流量。这里,我们将看到封装的流量。

在这个接口上,我们可能会看到许多不同类型的流量:到计算节点2的流量,到其它计算节点的流量,到控制节点的流量。此外,并非所有的流量都是MPLSoUDP。我们可以有VXLAN(L2虚拟化)流量或普通IP流量(XMPP)。出于这个原因,适当地过滤流量可能是有用的。

MPLSoUDP的流量可以通过6635端口过滤udp流量来缩小范围;VXLAN可以通过设置4789端口过滤udp流量。此外,我们还可以在目的主机IP上进行过滤,如之前学习的使用“rt”和“nh”,流量被发送到192.168.200.4:

[root@compute1 ~]# tcpdump -i ens3f1 -nn udp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens3f1, link-type EN10MB (Ethernet), capture size 262144 bytes
09:33:24.394590 IP 192.168.200.3.54199 > 192.168.200.4.6635: UDP, length 102
09:33:24.395915 IP 192.168.200.4.56128 > 192.168.200.3.6635: UDP, length 102
09:33:25.395362 IP 192.168.200.3.54199 > 192.168.200.4.6635: UDP, length 102
09:33:25.398488 IP 192.168.200.4.56128 > 192.168.200.3.6635: UDP, length 102
09:33:26.395541 IP 192.168.200.3.54199 > 192.168.200.4.6635: UDP, length 102
09:33:26.399384 IP 192.168.200.4.56128 > 192.168.200.3.6635: UDP, length 102
^C
6 packets captured
6 packets received by filter
0 packets dropped by kernel

正如你所看到的,我们在这些计算节点之间有双向的MPLSoUDP流量。无论如何,还不能确定这真的是我们的流量。为了确定这一点,我们可以将捕获到的数据保存到一个文件中,然后用wireshark打开,wireshark能够解码MPLSoUDP。

根据配置的封装优先级,可能VXLAN是用于计算到计算的流量。事实上,VXLAN是VN内部流量的默认选择,除非MPLSoUDP被配置在优先级列表中的第一位(无论如何,现在这并不重要……)。

我们只能说,我们必须期望处理不同类型的overlay流量。

其实VXLAN更方便用户使用,因为tcpdump可以显示内部数据包的内容:

[root@compute1 ~]# tcpdump -i ens3f1 -nn udp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens3f1, link-type EN10MB (Ethernet), capture size 262144 bytes
09:36:24.478515 IP 192.168.200.3.54199 > 192.168.200.4.4789: VXLAN, flags [I] (0x08), vni 5
IP 192.168.10.3 > 192.168.10.4: ICMP echo request, id 49409, seq 1377, length 64
09:36:24.479659 IP 192.168.200.4.56128 > 192.168.200.3.4789: VXLAN, flags [I] (0x08), vni 5
IP 192.168.10.4 > 192.168.10.3: ICMP echo reply, id 49409, seq 1377, length 64
09:36:25.478920 IP 192.168.200.3.54199 > 192.168.200.4.4789: VXLAN, flags [I] (0x08), vni 5
IP 192.168.10.3 > 192.168.10.4: ICMP echo request, id 49409, seq 1378, length 64
09:36:25.480214 IP 192.168.200.4.56128 > 192.168.200.3.4789: VXLAN, flags [I] (0x08), vni 5
IP 192.168.10.4 > 192.168.10.3: ICMP echo reply, id 49409, seq 1378, length 64
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel
[root@compute1 ~]#

在这里,我们可以看到实际的VM ICMP数据包。这样就可以确定是否为我们的流量。

只要我们的计算节点是在内核模式下,使用tcpdump就是可能的。如果我们有一个dpdk vRouter,那么就不能在主机上使用tcpdump,因为dpdk会“吃掉接口”,使它们对内核不可见(tcpdump在内核可见的接口上工作)。在这种情况下,hypervisor层消失了,我们必须依靠vRouter层。

一旦我们进入vRouter容器,一个至今没有见过的工具就成了基础:vifdump。Vifdump就像tcpdump一样,只是它工作在DPDK接口上,只能在vRouter容器内部运行。

要嗅探一个虚拟机接口:

vifdump -i vif0/3 -nn icmp

要嗅探一个物理接口:

vifdump -i vif0/0

总结

就是这样!让我们总结一下所有的可能性——

在VNF层面,使用厂商/VNF特定的工具。

在vRouter层面(工具要在vRouter容器内运行):

  • vif,列出虚拟接口
  • nh,了解流量计算一个特定的nexth-hop索引是在哪里发送的
  • flow,查看vRouter上的活动流量
  • rt,查看vRouter路由表内部

在hypervisor层面,使用tcpdump来嗅探虚拟接口和物理接口上的数据包。

最后,如果节点是DPDK节点,那么主机级的tcpdump就没有用了,用vRouter容器里面运行的“vifdump”代替。

现在没有秘密了吧?一句话,在正确的层面上使用正确的工具~


作者:Umberto Manferdini 译者:TF编译组 原文链接: https://iosonounrouter.wordpress.com/2020/04/13/troubleshooting-contrail-vms-traffic-the-right-tool-at-the-right-moment/

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • TF功能开发路线图:盘点2021年Tungsten Fabric聚焦领域

    在Linux基金会主办的“LFN技术会议”上,Tungsten Fabric社区进行了一系列演讲,介绍最新的功能和未来发展方向。今天带来第一篇演讲,看看Tung...

    Tungsten Fabric
  • pps数据无法回答“哪种SDN解决方案更好”,你需要考虑这些

    最近我参与了一个项目,我们在Tungsten Fabric(注:原文为Contrail,本文将以功能一致的Tungsten Fabric替换)集群中部署了虚拟移...

    Tungsten Fabric
  • TF+ OpenStack部署指南丨利用OpenStack TF配置虚拟网络

    成功安装Tungsten Fabric的下一步,是了解在具体的配置场景中使用编排器部署Tungsten Fabric的工作流程。前面讨论了Kubernetes的...

    Tungsten Fabric
  • Tungsten Fabric:连接CMP的金钥匙丨TF Meetup演讲实录

    本文所有相关资料 https://tungstenfabric.org.cn/assets/uploads/files/cmp-key-shuxun.pdf

    Tungsten Fabric
  • Tungsten Fabric如何编排

    OpenStack是虚拟机和容器的领先的开源编排系统。Tungsten Fabric提供了Neutron网络服务的实现,并提供了许多附加功能。

    Tungsten Fabric
  • 在NVIDIA Jetson TX2上安装TensorFlow

    刷机的目的是把Ubuntu操作系统和JetPack SDK安装到Jetson TX2上。刷机的操作按照官方教程即可,比较容易。这个过程中有一点需要注意:Jets...

    用户1332428
  • 资源 | 给卷积神经网络“修理工”的一份“说明书”

    这篇文章的主要内容来自作者的自身经验和一些在线资源(如最出名的斯坦福大学的CS231n课程讲义),是关于如何调试卷积神经网络从而提升其性能的。

    大数据文摘
  • 配置SDN网关:关于VRF、本地路由及inet-vpn路由

    上次谈到SDN网关及其在Tungsten Fabric集群中的作用,简单地说,SDN网关是Tungsten Fabric和网络其它部分之间的“胶水”。

    Tungsten Fabric
  • 为OpenStack和K8s集群提供无缝虚拟网络

    现实情况下,可能会发生虚拟机和容器需要相互“交谈”的情况。如果是这样,我们需要以某种方式实现两个独立集群之间的通信。

    Tungsten Fabric
  • 面试总问的jvm调优到底是要干什么?

    没有那家卖瓜的会说自己家的不甜,同样,没有哪个开源项目愿意告诉你在对它条件最苛刻的时候压力情况是多少,一般官网号称给你看的性能指标都是在最理想环境下的,...

    田维常
  • 闲置资源再利用:个人电脑上畅玩 TensorFlow

    眼下 github 社区最火的开源项目莫过于 tensorflow (后简称TF),本文介绍一种基于windows平台下搭建 TF 运行和开发环境,带大家畅玩 ...

    陈林峰
  • Tungsten Fabric入门宝典丨关于服务链、BGPaaS及其它

    Tungsten Fabric入门宝典系列文章,来自技术大牛倾囊相授的实践经验,由TF中文社区为您编译呈现,旨在帮助新手深入理解TF的运行、安装、集成、调试等全...

    Tungsten Fabric
  • Learning to Rank 小结

    一、学习排序(Learning to Rank) LTR(Learning torank)学习排序是一种监督学习(SupervisedLearnin...

    智能算法
  • 如何在SDN GW上汇总虚拟机路由

    在Tungsten Fabric中,每个虚拟网络都不过是vRouter上的一个VRF。这使得vRouter在经典的L3VPN场景中看起来像是一个PE节点。

    Tungsten Fabric
  • Tungsten Fabric:为云网络而生的SDN控制器

    在当前的IT市场中,组织正将其旧的基础设施迁移到云上,其基础设施的每个部分都在向云化的方向发展。因此,我们有必要来看一下为云级网络(cloud-grade ne...

    Tungsten Fabric
  • TF Live丨KK/建勋:多云、SDN,还有网工进化论

    3月18日,第一场【TF Live】如约而至,活动持续了两个多小时,在线人数将近1000人,互动讨论热闹十足。TF中文社区技术代表、瞻博网络全国合作伙伴技术经理...

    Tungsten Fabric
  • 【AI in 美团】深度学习在美团搜索广告排序的应用实践

    AI(人工智能)技术已经广泛应用于美团的众多业务,从美团App到大众点评App,从外卖到打车出行,从旅游到婚庆亲子,美团数百名最优秀的算法工程师正致力于将AI技...

    美团技术团队
  • 【AI in 美团】深度学习在美团搜索广告排序的应用实践

    AI(人工智能)技术已经广泛应用于美团的众多业务,从美团App到大众点评App,从外卖到打车出行,从旅游到婚庆亲子,美团数百名最优秀的算法工程师正致力于将AI技...

    石晓文
  • Tungsten Fabric架构和最新技术进展

    本文整理自瞻博网络杰出工程师Sukhdev Kapur在“TF中文社区成立暨第一次全员大会”上的演讲,增加了对于TF功能的描述。

    Tungsten Fabric

扫码关注云+社区

领取腾讯云代金券