Calico 簡介
Calico 是一個基於BGP協議的網絡互聯解決方案。它是一個純3層的方法,使用路由來實現報文尋址和傳輸。
相比 flannel
, ovs
等SDN解決方案,Calico 避免了層疊網絡帶來的性能損耗。將節點當做 router ,位於節點上的 container 被當做 router 的直連設備。利用 Kernel 來實現高效的路由轉發。 節點間的路由信息通過 BGP 協議在整個 Calico 網絡中傳播。 具有以下特點:
1. 在 calico 中的數據包不需要進行封包和解封。
2. 基於三層網絡通信,troubleshoot 會更方便。
3. 網絡安全策略使用 ACL 定義,基於 iptables 實現,比起 overlay 方案中的複雜機制更只管和容易操作。
Environment
server | ip | mac | gw mac |
---|---|---|---|
walker-1 | 172.16.6.47 | fa:16:3e:02:8b:17 | 00:23:89:8C:E8:31 |
walker-2 | 172.16.6.249 | fa:16:3e:8c:21:13 | 00:23:89:8C:E8:31 |
demi-1 | 172.16.199.114 | fa:16:3e:d9:a0:5e | 00:23:89:8C:E8:31 |
busybox-1 | 192.168.187.211 | 3a:1d:1e:91:f5:9e | 66:39:fa:e7:9f:a9 |
busybox-2 | 192.168.135.74 | de:16:fc:1c:44:35 | 5a:4a:df:5e:c9:6c |
busybox-3 | 192.168.121.2 | de:16:fc:1c:44:35 | 8e:6b:fa:f7:5d:3b |
node2 單獨位於vlan 199
中,和master以及node1間的通信需要經過網關(Router)轉發。
使用 IP-in-IP
ipip enable=false
$ calicoctl apply -f - << EOF
apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.0.0/16
spec:
nat-outgoing: true
EOF
ipip 模式禁用時,busybox-3
和 busybox-{1,2}
之間無法通信。
分析如下:
主機路由:
[root@walker-1 manifests]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.16.6.254 0.0.0.0 UG 0 0 0 eth0
169.254.169.254 172.16.6.87 255.255.255.255 UGH 0 0 0 eth0
172.16.6.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.121.0 172.16.199.114 255.255.255.192 UG 0 0 0 eth0
192.168.135.64 172.16.6.249 255.255.255.192 UG 0 0 0 eth0
192.168.187.192 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.187.209 0.0.0.0 255.255.255.255 UH 0 0 0 calic6611247c43
192.168.187.211 0.0.0.0 255.255.255.255 UH 0 0 0 calie50081a277c
從busybox-1
發往 busybox-3
的報文頭部如下所示:
src max | dst mac | src ip | dst ip
--- | --- | --- | ---
3a:1d:1e:91:f5:9e | 66:39:fa:e7:9f:a9 | 192.168.187.211 | 192.168.121.2
根據宿主機路由,報文會從eth0 發往 172.16.199.114。
由於二者位於不通廣播域,需要通過網關轉發。因此報文的 dst mac
會被修改爲 172.16.6.254(gw) 對應的mac。
src max | dst mac | src ip | dst ip | enc src IP | enc dst IP
--- | --- | --- | --- | --- | ---
fa:16:3e:02:8b:17 | 00:23:89:8C:E8:31 | 192.168.187.211 | 192.168.121.2
gw 收到該報文後,會比對本地路由條目。由於 router 中並沒有到 192.168.121.0\26 網段的路由,因此報文被丟棄。
ipip enable=true
$ calicoctl apply -f - << EOF
apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.0.0/16
spec:
ipip:
enabled: true
mode: always
nat-outgoing: true
EOF
這種模式下,可實現跨網段節點上容器的互通。
[root@walker-1 manifests]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.16.6.254 0.0.0.0 UG 0 0 0 eth0
169.254.169.254 172.16.6.87 255.255.255.255 UGH 0 0 0 eth0
172.16.6.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.121.0 172.16.199.114 255.255.255.192 UG 0 0 0 tunl0
192.168.135.64 172.16.6.249 255.255.255.192 UG 0 0 0 tunl0
192.168.187.192 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.187.209 0.0.0.0 255.255.255.255 UH 0 0 0 calic6611247c43
192.168.187.211 0.0.0.0 255.255.255.255 UH 0 0 0 calie50081a277c
busybox-1 發送報文至 busybox-3 時,根據 master 上路由,會經過 tunl0
設備。tunl0
會爲原來的IP報文在封裝一層IP協議頭。過程如下:
busybox-1 向 busybox-3 發送 icmp 報文(略去容器至 calico 網卡步驟)。
src max dst mac src ip dst ip 3a:1d:1e:91:f5:9e 66:39:fa:e7:9f:a9 192.168.187.211 192.168.121.2 報文被node 截獲,查詢本機路由後由
tunl0
設備將報文發出。src max dst mac src ip dst ip enc src IP enc dst IP fa:16:3e:02:8b:17 00:23:89:8C:E8:31 192.168.187.211 192.168.121.2 172.16.6.47 172.16.199.114 報文發送至網關(router), 根據目的IP將報文路由至 172.16.199.114(略去ARP等步驟)。
src max dst mac src ip dst ip enc src IP enc dst IP 00:23:89:8C:E8:31 fa:16:3e:d9:a0:5e 192.168.187.211 192.168.121.2 172.16.6.47 172.16.199.114 到達 demi-1 後,根據 demi-1 上的路由策略,將報文發送至 busybox-3(略去容器至 calico 網卡步驟) 。
src max dst mac src ip dst ip 8e:6b:fa:f7:5d:3b de:16:fc:1c:44:35 192.168.187.211 192.168.121.2
Note: ==容器的 gw 爲和該容器對應的 calico 網卡。==
雖然實現了 calico 跨網段通信,但對於 busybox-{1,2} 間的通信來說,IP-in-IP 就有點多餘了,因爲2者宿主機處於同一廣播域,2層互通,直接走主機路由即可。
calico cross-subnet
$ calicoctl apply -f - << EOF
apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.0.0/16
spec:
ipip:
enabled: true
mode: cross-subnet
nat-outgoing: true
EOF
爲了解決IP-in-IP 模式下,同網段封裝報文的問題,calico 提供了 cross-subnet
的配置選項
[root@walker-1 k8s]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.16.6.254 0.0.0.0 UG 0 0 0 eth0
169.254.169.254 172.16.6.87 255.255.255.255 UGH 0 0 0 eth0
172.16.6.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.121.0 172.16.199.114 255.255.255.192 UG 0 0 0 tunl0
192.168.135.64 172.16.6.249 255.255.255.192 UG 0 0 0 eth0
192.168.187.192 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.187.209 0.0.0.0 255.255.255.255 UH 0 0 0 calic6611247c43
192.168.187.211 0.0.0.0 255.255.255.255 UH 0 0 0 calie50081a277c
從主機路由可看出,對於同一網段中的路由,直接走 eth0 網卡。
默認情況下,calico 在啓動時會自動選擇一塊網卡。當主機上有多塊網卡時,爲了保證路由的正確性,需要手動指定 calico 使用哪塊物理網卡。參考一下鏈接:
http://docs.projectcalico.org/v2.3/usage/configuration/node
Note
The
cross-subnet
mode option requires each Calico node to be configured with the IP address and subnet of the host. However, the subnet configuration was only introduced in Calico v2.1. If any nodes in your deployment were originally created with an older version of Calico, or if you if you are unsure whether your deployment is configured correctly, follow the steps in Upgrading from pre-v2.1 before enablingcross-subnet
IPIP.