1. 程式人生 > >基於calico網路策略

基於calico網路策略

一、簡介

Calico是一個純三層的協議,為OpenStack虛機和Docker容器提供多主機間通訊。Calico不使用重疊網路比如flannel和libnetwork重疊網路驅動,它是一個純三層的方法,使用虛擬路由代替虛擬交換,每一臺虛擬路由通過BGP協議傳播可達資訊(路由)到剩餘資料中心。

 為什麼Calico網路選擇BGP?

  參考地址:http://blog.51cto.com/weidawei/2152319

我們在Calico網路中使用BGP去宣告資料終端(end points)路由是因為如下原因:

(1)BGP是一種簡單的路由協議

(2)擁有當前行業的最佳實踐

(3)唯一能夠支撐Calico網路規模的協議

1、原理

如下圖所示,描述了從源容器經過源宿主機,經過資料中心的路由,然後到達目的宿主機最後分配到目的容器的過程。

1.png

整個過程中始終都是根據iptables規則進行路由轉發,並沒有進行封包,解包的過程,這和flannel相比效率就會快多了。

2、框架

2.png

calico包括如下重要元件:Felix,etcd,BGP Client,BGP Route Reflector。下面分別說明一下這些元件。

(1)Felix:主要負責路由配置以及ACLS規則的配置以及下發,它存在在每個node節點上。

(2)etcd:分散式鍵值儲存,主要負責網路元資料一致性,確保Calico網路狀態的準確性,可以與kubernetes共用;

(3)BGP Client(BIRD), 主要負責把 Felix寫入 kernel的路由資訊分發到當前 Calico網路,確保 workload間的通訊的有效性;

(4)BGPRoute Reflector(BIRD), 大規模部署時使用,摒棄所有節點互聯的mesh模式,通過一個或者多個 BGPRoute Reflector 來完成集中式的路由分發;

二、服務搭建

1、環境準備

1)系統環境

主機名

系統

宿主IP

服務

master01

CentOS7.4

172.169.18.210

docker1.13.1

etcd3.2.22

calico2.6.10

node01

CentOS7.4

172.169.18.162

docker1.13.1

etcd3.2.22

calico2.6.10

node02

CentOS7.4

172.169.18.180

docker1.13.1

etcd3.2.22

calico2.6.10

2)暫時關閉防火牆和selinux服務

3)配置hosts,新增如下

# vim /etc/hosts

172.169.18.210 master01

172.169.18.162 node01

172.169.18.180 node02

2、安裝docker服務(三個節點)

1)yum安裝docker1.13版本

# yum install docker -y

2)修改預設docker0的網絡卡資訊

# vim /etc/docker/daemon.json

#追加如下引數

"bip":"172.169.10.1/24"

其他節點:

node01網路地址:172.169.20.1/24

node01網路地址:172.169.30.1/24

重啟docker服務

3.png


3、安裝etcd服務(在三個節點機上都要安裝etcd,構成etcd叢集環境

1)yum安裝etcd3.2.22版本

# yum install etcd -y

2)修改etcd配置檔案

# vim /etc/etcd/etcd.conf

#maser01節點

ETCD_DATA_DIR="/var/lib/etcd/"

ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"

ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://127.0.0.1:4001"

ETCD_NAME="master01"

ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"

ETCD_INITIAL_CLUSTER="master01=http://172.169.18.210:2380,node01=http://172.169.18.162:2380,node02=http://172.169.18.180:2380"

ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"

ETCD_INITIAL_CLUSTER_STATE="new"

#node01節點

ETCD_DATA_DIR="/var/lib/etcd"

ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"

ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://127.0.0.1:4001"

ETCD_NAME="node01"

ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"

ETCD_INITIAL_CLUSTER="master01=http://172.169.18.210:2380,node01=http://172.169.18.162:2380,node02=http://172.169.18.180:2380"

ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"

ETCD_INITIAL_CLUSTER_STATE="new"

#node02

ETCD_DATA_DIR="/var/lib/etcd/default.etcd"

ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"

ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"

ETCD_NAME="node02"

ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"

