Calico是一個純三層的數據中心網絡方案(不需要Overlay),並且與 OpenStack、Kubernetes、AWS、GCE 等 IaaS 和容器平臺都有良好的集成。
Calico 在每一個計算節點利用 Linux Kernel 實現了一個高效的 vRouter 來負責數據轉發,而每個 vRouter 通過 BGP 協議負責把自己上運行的 workload 的路由信息像整個 Calico 網絡內傳播——小規模部署可以直接互聯,大規模下可通過指定的 BGP route reflector 來完成。 這樣保證最終所有的 workload 之間的數據流量都是通過 IP 路由的方式完成互聯的。Calico 節點組網可以直接利用數據中心的網絡結構(無論是 L2 或者 L3),不需要額外的 NAT,隧道或者 Overlay Network。
此外,Calico 基於 iptables 還提供了豐富而靈活的網絡 Policy,保證通過各個節點上的 ACLs 來提供 Workload 的多租戶隔離、安全組以及其他可達性限制等功能。
一、Calico架構
1、Calico組成
主要由 Felix、etcd、BGP client 以及 BGP Route Reflector 組成:
Felix: Calico agent,跑在每臺需要運行 workload 的節點上,主要負責配置路由及 ACLs 等信息來確保 endpoint 的連通狀態;
etcd: 分布式鍵值存儲,主要負責網絡元數據一致性,確保 Calico 網絡狀態的準確性;
BGPClient(BIRD): 主要負責把 Felix 寫入 kernel 的路由信息分發到當前 Calico 網絡,確保 workload 間的通信的有效性;
BGP Route Reflector(BIRD): 大規模部署時使用,摒棄所有節點互聯的 mesh 模式,通過一個或者多個BGP Route Reflector來完成集中式的路由分發;
2、Calico網絡方式
(1)IPIP
從字面來理解,就是把一個IP數據包又套在一個IP包裡,即把 IP 層封裝到 IP 層的一個 tunnel,看起來似乎是浪費,實則不然。它的作用其實基本上就相當於一個基於IP層的網橋!一般來說,普通的網橋是基於mac層的,根本不需 IP,而這個 ipip 則是通過兩端的路由做一個 tunnel,把兩個本來不通的網絡通過點對點連接起來。ipip 的原始碼在內核 net/ipv4/ipip.c 中可以找到。
(2)BGP
邊界網關協議(Border Gateway Protocol, BGP)是網際網路上一個核心的去中心化自治路由協議。它通過維護IP路由表或『前綴』表來實現自治系統(AS)之間的可達性,屬於矢量路由協議。BGP不使用傳統的內部網關協議(IGP)的指標,而使用基於路徑、網絡策略或規則集來決定路由。因此,它更適合被稱為矢量性協議,而不是路由協議。BGP,通俗的講就是將接入到機房的多條線路(如電信、聯通、移動等)融合為一體,實現多線單IP,BGP 機房的優點:伺服器只需要設置一個IP位址,最佳訪問路由是由網絡上的骨幹路由器根據路由跳數與其它技術指標來確定的,不會佔用伺服器的任何系統。
二、Calico原理
Calico把每個作業系統的協議棧認為是一個路由器,然後把所有的容器認為是連在這個路由器上的網絡終端,在路由器之間跑標準的路由協議——BGP的協議,然後讓它們自己去學習這個網絡拓撲該如何轉發。所以Calico方案其實是一個純三層的方案,也就是說讓每臺機器的協議棧的三層去確保兩個容器,跨主機容器之間的三層連通性。
對於控制平面,它每個節點上會運行兩個主要的程序,一個是Felix,它會監聽ECTD中心的存儲,從它獲取事件,比如說用戶在這臺機器上加了一個IP,或者是分配了一個容器等。接著會在這臺機器上創建出一個容器,並將其網卡、IP、MAC都設置好,然後在內核的路由表裡面寫一條,註明這個IP應該到這張網卡。綠色部分是一個標準的路由程序,它會從內核裡面獲取哪一些IP的路由發生了變化,然後通過標準BGP的路由協議擴散到整個其他的宿主機上,讓外界都知道這個IP在這裡,你們路由的時候得到這裡來。
由於Calico是一種純三層的實現,因此可以避免與二層方案相關的數據包封裝的操作,中間沒有任何的NAT,沒有任何的overlay,所以它的轉發效率可能是所有方案中最高的,因為它的包直接走原生TCP/IP的協議棧,它的隔離也因為這個棧而變得好做。因為TCP/IP的協議棧提供了一整套的防火牆的規則,所以它可以通過IPTABLES的規則達到比較複雜的隔離邏輯。
轉發流程如下圖所示:
三、基於kubeadm部署Calico網絡
[root@k8s-master ~] cat calico.yaml | grep image:
[root@k8s-master ~] docker pull calico/pod2daemon-flexvol:v3.13.3[root@k8s-master ~] docker pull calico/kube-controllers:v3.13.3
[root@k8s-master ~]34;10.244.0.0/16& kubectl apply -f calico.yaml
[root@k8s-master ~] kubectl get pods -n kube-system | grep calico
[root@k8s-master ~] kubectl get nodes
[root@k8s-master ~] kubectl cluster-info
2、查看網絡
在k8s-master上查看:
[root@k8s-master ~] ip a
在k8s-node-2上查看:
[root@k8s-node-2 ~] vim nginx-web.yml添加:apiVersion: v1kind: Servicemetadata: name: nginx labels: tier: frontendspec: type: NodePort selector: tier: frontend ports: - name: http port: 80 targetPort: 80---apiVersion: apps/v1kind: Deploymentmetadata: name: nginxspec: replicas: 2 selector: matchLabels: tier: frontend template: metadata: labels: tier: frontend spec: containers: - name: nginx image: nginx:1.16 ports: - name: http containerPort: 80
[root@k8s-master ~] kubectl get pods[root@k8s-master ~] ping 10.244.109.67[root@k8s-master ~] curl http://10.244.109.67
[root@k8s-master ~] wget https://github.com/projectcalico/calicoctl/releases/download/v3.14.0/calicoctl [root@k8s-master ~] cp calicoctl /usr/local/bin/ [root@k8s-master ~] scp calicoctl 192.168.1.2:/usr/local/bin/
[root@k8s-master ~] calicoctl node status
k8s-node-1查看網絡狀態
[root@k8s-node-1 ~] calicoctl node status
驗證網絡:
[root@k8s-master ~] netstat -antlp | grep ESTABLISHED | grep bird
[root@k8s-node-1 ~] netstat -antlp | grep ESTABLISHED | grep bird