1. IPIP跨节点通信
本次测试使用calico-ipip-control-plane节点上的pod ping calico-ipip-worker2节点上的pod。
1.1 请求链路梳理
当控制节点的wluo-2nsqg请求工作节点的wluo-gs29f时,会先查它自己的路由表,看怎么出去。
此时出的数据包封装为:
Src_IP: 10.244.51.193 Src_MAC: 12:05:01:b7:b9:a2。
-
Dst_IP: 10.244.244.69 Dst_MAC: $(169.254.1.1)。这里proxy_arp处理后,mac为ee:ee:ee:ee:ee:ee(cali*)。
可以抓包验证
1.1.1 抓包验证数据包
1.1.1.1 源pod抓包(终端一)
1.1.1.2 源pod发起请求(终端二)
1.1.2 分析报文(终端一)
1.1.2.1 ARP请求报文
05:24:59.203119 12:05:01:b7:b9:a2 > ee:ee:ee:ee:ee:ee, ethertype ARP (0x0806), length 42: Request who-has 169.254.1.1 tell 10.244.51.193, length 28
- 05:24:59.203119:时间戳,表示报文被捕获的时间。
- 12:05:01:b7:b9:a2:源MAC地址,也就是源pod的。
- ee:ee:ee:ee:ee:ee:目的MAC地址。这里其实就是对应的cali*。这里,就相当于是把数据包从容器的net_ns发送到了宿主机的net_ns。
- ethertype ARP (0x0806):以太网类型。0x0806表示以太网帧中封装的是ARP协议的报文。
- length 42:报文长度。
下面就是ARP请求的详情了
- Request:请求类型。Request表明这是一个ARP请求报文。
- who - has 169.254.1.1:查询内容。表示发送方想知道169.254.1.1对应的mac地址是啥。
- tell 10.244.51.193:告知信息。发送方告知局域网内的其他设备自己的IP是10.244.51.193,这样当有设备知道169.254.1.1对应的MAC时,就会直接将APR响应报文发给10.244.51.193。
- length 28:表示ARP报文的数据长度。
综上所述,这条报文的含义是,MAC 地址为 12:05:01:b7:b9:a2 且 IP 地址为 10.244.51.193 的设备在局域网内广播询问,谁拥有 IP 地址 169.254.1.1,并希望知道该 IP 对应的 MAC 地址。
1.1.2.2 ARP响应报文
06:27:30.339608 ee:ee:ee:ee:ee:ee > ee:ba:da:fa:fb:6d, ethertype ARP (0x0806), length 42: Reply 169.254.1.1 is-at ee:ee:ee:ee:ee:ee, length 28
- ee:ee:ee:ee:ee:ee:源MAC地址。就是对应pod的cali*,同时也就是169.254.1.1。
- ee:ba:da:fa:fb:6d:目的MAC,就是上面我们的请求发送方。
下面就是ARP响应的详情了
- Reply:响应类型。表明这是一个 ARP 响应报文。
- 169.254.1.1 is-at ee:ee:ee:ee:ee:ee:响应内容。告知请求方,IP 地址 169.254.1.1 对应的 MAC 地址是 ee:ee:ee:ee:ee:ee。
1.1.2.3 ICMP请求报文
分析方式同APR
1.1.2.4 ICMP响应报文
分析方式同APR
1.1.3 容器的报文到了宿主机路由匹配的过程
通过上面的报文分析,pod的请求从它自己的eth0接口发给路由中的169.254.1.1(宿主机)后,又会进行一次路由匹配,具体如下:
root@localhost:~# docker exec -it calico-ipip-control-plane route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.18.0.1 0.0.0.0 UG 0 0 0 eth0 10.244.51.192 0.0.0.0 255.255.255.192 U 0 0 0 * 10.244.51.193 0.0.0.0 255.255.255.255 UH 0 0 0 cali7b75f7586c9 10.244.79.0 172.18.0.4 255.255.255.192 UG 0 0 0 tunl0 10.244.244.64 172.18.0.2 255.255.255.192 UG 0 0 0 tunl0 172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
那么对应的路由就是:
- 10.244.244.64 172.18.0.2 255.255.255.192 UG 0 0 0 tunl0
为啥路由不是到10.244.244.69呢?
Calico使用IPIP模式时,路由表不会为每个pod ip都配置路由条目,而是为每个节点的Pod CIDR(Pod ip地址范围)设置一个汇总的地址,如上244.64,只要是跟他同一个子网内的请求,都会匹配上这条路由。
该路由的下一跳是172.18.0.2,出接口为tunl0,也就意味这个该请求是要进行IP-IN-IP封装的。但请求到了tunl0的时候,是还没有封装的,要等tunl0往外发的时候,才会封装。
1.1.4 在calico-ipip-control-plane抓包tunl0
1.1.4.1 终端一
root@calico-ipip-control-plane:/# tcpdump -pne -i tunl0
1.1.4.2 终端二
root@calico-ipip-control-plane:/# ping 10.244.244.69 -c 1
1.1.4.3 终端一
从上图可以看到,从tunl0走的请求,没有mac地址部分了。
注意:数据包要从tunl0出去的时候才会封装。
1.1.5 在在calico-ipip-control-plane抓包eth0
1.1.5.1 终端一
root@localhost:~# docker exec -it calico-ipip-control-plane tcpdump -pne -i eth0 "ip proto 4"
# ip proto 4,表示IPIP协议。这里的意思是只在eth0捕获IPIP协议类型的包
1.1.5.2 终端二
root@localhost:~# docker exec -it calico-ipip-control-plane ping -c 1 10.244.244.69
1.1.5.3 终端一
从上图报文,就能看出IPIP封装了:172.18.0.3 > 172.18.0.2: 10.244.51.192 > 10.244.244.69
- 172.18.0.3:外层源IP(宿主机)
- 172.18.0.2:外层目的IP(宿主机)
- 10.244.51.192:内层源IP(Pod)
- 10.244.244.69:内层目的IP(Pod)
接下来就是要去往目标宿主机了,所以还会在继续进行最后一次路由匹配。
1.2 IPIP跨节点通信拓扑图
2. IPIP CrossSubnet模式
“Cross - subnet” 直译为 “跨子网”,该模式的主要作用就是:仅当数据包需要跨子网传输时,开会进行IPIP封装。
2.1 基本介绍
2.1.1 工作原理
- 同子网通信
○ 在同一子网内的 Pod 之间通信时,数据包直接通过底层网络传输,不进行封装。
○ 这种方式类似于 BGP 模式,利用直接路由实现高效通信,减少了封装和解封装的开销。- 跨子网通信
○ 当 Pod 位于不同子网时,数据包会通过tunl0接口,来实现 IPIP 封装并进行跨子网传输。
2.1.2 性能特点
- 性能平衡
○ CrossSubnet 模式在性能上介于纯 IPIP 模式和纯 BGP 模式之间。同子网通信时,性能接近 BGP 模式;跨子网通信时,性能略低于 BGP 模式。- 网络开销
○ IPIP 封装会引入一定的网络开销,但相比 VXLAN,其开销较小。
2.2 本次实验的网络拓扑
注意:本次测试,只是为了验证CrossSubnet跨网段通信才会进行IPIP封装的特性,所以不会详细的分析每一跳都做了什么。
2.3 删除之前的k8s集群
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# kind get clusters
calico-ipip
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# kind delete cluster --name calico-ipip
Deleting cluster "calico-ipip" ...
Deleted nodes: ["calico-ipip-worker2" "calico-ipip-worker" "calico-ipip-control-plane"]
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# kind get clusters
No kind clusters found.
2.4 部署crosssubnet模式的k8s集群
2.4.1 编辑相关配置文件
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# grep image 1-setup-env.sh
#cat <<EOF | kind create cluster --name=calico-ipip-crosssubnet --image=kindest/node:v1.27.3 --config=-
cat <<EOF | kind create cluster --name=calico-ipip-crosssubnet --image=registry.cn-beijing.aliyuncs.com/sanhua-k8s/kindest_node:v1.27.3 --config=-
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# grep image 2-setup-clab.sh
#image: 192.168.2.100:5000/vyos/vyos:1.4.9
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/vyos:1.4.9
#image: 192.168.2.100:5000/nettool
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
#image: 192.168.2.100:5000/nettool
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
#image: 192.168.2.100:5000/nettool
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
#image: 192.168.2.100:5000/nettool
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# grep 'image:' calico.yaml
#image: 192.168.2.100:5000/calico/cni:v3.23.2
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/calico_cni:v3.23.2
#image: 192.168.2.100:5000/calico/cni:v3.23.2
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/calico_cni:v3.23.2
#image: 192.168.2.100:5000/calico/node:v3.23.2
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/calico_node:v3.23.2
#image: 192.168.2.100:5000/calico/kube-controllers:v3.23.2
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/calico_kube-controllers:v3.23.2
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# grep 'image:' clab.yaml
#image: 192.168.2.100:5000/vyos/vyos:1.4.9
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/vyos:1.4.9
#image: 192.168.2.100:5000/nettool
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# grep 'image:' cni.yaml
#- image: 192.168.2.100:5000/nettool
- image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
2.4.2 kind部署k8s集群
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# ./1-setup-env.sh
root@superadmin-virtual-machine:~# kubectl get no
NAME STATUS ROLES AGE VERSION
calico-ipip-crosssubnet-control-plane Ready control-plane 6m32s v1.27.3
calico-ipip-crosssubnet-worker Ready <none> 6m7s v1.27.3
calico-ipip-crosssubnet-worker2 Ready <none> 6m13s v1.27.3
calico-ipip-crosssubnet-worker3 Ready <none> 6m12s v1.27.3
# containerlab一定要安装,否则这一步执行失败
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# ./2-setup-clab.sh
2.4.3 CrossSubnet模式是如何开启的
2.5 抓包验证链路
2.5.1 部署测试pod
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# cat cni.yaml
apiVersion: apps/v1
kind: DaemonSet
#kind: Deployment
metadata:
labels:
app: wluo
name: wluo
spec:
#replicas: 2
selector:
matchLabels:
app: wluo
template:
metadata:
labels:
app: wluo
spec:
containers:
#- image: 192.168.2.100:5000/nettool
- image: registry.cn-beijing.aliyuncs.com/sanhua-k8s/nettool
name: nettoolbox
env:
- name: NETTOOL_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
securityContext:
privileged: true
---
apiVersion: v1
kind: Service
metadata:
name: wluo
spec:
type: NodePort
selector:
app: wluo
ports:
- name: wluo
port: 80
targetPort: 80
nodePort: 32000
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# kubectl apply -f cni.yaml
daemonset.apps/wluo created
service/wluo created
root@superadmin-virtual-machine:~/wcni-kind/LabasCode/calico/02-calico-ipip-crosssubnet# kubectl get po
NAME READY STATUS RESTARTS AGE
wluo-2w79m 1/1 Running 0 46s
wluo-5mkh4 1/1 Running 0 46s
wluo-nsm4m 1/1 Running 0 46s
wluo-sqmmd 1/1 Running 0 46s
2.5.2 同网段抓包
2.5.2.1 终端一抓包
注意:这里之所以抓net0的包,是因为当前网络环境做过调整,实际工作中,还是要通过路由确认最终网卡。
root@superadmin-virtual-machine:~# docker exec -it calico-ipip-crosssubnet-control-plane tcpdump -pne -i net0 -w eth0.cap
2.5.2.2 终端二发起icmp请求
2.5.2.3 终端一分析报文
通过报文很明显的就能看出,是没有经过overlay封装的,因为网络可以直达。
这里的mac就是对应源pod所在宿主机的mac和目标pod所在宿主机的mac。
这里因为是在宿主机抓的net0的包,所以只能看到该接口的mac,但实际上每一个环节的mac都是不一样的。
2.5.3 跨节点通信抓包
2.5.3.1 终端一抓包
这里每一个接口的链路和之前测试的是相同的,本次测试只展示crosssubnet的特性。
root@superadmin-virtual-machine:~# docker exec -it calico-ipip-crosssubnet-control-plane tcpdump -pne -i net0
2.5.3.2 终端二发起icmp请求
2.5.3.3 终端一查看报文
通过报文可以看到,只有跨网段的通信,才会进行IPIP封装。