ETCD_INITIAL_CLUSTER="master01=http://172.169.18.210:2380,node01=http://172.169.18.162:2380,node02=http://172.169.18.180:2380"

ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"

ETCD_INITIAL_CLUSTER_STATE="new"

按如上配置分別啟動叢集,啟動集群后,將會進入叢集選舉狀態,若出現大量超時,則需要檢查主機的防火牆是否關閉,或主機之間是否能通過2380埠通訊,叢集建立後通過以下命令檢查叢集狀態。

3)在任意節點檢視叢集狀態

# etcdctl member list

4.png

當關閉master01節點後,選舉自動切換到node02上

5.png

4)檢查叢集健康狀態(在三個節點中的任意一個上面都可以檢視)

# etcdctl cluster-health

6.png

到此,etcd叢集搭建完畢!!!


4、搭建Calico服務(docker集合採用2.6版本)

備註:新老版本的執行命令有所差異,注意了!!!

Calico實現了一個Docker網路外掛,可用於為Docker容器提供路由和高階網路策略。

calico地址:https://github.com/projectcalico/calicoctl/tags

1)下載

# wget -O  /usr/local/bin/calicoctl https://github.com/projectcalico/calicoctl/releases/download/v1.6.4/calicoctl

# chmod +x /usr/local/bin/calicoctl

7.png

2)配置calicoctl - etcdv2資料儲存區

官方配置地址:https://docs.projectcalico.org/v2.6/reference/calicoctl/setup/etcdv2

# mkdir -p /etc/calico

# vim /etc/calico/calicoctl.cfg

# cat /etc/calico/calicoctl.cfg

apiVersion: v1

kind: calicoApiConfig

metadata:

spec:

 datastoreType: "etcdv2"

 etcdEndpoints: http://172.169.18.210:2379,http://172.169.18.162:2379,http://172.169.18.180:2379

3)幫助資訊

# calicoctl -help

8.png

啟動Calico服務

在Docker環境中Calico服務是做為容器來執行的,使用host的網路配置。所有容器配置使用Calico服務,做為calico節點互相通訊。

Calico在每個主機上通過一個自己的container與其他主機或者網路通訊,即calico-node的container,這個container裡面包含了Bird路由管理、Felix協議等。

4)在三個節點上都要下載calico的node映象

(可以先在一個節點上下載映象,然後將映象通過docker save匯出儲存到本地,再將映象拷貝到其他節點上通過docker load匯入,這樣對於其他節點來說,比使用docker pull要快)

[[email protected] ~]# docker pull calico/node:v2.6.10

[[email protected] ~]# docker pull calico/node-libnetwork

9.png

5.1)啟動三個節點的node服務(方法一)

#master01節點(指定版本--node-image=calico/node:v2.6.10

# calicoctl node run --node-image=calico/node:v2.6.10 --ip=172.169.18.210

10.png

#node01

# calicoctl node run --node-image=calico/node:v2.6.10 --ip=172.169.18.162

#node02

# calicoctl node run --node-image=calico/node:v2.6.10 --ip=172.169.18.180

5.2)啟動三個節點的node服務(方法二)

#建立system service檔案

# EnvironmentFile:ExecStart中大量引用的環境變數,在/etc/calico/calico.env檔案中設定;

# ExecStartPre操作:如果環境中存在calico-node服務,刪除;

# ExecStart操作:”--net”設定網路引數;“--privileged”以特權模式執行;‘“--nam”設定容器名;“calico/node:v2.6.10”指定映象,這裡預設是“quay.io/calico/node:v2.6.10”;

# ExecStop操作:停止容器;

# -v /var/run/docker.sock:/var/run/docker.sock:此對映關係在官方文件中未給出;

# 會導致在建立容器時報錯“docker: Error response from daemon: failed to create endpoint test1 on network net1: NetworkDriver.CreateEndpoint: Network 44322b3b9b8c5eface703e1dbeb7e3755f47ede1761a72ea4cb7cec6d31ad2e5 inspection error: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.”;

