docker容器技術(shù)學(xué)習(xí)筆記(9、跨主機(jī)網(wǎng)絡(luò))

跨主機(jī)網(wǎng)絡(luò)

跨主機(jī)網(wǎng)絡(luò)方案包括:
1、docker 原生的 overlay 和 macvlan。
2、第三方方案:常用的包括 flannel、weave 和 calico。

docker 網(wǎng)絡(luò)是一個(gè)非常活躍的技術(shù)領(lǐng)域,不斷有新的方案開發(fā)出來(lái),那么要問個(gè)非常重要的問題了:如此眾多的方案是如何與 docker 集成在一起的?答案是:libnetwork 以及 CNM。

libnetwork & CNM

libnetwork 是 docker 容器網(wǎng)絡(luò)庫(kù),最核心的內(nèi)容是其定義的 Container Network Model (CNM),這個(gè)模型對(duì)容器網(wǎng)絡(luò)進(jìn)行了抽象,由以下三類組件組成:

  • Sandbox

Sandbox 是容器的網(wǎng)絡(luò)棧,包含容器的 interface、路由表和 DNS 設(shè)置。 Linux Network Namespace 是 Sandbox 的標(biāo)準(zhǔn)實(shí)現(xiàn)。Sandbox 可以包含來(lái)自不同 Network 的 Endpoint。

  • Endpoint

Endpoint 的作用是將 Sandbox 接入 Network。Endpoint 的典型實(shí)現(xiàn)是 veth pair,。一個(gè) Endpoint 只能屬于一個(gè)網(wǎng)絡(luò),也只能屬于一個(gè) Sandbox。

  • Network

Network 包含一組 Endpoint,同一 Network 的 Endpoint 可以直接通信。Network 的實(shí)現(xiàn)可以是 Linux Bridge、VLAN 等。

下面是 CNM 的示例:


如圖所示兩個(gè)容器,一個(gè)容器一個(gè) Sandbox,每個(gè) Sandbox 都有一個(gè) Endpoint 連接到 Network 1,第二個(gè) Sandbox 還有一個(gè) Endpoint 將其接入 Network 2。

libnetwork CNM 定義了 docker 容器的網(wǎng)絡(luò)模型,按照該模型開發(fā)出的 driver 就能與 docker daemon 協(xié)同工作,實(shí)現(xiàn)容器網(wǎng)絡(luò)。docker 原生的 driver 包括 none、bridge、overlay 和 macvlan,第三方 driver 包括 flannel、weave、calico 等。


overlay driver

為支持容器跨主機(jī)通信,Docker 提供了 overlay driver,使用戶可以創(chuàng)建基于 VxLAN 的 overlay 網(wǎng)絡(luò)。VxLAN 可將二層數(shù)據(jù)封裝到 UDP 進(jìn)行傳輸,VxLAN 提供與 VLAN 相同的以太網(wǎng)二層服務(wù),但是擁有更強(qiáng)的擴(kuò)展性和靈活性。

  • 實(shí)驗(yàn)環(huán)境

在 docker 主機(jī) host1(10.10.8.126)和 host2(10.10.8.127)上實(shí)踐各種跨主機(jī)網(wǎng)絡(luò)方案,在 10.10.8.125 上部署支持的組件,比如 Consul。

最簡(jiǎn)單的方式是以容器方式運(yùn)行 Consul:
docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap

容器啟動(dòng)后,可以通過 http://10.10.8.125:8500 訪問 Consul。

接下來(lái)修改 host1 和 host2 的 docker daemon 的配置文件/etc/systemd/system/docker.service。
--cluster-store 指定 consul 的地址。
--cluster-advertise 告知 consul 自己的連接地址。

重啟 docker daemon。
systemctl daemon-reload
systemctl restart docker.service
host1 和 host2 將自動(dòng)注冊(cè)到 Consul 數(shù)據(jù)庫(kù)中。

  • 創(chuàng)建 overlay 網(wǎng)絡(luò)

在 host1 中創(chuàng)建 overlay 網(wǎng)絡(luò) ov_net1,-d overlay 指定 driver 為 overaly:

docker network create -d overlay ov_net1

