docker(7、容器網絡6) weave 網絡 Weave 跨主機的連通和隔離特性

weave 是 Weaveworks 開發的容器網絡解決方案。weave 創建的虛擬網絡可以將部署在多個主機上的容器連接起來。對容器來說,weave 就像一個巨大的以太網交換機,所有容器都被接入這個交換機,容器可以直接通信,無需 NAT 和端口映射。除此之外,weave 的 DNS 模塊使容器可以通過 hostname 訪問。https://www.weave.works/docs/cloud/latest/install/installing-agents/#weave-cloud

介紹

Weave在Docker主機之間實現Overlay網絡,使用業界標準VXLAN封裝,基於UDP傳輸,也可以加密傳輸。 Weave Net創建一個連接多個Docker主機的虛擬網絡,類似於一個以太網交換機,所有的容器都連接到這上面,互相通信。 Weave Net由多個peer組成,Weave路由器運行不同Docker主機上,是一個用戶空間的進程;每個peer都有一個名稱,重啓保持不變。它們通過TCP連接彼此,建立後交換拓撲信息。 Weave Net可以在具有編號拓撲的部分連接的網絡中路由數據包。

特點

# IP地址管理(IPAM)
Weave自動爲容器分配唯一的IP地址。可通過weave ps查看
# 命名和發現
命名的容器自動會註冊到Weave DNS中,並可以通過容器名稱訪問。
注:weave自己維護了一個微型的dns服務器。可以實現主機名通信。
# 負載均衡
允許註冊多個相同名稱的容器,Weave DNS隨機爲每個請求返回地址,提供基本的負載均衡功能。
注:如果訪問容器名相同,則會自動輪詢訪問該容器,實現負載均衡。
# 手動指定IP地址
docker run –it –e WEAVE_CIDR=10.32.0.100/24 busybox
# 動態拓撲
可以在不停止或重新配置剩餘Docker主機的情況下添加主機到Weave網絡中或從Weave網絡中刪除
# 容錯
weave peer不斷交換拓撲信息,監視和建立與其他peer的網絡連接。如果有主機或網絡出現故障,Weave會繞過這個主機,保證兩邊容器可以繼續通信,當恢復時,恢復完全連接

Docker Weave 工作原理

網卡設備
Container eth0:      eth0是容器主機的默認網絡,主要提供容器訪問外網所提供的服務,走的默認docker網絡架構,只不過他創建了docker_gwbridge這個網橋。
docker_gwbridge:     docker_gwbridge是容器所創建的網橋它替代了docker0的服務。
Contailner ethwe:    它是veth pair虛擬設備對,與其他容器通信的網絡虛擬網卡。
vethwe-bridge:       是ethwe設備對創建的weave網橋。網橋內分配的具體的IP與網關。
weave:               weave網橋,通過route路由表找到目標,通過端口將數據包轉發到對端端口節點。
eth0:                真機網卡與外界網卡連接得真機網卡,它用來轉發,容器VXLAN與NAT兩種網卡類型的數據包到指定的對端節點。
注:weave會將相鄰的節點互相學習,通過route路由表進行相互通信,並通過單獨的端口發送數據。類似於靜態路由。

Contailner ethwe 發送數據包到對端容器通信

1、ethwe 會將數據包發送給vethwe-bridge網橋。
2、vethwe-bridge接收到數據包後由weave去處理這個數據,通過UDP6783數據端口依照weave的路由錶轉發到下一路由節點。
3、如果該節點就是目的地,本地weave會把信息轉發到內核的TCP協議站,再轉發到目的節點。

實驗環境描述

weave 不依賴分佈式數據庫(例如 etcd 和 consul)交換網絡信息,每個主機上只需運行 weave 組件就能建立起跨主機容器網絡。我們會在 host1 和 host2 上部署 weave 並實踐 weave 的各項特性

Weave不需要集中式的key-value存儲,所以安裝和運行都很簡單。直接把Weave二進制文件下載到系統中就可以了

192.168.1.122   部署docker  weave           主機名:host1 
192.168.1.123 部署docker  weave           主機名:host2


 

 