# 即在calico型別的網路上不能建立容器,因為無法呼叫docker服務的sock,需要指明calico服務呼叫docker sock的路徑,請見:https://github.com/projectcalico/calico/issues/1303

# vim /usr/lib/systemd/system/calico.service

[Unit]

Description=calico-node

After=docker.service

Requires=docker.service

[Service]

EnvironmentFile=/etc/calico/calico.env

ExecStartPre=-/usr/bin/docker rm -f calico-node

ExecStart=/usr/bin/docker run --net=host --privileged \

--name=calico-node \

-e NODENAME=${CALICO_NODENAME} \

-e IP=${CALICO_IP} \

-e IP6=${CALICO_IP6} \

-e CALICO_NETWORKING_BACKEND=${CALICO_NETWORKING_BACKEND} \

-e AS=${CALICO_AS} \

-e NO_DEFAULT_POOLS=${CALICO_NO_DEFAULT_POOLS} \

-e CALICO_LIBNETWORK_ENABLED=${CALICO_LIBNETWORK_ENABLED} \

-e ETCD_ENDPOINTS=${ETCD_ENDPOINTS} \

-e ETCD_CA_CERT_FILE=${ETCD_CA_CERT_FILE} \

-e ETCD_CERT_FILE=${ETCD_CERT_FILE} \

-e ETCD_KEY_FILE=${ETCD_KEY_FILE} \

-v /var/log/calico:/var/log/calico \

-v /run/docker/plugins:/run/docker/plugins \

-v /var/run/docker.sock:/var/run/docker.sock \

-v /lib/modules:/lib/modules \

-v /var/run/calico:/var/run/calico \

calico/node:v2.6.10

ExecStop=-/usr/bin/docker stop calico-node

Restart=on-failure

StartLimitBurst=3

StartLimitInterval=60s

[Install]

WantedBy=multi-user.target

#calico.env變數檔案

# vim /etc/calico/calico.env

ETCD_ENDPOINTS=http://172.169.128.210:2379,http://172.169.18.162:2379,http://172.169.18.180:2379

# 啟用ssl/tls時,認證相關檔案位置

ETCD_CA_FILE=""

ETCD_CERT_FILE=""

ETCD_KEY_FILE=""

# 留空時預設採用主機hostname作為辨識,所以留空時請確保主機名唯一

CALICO_NODENAME=""

CALICO_NO_DEFAULT_POOLS=""

# 設定路由下一跳,留空時從主機當前埠中自動選擇,有引數”autodetect”強制每次啟動時間自動檢測

CALICO_IP="172.169.18.210"

CALICO_IP6=""

# as number,預設從全域性預設設定繼承

CALICO_AS=""

# 啟用libnetwork drive

CALICO_LIBNETWORK_ENABLED=true

# 路由協議,可選”bird”,“gobgp”,“none”,預設即”bird”, “gobgp”無ipip模式

CALICO_NETWORKING_BACKEND=bird

#啟動服務

# systemctl daemon-reload

# systemctl enable calico

# systemctl restart calico

# systemctl status calico

6)檢視狀態

可以在三個節點上檢視calico-node啟動情況

# docker ps -a

# ps -ef | grep calico

15.png

檢視節點狀態資訊(在三個節點上都可以檢視)

# calicoctl node status

16.png

5、使用calicoctl建立ipPool

    官方參考地址:https://docs.projectcalico.org/v2.6/reference/calicoctl/resources/ippool

在啟動別的容器之前,我們需要配置一個IP地址池帶有ipip和nat-outgoing選項。所以帶有有效配置的容器就可以訪問網際網路,在每個節點上執行下面的命令:

先檢視calico的ip池(任意一個節點上都能檢視)

# calicoctl get ipPool -o wide

17.png

引數解釋:

# 執行calico服務後,預設含1個192.168.0.0/16的ipv4地址池,1個64位的ipv6的地址池,後續網路分配即地址池獲取;

# NAT:容器獲得的地址是否可nat出host;