docker network ls 查看當(dāng)前網(wǎng)絡(luò):

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
db19978034cb        bridge              bridge              local
bae92bff8199        host                host                local
deb4cbe62ba0        none                null                local
48b4931748ef        ov_net1             overlay             global

注意到 ov_net1 的 SCOPE 為 global,而其他網(wǎng)絡(luò)為 local。host2 上也能看到 ov_net1。這是因?yàn)閯?chuàng)建 ov_net1 時(shí) host1 將 overlay 網(wǎng)絡(luò)信息存入了 consul,host2 從 consul 讀取到了新網(wǎng)絡(luò)的數(shù)據(jù)。之后 ov_net 的任何變化都會(huì)同步到 host1 和 host2。

docker network inspect 查看 ov_net1 的詳細(xì)信息:

docker network inspect ov_net1 
[
    {
        "Name": "ov_net1",
        "Id": "48b4931748ef3f7b33014b8e1a17fcf9786ff0114766d659d23a5b97fa90dfa2",
        "Created": "2018-09-04T10:20:33.247929912+08:00",
        "Scope": "global",
        "Driver": "overlay",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.0.0.0/24",
                    "Gateway": "10.0.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

IPAM 是指 IP Address Management,docker 自動(dòng)為 ov_net1 分配的 IP 空間為 10.0.0.0/24。

  • 在overlay中運(yùn)行容器

運(yùn)行一個(gè) busybox 容器并連接到 ov_net1:

docker run -itd --name bbox1 --network ov_net1 busybox

查看容器的網(wǎng)絡(luò)配置:

docker exec  bbox1 ip r
default via 172.18.0.1 dev eth1 
10.0.0.0/24 dev eth0 scope link  src 10.0.0.2 
172.18.0.0/16 dev eth1 scope link  src 172.18.0.2 

bbox1 有兩個(gè)網(wǎng)絡(luò)接口 eth0 和 eth1。eth0 IP 為 10.0.0.2,連接的是 overlay 網(wǎng)絡(luò) ov_net1。eth1 IP 172.18.0.2,容器的默認(rèn)路由是走 eth1,eth1 是哪兒來(lái)的呢?

其實(shí),docker 會(huì)創(chuàng)建一個(gè) bridge 網(wǎng)絡(luò) “docker_gwbridge”,為所有連接到 overlay 網(wǎng)絡(luò)的容器提供訪問外網(wǎng)的能力。

如果外網(wǎng)要訪問容器,可通過主機(jī)端口映射,比如:
docker run -p 80:80 -d --net ov_net1 --name web1 httpd

  • overlay 網(wǎng)絡(luò)跨主機(jī)通信

在 host2 中運(yùn)行容器 bbox2:

docker run -itd --name bbox2 --network ov_net1 busybox 

bbox2 IP 為 10.0.0.3,可以直接 ping bbox1,可見 overlay 網(wǎng)絡(luò)中的容器可以直接通信,同時(shí) docker 也實(shí)現(xiàn)了 DNS 服務(wù)。

docker 會(huì)為每個(gè) overlay 網(wǎng)絡(luò)創(chuàng)建一個(gè)獨(dú)立的 network namespace,其中會(huì)有一個(gè) linux bridge br0,endpoint 還是由 veth pair 實(shí)現(xiàn),一端連接到容器中(即 eth0),另一端連接到 namespace 的 br0 上。

br0 除了連接所有的 endpoint,還會(huì)連接一個(gè) vxlan 設(shè)備,用于與其他 host 建立 vxlan tunnel。容器之間的數(shù)據(jù)就是通過這個(gè) tunnel 通信的。邏輯網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)如圖所示:

要查看 overlay 網(wǎng)絡(luò)的 namespace 可以在 host1 和 host2 上執(zhí)行 ip netns(請(qǐng)確保在此之前執(zhí)行過 ln -s /var/run/docker/netns /var/run/netns),可以看到兩個(gè) host 上有一個(gè)相同的 namespace “1-f4af9b33c0”:

ip netns
1-f4af9b33c0

這就是 ov_net1 的 namespace,查看 namespace 中的 br0 上的設(shè)備。

ip netns exec 1-f4af9b33c0 brctl show

查看 vxlan1 設(shè)備的具體配置信息可知此 overlay 使用的 VNI(VxLAN ID)為 256。

ip netns exec 1-f4af9b33c0 ip -d l show vxlan1
  • overlay 的網(wǎng)絡(luò)隔離特性

不同的 overlay 網(wǎng)絡(luò)是相互隔離的。創(chuàng)建第二個(gè) overlay 網(wǎng)絡(luò) ov_net2 并運(yùn)行容器 bbox3。bbox3 分配到的 IP 是 10.0.1.2,嘗試 ping bbox1(10.0.0.2)。ping 失敗,可見不同 overlay 網(wǎng)絡(luò)之間是隔離的。即便是通過 docker_gwbridge 也不能通信。
如果要實(shí)現(xiàn) bbox3 與 bbox1 通信,可以將 bbox3 也連接到 ov_net1。

docker network connect ov_net1 bbox3

docker 默認(rèn)為 overlay 網(wǎng)絡(luò)分配 24 位掩碼的子網(wǎng)(10.0.X.0/24),所有主機(jī)共享這個(gè) subnet,容器啟動(dòng)時(shí)會(huì)順序從此空間分配 IP。當(dāng)然我們也可以通過 --subnet 指定 IP 空間。
docker network create -d overlay --subnet 10.22.1.0/24 ov_net3

macvlan 網(wǎng)絡(luò)

除了 overlay,docker 還開發(fā)了另一個(gè)支持跨主機(jī)容器網(wǎng)絡(luò)的 driver:macvlan。

macvlan 本身是 linxu kernel 模塊,其功能是允許在同一個(gè)物理網(wǎng)卡上配置多個(gè) MAC 地址,即多個(gè) interface,每個(gè) interface 可以配置自己的 IP。macvlan 本質(zhì)上是一種網(wǎng)卡虛擬化技術(shù),Docker 用 macvlan 實(shí)現(xiàn)容器網(wǎng)絡(luò)就不奇怪了。

macvlan 的最大優(yōu)點(diǎn)是性能極好,相比其他實(shí)現(xiàn),macvlan 不需要?jiǎng)?chuàng)建 Linux bridge,而是直接通過以太 interface 連接到物理網(wǎng)絡(luò)。

  • 準(zhǔn)備實(shí)驗(yàn)環(huán)境

