AWS上的Cilium网络拓扑和流量路径
Table of Contents
1准备
1.1测试环境
1.2容器网和 nsenter
1.3验证基本连接
2个出口:Pod->主机-> VPC网络
2.1容器内部网络
1.2 Veth对连接到主机
1.3出口BPF代码
1.4主机路由表
2入口
2.1主机路由表
2.2入口BPF代码
2.3集装箱收货
3小结
参考文献
相关阅读
发表于2019-10-26 | 最后更新2019-10-26
这篇文章探讨了在AWS上由Cilium驱动的K8S集群中两个跨主机Pod之间的网络拓扑和流量路径。我们将使用普通的Linux命令来完成此任务。在这篇文章的结尾,我们将获得如下图片:
1准备
1.1测试环境
我们有两个K8S主机:
- 节点1:
10.5.2.48
- 节点2:
10.5.2.58
和两个豆荚:
- 节点1
10.5.2.11
上的pod1 10.5.2.22
node2上的pod2
节点和Pod在同一VPC中,带有VPC网关10.5.2.1
。
注意:出于安全原因以及易于理解,我用伪造的IP / MAC地址代替了真实的IP / MAC地址。这不应破坏此职位的意义。
1.2容器网和 nsenter
我们将使用nsenter
工具工具在主机上容器的网络名称空间中执行命令,格式为:
$ nsenter -t <pid> -n <command>
哪里,
-t <pid>
:目标过程<pid>
-n
:输入网络名称空间<command>
:执行命令
这等效于docker exec <container> <command>
,但比后者更灵活,因为通常缺少网络工具或容器内部没有特权,因此在主机上执行命令没有此限制。
获取容器进程ID:
root@node1 # docker inspect 04d740a33726 | grep Pid"Pid": 75869,
75869
就是pid
我们想要的。
1.3验证基本连接
从pod1 ping pod2,确保其可访问:
root@node1 # nsenter -t 75869 -n ping 10.5.2.22 -c 2
64 bytes from 10.5.2.22: icmp_seq=1 ttl=61 time=0.248 ms
64 bytes from 10.5.2.22: icmp_seq=2 ttl=61 time=0.208 ms
好!接下来,我们将探索这些数据包的确切路径,即网络设备,路由表,arp表,BPF挂钩。
2个出口:Pod->主机-> VPC网络
2.1容器内部网络
从pod1开始我们的旅程。检查pod1内的网络设备:
root@node1 # nsenter -t 75869 -n ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000...
42: eth0@if43: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UPlink/ether ee:14:d3:9a:62:42 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 10.5.2.11/32 brd 10.5.2.11 scope global eth0
可以看出,它具有一个loopbak接口lo
和一个eth0
IP地址为IP的网络接口10.5.2.11
。
请注意42: eth0@if43
,此特殊符号表示eth0
具有 ifindex
编号42
,并且设备带有ifindex
42
并43
组成veth对。这ifindex
在主机(在本例中为node1)中是唯一的,稍后我们将再次看到。
接下来,检查容器内的路由表:
root@node1 # nsenter -t 75869 -n route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.5.2.191 0.0.0.0 UG 0 0 0 eth0
10.5.1.191 0.0.0.0 255.255.255.255 UH 0 0 0 eth0
可以看出,该Pod的网关为10.5.1.191
,所有出口流量都将转发到该网关。在主机上查找网关:
root@node1 # ip a | grep 10.5.2.191 -B 2
31: cilium_host@cilium_net: <...> mtu 9001 ... qlen 1000link/ether 0a:ee:d6:5f:6c:32 brd ff:ff:ff:ff:ff:ffinet 10.5.2.191/32 scope link cilium_host
我们可以看到容器网关是由device持有的cilium_host
。其实 cilium_host
并cilium_net
撰写另一VETH对,他们都对主机的网络空间,并将于纤毛代理开始创建。
接下来,检查容器内的ARP表:
root@node1 # nsenter -t 75869 -n arp -n
Address HWtype HWaddress Flags Mask Iface
10.5.2.191 ether 86:05:d4:99:a9:f5 C eth0
10.5.2.48 ether 86:05:d4:99:a9:f5 C eth0
可以看出,容器的网关和主机IP都指向相同的MAC地址86:05:d4:99:a9:f5
。让我们进一步确定哪个设备拥有该地址。
可以看出,容器的网关和主机IP都指向相同的MAC地址86:05:d4:99:a9:f5
。让我们进一步确定哪个设备拥有该地址。
1.2 Veth对连接到主机
root@node1 # ip link | grep 86:05:d4:99:a9:f5 -B 1
43: lxc050ba70e11a8@if42: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc ... qlen 1000link/ether 86:05:d4:99:a9:f5 brd ff:ff:ff:ff:ff:ff link-netnsid 1
而已!设备lxc050ba70e11a8
持有它。请注意43: lxc050ba70e11a8@if42
符号,并回想一下容器的eth0
实际持有ifindex=42
,因此我们现在确保:
- pod1通过veth对(
if42 <--> if43
或名称表示eth0 <--> lxc050ba70e11a8
)连接到主机 - Pod中的默认网关指向
cilium_host
主机上的设备 - Pod生成流量的下一个L3跃点是
cilium_host
- Pod产生流量的下一个L2跳是第ve对(
lxc050ba70e11a8
)的主机端
这正是Pod出口流量从容器流向主机的方式。
1.3出口BPF代码
Cilium的强大功能之一是动态流量操纵。它通过利用BPF来实现。关于此主题的详细说明不在本文的范围之内,如果您有兴趣的话,请参阅官方文档《BPF和XDP参考指南》( 如果您可以阅读中文,请参阅我的 翻译)。
Cilium使用tc
BPF过滤容器的进出流量。让我们看一下出口部分:
root@node1:~ # tc filter show dev lxc050ba70e11a8 egress
filter protocol all pref 1 bpf
filter protocol all pref 1 bpf handle 0x1 bpf_lxc.o:[from-container] direct-action not_in_hw tag db59e2ea8177ded3
注意:如果以上命令的输出未显示该
bpf_lxc.o:[from-container] direct-action not_in_hw tag db59e2ea8177ded3
信息,则可能是您的iproute2
软件包太旧了,请尝试升级到新版本。
列出此主机(节点1)上所有已加载的BPF程序:
root@node1:~ # bpftool prog
288: sched_cls tag a390cb0eda39ede9loaded_at Oct 22/10:48 uid 0xlated 808B jited 637B memlock 4096B map_ids 182,169
...
294: sched_cls tag 596c1921e0319e72loaded_at Oct 22/10:48 uid 0xlated 176B jited 157B memlock 4096B
297: sched_cls tag db59e2ea8177ded3loaded_at Oct 22/10:48 uid 0xlated 19144B jited 11706B memlock 20480B map_ids 285,169,171,286,287,172,277,183,283,173,179,167,180
让我们进一步了解BPF代码/规则是什么样的。转储解释的BPF代码:
root@node1:~ # bpftool prog dump xlated id 2970: (bf) r6 = r11: (b7) r7 = 02: (63) *(u32 *)(r6 +60) = r73: (63) *(u32 *)(r6 +56) = r74: (63) *(u32 *)(r6 +52) = r75: (63) *(u32 *)(r6 +48) = r76: (63) *(u32 *)(r6 +64) = r77: (18) r2 = 0xffffff5a9: (79) r1 = *(u64 *)(r6 +80)10: (79) r8 = *(u64 *)(r6 +216)...
转储JITed BPF代码:
root@node1:~ # bpftool prog dump jited id 2970: push %rbp1: mov %rsp,%rbp4: sub $0x228,%rspb: sub $0x28,%rbpf: mov %rbx,0x0(%rbp)13: mov %r13,0x8(%rbp)17: mov %r14,0x10(%rbp)1b: mov %r15,0x18(%rbp)1f: xor %eax,%eax21: mov %rax,0x20(%rbp)...
好的,无需进一步挖掘。如果出口流量没有被BPF代码/规则丢弃,它将到达主机,主机路由设施将对其进行处理。
1.4主机路由表
查看主机路由表:
root@node1:~ # ip rule list
9: from all fwmark 0x200/0xf00 lookup 2004
100: from all lookup local
32766: from all lookup main
32767: from all lookup default
我们看到,有4个路由表:2004
,local
,main
,default
。检查每个内容:
root@node1:~ # ip route show table 2004
local default dev lo scope hostroot@node1 $ ip route show table main
default via 10.5.2.1 dev eth0
10.5.2.0/24 dev eth0 proto kernel scope link src 10.5.2.48
来自Pod1的出口流量将到达main
桌面。
注意:更具体地说,Pod IP是从ENI分配的,每个ENI都有自己的路由表以用于出口流量。在我的情况下,Pod1的IP来自节点1的默认ENI(eth0),因此流量将到达
main
表中。如果您有多个ENI,则此处的路由应该有所不同。
该main
路由表也是节点1的默认路由表(不要”由误导default
表上方,它只是一个名称表default
,而不是主机的默认表)。
node1的默认网关为10.5.2.1
(VPC网关)。因此,pod1的出口流量最终将被发送到VPC网关。
这样就完成了我们的交通旅程的出口部分。
2入口
如果VPC网络将流量正确路由到Node2(供应商的责任),则这些数据包将到达Node2的相应ENI。让我们来看看如何处理这些数据包。
2.1主机路由表
root@node2:~ # ip rule list
9: from all fwmark 0x200/0xf00 lookup 2004
100: from all lookup local
32766: from all lookup main
32767: from all lookup default
root@node2:~ # ip route show table 2004
local default dev lo scope hostnode2 $ ip route show table main
default via 10.5.1.1 dev eth0
10.5.2.22 dev lxcd86fc95bf974 scope link
...
可以看出,Pod2有一条专用的路由:
10.5.2.22 dev lxcd86fc95bf974 scope link
这意味着所有发10.5.2.22
往的流量都将转发到 lxcd86fc95bf974
。
2.2入口BPF代码
Cilium将lxcxx
为其创建的每个设备注入入口BPF规则。让我们检查一下这个:
root@node2:~ # tc filter show dev lxcd86fc95bf974 ingress
filter protocol all pref 1 bpf
filter protocol all pref 1 bpf handle 0x1 bpf_lxc.o:[from-container] direct-action not_in_hw tag c17fab4b3f874a54
如果您对确切的BPF代码感兴趣,那么以下步骤与我们之前的出口部分大致相同:
root@node2:~ # bpftool prog
156: sched_cls tag a390cb0eda39ede9loaded_at Oct 22/10:59 uid 0xlated 808B jited 637B memlock 4096B map_ids 46,33
...
165: sched_cls tag c17fab4b3f874a54loaded_at Oct 22/10:59 uid 0xlated 19144B jited 11706B memlock 20480B map_ids 155,33,35,156,157,36,147,47,153,37,43,31,44root@node2:~ # bpftool prog dump xlated id 165 | head -n 100: (bf) r6 = r11: (b7) r7 = 02: (63) *(u32 *)(r6 +60) = r73: (63) *(u32 *)(r6 +56) = r74: (63) *(u32 *)(r6 +52) = r75: (63) *(u32 *)(r6 +48) = r76: (63) *(u32 *)(r6 +64) = r77: (18) r2 = 0xffffff5a9: (79) r1 = *(u64 *)(r6 +80)10: (79) r8 = *(u64 *)(r6 +216)
2.3集装箱收货
如果流量没有被Cilium网络策略规则(入口BPF)丢弃,则数据包将通过主机端的veth对,并最终到达 eth0
内部容器-我们旅程的最终目的地。
现在在这里重新描述全局数据流图:
3小结
这篇文章探讨了AWS上由Cilium驱动的K8S集群中两个Pod之间的主机间流量的网络拓扑和数据流。我们使用了常见的Linux命令行工具来完成此任务。希望对您有帮助!
参考文献
- Cilium:BPF和XDP参考指南
- Cilium:AWS ENI
- Cilium:AWS ENI数据路径
相关阅读
《深入理解 Cilium 的 eBPF(XDP)收发包路径:数据包在Linux网络协议栈中的路径》
《iptables详解(1):iptables概念》
《iptables详解(2):路由表》
《eBPF.io eBPF文档:扩展的数据包过滤器(BPF)》
《介绍Calico eBPF数据平面:Linux内核网络、安全性和跟踪(Kubernetes、kube-proxy)》
《Linux eBPF和XDP高速处理数据包;使用EBPF编写XDP网络过滤器;高性能ACL》
《深入理解 Cilium 的 eBPF 收发包路径》
《Understanding (and Troubleshooting) the eBPF Datapath in Cilium》
《kubernetes(K8s):管理云平台中多个主机上的容器化的应用》
AWS上的Cilium网络拓扑和流量路径相关推荐
- AWS — AWS 上的 5G 网络及 MEC 边缘计算商业案例
目录 文章目录 目录 AWS 与 Verizon 推出的 Private MEC AWS 与 Vodafone Business 合作推出 MEC 解决方案 AWS.ERICSSON 与 Telefo ...
- AWS — AWS 上的 5G 网络切片
目录 文章目录 目录 5G 网络切片 AWS 上的 5G 网络切片 Native Solution Cloudify Solution 使用 Cloudify Catalog 作为管理 NSI 的一个 ...
- AWS — AWS 上的 5G 网络
目录 文章目录 目录 AWS 上的 E2E 5G 网络 AWS 上的 5G Core Network Service Based Architecture CP 的高可用部署 UP 的多网络平面 St ...
- 无浮动IP的虚机出公网流量路径
女主宣言 通过Neutron构建网络时涉及的知识点比较广,虚拟化网络实施上又具有非常大的灵活性,这往往会让刚接触的同学摸不着头脑.本文特意对"无浮动IP的虚机出公网流量路径"这一场 ...
- AWS — AWS 上的 DevOps
目录 文章目录 目录 AWS 上的 DevOps AWS 上的 DevOps 在 AWS 上部署 5G 网络的好处之一是,用户可以根据需要,使用一系列的 AWS DevOps 开发者工具集来轻松快速地 ...
- 端口镜像 流量过滤_在 AWS 云环境中滥用 VPC 流量镜像抓取网络流量
云环境下的网络检测问题 人们可能希望监视云环境中的网络流量有很多原因--出于攻击和防御的目的.被动的网络检查在云环境中可能很困难,而且在这之前需要对网络配置进行重大修改,以确保每台主机都被监控,并且不 ...
- 想做网上线上引流怎么做?如何通过网络获取流量?
想做网上线上引流怎么做?如何通过网络获取流量? 现在很多人都在问关于"引流"."流量"的问题,对于这些问题实际上背后的道理都是一样的,我们需要了解的是: &qu ...
- Cilium网络概述
K8s已经成为一线大厂分布式平台的标配技术.你是不是还在惆怅怎么掌握它?来这里,大型互联网公司一线工程师亲授,不来虚的,直接上手实战,3天时间带你搭建K8s平台,快速学会K8s,点击下方图片可了解培训 ...
- 最强 CNI 基准测试:Cilium 网络性能分析
作者:Thomas Graf 译者:罗煜.张亮,均来自 KubeSphere 团队 Thomas Graf 是 Cilium 的联合创始人,同时也是 Cilium 母公司 Isovalent[1] 的 ...
最新文章
- hihoCoder #1142 : 三分求极值
- python 之三级菜单
- linux ar 命令详解
- openwrt x86 登录不上_求助,关于OpenWRT外接硬盘不识别的问题
- JUnit 5 Alpha版本简化了单元测试
- 清华大学操作系统OS学习(十二)——信号量与管程
- DPDK - flow Haripin
- 通过银行卡号获取银行名称和银行图标的ICON
- C++死锁与哲学家就餐问题
- 走火入魔的macfans,披着mac皮的ubuntu macbuntu安装指南
- 项目如行军——《孙子兵法》之九地篇
- 亲爱的,60句感人歌词,有没有一句触动了你
- 大厂软件测试流程完整版
- TSV文件与CSV文件的区别
- vue项目将px转为rem实践
- socketDemo套接字
- SpringBoot物流管理项目(源码下载)
- Android animation呼吸动画 心形动画
- CSSAPP稀里糊涂的读书笔记(一)计算机系统漫游
- 项目管理工具之apizza
热门文章
- ORA-01034: ORACLE not available
- SPSS 限制检索个案
- Netty 编解码器和 Handler 调用机制
- vue中的状态管理 vuex store
- python写exploit采集器
- [转载]如何做一个出色的程序员
- 3 - Spring AOP
- 输入法中的全角和半角是什么,角又是什么
- linux 启动tomcat 怎么显示日志文件,随着LINUX的启动,打开一个终端显示TOMCAT的日志文件,请问如何做到?...
- linux修改ip dhcp,Linux下在静态IP与动态DHCP之间切换的脚本