# IPIP:ipip是在宿主機網路不完全支援bgp時,一種妥協的overlay機制,在宿主機建立1個”tunl0”虛擬埠;設定為false時,路由即純bgp模式,理論上ipip模式的網路傳輸效能低於純bgp模式;設定為true時,又分ipip always模式(純ipip模式)與ipip cross-subnet模式(ipip-bgp混合模式),後者指“同子網內路由採用bgp,跨子網路由採用ipip”

1)在任意節點上定義都可以,ipPool屬於全域性;

[[email protected] ~]# vim new-pool-1.yaml

apiVersion: v1

kind: ipPool

metadata:

cidr: 172.169.10.0/24

spec:

ipip:

enabled: true

mode: cross-subnet

nat-outgoing: true

disabled: false

18.png

2)#建立

# calicoctl create -f new-pool-1.yaml

19.png

同理繼續把後面兩個節點的網段新增完成即可,如下如

20.png

3)刪除預設的ip地址池

# calicoctl delete ipPool 192.168.0.0/16

21.png

檢視docker三個節點網路30.png

4)容器網路配置

#修改docker配置檔案(三節點修改)

# vim /usr/lib/systemd/system/docker.service

新增如下引數:

-H unix:///var/run/docker.sock -H 0.0.0.0:2375 --cluster-store etcd://172.169.18.210:2379,172.169.18.162:2379,172.169.18.180:2379 \

6.png

重啟服務

# systemctl daemon-reload

# systemctl restart docker

#建立network(任意一個節點建立即可)

# docker network create --driver calico --ipam-driver calico-ipam net1

# docker network ls

7.png

5)建立容器測試

docker run --name web1 --privileged -itd --net=net1 centos:7.4.1708 /usr/sbin/init

(1)#檢視容器資訊

# docker inspect web1

8.png

(2)網路節點變化

9.png

(3)host節點routing table

# ip route show

10.png

(4)容器routing table

# 容器閘道器“169.254.1.1”是1個預留本地ip地址,通過cali0埠傳送到閘道器;

# calico為簡化網路配置,將容器的閘道器設定為1個固定的本地保留地址,容器內路由規則都是一樣的,不需要動態更新;

# 確定下一跳後,容器會查詢下一跳”169.254.1.1”的mac地址

# docker exec web1 ip route show

11.png

# docker exec web1 ping 114.114.114.114

12.png

通過”ip neigh show”可查詢arp表(需要觸發),這裡查詢到”169.254.1.1”的mac地址是”7a:b2:59:f7:0c:91”,仔細觀察會發現此mac地址即host節點網絡卡”calic255b5bfca1”的mac地址

# docker exec web1 ip neigh show

13.png

host節點對應容器的網絡卡並沒有配置ip地址,無論容器發出的arp的請求地址是什麼,其直接以自己的mac地址響應即”arp proxy”;

# 容器的後續報文目的IP不變,但mac地址變成了宿主機上對應interface的地址,即所有的報文都會發給宿主機,然後宿主機根據ip地址進行轉發,此feature是calico預設開啟的,可通過如下方式確認:

# cat /proc/sys/net/ipv4/conf/cali7d1d9f06ed8/proxy_arp

14.png

(5)在node02節點建立一個容器web2

# docker run --name web2 --privileged -itd --net=net1 centos:7.4.1708 /usr/sbin/init

# docker exec -ti web2 /bin/bash

15.png

即可


補充知識點:


Flannel

Calico

overlay方案

1. udp

2. vxlan

ipip,宿主機網路不能完全支援bgp時,可採用ipip模式

host-gw方案

host-gw,要求宿主機在相同subnet

bgp

網路策略

不支援

支援

ipam

不支援去中心化ipam

不支援去中心化ipam

效能

理論值:

1. host-gw模式的效能優於overlay模式,甚至接近於宿主機直接通訊;

2. flannel host-gw模式與calico bgp模式相當;

3. flannel overlay模式與calico ipip模式相當或略差,ipip包頭較vxlan小;

4. flannel udp 模式相對最差,udp封裝方式在linux使用者態,vxlan與ipip封裝在linux核心態完成(ipip安全性不如vxlan)。