我們會(huì)使用 host1 和 host2 上單獨(dú)的網(wǎng)卡 eth0 創(chuàng)建 macvlan。為保證多個(gè) MAC 地址的網(wǎng)絡(luò)包都可以從 eth0 通過,我們需要打開網(wǎng)卡的混雜模式。
ip link set eth0 promisc on
確保 eth0 狀態(tài) UP 并且 promisc 模式已經(jīng)生效。

  • 創(chuàng)建 macvlan網(wǎng)絡(luò)
    在 host1 和 host2 中創(chuàng)建 macvlan 網(wǎng)絡(luò) mac_net1:
# docker network create -d macvlan \
> --subnet=172.16.86.0/24 \
> --gateway=172.16.86.1 \
> -o parent=eth0 mac_net1

注意:在 host2 中也要執(zhí)行相同的命令。

① -d macvlan 指定 driver 為 macvlan。
② macvlan 網(wǎng)絡(luò)是 local 網(wǎng)絡(luò),為了保證跨主機(jī)能夠通信,用戶需要自己管理 IP subnet。
③ 與其他網(wǎng)絡(luò)不同,docker 不會(huì)為 macvlan 創(chuàng)建網(wǎng)關(guān),這里的網(wǎng)關(guān)應(yīng)該是真實(shí)存在的,否則容器無(wú)法路由。
④ -o parent 指定使用的網(wǎng)絡(luò) interface。

在 host1 中運(yùn)行容器 bbox1 并連接到 mac_net1。

docker run -itd --name bbox1 --ip=172.16.86.10 --network mac_net1 busybox
由于 host1 中的 mac_net1 與 host2 中的 mac_net1 本質(zhì)上是獨(dú)立的,為了避免自動(dòng)分配造成 IP 沖突,我們最好通過 --ip 指定 bbox1 地址為 172.16.86.10。

