层级网络概念

二层网络和三层网络区别:
1、二层网络仅仅通过MAC寻址即可实现通讯,三层网络需要通过IP路由实现跨网段的通讯,可以跨多个冲突域
2、二层网络的组网能力非常有限,一般是小局域网;三层网络则可以组大型的网络
3、二层网络基本上是一个安全域,也就是说在同一个二层网络内,终端的安全性从网络上来讲基本上是一样的,除非有其他特殊的安全措施;三层网络则可以划分出相对独立的多个安全域

三层交换机和二层交换机:
普通的交换机是二层交换机,二层交换机只识别MAC地址,不识别IP地址(IP地址由电脑负责转换),不能路由,所以叫二层交换机。三层交换机不但能识别MAC地址,还能把MAC地址中的IP地址识别出来,进行路由。

Calico概念

Calico是一个纯三层的数据中心网络方案。其在每一个计算节点利用 Linux Kernel 实现了一个高效的虚拟路由器( vRouter) 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播。

Calico BGP模式

BGP概述

Calico项目提供的网络解决方案,与Flannel的host-gw模式类似。Calico也是基于路由表实现容器数据包转发。不同点在于Flannel使用flanneld进程来维护路由信息,而Calico使用BGP协议来自动维护整个集群的路由信息,集群规模到达一定量时,也能保证较好的性能。

在互联网中,一个自治系统(AS)是一个有权自主地决定在本系统中应采用何种路由协议的小型单位。这个网络单位可以是一个简单的网络也可以是一个由一个或多个普通的网络管理员来控制的网络群体,它是一个单独的可管理的网络单元(例如一所大学,或者一个公司个体)。

一个自治系统有时也被称为是一个路由选择域(routing domain)。一个自治系统会分配一个全局的唯一的16位号码,叫做自治系统号(ASN)。在正常情况下,自治系统之间不会有任何来往。如果两个自治系统里的主机,要通过 IP 地址直接进行通信,就必须使用路由器把这两个自治系统连接起来。BGP协议就是让他们互联的一种方式。

BGP(Border Gateway Protocol)即边界网关协议,它是一种自治系统间的动态路由发现协议,与其他 BGP 系统交换网络可达信息。

image.png

上图中,有两个自治系统(autonomous system,简称为AS):AS1 和 AS2

A公司的网络和B公司的网络,可以理解为两个自治系统,每个自治系统是由自己的交换机,路由器来组成的,公司和公司之间没有任何的网络依赖,所以这些交换机路由器可以单独去运行。

但是如果他们想通信,他们本身就不在一个网络里面,而且A公司的员工电脑都是私网IP,B公司也用的是私网IP,甚至这些IP都是冲突的,如果想实现两家的网络内网能够通信,首先保证用到的ip地址不能冲突,还要保证A公司和B公司的网络上层的网络出口的交换机必须相互学习到自己的路由表。

BGP的作用就是将两个自治系统进行连接起来,使得两个能够相互的通信。AS1、AS2 可以好比 A、B 两个公司,两个都不是同网络,现在要想 AS1 下的 192.168.x.x 与 AS2 下的 172.17.x.x 进行去通信,应该怎么走?

两个公司要是想通信,路由器必须是可以通信的,只要建立了通信之后,192.168.1.10 先走交换机,再到路由器,从路由器的A口进去,数据包到达了B口,然后它怎么知道转发到路由器2呢?所以就需要路由表的存在,路由器1根据转发的目的地址,172.17.1.20这个网段,看本地有没有路由表,它会发现本地有个路由表,是转发到路由器2的,是从B口出去的,然后就会转发到路由器2上面,路由器2本身就学习到了自己的目的地址,知道自己管辖的网络是多少,不过没有下一跳,因为在自己的管辖之内,比如172.17.1.20,有这个IP,那么就不需要下一跳,然后之间根据接口转发到A口里面,A口里面正好接的是交换机,然后交换机从二层传输到对应的目的地址上,这样节点就可以通信了。

整个流程中BGP启了什么作用?
路由表也可以手动的进行添加,然后指向下一跳就是这个route的路由器,它也会转发过来,只要他们的网络是通的,如果节点很多,添加路由表就很大,而且在互联网中还会有别的路由器,可能还会用到别的网络进行通信,所以这里的BGP就是可以相互的去学习到相互的路由表信息,那么AS1要访问AS2的节点,首先它的路由表也能学到目标地址,那么就能之间转发到路由器中,然后转发到目的的服务器上

