k8s安装calico时如何选择网卡问题
作者:跳跃音符#3712
1.了解calico的通信
默认情况下calico使用的是IPIP模式进行通信,所有节点之间建立tunl0隧道。
每创建一个pod在宿主机上都会产生一个以cali开头的虚拟接口,如下图pod1生成了一个calixxxxx网卡,pod2生成了一个caliyyyyy虚拟网卡。
每个pod发出去的数据包会直接转发到cali开头的网卡,这个接口跟pod里的网卡是veth pair的关系。
veth pair最直接的理解就是“网线直连”,pod1发出去的所有数据包,“闭着眼”转发给calixxxxx,calixxxxx从其他地方收到的数据包“闭着眼”转发给pod1。
cali开头的网卡会连接到tunl0上,pod1和pod2通信时,pod1发出的数据包先到达calixxxxx,然后进入vms71的tunl0接口,再然后到达隧道的另一端vms72的tunl0接口,然后转发到caliyyyy,最终到达了pod2。所以tunl0隧道的作用就是封装所有pod之间的流量。
现在的问题是tunl0隧道所走的物理线路是哪条呢?默认情况下calico会自动选择,但是如果有多张网卡的话我们想手动选择网卡,下面分成5种情况来看tunl0如何选择物理线路。
2.实验准备
本实验共两台节点,如下。
[root@vms71 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION vms71.rhce.cc Ready control-plane,master 54m v1.23.2 vms72.rhce.cc Ready <none> 54m v1.23.2 [root@vms71 ~]#
为了测试,特地把vms72上的网卡名做了修改,原来的ens32修改名为eth0,原来的ens33修改名为eth1。
vms71上ens32 ----- vms72上eth1 同一网段。 vms71上ens33 ----- vms72上eth0 同一网段。
同一网段的网卡,结合上图,我这里并没写错。
练习时会在vms71上创建pod1,在vms72上创建pod2,所编写的pod.yaml内容如下
[root@vms71 ~]# cat pod.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: pod1 name: pod1 spec: nodeName: vms71.rhce.cc terminationGracePeriodSeconds: 0 containers: - image: localhost/centos:test imagePullPolicy: IfNotPresent command: ["sh","-c","sleep 1d"] name: pod1 resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} --- apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: pod2 name: pod2 spec: nodeName: vms72.rhce.cc terminationGracePeriodSeconds: 0 containers: - image: localhost/centos:test imagePullPolicy: IfNotPresent command: ["sh","-c","sleep 1d"] name: pod2 resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} [root@vms71 ~]#
第一种情况 指定网卡1
修改calico.yaml的内容,找到IP_AUTODETECTION_METHOD
- name: IP_AUTODETECTION_METHOD value: "interface=ens33,eth0"
这里指定tunl0隧道所对应的物理接口为ens33或者eth0。
在vms71上他会选择ens33,在vms72上会选择eth0。
安装calico。
[root@vms71 ~]# kubectl apply -f calico.yaml configmap/calico-config created ...输出... [root@vms71 ~]#
创建测试用的pod。
[root@vms71 ~]# kubectl apply -f pod.yaml pod/pod1 created pod/pod2 created [root@vms71 ~]# [root@vms71 ~]# kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE pod1 1/1 Running 0 14s 10.244.118.193 vms71.rhce.cc pod2 1/1 Running 0 14s 10.244.5.194 vms72.rhce.cc [root@vms71 ~]#
整个拓扑图应该如下。
进入到pod1里去,然后通过traceroute访问 pod2的IP即 10.244.5.194。
[root@vms71 ~]# kubectl exec -it pod1 -- bash [root@pod1 /]# [root@pod1 /]# traceroute 10.244.5.194 traceroute to 10.244.5.194 (10.244.5.194), 30 hops max, 60 byte packets 1 192-168-26-71.kubernetes.default.svc.cluster.local (192.168.26.71) 0.049 ms 0.009 ms 0.007 ms 2 10.244.5.192 (10.244.5.192) 0.477 ms 0.414 ms 0.378 ms 3 10.244.5.194 (10.244.5.194) 0.615 ms 0.577 ms 0.540 ms [root@pod1 /]# exit [root@vms71 ~]#
从这里可以看到在pod1发出去的包,直接到达隧道另一端即vms72上的tunl0,然后再转发到pod2的。
那么vms71和vms72之间的隧道之间是怎么走的呢?
先查看vms71的路由。
[root@vms71 ~]# ip route | grep tunl0 10.244.5.192/26 via 192.168.30.72 dev tunl0 proto bird onlink [root@vms71 ~]#
凡是去往网段10.244.5.192/26的数据包都发送到192.168.30.72(这是vms72的eth0接口,也是隧道tunl0的另一端)。
查看vms72的路由。
[root@vms72 ~]# ip route | grep tunl0 10.244.118.192/26 via 192.168.30.71 dev tunl0 proto bird onlink [root@vms72 ~]# 凡是去往网段10.244. ```118.192/26的数据包都发送到192.168.30.71(这是vms71的ens33接口,也是隧道tunl0的另一端)。 删除pod1和pod2。 ```shell [root@vms71 ~]# kubectl delete -f pod.yaml pod "pod1" deleted pod "pod2" deleted [root@vms71 ~]# 删除calico。
[root@vms71 ~]# kubectl delete -f calico.yaml configmap "calico-config" deleted ...输出... [root@vms71 ~]#
第二种情况 指定网卡2
修改calico.yaml的内容,修改IP_AUTODETECTION_METHOD的值。
- name: IP_AUTODETECTION_METHOD value: "interface=ens32,eth1"
这里指定tunl0所使用的物理线路是ens32或者eth1,vms71上有ens32所以选择ens32,vms72上有eth1则选择eth1。
安装calico。
[root@vms71 ~]# kubectl apply -f calico.yaml configmap/calico-config created ...输出... [root@vms71 ~]#
创建pod。
[root@vms71 ~]# kubectl apply -f pod.yaml pod/pod1 created pod/pod2 created [root@vms71 ~]# [root@vms71 ~]# kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE pod1 1/1 Running 0 3s 10.244.118.193 vms71.rhce.cc pod2 1/1 Running 0 3s 10.244.5.194 vms72.rhce.cc [root@vms71 ~]#
两个pod的IP保持和之前一样。
进入到pod1里去,然后通过traceroute访问 pod2的IP即 10.244.5.194。
[root@vms71 ~]# kubectl exec -it pod1 -- bash [root@pod1 /]# traceroute 10.244.5.194 traceroute to 10.244.5.194 (10.244.5.194), 30 hops max, 60 byte packets 1 192-168-26-71.kubernetes.default.svc.cluster.local (192.168.26.71) 0.050 ms 0.009 ms 0.007 ms 2 10.244.5.192 (10.244.5.192) 0.493 ms 0.407 ms 0.365 ms 3 10.244.5.194 (10.244.5.194) 0.482 ms 0.468 ms 0.461 ms [root@pod1 /]# exit exit [root@vms71 ~]#
查看vms71的路由。
[root@vms71 ~]# ip route | grep tunl0 10.244.5.192/26 via 192.168.26.72 dev tunl0 proto bird onlink [root@vms71 ~]#
凡是去往网段10.244.5.192/26的数据包都发送到192.168.26.72(这是vms72的eth1接口,也是隧道tunl0的另一端)。
查看vms72的路由。
[root@vms72 ~]# ip route | grep tunl0 10.244.118.192/26 via 192.168.26.71 dev tunl0 proto bird onlink [root@vms72 ~]#
凡是去往网段10.244.118.192/26的数据包都发送到192.168.26.71(这是vms71的ens32接口,也是隧道tunl0的另一端)。
删除pod1和pod2。
[root@vms71 ~]# kubectl delete -f pod.yaml pod "pod1" deleted pod "pod2" deleted [root@vms71 ~]#
删除calico。
[root@vms71 ~]# kubectl delete -f calico.yaml configmap "calico-config" deleted ...输出... [root@vms71 ~]#
第三种情况 跳过指定网卡
修改calico.yaml的内容,修改IP_AUTODETECTION_METHOD的值
- name: IP_AUTODETECTION_METHOD value: "skip-interface=eth1,ens32"
tunl0选择物理网卡时跳过eth1或者ens32。
在vms71上跳过ens32的话只能选择ens33,在vms72上跳过eth1的话只能选择eth0。
安装calico。
[root@vms71 ~]# kubectl apply -f calico.yaml configmap/calico-config created ...输出... [root@vms71 ~]#
先查看vms71的路由
[root@vms71 ~]# ip route | grep tunl0 10.244.5.192/26 via 192.168.30.72 dev tunl0 proto bird onlink [root@vms71 ~]#
凡是去往网段10.244.5.192/26的数据包都发送到192.168.30.72(这是vms72的eth0接口,也是隧道tunl0的另一端)。
先查看vms72的路由
[root@vms72 ~]# ip route | grep tunl0 10.244.118.192/26 via 192.168.30.71 dev tunl0 proto bird onlink [root@vms72 ~]#
凡是去往网段10.244.118.192/26的数据包都发送到192.168.30.71(这是vms71的ens33接口,也是隧道tunl0的另一端)。删除calico。
[root@vms71 ~]# kubectl delete -f calico.yaml configmap "calico-config" deleted ...输出... [root@vms71 ~]#
第四种情况 通过网络连通性判断
修改calico.yaml的内容,修改IP_AUTODETECTION_METHOD的值。
- name: IP_AUTODETECTION_METHOD value: "can-reach=192.168.30.1"
tunl0要选择能和192.168.30.1通信的那张网卡,在vms71上ens33网卡和192.168.30.1是同一个网段,能够和192.168.30.1通信,被选中。
在vms72上eth0网卡和192.168.30.1是同一网段可以通信,被选中。
创建calico。
[root@vms71 ~]# kubectl apply -f calico.yaml configmap/calico-config created ...输出... [root@vms71 ~]#
先查看vms71的路由
[root@vms71 ~]# ip route | grep tunl0 10.244.5.192/26 via 192.168.30.72 dev tunl0 proto bird onlink [root@vms71 ~]#
凡是去往网段10.244.5.192/26的数据包都发送到192.168.30.72(这是vms72的eth0接口,也是隧道tunl0的另一端)。
先查看vms72的路由
[root@vms72 ~]# ip route | grep tunl0 10.244.118.192/26 via 192.168.30.71 dev tunl0 proto bird onlink [root@vms72 ~]#
凡是去往网段10.244.118.192/26的数据包都发送到192.168.30.71(这是vms71的ens33接口,也是隧道tunl0的另一端)。
删除calico。
[root@vms71 ~]# kubectl delete -f calico.yaml configmap "calico-config" deleted ...输出... [root@vms71 ~]#
第五种情况 通过cidr判断
修改calico.yaml的内容,修改IP_AUTODETECTION_METHOD的值。
- name: IP_AUTODETECTION_METHOD value: "cidr=192.168.26.0/24"
tunl0选择选择192.168.26.0/24网段的网卡,vms71选中的是ens32,vms72上选中的应该是eth1了,因为他们都是属于192.168.26.0/24网段的。
创建calico。
[root@vms71 ~]# kubectl apply -f calico.yaml configmap/calico-config created ...输出... [root@vms71 ~]#
查看vms71的路由。
[root@vms71 ~]# ip route | grep tunl0 10.244.5.192/26 via 192.168.26.72 dev tunl0 proto bird onlink [root@vms71 ~]#
凡是去往网段10.244.5.192/26的数据包都发送到192.168.26.72(这是vms72的eth1接口,也是隧道tunl0的另一端)。
查看vms72的路由。
[root@vms72 ~]# ip route | grep tunl0 10.244.118.192/26 via 192.168.26.71 dev tunl0 proto bird onlink [root@vms72 ~]#
凡是去往网段10.244.118.192/26的数据包都发送到192.168.26.71(这是vms71的ens32接口,也是隧道tunl0的另一端)。
删除calico。
[root@vms71 ~]# kubectl delete -f calico.yaml configmap "calico-config" deleted ...输出... [root@vms71 ~]#
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。