calico網絡模型中的路由原理

calico的部署

一、下載模板
wget https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yamlnode

能夠獲得一份calico官方提供的v3.1版本calico的部署模板(基於kubeadm)。固然裏面都是社區的鏡像,咱們能夠替換成本地鏡像.建議到網易雲的景象中心下載,不少其餘的國內鏡像倉庫都不作維護了。後端

二、啓/禁用 ip-ip網絡

目前官方提供的模板裏,默認打開了ip-ip功能,該功能會在node上建立一個設備:tunl0,容器的網絡數據會通過該設備被封裝一個ip頭再轉發。這裏,calico.yaml中經過修改calico-node的環境變量:CALICO_IPV4POOL_IPIP來實現ipip功能的開關:默認是Always,表示開啓;Off表示關閉ipip; cross-subnet表示開啓並支持跨子網,目前用不到這種類型。
sed -i "s#Always#Off#g" calico.yaml併發

三、部署:app

注意:部署前,要配置一個參數,讓calico-node組件可以識別node的IP,node上可能有多塊網卡,官方提供的yaml文件中,ip識別策略(IPDETECTMETHOD)沒有配置,即默認爲first-found,這會致使一個網絡異常的ip做爲nodeIP被註冊,從而影響node-to-node mesh。咱們能夠修改爲can-reach的策略,嘗試鏈接某一個Ready的node的IP,以此選擇出正確的IP。tcp

爲了方便,下面的腳本里,我以任意一個node的ip地址爲reach 地址ide

connective_ip=`kubectl get node -o wide |grep Ready |head -n1 |awk '{print $6}'`
sed -i  -rn 'p;/name: IP/,/autodetect/H;/autodetect/{g;s/^\n//;p}' calico.yaml 
sed -i '1,/name: IP/{s/name: IP/name: IP_AUTODETECTION_METHOD/}' calico.yaml
sed -i '1,/\"autodetect\"/{s/\"autodetect\"/can-reach=__ONE_CONNECTIVE_ENDPOINT__/}' calico.yaml
sed -i "s#__ONE_CONNECTIVE_ENDPOINT__#$connective_ip#g" calico.yaml

執行:
kubectl apply -f calico.yamlspa

四、calico使用過程當中的一些其餘點3d

  1. calico以ipip模式部署完畢後,node上會有一個tunl0的網卡設備,這是ipip作隧道封裝用的。當咱們把節點下線,calico容器都中止後,這個設備依然還在,執行 rmmod ipip 命令能夠將它刪除(若是calico-node仍在運行,會自動再建一個新的)
  2. calico部署完畢後,其數據記錄在calico-etcd容器運行節點的/var/etcd/calico-data目錄中,若是要徹底清理集羣中的etcd數據,須要將該目錄刪除。
  3. calico支持以kubernetes爲存儲後端,以這種方式部署時,calico再也不須要額外部署etcd,而是將數據以CRD的方式存到k8s中。calico的組件依賴kubeconfig與k8s交互。在這種模式下,部署calico須要執行:
wget https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml
wget https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
kubectl apply -f rbac-kdd.yaml
kubectl apply -f calico.yaml
此處下載的calico.yaml 仍能夠參照上文的部署方式進行ipip、ip pool等的定製化。

calico bgp 網絡

經過bgp方式部署好calico後,咱們在集羣中建立幾個pod:code

root@k8s-calico1:~# pods 
NAMESPACE     NAME                                       READY     STATUS    RESTARTS   AGE       IP                NODE
huang1        huangtest-69d9fddd97-cbzbm                 1/1       Running   0          20m       192.168.211.1     k8s-calico4
huang1        huangtest-69d9fddd97-pbvvw                 1/1       Running   0          3m        192.168.210.194   k8s-calico3
huang2        hhh-6897d64fcd-4zph4                       1/1       Running   0          1d        192.168.97.2      k8s-calico2

咱們在k8s-calico2這個node上來看。執行ip r, 在這個node的路由中,須要咱們關注的有:

192.168.97.2 dev calic285cddbb40 scope link 
blackhole 192.168.97.0/26 proto bird 
192.168.210.192/26 via 10.173.32.26 dev eth0 proto bird 
192.168.211.0/26 via 10.173.32.25 dev eth0 proto bird

192.168.97.2 dev calic285cddbb40 scope link 這條路由將通向容器ip的請求導向veth:calic285cddbb40 ,進而讓請求直達容器內的網卡。
blackhole 192.168.97.0/26 proto bird 表示發往192.168.97.0/26網段的報文都會被丟棄且不會回覆源端。配置這條路由的緣由是:這臺機器上的calico網絡可分配的cidr是192.168.97.0/26,容器裏訪問同網段的其餘IP時,配置該路由以免報文被髮到外部。
最後兩條,分別記錄了:要訪問calico網絡中的某個網段,須要以對應的node IP爲網關,經過eth0發包。也就是說經過這兩條路由,能夠將部分網段(目的IP)的包經由eth0發送到正確的地方。