在 host2 中運(yùn)行容器 bbox2,指定 IP 172.16.86.11。

docker run -itd --name bbox2 --ip=172.16.86.11 --network mac_net1 busybox
bbox2 能夠 ping 到 bbox1 的 IP 172.16.86.10,但無(wú)法解析 “bbox1” 主機(jī)名。
  • macvlan 網(wǎng)絡(luò)結(jié)構(gòu)

macvlan 不依賴 Linux bridge,brctl show 可以確認(rèn)沒有創(chuàng)建新的 bridge。
查看一下容器 bbox1 的網(wǎng)絡(luò)設(shè)備:

docker exec bbox1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
21: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:10:56:0a brd ff:ff:ff:ff:ff:ff

除了 lo,容器只有一個(gè) eth0,請(qǐng)注意 eth0 后面的 @if2,這表明該 interface 有一個(gè)對(duì)應(yīng)的 interface,其全局的編號(hào)為 2。根據(jù) macvlan 的原理,我們有理由猜測(cè)這個(gè) interface 就是主機(jī)的 eth0,確認(rèn)如下:
ip link show eth0
2: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 00:16:3e:0e:f7:cd brd ff:ff:ff:ff:ff:ff

可見,容器的 eth0 就是 主機(jī)的eth0 通過 macvlan 虛擬出來(lái)的 interface。容器的 interface 直接與主機(jī)的網(wǎng)卡連接,這種方案使得容器無(wú)需通過 NAT 和端口映射就能與外網(wǎng)直接通信(只要有網(wǎng)關(guān)),在網(wǎng)絡(luò)上與其他獨(dú)立主機(jī)沒有區(qū)別。當(dāng)前網(wǎng)絡(luò)結(jié)構(gòu)如圖所示:

  • 用 sub-interface 實(shí)現(xiàn)多 macvlan 網(wǎng)絡(luò)

macvlan 會(huì)獨(dú)占主機(jī)的網(wǎng)卡,也就是說一個(gè)網(wǎng)卡只能創(chuàng)建一個(gè) macvlan 網(wǎng)絡(luò)。但主機(jī)的網(wǎng)卡數(shù)量是有限的,如何支持更多的 macvlan 網(wǎng)絡(luò)呢?好在 macvlan 不僅可以連接到 interface(如 eth0),也可以連接到 sub-interface(如 eth0.xxx)。

VLAN 是現(xiàn)代網(wǎng)絡(luò)常用的網(wǎng)絡(luò)虛擬化技術(shù),它可以將物理的二層網(wǎng)絡(luò)劃分成多達(dá) 4094 個(gè)邏輯網(wǎng)絡(luò),這些邏輯網(wǎng)絡(luò)在二層上是隔離的,每個(gè)邏輯網(wǎng)絡(luò)(即 VLAN)由 VLAN ID 區(qū)分,VLAN ID 的取值為 1-4094。Linux 的網(wǎng)卡也能支持 VLAN(apt-get install vlan),同一個(gè) interface 可以收發(fā)多個(gè) VLAN 的數(shù)據(jù)包,不過前提是要?jiǎng)?chuàng)建 VLAN 的 sub-interface。

比如希望 eth0 同時(shí)支持 VLAN10 和 VLAN20,則需創(chuàng)建 sub-interface eth0.10 和 eth0.20。在交換機(jī)上,如果某個(gè) port 只能收發(fā)單個(gè) VLAN 的數(shù)據(jù),該 port 為 Access 模式,如果支持多 VLAN,則為 Trunk 模式。

下面演示如何在 eth0.10 和 eth0.20 上創(chuàng)建 macvlan 網(wǎng)絡(luò)。
首先編輯 host1 和 host2 的 /etc/network/interfaces,配置 sub-interface

iface eth0 inet manual
auto eth0.10
iface eth0.10 inet manual
vlan-raw-device eth0
auto eth0.20
iface eth0.20 inet manual
vlan-raw-device eth0

然后啟用 sub-interface:
ifup eth0.10
ifup eth0.20

創(chuàng)建 macvlan 網(wǎng)絡(luò):
docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=eth0.10 mac_net10
docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=eth0.20 mac_net20