1、設置主機名及綁定hosts
[root@host1 ~]# hostnamectl --static set-hostname  host1
2、關閉防火牆
[root@host1 ~]# systemctl disable firewalld.service
[root@host1 ~]# systemctl stop firewalld.service
3、安裝docker
[root@host1 ~]# yum install -y docker
[root@host1 ~]# systemctl daemon-reload && systemctl start docker      #啓動docker
[root@host1 ~]# chkconfig docker on         #加入開機啓動
4、下載weave 到/usr/local/bin/weave
[root@host1 ~]# curl -L git.io/weave -o /usr/local/bin/weave
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
100   595  100   595    0     0    217      0  0:00:02  0:00:02 --:--:--  581k
100 52227  100 52227    0     0  13476      0  0:00:03  0:00:03 --:--:--  112k
5、賦予權限/usr/local/bin/weave
[root@host1 ~]# chmod a+x /usr/local/bin/weave  
6、啓動weave
###host1上啓動wave,wave組建以容器方式運行
[root@host1 ~]# weave launch 
2.6.2: Pulling from weaveworks/weave
Digest: sha256:6f6839774ca225076116790145a415fa99706133310bcf7a56ce29fd89c245d3
Status: Downloaded newer image for weaveworks/weave:2.6.2
docker.io/weaveworks/weave:2.6.2
latest: Pulling from weaveworks/weavedb
72bf8a6af285: Pull complete 
Digest: sha256:7badb003b9c0bf5c51bf801be2a4d5d371f0738818f9cbe60a508f54fd07de9a
Status: Downloaded newer image for weaveworks/weavedb:latest
docker.io/weaveworks/weavedb:latest
Unable to find image 'weaveworks/weaveexec:2.6.2' locally
2.6.2: Pulling from weaveworks/weaveexec
Digest: sha256:a28b3c098a049d923fb08231a1bba22e6d57c83710257e41220c28ffccb2d66c
Status: Downloaded newer image for weaveworks/weaveexec:2.6.2
217ed2e604a7e2c5f9ab5d2557c088ccb0b41d23df6373152cd1ce5eb047
7、weave組建以容器方式運行
[root@host1 ~]# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS               NAMES                            bbox1
217ed2e604a7        weaveworks/weave:2.6.2   "/home/weave/weaver …"   12 hours ago        Up 12 hours                             weave
[root@host1 ~]# 

8、weave 會創建一個新的 Docker 網絡 weave

