您好,登錄后才能下訂單哦!
一、簡介
Calico是一個純三層的協議,為OpenStack虛機和Docker容器提供多主機間通信。Calico不使用重疊網絡比如flannel和libnetwork重疊網絡驅動,它是一個純三層的方法,使用虛擬路由代替虛擬交換,每一臺虛擬路由通過BGP協議傳播可達信息(路由)到剩余數據中心。
為什么Calico網絡選擇BGP?
參考地址:https://blog.51cto.com/weidawei/2152319
我們在Calico網絡中使用BGP去宣告數據終端(end points)路由是因為如下原因:
(1)BGP是一種簡單的路由協議
(2)擁有當前行業的最佳實踐
(3)唯一能夠支撐Calico網絡規模的協議
1、原理
如下圖所示,描述了從源容器經過源宿主機,經過數據中心的路由,然后到達目的宿主機最后分配到目的容器的過程。
整個過程中始終都是根據iptables規則進行路由轉發,并沒有進行封包,解包的過程,這和flannel相比效率就會快多了。
2、框架
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、安裝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
當關閉master01節點后,選舉自動切換到node02上
4)檢查集群健康狀態(在三個節點中的任意一個上面都可以查看)
# etcdctl cluster-health
到此,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
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
啟動Calico服務
在Docker環境中Calico服務是做為容器來運行的,使用host的網絡配置。所有容器配置使用Calico服務,做為calico節點互相通信。
Calico在每個主機上通過一個自己的container與其他主機或者網絡通訊,即calico-node的container,這個container里面包含了Bird路由管理、Felix協議等。
4)在三個節點上都要下載calico的node鏡像
(可以先在一個節點上下載鏡像,然后將鏡像通過docker save導出保存到本地,再將鏡像拷貝到其他節點上通過docker load導入,這樣對于其他節點來說,比使用docker pull要快)
[root@master01 ~]# docker pull calico/node:v2.6.10
[root@master01 ~]# docker pull calico/node-libnetwork
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
#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
查看節點狀態信息(在三個節點上都可以查看)
# calicoctl node status
5、使用calicoctl創建ipPool
官方參考地址:https://docs.projectcalico.org/v2.6/reference/calicoctl/resources/ippool
在啟動別的容器之前,我們需要配置一個IP地址池帶有ipip和nat-outgoing選項。所以帶有有效配置的容器就可以訪問互聯網,在每個節點上運行下面的命令:
先查看calico的ip池(任意一個節點上都能查看)
# calicoctl get ipPool -o wide
參數解釋:
# 運行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屬于全局;
[root@master01 ~]# 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
2)#創建
# calicoctl create -f new-pool-1.yaml
同理繼續把后面兩個節點的網段添加完成即可,如下如
3)刪除默認的ip地址池
# calicoctl delete ipPool 192.168.0.0/16
查看docker三個節點網絡
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 \
重啟服務
# systemctl daemon-reload
# systemctl restart docker
#創建network(任意一個節點創建即可)
# docker network create --driver calico --ipam-driver calico-ipam net1
# docker network ls
5)創建容器測試
docker run --name web1 --privileged -itd --net=net1 centos:7.4.1708 /usr/sbin/init
(1)#查看容器信息
# docker inspect web1
(2)網絡節點變化
(3)host節點routing table
# ip route show
(4)容器routing table
# 容器網關“169.254.1.1”是1個預留本地ip地址,通過cali0端口發送到網關;
# calico為簡化網絡配置,將容器的網關設置為1個固定的本地保留地址,容器內路由規則都是一樣的,不需要動態更新;
# 確定下一跳后,容器會查詢下一跳”169.254.1.1”的mac地址
# docker exec web1 ip route show
# docker exec web1 ping 114.114.114.114
通過”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
host節點對應容器的網卡并沒有配置ip地址,無論容器發出的arp的請求地址是什么,其直接以自己的mac地址響應即”arp proxy”;
# 容器的后續報文目的IP不變,但mac地址變成了宿主機上對應interface的地址,即所有的報文都會發給宿主機,然后宿主機根據ip地址進行轉發,此feature是calico默認開啟的,可通過如下方式確認:
# cat /proc/sys/net/ipv4/conf/cali7d1d9f06ed8/proxy_arp
(5)在node02節點創建一個容器web2
# docker run --name web2 --privileged -itd --net=net1 centos:7.4.1708 /usr/sbin/init
# docker exec -ti web2 /bin/bash
即可
補充知識點:
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)。 |
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。