在 host1 中運(yùn)行容器:
docker run -itd --name bbox1 --ip=172.16.10.10 --network mac_net10 busybox
docker run -itd --name bbox2 --ip=172.16.20.10 --network mac_net20 busybox

在 host2 中運(yùn)行容器:
docker run -itd --name bbox3 --ip=172.16.10.11 --network mac_net10 busybox
docker run -itd --name bbox4 --ip=172.16.20.11 --network mac_net20 busybox

當(dāng)前網(wǎng)絡(luò)結(jié)構(gòu)如圖所示:


驗(yàn)證 macvlan 之間的連通性:
bbox1 能 ping 通 bbox3,bbox2 能 ping 通 bbox4。即:同一 macvlan 網(wǎng)絡(luò)能通信。

bbox1 無(wú)法 ping 通 bbox2 和 bbox4。即:不同 macvlan 網(wǎng)絡(luò)之間不能通信。但更準(zhǔn)確的說法應(yīng)該是:不同 macvlan 網(wǎng)絡(luò)不能 在二層上 通信。在三層上可以通過網(wǎng)關(guān)將 macvlan 連通,下面我們就啟用網(wǎng)關(guān)。

我們會(huì)將 Host 10.10.8.125 配置成一個(gè)虛擬路由器,設(shè)置網(wǎng)關(guān)并轉(zhuǎn)發(fā) VLAN10 和 VLAN20 的流量。當(dāng)然也可以使用物理路由器達(dá)到同樣的效果。首先確保操作系統(tǒng) IP Forwarding 已經(jīng)啟用。

# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

flannel網(wǎng)絡(luò)

flannel 是 CoreOS 開發(fā)的容器網(wǎng)絡(luò)解決方案。flannel 為每個(gè) host 分配一個(gè) subnet,容器從此 subnet 中分配 IP,這些 IP 可以在 host 間路由,容器間無(wú)需 NAT 和 port mapping 就可以跨主機(jī)通信。

每個(gè) subnet 都是從一個(gè)更大的 IP 池中劃分的,flannel 會(huì)在每個(gè)主機(jī)上運(yùn)行一個(gè)叫 flanneld 的 agent,其職責(zé)就是從池子中分配 subnet。為了在各個(gè)主機(jī)間共享信息,flannel 用 etcd(與 consul 類似的 key-value 分布式數(shù)據(jù)庫(kù))存放網(wǎng)絡(luò)配置、已分配的 subnet、host 的 IP 等信息。

數(shù)據(jù)包如何在主機(jī)間轉(zhuǎn)發(fā)是由 backend 實(shí)現(xiàn)的。flannel 提供了多種 backend,最常用的有 vxlan 和 host-gw,我們將在本章討論這兩種 backend。其他 backend 請(qǐng)參考 https://github.com/coreos/flannel。

  • 實(shí)驗(yàn)環(huán)境

etcd 部署在 10.10.8.125,host1 和 host2 上運(yùn)行 flanneld,首先安裝配置 etcd。

  • 安裝配置 etcd

在10.10.8.125運(yùn)行如下腳本:

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/

該腳本從 github 上下載 etcd 的可執(zhí)行文件并保存到 /usr/local/bin/,啟動(dòng) etcd 并打開 2379 監(jiān)聽端口。

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

weave網(wǎng)絡(luò)

weave 是 Weaveworks 開發(fā)的容器網(wǎng)絡(luò)解決方案。weave 創(chuàng)建的虛擬網(wǎng)絡(luò)可以將部署在多個(gè)主機(jī)上的容器連接起來(lái)。對(duì)容器來(lái)說,weave 就像一個(gè)巨大的以太網(wǎng)交換機(jī),所有容器都被接入這個(gè)交換機(jī),容器可以直接通信,無(wú)需 NAT 和端口映射。除此之外,weave 的 DNS 模塊使容器可以通過 hostname 訪問。

Calico網(wǎng)絡(luò)

Calico 是一個(gè)純?nèi)龑拥奶摂M網(wǎng)絡(luò)方案,Calico 為每個(gè)容器分配一個(gè) IP,每個(gè) host 都是 router,把不同 host 的容器連接起來(lái)。與 VxLAN 不同的是,Calico 不對(duì)數(shù)據(jù)包做額外封裝,不需要 NAT 和端口映射,擴(kuò)展性和性能都很好。