这种动态路由协议跟flannel中host-gw模式有点类似,在kubernetes集群中,AS1,AS2可以当成集群中的的两个node节点,flannel的方式是把当前节点当作一个网关,而Calico引入BGP,它是将每个node节点都做成一个虚拟路由器,他们通过BGP实现相互路由信息的交换,而flannel是由一个守护进程维护每个路由表,发送到本地的节点,而calico采用的是BGP来实现数据交换,但路由表也要写到每个节点上。

image.png
以kubernetes集群中有多个node节点,每个node节点上有多个pod的通信场景为示例进行说明。

图中10.0.0.1是容器1,10.0.0.2是容器2,这里会有一个cali的接口,它把宿主机(node节点)当作一个虚拟路由器,此虚拟路由器走的BGP协议。涉及到两个组件一个是Client,一个是Felix主要负责写入机器的路由表信息。是使用daemonset方式部署到每个节点上。图中calico是使用etcd来保持calico设置的网络策略以及配置状态,组件BGP client主要提供这个协议,即每个node节点都有一个BGP client,node节点之间建立一个BGP的连接,把各自的路由表信息进行交换,这样整个集群中的每个容器就形成了一个完整的拓扑规则。

Calico主要由三个部分组成:
Felix:以DaemonSet方式部署,运行在每一个Node节点上,主要负责维护宿主机上路由规则以及ACL规则。
BGP Client(BIRD):主要负责把 Felix 写入 Kernel 的路由信息分发到集群 Calico 网络。
Etcd:分布式键值存储,保存Calico的策略和网络配置状态。
calicoctl:允许通过命令行实现高级策略和网络。

BGP实现

环境描述

  • 基于kubernetes容器环境
    • m1 192.168.10.101
    • m2 192.168.10.102
    • m3 192.168.10.103
  • 数据存储用到etcd服务
  • calico版本v3.18
  • svc 网段:10.254.0.0/16
  • pod 网段: 10.244.0.0/16

环境清理

若kubernetes集群中之前应用过flannel网络,要进行彻底清除,不然将影响calico的部署。

操作如下:

  1. # 删除flannel资源
  2. # kubectl delete -f kube-flannel.yaml
  3. #删除flannel生成的虚拟网卡和网桥cni
  4. # ip route
  5. default via 10.4.7.1 dev eth0 proto static metric 100
  6. 10.4.7.0/24 dev eth0 proto kernel scope link src 10.4.7.11 metric 100
  7. 10.244.0.0/24 via 10.4.7.21 dev eth0
  8. 10.244.1.0/24 dev cni0 proto kernel scope link src 10.244.1.1
  9. 10.244.2.0/24 via 10.4.7.12 dev eth0
  10. 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
  11. # ip link delete cni0
  12. # ip link delete flannel.1
  13. # ip route delete 10.244.0.0/24 via 10.4.7.21 dev eth0
  14. # ip route delete 10.244.1.0/24 via 10.4.7.12 dev eth0

安装部署

安装操作

0、下载文件
wget https://docs.projectcalico.org/archive/v3.18/manifests/calico-etcd.yaml --no-check-certificate

1、etcd内容配置
ETCD_ENDPOINTS="https://192.168.10.101:2379,https://192.168.10.102:2379,https://192.168.10.103:2379"

sed -i "s#.*etcd_endpoints:.*#  etcd_endpoints: \"${ETCD_ENDPOINTS}\"#g" calico-etcd.yaml

# 根据实际etcd证书路径按需配置
ETCD_CERT=`cat /opt/etcd/ssl/etcd.pem | base64 | tr -d '\n'`
ETCD_KEY=`cat /opt/etcd/ssl/etcd-key.pem | base64 | tr -d '\n'`
ETCD_CA=`cat /opt/etcd/ssl/ca.pem | base64 | tr -d '\n'`

# 配置etcd证书
sed -i "s#.*etcd-cert:.*#  etcd-cert: ${ETCD_CERT}#g" calico-etcd.yaml
sed -i "s#.*etcd-key:.*#  etcd-key: ${ETCD_KEY}#g" calico-etcd.yaml
sed -i "s#.*etcd-ca:.*#  etcd-ca: ${ETCD_CA}#g" calico-etcd.yaml

