21、《每天5分鐘玩轉Docker容器技術》學習--Flannel Network

------------------------------------重要說明------------------------------------

本文內容都是參考Cloudman系列進行學習,是個人學習過程記錄,與原版不同!

原版請參考cloudman《每天5分鐘玩轉Docker容器技術》Cloudman博客如下:

http://blog.51cto.com/cloudman

------------------------------------重要說明------------------------------------

flannel 是 CoreOS 開發的容器網絡解決方案。flannel 爲每個 host 分配一個 subnet,容器從此 subnet 中分配 IP,這些 IP 可以在 host 間路由,容器間無需 NAT 和 port mapping 就可以跨主機通信。

每個 subnet 都是從一個更大的 IP 池中劃分的,flannel 會在每個主機上運行一個叫 flanneld 的 agent,其職責就是從池子中分配 subnet。爲了在各個主機間共享信息,flannel 用 etcd(與 consul 類似的 key-value 分佈式數據庫)存放網絡配置、已分配的 subnet、host 的 IP 等信息。

數據包如何在主機間轉發是由 backend 實現的。flannel 提供了多種 backend,最常用的有 vxlan 和 host-gw,我們將在本章討論這兩種 backend。其他 backend 請參考 https://github.com/coreos/flannel。

圖片.png 

etcd 部署在 192.168.56.129【docker01】docker02 和 docker03 上運行 flanneld,首先安裝配置 etcd。

a) 安裝配置 etcd

在 192.168.56.129 上運行如下腳本: 

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/

圖片.png

該腳本從 github 上下載 etcd 的可執行文件並保存到 /usr/local/bin/,啓動 etcd 並打開 2379 監聽端口。

etcd -listen-client-urls http://192.168.56.129:2379 -advertise-client-urls http://192.168.56.129:2379

圖片.png

圖片.png 

該終端不要結束,新開一個終端

測試 etcd 是否可用:

圖片.png 

圖片.png 

可以正常在 etcd 中存取數據了。

當前網絡結構

 

b) 安裝配置 flannel 

flannel 沒有現成的執行文件可用,必須自己 build,最可靠的方法是在 Docker 容器中 build。不過用於做 build 的 docker 鏡像託管在 gcr.io,國內可能無法直接訪問,爲方便大家,我把它 mirror 到了 docker hub,構建步驟如下:

1.下載並重命名 image

docker pull cloudman6/kube-cross:v1.6.2-2

docker tag cloudman6/kube-cross:v1.6.2-2 gcr.io/google_containers/kube-cross:v1.6.2-2

圖片.png

2.下載 flannel 源碼

git clone https://github.com/coreos/flannel.git

圖片.png

圖片.png

3.開始構建

cd flannel

圖片.png 

make dist/flanneld-amd64

圖片.png
 

4.將 flanneld 執行文件拷貝到 host1 和 host2

scp dist/flanneld-amd64 192.168.56.130:/usr/local/bin/flanneld

scp dist/flanneld-amd64 192.168.56.128:/usr/local/bin/flanneld

圖片.png 

c) 將 flannel 網絡的配置信息保存到 etcd

先將配置信息寫到文件 flannel-config.json 中:

cat >>flannel-config.json<<EOF

{

  "Network": "10.2.0.0/16",

  "SubnetLen": 24,

  "Backend": {

    "Type": "vxlan"

  }

}

EOF

圖片.png 

Network 定義該網絡的 IP 池爲 10.2.0.0/16。

SubnetLen 指定每個主機分配到的 subnet 大小爲 24 位,即10.2.X.0/24。

Backend 爲通信類型。 vxlan,即主機間通過 vxlan 通信,後面我們還會討論host-gw。

將配置存入 etcd

etcdctl --endpoints=192.168.56.129:2379 set /docker-test/network/config < flannel-config.json

/docker-test/network/config 是此 etcd 數據的 key,其 value 爲 flannel-config.json 的內容。

key 可以任意指定,這個 key 後面會作爲 flanneld 的一個啓動參數。執行 etcdctl get 確保設置成功。

圖片.png

d) 啓動 flannel

在 docker02 和 docker03 上執行如下命令,NOTE:Don’t close current terminal!

flanneld -etcd-endpoints=http://192.168.56.129:2379 -iface=ens33 -etcd-prefix=/docker-test/network

-etcd-endpoints 指定 etcd url。

-iface 指定主機間數據傳輸使用的 interface。

-etcd-prefix 指定 etcd 存放 flannel 網絡配置信息的 key。

圖片.png 

圖片.png 

圖片.png

① enp0s8 被選作與外部主機通信的 interface。

② 識別 flannel 網絡池 10.2.0.0/16。

③ 分配的 subnet 爲 10.2.40.0/24。

flanneld 啓動後,docker02 docker03 內部網絡會發生一些變化:

1.一個新的 interface flannel.1 被創建,而且配置上 subnet 的第一個 IP 10.2.3.0。

圖片.png

圖片.png 

2.docker02 docker03 添加了一條路由:目的地址爲 flannel 網絡 10.2.0.0/16 的數據包都由 flannel.1 轉發

圖片.png

圖片.png 

當前環境網絡拓撲如下:

圖片.png
 

e) 配置 Docker 連接 flannel

cat /run/flannel/subnet.env 中 FLANNEL_SUBNET 和FLANNEL_MTU 

docker02

圖片.png 

docker03

圖片.png
 

