跨主機間的 Docker overlay network (使用 flannel)

接續之前的主題,這裡說說另一種能讓不同主機間的 Docker container 互相溝通 (讓他們在同個網路底下) 的方式。

透過 flannel

flannel 最早是由 CoreOS 公司為 Kubernetes 所設計的 IPv4 Layer 3 網路服務,透過以 agent 的形式運作在各 Docker node 中,將節點資訊透過 Kubernetes API 或 etcd 同步到其他節點,並操作本地 Linux Kernel 的 VXLAN (layer 3) 或 host-gw (layer 2) 網路設定,也可配合如 AWS, GCE, AliCloud 的架構使用。

因我們沒有部署 Kubernetes,故下面我們需要先準備 etcd 分散式儲存服務:

hostname ip addr
sx01 10.1.1.70
sx02 10.1.1.71

我們先分別在 sx01, sx02 安裝 etcd

  • sx01
1
2
3
4
5
6
7
8
9
10
wget https://github.com/coreos/etcd/releases/download/v3.0.12/etcd-v3.0.12-linux-amd64.tar.gz
tar zxvf etcd-v3.0.12-linux-amd64.tar.gz
cd etcd-v3.0.12-linux-amd64
nohup ./etcd --name sx01 --initial-advertise-peer-urls http://10.1.1.70:2380 \
--listen-peer-urls http://10.1.1.70:2380 \
--listen-client-urls http://10.1.1.70:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://10.1.1.70:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster sx01=http://10.1.1.70:2380,sx02=http://10.1.1.71:2380 \
--initial-cluster-state new &
  • sx02
1
2
3
4
5
6
7
8
9
10
wget https://github.com/coreos/etcd/releases/download/v3.0.12/etcd-v3.0.12-linux-amd64.tar.gz
tar zxvf etcd-v3.0.12-linux-amd64.tar.gz
cd etcd-v3.0.12-linux-amd64
nohup ./etcd --name sx02 --initial-advertise-peer-urls http://10.1.1.71:2380 \
--listen-peer-urls http://10.1.1.71:2380 \
--listen-client-urls http://10.1.1.71:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://10.1.1.71:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster sx01=http://10.1.1.70:2380,sx02=http://10.1.1.71:2380 \
--initial-cluster-state new &

透過在 sx02 輸入 ./etcdctl cluster-health 我們可以確認 etcd 服務有正確啟動:

1
2
member 21eca106efe4caee is healthy: got healthy result from http://10.1.1.70:2379
member 8614974c83d1cc6d is healthy: got healthy result from http://10.1.1.71:2379

接著在各節點下載 flanneld

1
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flanneld-amd64 && chmod +x flanneld-amd64

sx01 我們編輯 flannel 的網路設定檔 flannel-network-config.json

1
2
3
4
5
6
7
8
9
10
11
{
"Network": "10.0.0.0/8",
"SubnetLen": 20,
"SubnetMin": "10.10.0.0",
"SubnetMax": "10.99.0.0",
"Backend": {
"Type": "vxlan",
"VNI": 100,
"Port": 8472
}
}

透過 etcdctl 發佈到 etcd 中:

1
./etcdctl set /coreos.com/network/config < flannel-network-config.json

接著可以透過下面指令在 sx02 中看到一樣的內容:

1
./etcdctl get /coreos.com/network/config

我們現在可以將各 Docker node 的 flanneld 跑起來了,它會為我們新增一 flannel.100 的網路介面,可透過 ifconfig 看到:

1
2
3
4
5
# sx01
nohup sudo ./flanneld-amd64 -iface=10.1.1.70 &

# sx02
nohup sudo ./flanneld-amd64 -iface=10.1.1.71 &
1
2
3
4
5
6
7
8
9
#ifconfig flannel.100
flannel.100 Link encap:Ethernet HWaddr 92:70:f1:94:9a:f8
inet addr:10.15.48.0 Bcast:0.0.0.0 Mask:255.255.255.255
inet6 addr: fe80::9070:f1ff:fe94:9af8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:114 errors:0 dropped:0 overruns:0 frame:0
TX packets:113 errors:0 dropped:31 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:9428 (9.4 KB) TX bytes:9372 (9.3 KB)

最後我們只要將各自 dockerd 的啟動 script 修改一下,讓它可以使用 flannel 做為網路的底層服務:

1
systemctl edit docker

會自動開啟編輯器,在當中填入

1
2
3
4
[Service]
EnvironmentFile=/run/flannel/subnet.env
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}

再重啟 Docker 服務就完成了

1
systemctl restart docker

測試看看,應可正確 ping 到對方:

1
2
3
4
5
# sx01
docker run -it --rm bash sh -c 'ifconfig eth0; sleep 60'

# sx02
docker run -it --rm bash ping [上面看到的 ip]

References