# 要读取的secret落地到容器中指定的位置,替换操作实际是将注释去掉
sed -i 's#.*etcd_ca:.*#  etcd_ca: "/calico-secrets/etcd-ca"#g' calico-etcd.yaml
sed -i 's#.*etcd_cert:.*#  etcd_cert: "/calico-secrets/etcd-cert"#g' calico-etcd.yaml
sed -i 's#.*etcd_key:.*#  etcd_key: "/calico-secrets/etcd-key"#g' calico-etcd.yaml

2、选择工作模式,关闭IPIP模式,则自动启用BGP模式
sed -i '/CALICO_IPV4POOL_IPIP/{n;s/Always/Never/g}' calico-etcd.yaml

3、根据实际网络规划pod cidr
手动打开文件取消注释,将CALICO_IPV4POOL_CIDR对应的value替换成pod网段,一定要注意和上下内容空格对齐
...
            - name: CALICO_IPV4POOL_CIDR
              value: "10.244.0.0/16"
...


4、应用资源
kubectl apply -f calico-etcd.yaml

5、查看
[root@m1 ~]# kubectl get pod -n kube-system -owide
NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE   NOMINATED NODE   READINESS GATES
calico-kube-controllers-67766b8b46-sqznn   1/1     Running   0          12h   192.168.10.102   m2     <none>           <none>
calico-node-7hkq6                          1/1     Running   0          12h   192.168.10.103   m3     <none>           <none>
calico-node-l5smj                          1/1     Running   0          12h   192.168.10.102   m2     <none>           <none>
calico-node-z22jg                          1/1     Running   0          9h    192.168.10.101   m1     <none>           <none>

故障排除

#应用资源后calico-kube-controllers会报错权限不够
[root@m1 ~]# kubectl  logs -f calico-kube-controllers-5f7cd75c8f-fn6vb
2022-05-08 12:29:26.056 [INFO][1] main.go 92: Loaded configuration from environment config=&config.Config{LogLevel:"info", WorkloadEndpointWorkers:1, ProfileWorkers:1, PolicyWorkers:1, NodeWorkers:1, Kubeconfig:"", DatastoreType:"etcdv3"}
2022-05-08 12:29:26.056 [FATAL][1] main.go 105: Failed to start error=failed to build Calico client: could not initialize etcdv3 client: open /calico-secrets/etcd-cert: permission denied

#解决
将calico-etcd.yaml文件中以下内容的 0400 改为 0440 即可。
...
        - name: etcd-certs
          secret:
            secretName: calico-etcd-secrets
            defaultMode: 0400
...

CALICOCTL

calicoctl是calico的一个管理工具。

安装
wget https://github.com/projectcalico/calicoctl/releases/download/v3.18.4/calicoctl
chmod +x calicoctl
mv calicoctl /usr/sbin/

