一、簡介
Flannel是CoreOS團隊針對Kubernetes設計的一個網絡規劃服務,簡單來說,它的功能是讓集羣中的不同節點主機創建的Docker容器都具有全集羣唯一的虛擬IP地址。
Flannel的設計目的就是爲集羣中的所有節點重新規劃IP地址的使用規則,從而使得不同節點上的容器能夠獲得“同屬一個內網”且”不重複的”IP地址,並讓屬於不同節點上的容器能夠直接通過內網IP通信。
二、Flannel的工作原理
Flannel實質上是一種“覆蓋網絡(overlay network)”,也就是將TCP數據包裝在另一種網絡包裏面進行路由轉發和通信,目前已經支持UDP、VxLAN、AWS VPC和GCE路由等數據轉發方式。
默認的節點間數據通信方式是UDP轉發,在Flannel的GitHub頁面有如下的一張原理圖:
對上圖的簡單解釋:
1)數據從源容器中發出後,經由所在主機的docker0虛擬網卡轉發到flannel0虛擬網卡,這是個P2P的虛擬網卡,flanneld服務監聽在網卡的另外一端。
2)Flannel通過Etcd服務維護了一張節點間的路由表,在稍後的配置部分我們會介紹其中的內容。
3)源主機的flanneld服務將原本的數據內容UDP封裝後根據自己的路由表投遞給目的節點的flanneld服務,數據到達以後被解包,然後直接進入目的節點的flannel0虛擬網卡,
然後被轉發到目的主機的docker0虛擬網卡,最後就像本機容器通信一下的有docker0路由到達目標容器。
這樣整個數據包的傳遞就完成了,這裏需要解釋三個問題:
1)UDP封裝是怎麼回事?
在UDP的數據內容部分其實是另一個ICMP(也就是ping命令)的數據包。原始數據是在起始節點的Flannel服務上進行UDP封裝的,投遞到目的節點後就被另一端的Flannel服務
還原成了原始的數據包,兩邊的Docker服務都感覺不到這個過程的存在。
2)爲什麼每個節點上的Docker會使用不同的IP地址段?
這個事情看起來很詭異,但真相十分簡單。其實只是單純的因爲Flannel通過Etcd分配了每個節點可用的IP地址段後,偷偷的修改了Docker的啓動參數。
在運行了Flannel服務的節點上可以查看到Docker服務進程運行參數(ps aux|grep docker|grep "bip"),例如“--bip=182.48.56.1/24”這個參數,它限制了所在節
點容器獲得的IP範圍。這個IP範圍是由Flannel自動分配的,由Flannel通過保存在Etcd服務中的記錄確保它們不會重複。
3)爲什麼在發送節點上的數據會從docker0路由到flannel0虛擬網卡,在目的節點會從flannel0路由到docker0虛擬網卡?
例如現在有一個數據包要從IP爲172.17.18.2的容器發到IP爲172.17.46.2的容器。根據數據發送節點的路由表,它只與172.17.0.0/16匹配這條記錄匹配,因此數據從docker0出來以後就被投遞到了flannel0。同理在目標節點,由於投遞的地址是一個容器,因此目的地址一定會落在docker0對於的172.17.46.0/24這個記錄上,自然的被投遞到了docker0網卡。
三、搭建服務
1、環境準備(相同配置)
1)系統環境
2)建議暫時關閉防火牆,測試完畢再開啓防火牆和相關端口
3)設置主機名及綁定hosts
# vim /etc/hosts
192.168.56.128 master
192.168.56.128 etcd
192.168.56.130 slave1
3)安裝docker(再次省略)
2、在master節點配置
2.1、安裝etcd服務
1)yum安裝
# yum install etcd -y
2)修改etcd配置文件
# cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf_bak
3)啓動服務
[root@master ~]# systemctl start etcd.service
[root@master ~]# systemctl enable etcd.service
# netstat -tnlp | grep -E "4001|2380"
# ps -ef | grep etcd
4)驗證
# etcdctl --help
# etcdctl set etcdkey "hello"
# etcdctl get etcdkey
# etcdctl -C http://etcd:4001 cluster-health
# etcdctl -C http://etcd:2379 cluster-health
2.2、安裝Flannel服務
1)yum安裝flannel
# yum install flannel -y
2)配置flannel文件
# cp /etc/sysconfig/flanneld /etc/sysconfig/flanneld_bak
# vim /etc/sysconfig/flanneld
3)配置etcd中關於flannel的key(只能在etcd節點上操作)
Flannel使用Etcd進行配置,來保證多個Flannel實例之間的配置一致性,所以需要在etcd上進行如下配置('/atomic.io/network/config'這個key與上面的/etc/sysconfig/flannel中的配置項FLANNEL_ETCD_PREFIX是相對應的,錯誤的話啓動就會出錯):
# etcdctl mk /atomic.io/network/config '{ "Network": "172.18.0.0/16" }'
備註:該ip網段可以任意設定,隨便設定一個網段都可以。容器的ip就是根據這個網段進行自動分配的,ip分配後,容器一般是可以對外聯網的(網橋模式,只要宿主機能上網就可以)
4)啓動服務
[root@master ~]# systemctl start flanneld.service
[root@master ~]# systemctl enable flanneld.service
重啓docker
# systemctl restart docker
3、在slave1節點配置
3.1、安裝Flannel服務
1)yum安裝flannel
# yum install flannel -y
2)配置flannel文件
# cp /etc/sysconfig/flanneld /etc/sysconfig/flanneld_bak
# vim /etc/sysconfig/flanneld
3)啓動服務
[root@slave1 ~]# systemctl start flanneld.service
[root@slave1 ~]# systemctl enable flanneld.service
重啓docker,獲取分配的ip段
4、創建容器,測試網絡互聯
4.1、查看master容器獲取的ip
172.18.23.0/24網段
4.2、查看slave1容器獲取的ip
172.18.7.0/24網段
容器之間相互訪問
5、查看宿主獲取的IP段
# ps aux|grep docker|grep "bip"
“--bip=172.18.23.1/24”這個參數,它限制了所在節點容器獲得的IP範圍。 該IP範圍是由Flannel自動分配的,由Flannel通過保存在Etcd服務中的記錄確保它們不會重複。