Calico IPIP模式詳解

Kubernetes 集羣中的Calico網絡插件有幾種網絡模式,例如BGP, IPIP, VXLAN (Calico v3.7以後支持此模式),本文主要介紹IPIP模式。node

 

Calico IPIP模式實際上是利用了Linux 的tun/tap設備,對IP層的報文再加了一層IP層的封裝實現的一種overlay模式。由於IPIP模式比BGP模式多了一層封包與拆包,因此性能會有所損耗。既然如此,爲何不直接使用BGP模式就好了呢?由於BGP模式是須要經過路由廣播交換容器網絡的路由信息,而路由廣播只能在局域網中進行,在BGP模式下,若是kubernetes集羣中的工做節點不在同一個子網,則跨子網的工做節點上的POD沒法正常通訊。docker

 

下面經過一些例子來詳細瞭解Calico IPIP模式是如何工做的。api

 

咱們使用的集羣中加上管理節點總共有兩個工做節點網絡

[root@master01 /]# kubectl get node
NAME       STATUS   ROLES    AGE   VERSION
master01   Ready    master   57d   v1.15.12
node01     Ready    <none>   62m   v1.15.12

 

部署了calico網絡插件tcp

[root@master01 /]# kubectl -n kube-system get po -owide | grep calico-node
calico-node-9shgc                          1/1     Running   0          11m   192.168.92.128   master01   <none>           <none>
calico-node-c2scz                          1/1     Running   0          11m   192.168.92.129   node01     <none>           <none>

 

容器網段爲172.16.0.0/16ide

        - name: CALICO_IPV4POOL_CIDR
          value: 172.16.0.0/16

 

kubectl get ipamblocks能夠看到有兩個容器網段分別分配給了master01和node01。性能

[root@master01 ~]# kubectl get ipamblocks
NAME                AGE
172-16-196-128-26   59m
172-16-241-64-26    60m
[root@master01 ~]# kubectl get ipamblocks 172-16-196-128-26 -oyaml
apiVersion: crd.projectcalico.org/v1
kind: IPAMBlock
metadata:
  annotations:
    projectcalico.org/metadata: '{"creationTimestamp":null}'
  creationTimestamp: "2021-03-30T04:17:26Z"
  generation: 6
  name: 172-16-196-128-26
  resourceVersion: "2380"
  selfLink: /apis/crd.projectcalico.org/v1/ipamblocks/172-16-196-128-26
  uid: f10cf88f-f999-49c6-bd7f-17670ed0e173
spec:
  Deleted: false
  affinity: host:node01
[root@master01 ~]# kubectl get ipamblocks 172-16-241-64-26 -oyaml
apiVersion: crd.projectcalico.org/v1
kind: IPAMBlock
metadata:
  annotations:
    projectcalico.org/metadata: '{"creationTimestamp":null}'
  creationTimestamp: "2021-03-30T04:16:40Z"
  generation: 6
  name: 172-16-241-64-26
  resourceVersion: "983"
  selfLink: /apis/crd.projectcalico.org/v1/ipamblocks/172-16-241-64-26
  uid: 97e63164-1f4b-4621-9c08-2b1fdb766cb1
spec:
  Deleted: false
  affinity: host:master01

 

查看主機master01上的路由表,能夠看到目標地址爲172.26.196.128/26的請求會被經過網卡tunl0轉發到192.168.92.129,也就是node01上。ui

而master01節點本機上的POD IP,則會直接被路由到對應的calico網卡。spa

[root@master01 /]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.92.2    0.0.0.0         UG    100    0        0 ens33
172.16.196.128 192.168.92.129 255.255.255.192 UG 0 0 0 tunl0 172.16.241.64   0.0.0.0         255.255.255.192 U     0      0        0 *
172.16.241.69 0.0.0.0 255.255.255.255 UH 0 0 0 cali68d0bd52ca7 172.16.241.70 0.0.0.0 255.255.255.255 UH 0 0 0 cali55ce5618d78 172.16.241.71 0.0.0.0 255.255.255.255 UH 0 0 0 cali6156df79841 172.16.241.72 0.0.0.0 255.255.255.255 UH 0 0 0 cali81d206a1716 172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.92.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.241.64  0.0.0.0         255.255.255.192 U     0      0        0 *

 

一樣,在node01上也能夠看到相似的路由條目。插件

