系列文章目录
文章目录
前言
前面两篇学会了Calico的三个功能:
(1) 给Pod分配虚拟IP, 并完成Pod之间网络通信(同一节点Pod和不同节点Pod)
(2) IPPool给Pod分配固定IP
(3) Calico给Pod分配网络策略
第三篇学会了使用calicoctl操作calico各种资源,即 calicoctl + verb + resource
这是第四篇,来学习一下,不同节点间Pod通信的时候,是 tunl0+calixx 实现的:每个有虚拟IP的Pod 网络直连一个确定的 calixxx 网卡,然后 calixxx 网卡连接自己所在 linux 机器上的 tunl0 网卡,然后 tunl0 网卡连接自己所在 linux 机器上的某个具体网卡,将网络请求发送出去,发送给 目的Pod 所在机器的 tunl0 连接的网卡上,然后目的机器网卡发送给目的机器tunl0,然后目的机器 tunl0 发给目的Pod 的calixxx,然后目的Pod的calixxx 网络直连目的Pod。如此,整个过程完成不同节点上的Pod网络通信。
但是这里有一个问题,无论是源Linux服务器,还是目的Linux机器,如果机器上有多张网卡,那么 tunl0 会绑定哪个网卡呢?这可以通过 calico-node 的 yaml 来配置指定,各种情况下如何配置指定就是本文的重点。
Calico通过calixxx和tunl0网卡完成节点间Pod通信
默认情况下calico使用的是IPIP模式进行通信(IPIP模式和BGP模式两种,当前正在使用哪种看ippool),所有节点之间建立tunl0隧道(本质是所有node上有一个tul0网卡)。每创建一个pod在宿主机上都会产生一个以cali开头的虚拟接口,如下图pod1生成了一个calixxxxx网卡,pod2生成了一个caliyyyyy虚拟网卡。每个pod发出去的数据包会直接转发到cali开头的网卡,这个接口跟pod里的calixxx网卡是veth pair的关系。
这种veth pair最直接的理解就是“网线直连”,一方面,pod1发出去的所有数据包,“闭着眼”转发给calixxxxx;另一方面,calixxxxx从其他地方收到的数据包“闭着眼”转发给pod1。这种网线直连底层是通过 linux route 本机网路路由实现的。
cali开头的网卡会连接到tunl0上,pod1和pod2通信时,pod1发出的数据包先到达calixxxxx,然后进入vms71的tunl0接口,再然后到达隧道的另一端vms72的tunl0接口,然后转发到caliyyyy,最终到达了pod2。所以tunl0隧道的作用就是封装所有pod之间的流量。如下图:
现在的问题是tunl0隧道所走的物理线路是哪条呢?默认情况下calico会自动选择,但是如果有多张网卡,比如上图中左边Linux机器有 ens32 和 ens33 两个网卡,则这个机器上 tunl0 要绑定哪个网卡;右边Linux机器有 eth0 和 eth1 两个网卡,则这个机器 tunl0 绑定哪个网卡。我们想手动选择 tunl0 绑定的网卡,下面分成5种情况来看tunl0如何选择物理线路。
准备两台机器
本实验共两台节点,如下。
[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 # 将 pod1 放到 vms71
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 # 将 pod2 放到 vms72
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"
这个IP_AUTODETECTION_METHOD参数的含义是:指定tunl0隧道所对应的物理接口为ens33或者eth0。在vms71上他会选择ens33,在vms72上会选择eth0。
如果缺省这个 IP_AUTODETECTION_METHOD 参数,tunl0 就会自动选择。开发过程中,如果linux上只有一张网卡,无需指定 IP_AUTODETECTION_METHOD 参数,因为 tunl0 隧道会自动连接这个网卡;如果linux上只有多张网卡,建议指定 IP_AUTODETECTION_METHOD 参数,因为如果 tunl0 隧道对应的本机物理网卡,如果和 route 中配置的网关不通,会导致不同Node之间的Pod无法通信。
不同Node之间的Pod无法通信:
(1) 要么就是缺少route路由配置,需要增加一条route路由,通向另一个node的Block (另一个node的Block是什么可以在另一个node route 中看到)
(2) 要么就是 tunl0 绑定的网卡与到达目的地址的经过的gateway不通,需要在calico-node.yaml 这个ds中手动配置一个和 route规则中gateway网络通的 本机网卡
安装calico。
[root@vms71 ~]