與其他容器網(wǎng)絡(luò)方案相比,Calico 還有一大優(yōu)勢(shì):network policy。用戶可以動(dòng)態(tài)定義 ACL 規(guī)則,控制進(jìn)出容器的數(shù)據(jù)包,實(shí)現(xiàn)業(yè)務(wù)需求。

docker網(wǎng)絡(luò)總結(jié)

Docker Overaly,Macvaln,F(xiàn)lannel,Weave 和 Calico 跨主機(jī)網(wǎng)絡(luò)方案。目前這個(gè)領(lǐng)域是百家爭(zhēng)鳴,而且還有新的方案不斷涌現(xiàn)。

我們將從如下幾個(gè)方面比較,大家可以根據(jù)不同場(chǎng)景選擇最合適的方案。

網(wǎng)絡(luò)模型
采用何種網(wǎng)絡(luò)模型支持 multi-host 網(wǎng)絡(luò)?

Distributed Store 
是否需要 etcd 或 consul 這類分布式 key-value 數(shù)據(jù)庫(kù)存儲(chǔ)網(wǎng)絡(luò)信息?

IPMA
如何管理容器網(wǎng)絡(luò)的 IP?

連通與隔離
提供怎樣的網(wǎng)絡(luò)連通性?支持容器間哪個(gè)級(jí)別和哪個(gè)類型的隔離?

性能
性能比較。
  • 網(wǎng)絡(luò)模型

跨主機(jī)網(wǎng)絡(luò)意味著將不同主機(jī)上的容器用同一個(gè)虛擬網(wǎng)絡(luò)連接起來(lái)。這個(gè)虛擬網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu)和實(shí)現(xiàn)技術(shù)就是網(wǎng)絡(luò)模型。

Docker overlay 如名稱所示,是 overlay 網(wǎng)絡(luò),建立主機(jī)間 VxLAN 隧道,原始數(shù)據(jù)包在發(fā)送端被封裝成 VxLAN 數(shù)據(jù)包,到達(dá)目的后在接收端解包。

Macvlan 網(wǎng)絡(luò)在二層上通過 VLAN 連接容器,在三層上依賴外部網(wǎng)關(guān)連接不同 macvlan。數(shù)據(jù)包直接發(fā)送,不需要封裝,屬于 underlay 網(wǎng)絡(luò)。

Flannel 我們討論了兩種 backend:vxlan 和 host-gw。vxlan 與 Docker overlay 類似,屬于 overlay 網(wǎng)絡(luò)。host-gw 將主機(jī)作為網(wǎng)關(guān),依賴三層 IP 轉(zhuǎn)發(fā),不需要像 vxlan 那樣對(duì)包進(jìn)行封裝,屬于 underlay 網(wǎng)絡(luò)。

Weave 是 VxLAN 實(shí)現(xiàn),屬于 overlay 網(wǎng)絡(luò)。

各方案的網(wǎng)絡(luò)模型描述如下:

  • Distributed Store

Docker Overlay、Flannel 和 Calico 都需要 etcd 或 consul。Macvlan 是簡(jiǎn)單的 local 網(wǎng)絡(luò),不需要保存和共享網(wǎng)絡(luò)信息。Weave 自己負(fù)責(zé)在主機(jī)間交換網(wǎng)絡(luò)配置信息,也不需要 Distributed Store。

  • IPAM

Docker Overlay 網(wǎng)絡(luò)中所有主機(jī)共享同一個(gè) subnet,容器啟動(dòng)時(shí)會(huì)順序分配 IP,可以通過 --subnet 定制此 IP 空間。

Macvlan 需要用戶自己管理 subnet,為容器分配 IP,不同 subnet 通信依賴外部網(wǎng)關(guān)。

Flannel 為每個(gè)主機(jī)自動(dòng)分配獨(dú)立的 subnet,用戶只需要指定一個(gè)大的 IP 池。不同 subnet 之間的路由信息也由 Flannel 自動(dòng)生成和配置。