查看当前节点BGP状态(只有running了calico-node的pod上的节点才能查看)
[root@m2 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+————————+—————————-+———-+—————+——————-+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+————————+—————————-+———-+—————+——————-+
| 192.168.10.103 | node-to-node mesh | up | 12:23:30 | Established |
+————————+—————————-+———-+—————+——————-+

IPv6 BGP status
No IPv6 peers found.

此工具是和etcd里数据交互,这个表是从etcd中进行长链接拿到信息格式化输出。

通过以下命令可以看出:
[root@m2 ~]# netstat -anpt |grep bird
tcp 0 0 0.0.0.0:179 0.0.0.0:* LISTEN 65680/bird
tcp 0 0 192.168.10.102:179 192.168.10.103:32876 ESTABLISHED 65680/bird

创建配置文件,拥有全局查看权限

mkdir /etc/calico
cat /etc/calico/calicoctl.cfg 
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
  datastoreType: "etcdv3"
  etcdEndpoints: "https://192.168.10.101:2379,https://192.168.10.102:2379,https://192.168.10.103:2379"
  etcdKeyFile: "/opt/etcd/ssl/etcd-key.pem"
  etcdCertFile: "/opt/etcd/ssl/etcd.pem"
  etcdCACertFile: "/opt/etcd/ssl/ca.pem"
#查看节点
[root@m1 ~]# calicoctl get nodes
NAME   
m2     
m3 

#查看ipam的ip地址池
[root@m1 ~]# calicoctl get ippool -o wide
NAME                  CIDR            NAT    IPIPMODE   VXLANMODE   DISABLED   SELECTOR   
default-ipv4-ippool   10.244.0.0/16   true   Never      Never       false      all()

BGP原理剖析

image.png

默认的BGP工作的流程:
跨节点之间的通信,这里是没有网桥存在的,完全就是通过路由来实现的,这个数据包先从veth的设备对另一口发出,到达宿主机上的cali开头的虚拟网卡(宿主机上的网络协议栈)上。当创建一个pod时会先起一个infra containers的容器,然后会调用calico去配置容器的网络,接着根据路由表决定数据包发送的目的地,可以从ip route看到路由表信息,这里是目的cni分配的子网络和目的宿主机的网络,也就是当进行跨主机通信的时候转发到下一跳地址走宿主机的eth0网卡出去,也就是一个直接的静态路由,这个下一跳就跟flannel的host-gw形式类似,最大的区别是calico使用的是BGP路由的交换,而host-gw是使用flannel自身的路由交换,BGP方案比较成熟,在大型网络中用的较多。

BPG为什么叫边界网关协议呢?BGP主要是在每个自治系统的最边界与其他自治系统传输规则,一个node节点和其他node节点组成的BGP网络是一个全网通的网络,这个节点可称为一个BGP Peer。

启动二进制文件目录:/opt/cni/bin
子网配置信息文件:/etc/cni/net.d/10-calico.conflist

Pod 1 访问 Pod 2大致流程:
数据包从Pod1到Veth Pair另一端(宿主机上,以cali前缀开头的虚拟网卡);
宿主机根据路由规则,将数据包转发给下一跳(网关);
到达Node2,根据路由规则将数据包转发给cali设备,从而到达Pod2。

最核心的“下一跳”路由规则是由 Calico 的 Felix 进程负责维护的。路由规则信息则是通过 BGP Client(BIRD 组件)使用 BGP 协议传输。可以看出,Calico 项目实际上将集群里的所有node节点,都当作是边界路由器来处理,它们一起组成了一个全连通的网络,互相之间通过 BGP 协议交换路由规则。每个都节点称为一个 BGP Peer。

calico没有网桥,数据包是怎么出去的?
pod1的数据包从veth的设备到宿主机的eth0上,数据包走的默认宿主机的网关,将流量转发到calico的cali的设备上,通过路由表信息下一跳地址到宿主机然后转发到对应的容器中。

Route Reflector

Calico 维护的网络默认是(Node-to-Node Mesh)全互联模式,通过calicoctl node status命令可查看到。Calico集群中的节点之间都会相互建立连接,用于路由交换。默认的BGP在kubernetes的每个node节点担任了一个BGP的一个喇叭,一直吆喝着扩散到其他节点,随着集群节点的数量的增加,那么上百台节点就要构建上百台链接,就是全互联的方式,都要来回建立连接来保证网络的互通性,那么增加一个节点就要成倍的增加这种链接保证网络的互通性,会使用大量的网络消耗。

这时就需要使用 Route Reflector(路由器反射)模式,简称RR模式来解决这个问题。使用node-to-node Mesh模式建议100个节点以下,当超过100台节点官方建议使用路由反射RR模式。确定一个或多个Calico节点充当路由反射器,让其他节点从此RR节点获取路由信息。建议至少是2到3个,一个做备用,一个在维护的时候不影响其他的使用。

实操路由反射RR模式

1、关闭 node-to-node BGP网格,配置asNumber
# cat bgp.yaml 
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
  name: default
spec:
  logSeverityScreen: Info
  nodeToNodeMeshEnabled: false  
  asNumber: 63400

# calicoctl apply -f bgp.yaml
Successfully applied 1 'BGPConfiguration' resource(s)

# calicoctl get bgpconfig
NAME      LOGSEVERITY   MESHENABLED   ASNUMBER   
default   Info          false         63400   

# 编号ASN63400,一个编号代表一个自治系统
# calicoctl get nodes --output=wide
NAME   ASN       IPV4                IPV6   
m2     (63400)   192.168.10.102/24          
m3     (63400)   192.168.10.103/24  

#此为禁用node-to-node mesh之前的状态
[root@m2 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+----------------+-------------------+-------+----------+-------------+
| 192.168.10.103 | node-to-node mesh | up    | 12:23:29 | Established |
+----------------+-------------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.

#关闭后状态
[root@m2 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
No IPv4 peers found.

IPv6 BGP status
No IPv6 peers found.


2、配置指定节点m2充当路由反射器
# 在kubernetes集群中通过label方式指定node节点作为RR节点
# kubectl label node m2 route-reflector=true

[root@m1 ~]# calicoctl get node
NAME   
m2     
m3     

[root@m1 ~]# calicoctl get node m2 -oyaml > rr1.yaml

# 配置路由器反射器节点routeReflectorClusterID
[root@m1 ~]# cat rr1.yaml 
apiVersion: projectcalico.org/v3
kind: Node
metadata:
  annotations:
    projectcalico.org/kube-labels: '{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"m2","kubernetes.io/os":"linux"}'
  creationTimestamp: "2022-05-08T12:23:24Z"
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: m2
    kubernetes.io/os: linux
  name: m2
  resourceVersion: "96050"
  uid: 1a65583b-6429-4143-8342-783b422a9f7d
spec:
  bgp:
    ipv4Address: 192.168.10.102/24
    routeReflectorClusterID: 244.0.0.1   # 集群ID
  orchRefs:
  - nodeName: m2
    orchestrator: k8s

[root@m1 ~]# calicoctl apply -f rr1.yaml 
Successfully applied 1 'Node' resource(s)

# 配置集群其他node节点去连接路由反射器(带有标签route-reflector == 'true'的m2节点)
[root@m1 ~]# cat bgp1.yaml 
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: peer-with-route-reflectors
spec:
  nodeSelector: all()    #所有的节点
  peerSelector: route-reflector == 'true'

[root@m1 ~]# calicoctl apply -f bgp1.yaml 
Successfully applied 1 'BGPPeer' resource(s)

# 查看
## 下列信息可得出m1和m3节点上连接的peer都是m2,而m2上连接的peer是m1和m3
[root@m1 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+---------------+-------+----------+-------------+
|  PEER ADDRESS  |   PEER TYPE   | STATE |  SINCE   |    INFO     |
+----------------+---------------+-------+----------+-------------+
| 192.168.10.102 | node specific | up    | 15:41:04 | Established |
+----------------+---------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.

[root@m3 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+---------------+-------+----------+-------------+
|  PEER ADDRESS  |   PEER TYPE   | STATE |  SINCE   |    INFO     |
+----------------+---------------+-------+----------+-------------+
| 192.168.10.102 | node specific | up    | 15:35:17 | Established |
+----------------+---------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.

[root@m2 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+---------------+-------+----------+-------------+
|  PEER ADDRESS  |   PEER TYPE   | STATE |  SINCE   |    INFO     |
+----------------+---------------+-------+----------+-------------+
| 192.168.10.103 | node specific | up    | 15:35:17 | Established |
| 192.168.10.101 | node specific | up    | 15:41:06 | Established |
+----------------+---------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.

# 测试网络连通性
[root@m1 ~]# cat ng.yaml 
apiVersion: apps/v1
kind: Deployment  
metadata:
  name:  nginx-deploy
  namespace: default
spec:
  replicas: 3  # 期望的 Pod 副本数量,默认值为1
  selector:  # Label Selector,必须匹配 Pod 模板中的标签
    matchLabels:
      app: nginx
  template:  # Pod 模板
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

[root@m1 ~]# kubectl apply -f ng.yaml 

[root@m1 ~]# kubectl get po -owide
NAME                           READY   STATUS    RESTARTS   AGE    IP               NODE   NOMINATED NODE   READINESS GATES
nginx-deploy-d46f5678b-kwpwv   1/1     Running   0          136m   10.244.139.192   m2     <none>           <none>
nginx-deploy-d46f5678b-rvp7j   1/1     Running   0          136m   10.244.204.64    m3     <none>           <none>
nginx-deploy-d46f5678b-sm9d5   1/1     Running   0          136m   10.244.204.65    m3     <none>           <none>

[root@m1 ~]# curl -I  10.244.204.65
HTTP/1.1 200 OK
Server: nginx/1.21.5
Date: Sun, 08 May 2022 15:45:32 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 28 Dec 2021 15:28:38 GMT
Connection: keep-alive
ETag: "61cb2d26-267"
Accept-Ranges: bytes

添加多个路由反射器

# 将 m3 节点添加为路由反射器

1、对m3节点打标签
[root@m1 ~]# kubectl label node m3 route-reflector=true

2、配置路由反射器的cluster id 
# 命令等效于前面操作-o yaml导出配置文件后修改内容再应用
[root@m1 ~]# calicoctl patch node m3 -p '{"spec": {"bgp": {"routeReflectorClusterID": "244.0.0.1"}}}'

3、查看节点状态
[root@m1 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+---------------+-------+----------+-------------+
|  PEER ADDRESS  |   PEER TYPE   | STATE |  SINCE   |    INFO     |
+----------------+---------------+-------+----------+-------------+
| 192.168.10.102 | node specific | up    | 15:41:05 | Established |
| 192.168.10.103 | node specific | up    | 01:10:30 | Established |
+----------------+---------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.

重点说明
当整个kubernetes集群中有10个node节点,其中有2个node节点被设置成了路由发射器(RR)。在所有node节点上执行 calicoctl node status 命令查看当前节点的calico状态时,被设置成RR的2个节点的输出信息中PEER ADDRESS栏显示的是除自身ip外的其他所有node节点的ip,而另外8个节点的输出信息中PEER ADDRESS栏显示的是2个ip,即被设置成RR的node节点对应的ip。

Calico IPIP模式

IPIP概述

image.png

ipip模式与flannel的vxlan模式类似,也是对数据包的一个封装。IPIP是linux内核的驱动程序,可以对数据包进行隧道,是基于现有的以太网的网络将你原来包里的原始IP进行一次封装。

Pod 1 访问 Pod 2 大致流程:
1、数据包从pod1出到达Veth Pair另一端(宿主机上,以cali前缀开头);
2、进入IP隧道设备(tunl0),由Linux内核IPIP驱动封装在宿主机网络的IP包中(新的IP包目的地址是原IP包的下一跳地址,即192.168.31.63),这样就成了Node1到Node2的数据包;
此时包的类型:
原始IP包:
源IP:10.244.1.10
目的IP:10.244.2.10

  TCP:<br />      源IP: 192.168.31.62<br />      目的iP:192.168.32.63

IPIP本身和vxlan一样,工作在三层的,它用以太网进行传输,数据包经过路由器三层转发到Node2;Node2收到数据包后,网络协议栈会使用IPIP驱动进行解包,从中拿到原始IP包;然后根据路由规则将数据包转发给cali设备,从而到达pod2。

当Calico使用IPIP模式的时候,集群的网络性能会因为额外的封包和解包工作而下降。

IPIP实现

修改为IPIP模式:

[root@m1 ~]# calicoctl get ippool -o yaml > ipip.yaml

[root@m1 ~]# cat ipip.yaml 
apiVersion: projectcalico.org/v3
items:
- apiVersion: projectcalico.org/v3
  kind: IPPool
  metadata:
    creationTimestamp: "2022-05-08T12:15:23Z"
    name: default-ipv4-ippool
    resourceVersion: "91151"
    uid: 3ae84b0a-b3cd-4bd8-a765-9a1e04003ef2
  spec:
    blockSize: 26
    cidr: 10.244.0.0/16
    ipipMode: Always  #修改此行,开启ipip模式
    natOutgoing: true
    nodeSelector: all()
    vxlanMode: Never
kind: IPPoolList
metadata:
  resourceVersion: "215704"

[root@m1 ~]# calicoctl apply -f ipip.yaml 
Successfully applied 1 'IPPool' resource(s)

[root@m1 ~]# calicoctl get ippool -o wide
NAME                  CIDR            NAT    IPIPMODE   VXLANMODE   DISABLED   SELECTOR   
default-ipv4-ippool   10.244.0.0/16   true   Always     Never       false      all()      

# 可查看到新增了一个tun10的虚拟隧道网卡
[root@m1 ~]# ifconfig 
...
tunl0: flags=193<UP,RUNNING,NOARP>  mtu 1480
        inet 10.244.202.2  netmask 255.255.255.255
        tunnel   txqueuelen 1000  (IPIP Tunnel)
...