[root@node01 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.92.2    0.0.0.0         UG    100    0        0 ens33
172.16.196.128  0.0.0.0         255.255.255.192 U     0      0        0 *
172.16.196.129 0.0.0.0 255.255.255.255 UH 0 0 0 cali6321cd990f9 172.16.196.131 0.0.0.0 255.255.255.255 UH 0 0 0 cali63b1569e518 172.16.241.64 192.168.92.128 255.255.255.192 UG 0 0 0 tunl0 172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.92.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33

 

如今咱們在每一個工做節點上分別部署一個busybox POD,而後再詳細看看跨節點的POD之間是怎麼通訊的。

[root@master01 ~]# kubectl -n kube-system get po -owide | grep busybox
busybox-b8ffb94c4-2ltgw                    1/1     Running            0          17s     172.16.196.132   node01     <none>           <none>
busybox-b8ffb94c4-c84gp                    1/1     Running            0          17s     172.16.241.69    master01   <none>           <none>

 

在其中一個busybox POD上訪問另外一個節點上的busybox。

[root@master01 ~]# kubectl -n kube-system exec -it busybox-b8ffb94c4-c84gp sh
/ # ping 172.16.196.132
PING 172.16.196.132 (172.16.196.132): 56 data bytes
64 bytes from 172.16.196.132: seq=0 ttl=62 time=0.580 ms

 

在另外一臺主機上抓包。

[root@node01 ~]# tcpdump -i any -nn -vvvv host \(192.168.92.128 or 172.16.241.69\) -w /tmp/busybox.cap

 

使用wireshark打開抓包文件,能夠看到報文在POD A (172.16.241.69) 和POD B (172.16.196.132)之間,通過了兩層的IP封裝。

 

由於跨節點的POD之間通訊時,報文須要經過宿主機的網絡發送到另外一個節點,但宿主機網絡沒法識別容器IP,因此,報文從POA A發送到宿主機A的tunl0網卡時,內核自動在報文基礎上封裝了一層IP頭,以後再轉發給主機B(192.168.92.129)。主機B拆開IP報文以後,根據本機的路由表匹配到目標POD的網卡,最終把報文轉發給了POD B。

 

 

 這裏有一個問題,主機192.168.92.128和192.168.92.129是在同一個子網的,他們之間實際上是能夠經過BGP路由信息交換,使到POD之間能夠直接路由可達,而不須要經過IPIP協議,畢竟IPIP協議仍是有損耗的。

 

在Calico IPIP模式下,其實有一個配置項(CALICO_IPV4POOL_IPIP),可讓calico只有在跨子網的狀況下才使用IPIP協議,同一子網中的POD直接經過路由信息直連。該參數爲以下,添加到calico-node的環境變量中便可。

 

        - name: CALICO_IPV4POOL_IPIP
          value: CrossSubnet

 

若是是已經部署了calico以後再修改這個參數,還須要修改ippool中的ipipMode參數。

[root@master01 ~]# kubectl get ippool default-ipv4-ippool -oyaml
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
  annotations:
    projectcalico.org/metadata: '{"uid":"3797d863-3b04-45cd-b9ba-ac1980a21520","creationTimestamp":"2021-03-30T04:16:40Z"}'
  creationTimestamp: "2021-03-30T04:16:40Z"
  generation: 1
  name: default-ipv4-ippool
  resourceVersion: "732"
  selfLink: /apis/crd.projectcalico.org/v1/ippools/default-ipv4-ippool
  uid: 4c7acedb-0026-4062-994d-e82d261f29cc
spec:
  blockSize: 26
  cidr: 172.16.0.0/16 ipipMode: CrossSubnet

 

修改完以上參數以後,咱們再看看主機上的路由表,能夠看到容器網段172.16.196.128/26的路由條目,出口的網卡變成了ens33,也就是再也不經過tunl0進行IPIP協議的封裝,而是直接根據路由信息轉發。

[root@master01 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.92.2    0.0.0.0         UG    100    0        0 ens33
172.16.196.128  192.168.92.129  255.255.255.192 UG    0      0        0 ens33 172.16.241.64   0.0.0.0         255.255.255.192 U     0      0        0 *
172.16.241.65   0.0.0.0         255.255.255.255 UH    0      0        0 cali99ba0e1a1c8
172.16.241.66   0.0.0.0         255.255.255.255 UH    0      0        0 cali3941b92be17
172.16.241.67   0.0.0.0         255.255.255.255 UH    0      0        0 cali0fd794bcf81
172.16.241.68   0.0.0.0         255.255.255.255 UH    0      0        0 cali291c708c629
172.16.241.69   0.0.0.0         255.255.255.255 UH    0      0        0 cali67beaa0e9f4
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.92.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33

 

一樣的在POD A ping POD B並抓包看看,咱們能夠看到此次只有一個IP層報文。

相關文章
相關標籤/搜索