Docker學習(八):flannel網路
Docker跨主機訪問
flannel
安裝配置etcd
先在主機10.211.55.17上建立並編寫指令碼a.sh
sudo vim a.sh
ETCD_VER=v2.3.7
DOWNLOAD_URL=https://github.com/coreos/etcd/releases/download
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
mkdir -p /tmp/test-etcd && tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/test-etcd --strip-components=1
cp /tmp/test-etcd/etcd* /usr/local/bin/
編寫好指令碼後儲存並退出,並賦予該指令碼可執行許可權
sudo chmod u+x a.sh
執行指令碼
啟動etcd並開啟2379監聽埠
etcd -listen-client-urls http://10.211.55.17:2379 -advertise-client-urls http://10.211.55.17:2379
測試etcd是否可用
etcdctl --endpoints=10.211.55.17:2379 set foo "bar" etcdctl --endpoints=10.211.55.17:2379 get foo
結果表明已經可以正常在etcd中存取資料了
安裝配置flannel
build flannel
(1)下載並重命名image
sudo docker pull cloudman6/kube-cross:v1.6.2-2
sudo docker tag cloudman6/kube-cross:v1.6.2-2 gcr.io/google_containers/kube-cross:v1.6.2-2
(2)下載flannel 原始碼
sudo git clone https://github.com/coreos/flannel.git
(3)開始構建
cd flannel
sudo make dist/flanneld-amd64
(4)將flanneld 執行檔案拷貝到host1 和host2
sudo scp dist/flanneld-amd64 10.211.55.20:/usr/local/bin/flanneld sudo scp dist/flanneld-amd64 10.211.55.21:/usr/local/bin/flanneld
將flannel 網路的配置資訊儲存到etcd
先將配置資訊寫到檔案flannel-config.json 中,內容為:
{ "Network":"10.2.0.0/16", "SubnetMin":"10.2.1.0", "SubnetMax":"10.2.255.0", "Backend":{"Type":"vxlan"} }
Network定義該網路的IP池為 10.2.0.0/16。
SubnetMin和SubnetMax指定IP分段
Backend為vxlan,即主機間通過vxlan通訊,後面我們還會討論host-gw。
將配置存入etcd
etcdctl --endpoints=10.211.55.17:2379 set /docker-test/network/config < flannel-config.json
/docker-test/network/config是此etcd資料項的key,其value為flannel-config.json的內容。key可以任意指定,這個key後面會作為flanneld的一個啟動引數。執行etcdctl get確保設定成功
啟動flannel
在兩臺主機上分別執行以下命令
sudo flanneld -etcd-endpoints=http://10.211.55.17:2379 -iface=enp0s5 -etcd-prefix=/docker-test/network
-etcd-endpoints指定etcd url
-iface指定主機間資料傳輸使用的interface
-etcd-prefix指定etcd存放flannel網路配置資訊的key
flanneld啟動後,主機內部網路會發生一些變化
(1)一個新的interface flannel.1被建立,而且配置上subnet的第一個IP 10.2.39.0
(2)第一臺主機添加了一條路由,目的地址為第二臺主機的flannel網路的資料包都由flannel.1轉發
配置Docker連線flannel
編輯第一臺主機的Docker配置檔案/etc/systemd/system/multi-user.target.wants/docker.service,設定--bip和--mtu
這兩個引數的值必須與/run/flannel/subnet.env中的FLANNEL_SUBNET和FLANNEL_MTU一致
重啟Docker daemon
sudo systemctl daemon-reload
sudo systemctl restart docker.service
Docker會將10.2.39.1 配置到Linux bridge docker0 上,並新增10.2.39.0/24 的路由
另一臺主機配置類似
將容器連線到flannel網路
在兩臺主機上分別執行容器bbox1和bbox2
兩個容器的IP分別為10.2.39.2和10.2.101.2
flannel網路連通性
測試bbox1和bbox2的連通性
bbox1能夠ping到位於不同subnet的bbox2,通過traceroute分析bbox1到bbox2的路徑
(1)bbox1與bbox2不是一個subnet,資料包傳送給預設閘道器10.2.39.1(docker0)
(2)根據第一臺主機的路由表(如下圖),資料包會發送給flannel.1
(3)flannel.1將資料包封裝成VxLAN,通過enp0s5傳送給第二臺主機
(4)第二臺主機收到包解封裝,發現數據包目的地址為10.2.101.2,根據如下路由表將資料包傳送給flannel.1,並通過docker0到達bbox2
另外,flannel是沒有DNS服務的,容器無法通過hostname通訊
flannel網路隔離
flannel為每個主機分配了獨立的subnet,但flannel.1將這些subnet連線起來,相互之間可以路由。本質上,flannel將各主機上相互獨立的docker0容器網路組成一個互通的大網路,實現了容器跨主機通訊。flannel沒有提供隔離
flannel host-gw backend
與vxlan不同,host-gw不會封裝資料包,而是在主機的路由表中建立到其他主機subnet的路由條目,從而實現容器跨主機通訊。要使用host-gw首先修改flannel的配置flannel-config.json
{ "Network":"10.2.0.0/16", "SubnetMin":"10.2.1.0", "SubnetMax":"10.2.255.0", "Backend":{"Type":"host-gw"} }
Type用host-gw替換原先的vxlan。更新etcd資料庫
停掉之前兩個主機的flannel程序並重新啟動
檢視第一臺主機的路由表,增加了10.2.101.0/24的路由,閘道器為第二臺主機的IP 10.211.55.20
第二臺主機類似
從 /run/flannel/subnet.env可以看出host-gw使用的MTU為1500
這與vxlan MTU=1450不同,所以應該修改docker啟動引數--mtu=1500並重啟docker daemon
下面對host-gw和vxlan做一個簡單的比較
(1)host-gw把每個主機都配置成閘道器,主機知道其他主機的subnet和轉發地址。vxlan則在主機間建立隧道,不同主機的容器都在一個大的網段內
(2)雖然vxlan與host-gw使用不同的機制建立主機之間連線,但對於容器則無需任何改變,bbox1和bbox2仍然可以通訊
(3)由於vxlan需要對資料進行額外打包和拆包,效能稍遜於host-gw