[root@host1 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3be562ae8342        bridge              bridge              local
8a47585430f3        host                host                local
14925807ce29        none                null                local
5d669a4aaa5e        weave               weavemesh           local   #weave網絡
[root@host1 ~]# 

9、查看weave網絡地址段

driver 爲 weavemesh,IP 範圍 10.32.0.0/12

[root@host1 ~]# docker network inspect 5d669a4aaa5e
[
    {
        "Name": "weave",
        "Id": "5d669a4aaa5e80345d2b341aa436bc777b80ad5b292bef107fe378292b361407",
        "Created": "2020-03-12T18:54:23.262355683-04:00",
        "Scope": "local",
        "Driver": "weavemesh",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "weavemesh",
            "Options": null,
            "Config": [
                {
                    "Subnet": "10.32.0.0/12"  #weave地址段
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "works.weave.multicast": "true"
        },
        "Labels": {}
    }
]
[root@host1 ~]#

10 在host1上運行容器

[root@host1 ~]# weave env
export DOCKER_HOST=unix:///var/run/weave/weave.sock
#將命令發給weave proxy,如果不需要了執行:# eval $(weave env --restore)
[root@host1 ~]# eval $(weave env)
[root@host1 ~]# docker run -itd  --name bbox1 busybox
d0a4d7c482ed69ee920f97cd809e978e3813d2e5f76c3c3e343361f7f9840c89
[root@host1 ~]# 

首先執行 eval $(weave env) 很重要,其作用是將後續的 docker 命令發給 weave proxy 處理。如果要恢復之前的環境,可執行 eval $(weave env --restore)

11、容器網絡分析

查看host1上容器bbox1的ip

查看一下當前容器 bbox1 的網絡配置:

[root@host1 ~]#  docker exec -it  bbox1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0   #默認連接docker0的bridge網絡
       valid_lft forever preferred_lft forever        
26: ethwe@if27: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1376 qdisc noqueue 
    link/ether ee:96:74:3b:d3:00 brd ff:ff:ff:ff:ff:ff
    inet 10.32.0.1/12 brd 10.47.255.255 scope global ethwe    #連接到主機的weave網絡接口
       valid_lft forever preferred_lft forever
[root@host1 ~]# 

bbox1 有兩個網絡接口 eth0 和 ethwe,其中 eth0 連接的是默認 bridge 網絡,即網橋 docker0。

現在我們重點分析 ethwe。從命名和分配的 IP 10.32.0.1/12 可以猜測 ethwe 與 weave 相關,ethwe@if27 告訴我們與 ethwe 對應的是編號 27 的 interface。從 host1 的 ip link 命令輸出中找到該 interface:

[root@host1 ~]#  ip link show
.........
27: vethwepl8618@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue master weave state UP mode DEFAULT group default 
    link/ether a6:39:fa:a4:a4:74 brd ff:ff:ff:ff:ff:ff link-netnsid 2  #這個接口是與容器相連的接口
[root@host1 ~]# 

 vethwepl8618@if26 與 ethwe 是一對 veth pair,而且  vethwepl8618 掛在 host1 的 Linux bridge weave 上。

[root@host1 ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.024286810522	no		veth24ed3f2
weave		8000.0e8e2735b12c	no		vethwe-bridge
							vethwepl8618

除了 ethwepl8618 ,weave 上還掛了一個 vethwe-bridge,這是什麼?讓我們更深入的分析一下,查看 ip -d link 輸出:

這裏出現了多個新 interface: 
① vethwe-bridge 與 vethwe-datapath 是 veth pair。 
② vethwe-datapath 的父設備(master)是 datapath。 
③ datapath 是一個 openvswitch。 
④ vxlan-6784 是 vxlan interface,其 master 也是 datapath,weave 主機間是通過 VxLAN 通信的。

weave 網絡包含兩個虛擬交換機:Linux bridge weave 和 Open vSwitch datapath,veth pair vethwe-bridge 和 vethwe-datapath 將二者連接在一起。
weave 和 datapath 分工不同,weave 負責將容器接入 weave 網絡,datapath 負責在主機間 VxLAN 隧道中並收發數據。

host1上運行第二個容器 在bbox1 ping bbox2 支持dns name

[root@host1 ~]# docker run --name bbox2 -itd busybox
61d93aa29198d445ac454ef02487f703febb7644079943a909ebac577b0cb591
[root@host1 ~]#  docker exec -it  bbox1 ping -c 4 bbox2
PING bbox2 (10.32.0.2): 56 data bytes
64 bytes from 10.32.0.2: seq=0 ttl=64 time=0.244 ms
64 bytes from 10.32.0.2: seq=1 ttl=64 time=0.084 ms
^C
--- bbox2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.084/0.164/0.244 ms

當前 host1 網絡結構爲:

 

Weave 跨主機的連通和隔離特性

host2安裝weave

1、設置主機名及綁定hosts
[root@host2 ~]# hostnamectl --static set-hostname  host2
2、關閉防火牆
[root@host2 ~]# systemctl disable firewalld.service
[root@host2 ~]# systemctl stop firewalld.service
3、安裝docker
[root@host2 ~]# yum install -y docker
[root@host2 ~]# systemctl daemon-reload && systemctl start docker      #啓動docker
[root@host2 ~]# chkconfig docker on         #加入開機啓動
4、下載weave 到/usr/local/bin/weave
[root@host1 ~]# curl -L git.io/weave -o /usr/local/bin/weave
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
100   595  100   595    0     0    217      0  0:00:02  0:00:02 --:--:--  581k
100 52227  100 52227    0     0  13476      0  0:00:03  0:00:03 --:--:--  112k
5、賦予權限/usr/local/bin/weave
[root@host2 ~]# chmod a+x /usr/local/bin/weave  

6、啓動weave
###host2上啓動wave,啓動weave指向host1的weave:wave組建以容器方式運行 

這裏必須指定 host1 的 IP 192.168.1.122,這樣 host1 和 host2 才能加入到同一個 weave 網絡。

[root@host2 ~]# weave launch 192.168.1.122
2.6.2: Pulling from weaveworks/weave
Digest: sha256:6f6839774ca225076116790145a415fa99706133310bcf7a56ce29fd89c245d3
Status: Downloaded newer image for weaveworks/weave:2.6.2
docker.io/weaveworks/weave:2.6.2
latest: Pulling from weaveworks/weavedb
72bf8a6af285: Pull complete 
Digest: sha256:7badb003b9c0bf5c51bf801be2a4d5d371f0738818f9cbe60a508f54fd07de9a
Status: Downloaded newer image for weaveworks/weavedb:latest
docker.io/weaveworks/weavedb:latest
Unable to find image 'weaveworks/weaveexec:2.6.2' locally
2.6.2: Pulling from weaveworks/weaveexec 
Digest: sha256:a28b3c098a049d923fb08231a1bba22e6d57c83710257e41220c28ffccb2d66c
Status: Downloaded newer image for weaveworks/weaveexec:2.6.2
a85d5a20516466b6e2c5f9ab5d2557c088ccb0b41d23df6373152cd1ce5eb047
[root@host2 ~]# docker  ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS               NAMES
a85d5a205164        weaveworks/weave:2.6.2   "/home/weave/weaver …"   13 seconds ago      Up 13 seconds                           weave
[root@host2 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
22c93b1df59e        bridge              bridge              local
e75a72e83f90        host                host                local
ac72879f7ab4        none                null                local
0fdf77b12596        weave               weavemesh           local

在host2上運行容器 bbox3:


[root@host2 ~]# eval $(weave env)
[root@host2 ~]# docker run --name bbox3 -itd busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
0669b0daf1fb: Pull complete 
Digest: sha256:b26cd013274a657b86e706210ddd5cc1f82f50155791199d29b9e86e935ce135
Status: Downloaded newer image for busybox:latest
0a0a544571db1c036f83cb46f42a09e5643a35ad4d5f4ac70a6d30a551045fce
[root@host2 ~]# docker exec bbox3 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
14: ethwe@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1376 qdisc noqueue 
    link/ether 46:eb:01:77:ba:1d brd ff:ff:ff:ff:ff:ff
    inet 10.44.0.0/12 brd 10.47.255.255 scope global ethwe   
       valid_lft forever preferred_lft forever

weave 網絡連通性

bbox3 能夠直接 ping bbox1 和 bbox2。

bbox1、bbox2 和 bbox3 的 IP 分別爲 10.32.0.1/12、10.32.0.2/12 和 10.44.0.0/12,注意掩碼爲 12 位,實際上這三個 IP 位於同一個 subnet 10.32.0.0/12。通過 host1 和 host2 之間的 VxLAN 隧道,三個容器邏輯上是在同一個 LAN 中的,當然能直接通信了。bbox3 ping bbox1 的數據流向如下圖所示:

① 數據包目的地址爲 10.32.0.1,根據 bbox3 的路由表,數據從 ethwe 發送出去。

② host2 weave 查詢到目的地主機,將數據通過 VxLAN 發送給 host1。

③ host1 weave 接受到數據,根據目的 IP 將數據轉發給 bbox1。

weave 網絡隔離

默認配置下,weave 使用一個大 subnet(例如 10.32.0.0/12),所有主機的容器都從這個地址空間中分配 IP,因爲同屬一個 subnet,容器可以直接通信。如果要實現網絡隔離,可以通過環境變量 WEAVE_CIDR 爲容器分配不同 subnet 的 IP,舉例如下:

[root@host1 ~]# docker run -e WEAVE_CIDR=net:10.32.2.0/24 -itd --name bbox4 busybox
ec3f37554696cf51b88740e11942f3f86a0244adea52f1b8438ed7c5eade85f0

[root@host1 ~]# docker exec bbox4 ip r
default via 172.17.0.1 dev eth0 
10.32.2.0/24 dev ethwe scope link  src 10.32.2.1 
172.17.0.0/16 dev eth0 scope link  src 172.17.0.4 
224.0.0.0/4 dev ethwe scope link 

[root@host1 ~]# docker exec bbox4 ping -c 4 bbox1
PING bbox1 (10.32.0.1): 56 data bytes

--- bbox1 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
[root@host1 ~]# 

 WEAVE_CIDR=net:10.32.2.0/24 的作用是使容器分配到 IP 10.32.2.2由於 10.32.0.0/12 與 10.32.2.0/24 位於不同的 subnet,所以無法 ping 到 bbox1

除了 subnet,我們還可以直接爲容器分配特定的 IP:

[root@host1 ~]# docker run -e WEAVE_CIDR=ip:10.32.6.6/24 -itd --name bbox5  busybox
036e2885c5eeedd202b2b023035f3cc4d5ebbb1c0a5d42d80361ff7468eeb59f
[root@host1 ~]# docker exec bbox5 ip r
default via 172.17.0.1 dev eth0 
10.32.6.0/24 dev ethwe scope link  src 10.32.6.6 
172.17.0.0/16 dev eth0 scope link  src 172.17.0.5 
224.0.0.0/4 dev ethwe scope link 
[root@host1 ~]# docker exec bbox5 ping -c 4 bbox1
PING bbox1 (10.32.0.1): 56 data bytes

--- bbox1 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
[root@host1 ~]# 

10.32.0.0/12 與 10.32.6.6/24 位於不同的 subnet,所以無法 ping 到 bbox1

Weave 與外網通信

  1. 首先將主機加入到 weave 網絡。

  2. 然後把主機當作訪問 weave 網絡的網關。

要將主機加入到 weave,執行 weave expose

[root@host1 ~]# weave expose
10.32.0.3
[root@host1 ~]# 

這個 IP 10.32.0.3 會被配置到 host1 的 weave 網橋上

[root@host1 ~]# ip a  show weave 
6: weave: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP group default qlen 1000
    link/ether 0e:8e:27:35:b1:2c brd ff:ff:ff:ff:ff:ff
    inet 10.32.0.3/12 brd 10.47.255.255 scope global weave
       valid_lft forever preferred_lft forever
    inet6 fe80::c8e:27ff:fe35:b12c/64 scope link 
       valid_lft forever preferred_lft forever
[root@host1 ~]# 

weave 網橋位於 root namespace,它負責將容器接入 weave 網絡。給 weave 配置同一 subnet 的 IP 其本質就是將 host1 接入 weave 網絡。 host1 現在已經可以直接與同一 weave 網絡中的容器通信了,無論容器是否位於 host1。

在 host1 中 ping 同一主機的 bbox1(10.32.0.1):

 ping host2 上的 bbox3(10.44.0.0):

接下來要讓其他非 weave 主機訪問到 bbox1 和 bbox3,只需將網關指向 host1。例如在 192.168.1.101 上添加如下路由:

例如一臺新的機器上添加   ip route add 10.32.0.0/12 via 192.168.1.104  

 

通過上面的配置我們實現了外網到 weave 這個方向的通信,反方向呢?

其實答案很簡單:因爲容器本身就掛在默認的 bridge 網絡上,docker0 已經實現了 NAT,所以容器無需額外配置就能訪問外網。

IPAM

10.32.0.0/12 是 weave 網絡使用的默認 subnet,如果此地址空間與現有 IP 衝突,可以通過 --ipalloc-range 分配特定的 subnet。

weave launch --ipalloc-range 10.2.0.0/16

不過請確保所有 host 都使用相同的 subnet。

weave --help  #查看幫助
weave ps #查看weave路由狀態:weave ps
weave connect  OTHER_HOST  #可以把一臺主機連接到weave網絡
weave attach #動態添加網絡對於不是通過weave啓動的容器,可以通過weave attach 10.0.1.1/24  $ContainerId來添加網絡(weave  detach刪除網絡)
weave expose #不使用docker的原生網絡容器和宿主機之間是無法互通的 , weave expose ip/24這個命令會把宿主機加入到weave 網絡中, 宿主機就可以和容器之間自由通信了
weave launch -password #安全性:可以通過weave launch -password wEaVe設置一個密碼用於weave peers之間加密通信

例如 weave ps

[root@host1 ~]# weave ps
weave:expose 0e:8e:27:35:b1:2c 10.32.0.3/12
036e2885c5ee 5a:e8:2a:bb:b8:b0 10.32.6.6/24
ec3f37554696 e2:7b:d0:be:ef:dd 10.32.2.1/24
0e626d17939b 72:1e:81:47:20:b0 10.32.0.2/12
1ccdad419a19 72:d6:1d:15:3b:99 10.32.0.1/12

1.eval $(weave env) 將docker命令代理給weave 執行,(如果先執行這個, docker命令啓動的容器就會被自動加入weave網絡,並自動分配IP)
2.docker run -d --rm nginx (正常啓動容器)
如果沒有執行步驟一直接啓動的docker容器是不能自動加入到weave網絡中的, 可以使用下列命令添加到weave網絡

  • weave attach IP/24 ContainerId #將容器加入到weave網絡並分配指定IP(24爲網絡地址範圍,決定了該網絡中最多可以有多少臺計算機)
  • weave attach ContainerId IP #將容器加入到weave網絡並自動分配IP
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章