咱們能夠這麼理解:pod hhh-6897d64fcd-4zph4中ping huangtest-69d9fddd97-pbvvw時,流量是這麼走的:

0、數據包封裝完成,srcip:192.168.97.2 , destip:192.168.210.194
一、容器中只有eth0網卡,容器裏ip r 看到的是default **** dev eth0,因此流量經過容器的eth0發送。
二、容器網卡的配置是經過vethpair作的,也就是說,容器裏網卡發的包,在宿主機上都會被calic285cddbb40設備發出。
三、經過第2步,網絡報文就在宿主機的網絡中,受宿主機路由影響,192.168.210.192/26 via 10.173.32.26 dev eth0 proto bird這條路由會將數據從eth0轉發,併發給路由中記錄的網關:10.173.32.26(這個ip,就是pod huangtest-69d9fddd97-pbvvw所在的node:k8s-calico3 的ip)
四、10.173.32.26是node:k8s-calico3上eth0的ip,收到包後,在機器自身的路由表中尋找合理的路由,固然這個地方也會有路由:192.168.210.194 dev calif6874dae1d2 scope link,因而包順利被對端接收

calico ipip 網絡

咱們經過ip-ip模式部署calico,而後將原有的pod所有刪掉重建,以下:

root@k8s-calico1:~# pods 
NAMESPACE     NAME                                       READY     STATUS             RESTARTS   AGE       IP                NODE
huang1        huangtest-69d9fddd97-2b8hr                 1/1       Running            0          1m        192.168.97.1      k8s-calico2
huang1        huangtest-69d9fddd97-npwzw                 1/1       Running            0          1m        192.168.210.65    k8s-calico4
huang2        hhh-6897d64fcd-kqsj4                       1/1       Running            0          10s       192.168.210.129   k8s-calico3

咱們再去看看k8s-calico2這個node 上的路由,一樣的須要咱們關注的路由有下面的幾條:

root@k8s-calico2:~# ip r  |grep bird
192.168.97.1 dev cali3683f65394b scope link
blackhole 192.168.97.0/26 proto bird 
192.168.110.64/26 via 10.173.32.24 dev tunl0 proto bird onlink 
192.168.210.64/26 via 10.173.32.25 dev tunl0 proto bird onlink 
192.168.210.128/26 via 10.173.32.26 dev tunl0 proto bird onlink

前兩條再也不贅述,咱們看到最後三條路由,其實他們描述的邏輯與BGP的那兩條沒有差異,只不過網卡換成了tunl0.

咱們以一個例子來解釋清楚:pod huangtest-69d9fddd97-2b8hr ping hhh-6897d64fcd-kqsj4

0、封裝報文,SRCIP:192.168.97.1 DESTIP:192.168.210.129
一、容器中只有eth0網卡,容器裏ip r 看到的是default **** dev eth0,因此流量經過容器的eth0發送。
二、容器網卡的配置是經過vethpair作的,也就是說,容器裏網卡發的包,在宿主機上都會被calic285cddbb40設備發出。
三、經過第2步,網絡報文就在宿主機的網絡中,受宿主機路由影響,192.168.210.128/26 via 10.173.32.26 dev tunl0 proto bird onlink 識別到匹配的對端IP,將報文從tunl0發出到10.173.32.26。這裏,tunl0會對報文進行封裝,在原有的ip報文之上封裝了一個ip頭部,新的頭部中,srcip是宿主機自身的ip:10.173.32.23, destip是對端的ip地址:10.173.32.26。
咱們能夠經過tcpdump抓包看到這個步驟:
封裝前:

clipboard.png

封裝後(注意到輸出內容結尾有ipip-proto-4):

clipboard.png
四、因爲宿主機上只有一個eth的物理機網卡,因此流量終究仍是從eth0向外發出到10.173.32.26。10.173.32.26這個節點的eth0網卡,收到了報文後,發現帶有ipip協議的標記(第3步中tcpdump抓包看到的ipip-proto-4),將ipip頭部解開,因而處理到了真實的報文。
五、宿主機上192.168.210.129 dev cali5ce61eb6bc2 scope link 這個路由將包發給vethpair,從而被容器內的eth0接收。
六、icmp響應包的走向與上述的走向邏輯上相同。

待定:補充ipip和bgp的使用場景。以及calico的BGP路由配置方法(AS,node-mesh)

相關文章
相關標籤/搜索