Weave 的默認(rèn)配置下所有容器使用 10.32.0.0/12 subnet,如果此地址空間與現(xiàn)有 IP 沖突,可以通過 --ipalloc-range 分配特定的 subnet。

Calico 從 IP Pool(可定制)中為每個(gè)主機(jī)分配自己的 subnet。

  • 連通與隔離

同一 Docker Overlay 網(wǎng)絡(luò)中的容器可以通信,但不同網(wǎng)絡(luò)之間無(wú)法通信,要實(shí)現(xiàn)跨網(wǎng)絡(luò)訪問,只有將容器加入多個(gè)網(wǎng)絡(luò)。與外網(wǎng)通信可以通過 docker_gwbridge 網(wǎng)絡(luò)。

Macvlan 網(wǎng)絡(luò)的連通或隔離完全取決于二層 VLAN 和三層路由。

不同 Flannel 網(wǎng)絡(luò)中的容器直接就可以通信,沒有提供隔離。與外網(wǎng)通信可以通過 bridge 網(wǎng)絡(luò)。

Weave 網(wǎng)絡(luò)默認(rèn)配置下所有容器在一個(gè)大的 subnet 中,可以自由通信,如果要實(shí)現(xiàn)隔離,需要為容器指定不同的 subnet 或 IP。與外網(wǎng)通信的方案是將主機(jī)加入到 weave 網(wǎng)絡(luò),并把主機(jī)當(dāng)作網(wǎng)關(guān)。

Calico 默認(rèn)配置下只允許位于同一網(wǎng)絡(luò)中的容器之間通信,但通過其強(qiáng)大的 Policy 能夠?qū)崿F(xiàn)幾乎任意場(chǎng)景的訪問控制。

  • 性能

性能測(cè)試是一個(gè)非常嚴(yán)謹(jǐn)和復(fù)雜的工程,這里我們只嘗試從技術(shù)方案的原理上比較各方案的性能。

最樸素的判斷是:Underlay 網(wǎng)絡(luò)性能優(yōu)于 Overlay 網(wǎng)絡(luò)。

Overlay 網(wǎng)絡(luò)利用隧道技術(shù),將數(shù)據(jù)包封裝到 UDP 中進(jìn)行傳輸。因?yàn)樯婕皵?shù)據(jù)包的封裝和解封,存在額外的 CPU 和網(wǎng)絡(luò)開銷。雖然幾乎所有 Overlay 網(wǎng)絡(luò)方案底層都采用 Linux kernel 的 vxlan 模塊,這樣可以盡量減少開銷,但這個(gè)開銷與 Underlay 網(wǎng)絡(luò)相比還是存在的。所以 Macvlan、Flannel host-gw、Calico 的性能會(huì)優(yōu)于 Docker overlay、Flannel vxlan 和 Weave。

Overlay 較 Underlay 可以支持更多的二層網(wǎng)段,能更好地利用已有網(wǎng)絡(luò),以及有避免物理交換機(jī) MAC 表耗盡等優(yōu)勢(shì),所以在方案選型的時(shí)候需要綜合考慮。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • docker之容器通信 這節(jié)屬于了解學(xué)習(xí),算是爛尾,最后我也沒找到合適的方式去固定容器ip,然后作為正式環(huán)境去跑,...
    道無(wú)虛閱讀 5,516評(píng)論 1 7
  • 概述 自從docker容器出現(xiàn)以來(lái),容器的網(wǎng)絡(luò)通信就一直是大家關(guān)注的焦點(diǎn),也是生產(chǎn)環(huán)境的迫切需求。而容器的網(wǎng)絡(luò)通信...
    糙老爺們兒吃什么櫻桃閱讀 3,644評(píng)論 1 5
  • [TOC] Docker容器平臺(tái)選型調(diào)研 編排選型 Swarm Swarm可以從一個(gè)Dockerfile來(lái)構(gòu)建鏡像...
    AllenWu閱讀 2,542評(píng)論 0 7
  • 轉(zhuǎn)自:http://ju.outofmemory.cn/entry/255894 概述自從docker容器出現(xiàn)以來(lái)...
    dleyanlin閱讀 1,519評(píng)論 0 7