博观而约取,厚积而薄发。这篇文章主要讲述Cilium native-routing 跨节点通信相关的知识,希望能为你提供帮助。
native routingvshost-routing,区别?
native routing 就是 flannel 中的 host-gateway模式,纯路由模式
host-routing = ??bpf_redict_peer()?
?和 ??bpf_redict_neigh()?
?,跳过 iptables
这俩一个是路由,一个是绕过iptables
在 cilium 的这篇博客中,详细说了eBPF Host-Routing
https://cilium.io/blog/2021/05/11/cni-benchmark
native routing??cilium-native-routing??
native routing 直接翻译过来就是本地路由
在官网的介绍中说的很明白,在 ??tunnel: disabled?
? 的情况下,默认开启 native routing 的转发模式。native routing 模式利用了 Cilium 网络的路由能力,而不是二次封装的模式。
如图:Cilium 维护的是 Routingtable,这意味着数据包将被路由,就和本地进程发出的数据包一样,所以连接集群节点的网络必须能都对 Pod CIDR 进行路由。
部署为 native routing 模式需要将之前生成的 yaml 文件修改如下图所示地方
需要先 delete 然后在 apply
# 修改tunnel
tunnel: disabled
# 添加 pod CIDR,使 node 节点能对 pod CIDR 进行路由
native-routing-cidr: "10.0.0.0/16"
# 修改如下选项为 true
auto-direct-node-routes: "true"
不同节点 pod 通信
node-1192.168.0.120
node-2192.168.0.130
pod1 10.0.0.85in node-1
pod2 10.0.1.124in node-2
root@master:~# kubectl get pod -o wide
NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES
cni-test-777bbd57c8-2f9861/1Running052s10.0.0.85node-1.whale.com<
none>
<
none>
cni-test-777bbd57c8-d7wlv1/1Running052s10.0.1.124node-2.whale.com<
none>
<
none>
查看 pod1 的 ip 和mac 对应关系
root@master:~# kubectl -n kube-system exec -it cilium-5tsv8 -- cilium bpf endpoint list | grep "10.0.0.85"
10.0.0.85:0id=1445flags=0x0000 ifindex=34mac=C6:6D:95:CD:34:A2 nodemac=2A:0A:D9:17:44:22
查看 pod2 的 ip 和 mac 对应关系
root@master:~# kubectl -n kube-system exec -it cilium-vrv2m -- cilium bpf endpoint list | grep "10.0.1.124"
10.0.1.124:0id=1580flags=0x0000 ifindex=26mac=42:EF:F8:7A:9E:F7 nodemac=CA:0E:FA:6C:0F:30
pod 内部地址(32 位)和路由,会发现和 calico ipip 模式类似,32位的MAC地址,只能走三层路由转发。
宿主机路由
我们查看 node-1 路由表,目的地址为 node-2 网络的路由
root@node-1:~# route -n | grep "192.168.0.130"
10.0.1.0192.168.0.130255.255.255.0UG000 ens33
查看 node-2 路由表,目的地址为 node-1 网络的路由
root@node-2:~# route -n | grep "192.168.0.120"
10.0.0.0192.168.0.120255.255.255.0UG000 ens33
tcpdump 抓包
我们知道 pod 内部是一定会收到 request 的包和 reply 的包的
所以我们要监听 podeth0 对应的 lxc 网卡,ens33
通过上边的 pod和 node 网卡 对应关系
# pod1 对应的lxc 网卡
root@node-1:<
sub>
# ip link show| grep "^34"
34: lxc449258345f59@if33: <
BROADCAST,MULTICAST,UP,LOWER_UP>
mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
# pod2 对应的 lxc 网卡
root@node-2:<
/sub>
# ip link show | grep "^26"
26: lxc5f949d4fd7fa@if25: <
BROADCAST,MULTICAST,UP,LOWER_UP>
mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
node-1 抓包tcpdump -pne -i lxc449258345f59 -w pod1-lxc_native_routing.cap
tcpdump -pne -i ens33 -w node1_ens33.cap
node-2 抓包tcpdump -pne -i lxc5f949d4fd7fa -w pod2-lxc_native_routing.cap
tcpdump -pne -i ens33 -w node2_ens33.cap
pod1 -->
pod2kubectl exec -it cni-test-777bbd57c8-2f986 -- ping -c 1 10.0.1.124
pod1-lxc_native_routing.cap
node1_ens33.cap
pod2-lxc_native_routing.cap
node2_ens33.cap
发现我们发现,在 ens33 上传输的包并没有经过二次封装,而是 pod 的原始包,说明这是经过了 node 的路由,因为我们也看到宿主机的路由表中也含有到目的地址的包
也就是报文流向如下图所示:
# 准备抓包
kubectl -n kube-system exec -it cilium-vrv2m -- cilium monitor -vv >
pod1.text
# ping 1个包
kubectl exec -it cni-test-777bbd57c8-2f986 -- ping -c 1 10.0.1.124
关键部分 ICMP request
CPU 03: MARK 0x0 FROM 1580 DEBUG: Conntrack lookup 1/2: src=https://www.songbingjia.com/android/10.0.0.85:3072 dst=10.0.1.124:0
CPU 03: MARK 0x0 FROM 1580 DEBUG: Conntrack lookup 2/2: nexthdr=1 flags=0
CPU 03: MARK 0x0 FROM 1580 DEBUG: CT verdict: New, revnat=0
CPU 03: MARK 0x0 FROM 1580 DEBUG: Conntrack create: proxy-port=0 revnat=0 src-identity=3352 lb=0.0.0.0
EthernetContents=[..14..] Payload=[..86..] SrcMAC=ca:0e:fa:6c:0f:30 DstMAC=42:ef:f8:7a:9e:f7 EthernetType=IPv4 Length=0
IPv4Contents=[..20..] Payload=[..64..] Version=4 IHL=5 TOS=0 Length=84 Id=45716 Flags=DF FragOffset=0 TTL=62 Protocol=ICMPv4 Checksum=29764 SrcIP=10.0.0.85 DstIP=10.0.1.124 Options=[] Padding=[]
ICMPv4Contents=[..8..] Payload=[..56..] TypeCode=EchoRequest Checksum=20861 Id=3072 Seq=0
Failed to decode layer: No decoder for layer type Payload
CPU 03: MARK 0x0 FROM 1580 to-endpoint: 98 bytes (98 captured), state new, interface lxc5f949d4fd7fa, , identity 3352->
3352, orig-ip 10.0.0.85, to endpoint 1580
ICMP reply 报文
CPU 03: MARK 0x0 FROM 1580 DEBUG: Conntrack lookup 1/2: src=https://www.songbingjia.com/android/10.0.1.124:0 dst=10.0.0.85:3072
CPU 03: MARK 0x0 FROM 1580 DEBUG: Conntrack lookup 2/2: nexthdr=1 flags=1
CPU 03: MARK 0x0 FROM 1580 DEBUG: CT entry found lifetime=16836113, revnat=0
CPU 03: MARK 0x0 FROM 1580 DEBUG: CT verdict: Reply, revnat=0
CPU 03: MARK 0x0 FROM 1580 DEBUG: Successfully mapped addr=10.0.0.85 to identity=3352
------------------------------------------------------------------------------
EthernetContents=[..14..] Payload=[..86..] SrcMAC=00:0c:29:8f:2d:28 DstMAC=00:0c:29:79:54:d3 EthernetType=IPv4 Length=0
IPv4Contents=[..20..] Payload=[..64..] Version=4 IHL=5 TOS=0 Length=84 Id=48973 Flags= FragOffset=0 TTL=63 Protocol=ICMPv4 Checksum=42635 SrcIP=10.0.1.124 DstIP=10.0.0.85 Options=[] Padding=[]
ICMPv4Contents=[..8..] Payload=[..56..] TypeCode=EchoReply Checksum=22909 Id=3072 Seq=0
Failed to decode layer: No decoder for layer type Payload
CPU 03: MARK 0x0 FROM 385 to-network: 98 bytes (98 captured), state new, orig-ip 0.0.0.0
------------------------------------------------------------------------------
【Cilium native-routing 跨节点通信】
推荐阅读
- JUC必知必会:线程和进程
- 夜莺5.5--实现impala自动关闭waiting to be closed会话
- 时间服务器 ntp和chrony
- 网络安全学习-WEB安全常见漏洞
- Gitlab的基本使用
- kubeadm init初始化失败运行reset后需要执行的clean up 命令
- MYSQL随笔十二 磁盘坏道
- 我们为什么要学习Linux()
- 牛逼!Linux命令速查手册出炉!