一、下載模板wget https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml
node
能夠獲得一份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.yaml
spa
四、calico使用過程當中的一些其餘點3d
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等的定製化。
經過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
,因而包順利被對端接收
咱們經過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抓包看到這個步驟:
封裝前:
封裝後(注意到輸出內容結尾有ipip-proto-4
):
四、因爲宿主機上只有一個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響應包的走向與上述的走向邏輯上相同。