flannel是由CoreOS研究的一種覆蓋網絡(overlay network)網絡工具,目的是幫助每一個host主機有一個完整的子網;
功能是:讓集群中不同節點的主機創建的容器都有一個唯一的虛擬IP
工作原理:將TCP數據包裝在另一種網絡包里進行路由轉發和通信,目前已經支持UDP,Vxlan,AWS,APC和GRE等路由轉發的模式。默認節點間通過UDP進行轉發
1.安裝配置etcd
etcd功能:與consul的功能差不多,維護主機間的路由表,flannel的配置信息全部存放在etcd里面,主要負責給各個主機分配subnet
可以根據官網的方式來搭建:https://github.com/coreos/etcd/releases
1.也可以直接yum install -y etcd
2.更改配置文件:vim /etc/etcd/etcd.conf
ETCD_LISTEN_CLIENT_URLS="http://192.168.7.222:2379" (第九行):監聽客戶端的請求
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.7.222:2379" (20行):通知客戶端的地址
3.保存退出后,設置host主機的subnet
先編輯一個文件:etcd.sh
vim /root/etcd.sh
{“Network”:“10.2.0.0/16”,“SubnetLen”:24,"Backend":{"Type":"vxlan"}}
Network:定義host主機的IP地址池為10.2.0.0/16,注:由於etcd並不是動態保存host上flannel網絡的,比如:當有節點被刪除后,etcd中的關於這個節點的subnet網絡並不會被刪除,所以使用10.X.X.X的網絡,保證有足夠的網絡可用
SubnetLen:指定每個主機分配的subnet大小為24位,即10.2.x.0/24
Backend為vxlan,即主機之間通過vxlan通信,我們主要討論vxlan和host-gw這兩種方式
4.將配置保存到etcd
etcdctl --endpoints=http://192.168.7.222:2379 set /usr/local/bin/network/config < /root/etcd.sh
--endpoints=http://192.168.7.222:2379 指定etcd的url
通過 etcdctl get /usr/local/bin/network/config 在etcd本機上獲取key
/usr/local/bin/network/config 保存key的地方,flanneld會讀取這個配置,保證自己能獲取到subnet,這個key可以任意指定,當host主機分配到subnet后,key會修改docker的啟動參數
2.安裝配置flanneld
1.yum install -y flannel.x86_64
2.修改配置文件:vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.7.222:2379" 連接etcd的地址
LANNEL_ETCD_PREFIX="/usr/local/bin/network" key的地址,注:這個地址一定要寫到最后一個目錄即可,否則會報錯,如下:
3.啟動flanneld
可以使用命令 flanneld 也可以systemctl start flanneld
如果啟動flanneld時出現一下錯誤:etcd集群配置錯誤,拒絕鏈接
解決辦法是:在etcd的服務器上的/etc/etcd/etcd.conf中將集群:ETCD_LISTEN_PEER_URLS="http://localhost:2380"這個注釋去掉
4.現在我們可以在host上看見一個flanneld1.1的網絡了
可以看到我的doker1和dokcer2各有一個flannel1.1,但不在同一個網段,怎么進行通信呢?
我們來看一下兩個host的路由情況:出現了一個flannel1.1的路由
路由都是10.2.0.0的,下面驗證一下容器是否可以通信
兩個容器使用的是同一個IP,肯定是沒法訪問對方
下面我們學習配置docker連接flannel
1.編輯docker的配置文件:/etc/systemd/system/docker.service.d/10-machine.conf
添加:--bip= --mtu=
這兩個參數要參考/run/flannel/subnet.env,必須與其保持一致
2.重啟docker服務
3.查看docker0的變化
docker會將flanneld配置到docker0上,並給docker0添加10.2.48.0的路由
docker1進行同樣的配置:
docker1上的flannel也被橋接到docker0上了
驗證容器的連通性:
到這里 ,還是ping不通!!!!!
為什么?????
開啟了路由轉發:echo 1 > /proc/sys/net/ipv4/ip_forward 還是不行
主機防火牆:firewalld和selinux已經關閉!!!!
但是,linux還有底層的iptables,所以在兩台主機上分別執行:iptables -P FORWARD ACCEPT后
可以ping通,證明就算兩個容器在不通的網段,使用flannel機制,可以使不同subnet的網絡互通
通過traceroute來看一下容器走的路徑
數據包先到docker0的網關10.2.55.1
根據路由表docker0將數據包轉發給flannel1.1
flannel1.1會將數據包封裝成Vxlan,通過ens160轉發給docker2
docker2收到數據包后進行解包,發現IP 目的IP 是10.2.48.2,根據docker2的路由表將數據包轉發給flannel1.1,flannel1.1再將數據包轉發給docker2的docker0,到達容器
注:flannel沒有DNS服務,容器無法通過hostname通信
flannel網絡隔離
flannel為每個主機分配了獨立的subnet,但是flannel1.1將這些subnet鏈接額起來,相互之間可以路由。本質上,flannel將個主機上相互獨立的docker0容器網絡組成了一個互通的大網絡,實現了容器跨主機通信。flannel沒有實現隔離
flannel與外網連通性:
因為flannel網絡是將flannel1.1橋接到docker0上,所以容器與外部通信的方式與docker0默認的bridge網絡一樣,即:
1.容器通過NAT連接外網
2.外網通過端口映射的方式訪問容器
flannel----host-gw
flannel支持多種backend,什么是backend:指的是host主機之間的通信方式
之前我們在寫etcd key的時候定義過backend
之前的試驗使用過的是vxlan,flannel支持多種的backend:目前已經支持UDP、VxLAN、AWS VPC和GCE路由等數據轉發方式,默認使用的是udp的方式
下面我們討論host-gw
與vxlan不同,host-gw不會封裝數據包,而是在主機的路由表中創建到其他主機的subnet的路由條目,從而實現容器跨主機通信
要使用host-gw首先修改etcd key
重啟docker1和docker2上的flanneld服務
可以看到flannel從etcd數據庫中檢索到docker1的subnet10.2.55.0/24,但是因為其是vxlan,所以立即忽略
我重啟了docker1上的flannel后,docker2上的flannel發現subnet10.2.55.0/24將其添加到路由表中
查看docker2的路由表添加了一條到10.2.55.0/24的路由,網關是192.168.7.235
同樣的docker1重啟flannel后也會發生相應的變化
由於我們更改了flannel的配置,所以docker服務也會受到影響,因為之前我們說過flannel會改變docker的開機自啟動,所以我們要根據/run/flanneld/subnet.env
更改 /etc/systemd/system/docker.service.d/10-machine.conf docker 的配置文件
重啟docker服務
在docker1上做同樣的操作
vxlan和 host-gw的區別;
1.host-gw把每個主機都配置成網關,主機知道其他主機的subnet和轉發地址。
vxlan則是在主機之間創建隧道,不同的主機的容器都在一個大的網段內,比如:10.2.0.0/16
2.雖然vxlan與host-gw使用不同的機制,但對於容器之間還是可以相互通信的
3.由於vxlan需要對數據進行打包和拆包,性能可能稍遜於host-gw