編輯 docker02  docker03的 Docker 配置文件 /etc/systemd/system/docker.service.d/10-machine.conf,設置 --bip 和 --mtu

docker02

圖片.png
 

docker03

圖片.png 

重啓 Docker daemon

systemctl daemon-reload

systemctl restart docker.service

Docker --bip配置到 Linux bridge docker0 上,並添加 10.2.xx.0/24 的路由。

docker02

圖片.png 

docker03

圖片.png
 

當前環境網絡拓撲如圖所示

圖片.png
 

可見:flannel 沒有創建新的 docker 網絡,而是直接使用默認的 bridge 網絡。同一主機的容器通過 docker0 連接,跨主機流量通過 flannel.1 轉發。

f) 將容器連接到 flannel 網絡

在 docker02 中運行容器 bbox1

圖片.png
 

在 docker03 中運行容器 bbox2

圖片.png
 

圖片.png
 

圖片.png 

Docker02 和 docker03 的 IP 分別爲 10.2.3.2 和 10.2.98.2。

當前網絡拓撲

圖片.png
 

g) flannel 網絡連通性

測試 bbox1 和 bbxo2 的連通性

圖片.png
 

bbox1 能夠 ping 到位於不同 subnet 的 bbox2通過 traceroute 分析一下 bbox1 到 bbox2 的路徑。

圖片.png

1.bbox1 與 bbox2 不是一個 subnet數據包發送給默認網關 10.2.98.1 docker0。

2.根據 docker02的路由表下圖數據包會發給 flannel.1。

3.flannel.1 將數據包封裝成 VxLAN通過 ens33 發送給 docker03

4.Docker03 收到包解封裝發現數據包目的地址爲 10.2.3.2根據路由表下圖將數據包發送給 flannel.1並通過 docker0 到達 bbox2。

圖片.png

另外flannel 是沒有 DNS 服務的容器無法通過 hostname 通信。

圖片.png 

h) flannel 網絡隔離

flannel 爲每個主機分配了獨立的 subnet但 flannel.1 將這些 subnet 連接起來了相互之間可以路由。本質上flannel 將各主機上相互獨立的 docker0 容器網絡組成了一個互通的大網絡實現了容器跨主機通信。flannel 沒有提供隔離。

i) flannel 與外網連通性

因爲 flannel 網絡利用的是默認的 bridge 網絡所以容器與外網的連通方式與 bridge 網絡一樣即

1.容器通過 docker0 NAT 訪問外網

2.通過主機端口映射外網可以訪問容器

j) 如何使用 flannel host-gw backend

flannel 支持多種 backend,前面我們討論的是 vxlan,host-gw 是 flannel 的另一個 backend,本節會將前面的 vxlan backend 切換成 host-gw。

與 vxlan 不同,host-gw 不會封裝數據包,而是在主機的路由表中創建到其他主機 subnet 的路由條目,從而實現容器跨主機通信。要使用 host-gw 首先修改 flannel 的配置 flannel-config.json:

先將配置信息寫到文件 flannel-config.json 中:

cat >>flannel-config.json<<EOF

{

  "Network": "10.2.0.0/16",

  "SubnetLen": 24,

  "Backend": {

    "Type": "host-gw"

  }

}

EOF

圖片.png

Type 用 host-gw 替換原先的 vxlan。更新 etcd 數據庫:

etcdctl --endpoints=192.168.56.129:2379 set /docker-test/network/config < flannel-config.json

Ctrl+C 掉之前 docker02 和 docker03 的 flanneld 進程並重啓。

flanneld -etcd-endpoints=http://192.168.56.129:2379 -iface=enp0s8 -etcd-prefix=/docker-test/network

docker02

圖片.png 

查看 docker02 的路由表,增加了一條到 10.2.98.0/24 的路由,網關爲 docker03 的 IP 192.168.56.128

圖片.png

docker03

圖片.png
 

查看 docker03 的路由表,增加了一條到 10.2.3.0/24 的路由,網關爲 docker02 的 IP 192.168.56.130

圖片.png

從 /run/flannel/subnet.env 可以看到 host-gw 使用的 MTU 爲 1500

圖片.png


 

這與 vxlan MTU=1450 不同,所以應該修改 docker 啓動參數 --mtu=1500並重啓 docker daemon。

下面對 host-gw 和 vxlan 這兩種 backend 做個簡單比較。

1. host-gw 把每個主機都配置成網關,主機知道其他主機的 subnet 和轉發地址。vxlan 則在主機間建立隧道,不同主機的容器都在一個大的網段內(比如 10.2.0.0/16)。

2. 雖然 vxlan 與 host-gw 使用不同的機制建立主機之間連接,但對於容器則無需任何改變,bbox1 仍然可以與 bbox2 通信。

3. 由於 vxlan 需要對數據進行額外打包和拆包,性能會稍遜於 host-gw。

------------------------------------重要說明------------------------------------

本文內容都是參考Cloudman系列進行學習,是個人學習過程記錄,與原版不同!

原版請參考cloudman《每天5分鐘玩轉Docker容器技術》Cloudman博客如下:

http://blog.51cto.com/cloudman

------------------------------------重要說明------------------------------------

書籍:

1.《每天5分鐘玩轉Kubernetes》
https://item.jd.com/26225745440.html

2.《每天5分鐘玩轉Docker容器技術》
https://item.jd.com/16936307278.html

3.《每天5分鐘玩轉OpenStack》
https://item.jd.com/12086376.html




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章