天天看點

docker網絡方案之weave實戰篇

什麼是weave?

Weave通過建立虛拟網絡使docker容器能夠跨主機通信并能夠自動互相發現。

通過weave網絡,由多個容器構成的基于微服務架構的應用可以運作在任何地方:主機,多主機,雲上或者資料中心。

應用程式使用網絡就好像容器是插在同一個網絡交換機上一樣,不需要配置端口映射,連接配接等。

在weave網絡中,使用應用容器提供的服務可以暴露給外部,而不用管它們運作在何處。類似地,現存的内部系統也可以接受來自于應用容器的請求,而不管容器運作于何處。

為什麼選擇weave?

  • 無憂的配置

Weave網絡能夠簡化容器網絡的配置。因為weave網絡中的容器使用标準的端口提供服務(如,Mysql預設使用3306),管理微服務是十分直接簡單的。

每個容器都可以通過域名來與另外的容器通信,也可以直接通信而無需使用NAT,也不需要使用端口映射或者複雜的linking.

部署weave容器網絡的最大的好處是無需修改你的應用代碼。

docker網絡方案之weave實戰篇
  • 服務發現

Weave網絡通過在每個節點上啟動一個"微型的DNS"服務來實作服務發現。你隻需要給你的容器起個名字就可以使用服務發現了,還可以在多個同名的容器上提供負載均衡的功能。

  • 不需要額外的叢集存儲

所有其它的Docker網絡插件,包括Docker自帶的"overlay"驅動,在你真正能使用它們之間,都需要安裝額外的叢集存儲----一個像Consul或者Zookeepr那樣的中心資料庫. 除了安裝,維護和管理困難外,甚至Docker主機需要始終與叢集存儲保持連接配接,如果你斷開了與其的連接配接,盡管很短暫,你也不能夠啟動和停止任何容器了。

Weave網絡是與Docker網絡插件捆綁在一起的,這意味着你可以馬上就使用它,而且可以在網絡連接配接出現問題時依舊啟動和停止容器。

關于更多Weave Docker插件的介紹,請檢視 Weave Network Plugin如何工作.

  • 在部分連接配接情況下進行操作

Weave網絡能夠在節點間轉發流量,它甚至能夠在網狀網絡部分連接配接的情況下工作。這意味着你可以在混合了傳統系統和容器化的應用的環境中使用Weave網絡來保持通信。

  • Weave網絡很快

Weave網絡自動在兩個節點之間選擇最快的路徑,提供接近本地網絡的吞吐量和延遲,而且這不需要你的幹預。

關于Fast Datapath如何工作請參考 How Fast Datapath Works .

  • 多點傳播支援

Weave網絡完全支援多點傳播位址和路徑。資料可以被發送給一個多點傳播位址,資料的副本可以被自動地廣播。

  • NAT 轉換

使用Weave網絡,部署你的應用---無論是點對點的檔案共享,基于ip的voice或者其它應用,你都可以充分利用内置的NAT轉換。通過Weave網絡,你的app将會是可移值的,容器化的,加上它對網絡标準化的處理,将又會使你少關心一件事。

與任何架構內建: Kubernetes, Mesos, Amazon ECS, …

如果你想為所有的架構使用一個工具,Weave網絡是一個好的選擇。比如: 除了作為Docker插件使用,你還可以将其作為一個Kubernetes插件plugin.你還可以在 Amazon ECS ,Mesos和Marathon中使用它.

weave的特性

  • Virtual Ethernet Switch
  • Fast Data Path
  • Seamless Docker Integration
  • Docker Network Plugin
  • CNI Plugin
  • Address Allocation (IPAM)
  • Naming and Discovery
  • Application Isolation
  • Network Policy
  • Dynamic Network Attachment
  • Security
  • Host Network Integration
  • Service Export
  • Service Import
  • Service Binding
  • Service Routing
  • Multi-cloud Networking
  • Multi-hop Routing
  • Dynamic Topologies
  • Container Mobility
  • Fault Tolerance

安裝weave網絡

確定核心在3.8以上,Docker版本在1.10以上

sudo curl -L git.io/weave -o /usr/local/bin/weave
sudo chmod a+x /usr/local/bin/weave
           

使用weave網絡

  • 在host1上啟動weave
host1$ weave launch
host1$ eval $(weave env)
host1$ docker run --name a2 -ti weaveworks/ubuntu
           
  • 第一步用于啟動weave虛拟路由器,每個weave網絡内的主機上都要運作,是一個go語言實作的虛拟路由器。.不同主機之間的通信依懶于它。它本身也是以容器的方式啟動
  • 第二步用于設定環境變量,這樣通過docker指令行啟動的容器就會自動地連接配接到weave網絡中了。
  • 最後我們用普通的docker指令啟動了一個容器。

a2:/# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1

    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

    inet6 ::1/128 scope host

       valid_lft forever preferred_lft forever

36: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default

    link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.11/16 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::42:acff:fe11:b/64 scope link

       valid_lft forever preferred_lft forever

38: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP group default

    link/ether da:fa:eb:dc:28:27 brd ff:ff:ff:ff:ff:ff

    inet 10.32.0.1/12 scope global ethwe

       valid_lft forever preferred_lft forever

    inet6 fe80::d8fa:ebff:fedc:2827/64 scope link

       valid_lft forever preferred_lft forever

[email protected]:/#

可以看到weave為a2設定的ip為10.32.0.1/12

  • 在主機間建立連接配接

在另外一台主機host2上建立遠端連接配接,HOST1為上面的主機名

host2$ weave launch $HOST1
host2$ eval $(weave env)
host2$ docker run --name a3 -ti weaveworks/ubuntu
           

a3:/# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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

    inet6 ::1/128 scope host

       valid_lft forever preferred_lft forever

76: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default

    link/ether 02:42:ac:11:00:0c brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.12/16 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::42:acff:fe11:c/64 scope link

       valid_lft forever preferred_lft forever

78: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP group default

    link/ether 72:0c:7b:a2:75:67 brd ff:ff:ff:ff:ff:ff

    inet 10.44.0.0/12 scope global ethwe

       valid_lft forever preferred_lft forever

    inet6 fe80::700c:7bff:fea2:7567/64 scope link

       valid_lft forever preferred_lft forever

[email protected]:/#

可以看到weave為a3配置設定的ip為10.44.0.0/12.

  • 測試2個容器的連通性:

a3:/# ping a2

PING a2.weave.local (10.32.0.1): 56 data bytes

64 bytes from 10.32.0.1: icmp_seq=0 ttl=64 time=5.490 ms

64 bytes from 10.32.0.1: icmp_seq=1 ttl=64 time=0.728 ms

64 bytes from 10.32.0.1: icmp_seq=2 ttl=64 time=0.600 ms

a2:/# ping a3

PING a3.weave.local (10.44.0.0): 56 data bytes

64 bytes from 10.44.0.0: icmp_seq=0 ttl=64 time=1.976 ms

64 bytes from 10.44.0.0: icmp_seq=1 ttl=64 time=1.421 ms

  • 指定多個遠端主機
host2$ weave launch <ip address> <ip address> 
           

指定配置設定IP的範圍

Weave網絡和docker預設配置都使用私有網絡。這些位址永遠不會在公有網絡中出現,這樣也減少了IP沖突的可能。然而,你的主機可能也在使用同樣範圍的私有位址,這将會引起沖突。

如果你在執行

weave launch之後有下面的錯誤:

Network 10.32.0.0/12 overlaps with existing route 10.0.0.0/8 on host.
ERROR: Default --ipalloc-range 10.32.0.0/12 overlaps with existing route on host.
You must pick another range and set it on all hosts.           

上面的錯誤消息說明,預設的weave網絡位址是

10.32.0.0/12

,

然而你的主機使用了重疊的路由

10.0.0.0/8

. 這樣,如果你使用預設的網絡位址,比如

10.32.5.6

,核心将無法确認這個位址是weave網絡位址

10.32.0.0/12

還是主機地

址10.0.0.0/8

.

如果你确認位址沒有被使用,你可以通過在weave launch指令行上顯式地指定

--ipalloc-range

來設定範圍。

手動指定容器的IP

容器自動從weave網絡中配置設定到唯一的IP,你可以通過weave ps指令檢視

# weave ps

weave:expose 32:3f:86:00:cf:b4

cf8b20300baf 72:0c:7b:a2:75:67 10.44.0.0/12

[email protected]:~#

Weave網絡會檢測到容器退出并回收配置設定的IP,這樣IP就可以被再使用。

如果你不想使用IPAM來自動配置設定IP,你可以為特定的容器或者叢集指定IP。

你可以顯式地指定IP位址和網絡,使用内部域路由或者 CIDR notation.

在$HOST1

:

host1$ docker run -e WEAVE_CIDR=10.2.1.1/24 -ti weaveworks/ubuntu
[email protected]:/#
           

$HOST2

:

host2$ docker run -e WEAVE_CIDR=10.2.1.2/24 -ti weaveworks/ubuntu
[email protected]:/#
           

然後測試連通性:

[email protected]:/# ping -c 1 -q 10.2.1.2
PING 10.2.1.2 (10.2.1.2): 48 data bytes
--- 10.2.1.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.048/1.048/1.048/0.000 ms
           
[email protected]:/# ping -c 1 -q 10.2.1.1
PING 10.2.1.1 (10.2.1.1): 48 data bytes
--- 10.2.1.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.034/1.034/1.034/0.000 ms
           

在weave網絡中隔離應用

weave網絡能夠跨多個主機,分離應用意味着每個應用運作的容器之間可以互相通信,但是與其它的應用容器隔離。

為了隔離應用,你可以使用

isolation-through-subnets

.

要開始隔離應用,配置weave的網絡IP配置設定不同的子網

配置多個子網:

host1$ weave launch --ipalloc-range 10.2.0.0/16 --ipalloc-default-subnet 10.2.1.0/24
host1$ eval $(weave env)
host2$ weave launch --ipalloc-range 10.2.0.0/16 --ipalloc-default-subnet 10.2.1.0/24 $HOST1
host2$ eval $(weave env)
           

這樣把整個10.2.0.0/16子網配置設定給了weave網絡,如果沒有單獨指定子網從10.2.1.0/24中配置設定位址。

然後啟動2個使用預設子網的容器:

host1$ docker run --name a1 -ti weaveworks/ubuntu
host2$ docker run --name a2 -ti weaveworks/ubuntu
           

然後為了測試隔離,我們啟動2個不同子網的容器:

host1$ docker run -e WEAVE_CIDR=net:10.2.2.0/24 --name b1 -ti weaveworks/ubuntu
host2$ docker run -e WEAVE_CIDR=net:10.2.2.0/24 --name b2 -ti weaveworks/ubuntu
           

通過ping測試a1,a2;b1,b2之間的連通性:

[email protected]:/# ping -c 1 -q b2
PING b2.weave.local (10.2.2.128) 56(84) bytes of data.
--- b2.weave.local ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.338/1.338/1.338/0.000 ms

[email protected]:/# ping -c 1 -q a1
PING a1.weave.local (10.2.1.2) 56(84) bytes of data.
--- a1.weave.local ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

[email protected]:/# ping -c 1 -q a2
PING a2.weave.local (10.2.1.130) 56(84) bytes of data.
--- a2.weave.local ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
           

如果有需要,還可以在啟動時将容器連接配接到不同的子網:

host1$ docker run -e WEAVE_CIDR="net:default net:10.2.2.0/24" -ti weaveworks/ubuntu
           

重要:必須阻止容器捕獲和注入原始網絡包,這可以通過在啟動時指定

--cap-drop net_raw

選項來實作。

注意:預設情況下,docker允許同一個主機上的容器之間互通,要隔離容器,需要在啟動docker daemon時指定

--icc=false

動态attaching和detaching應用

  • 動态attaching應用

當建立容器時可能不知道将容器attached到哪個網絡,Weave網絡讓你可以動态地attach和detach容器到已經存在的網絡,甚至在容器已經運作的情況下。

host1$ C=$(docker run -e WEAVE_CIDR=none -dti weaveworks/ubuntu)
host1$ weave attach $C
10.2.1.3
           
  • C=$(docker run -e WEAVE_CIDR=none -dti weaveworks/ubuntu)

    啟動一個容器并将ID賦給C
  • weave attach

    – 将容器attach到指定網絡
  • 10.2.1.3

    – 容器被配置設定的IP , 這種情況下是預設的網絡

需要注意 的是如果你在使用 Weave Docker API proxy, 你需要修改環境變量

DOCKER_HOST

将其指向proxy,你還需要指定

-e WEAVE_CIDR=none

來啟動視窗,這樣容器才不會自動地attach到weave網絡.

  • 動态detaching應用

一個容器可以通過weave detach指令來動态地deataching網絡

host1$ weave detach $C
10.2.1.3
           

你也可以從指定子網deatach并attach到指定子網

host1$ weave detach net:default $C
10.2.1.3
host1$ weave attach net:10.2.2.0/24 $C
10.2.2.3
           

或者attach多個子網

host1$ weave attach net:default
10.2.1.3
host1$ weave attach net:10.2.2.0/24
10.2.2.3
           

也可以在一個指令行上同時指定

host1$ weave attach net:default net:10.2.2.0/24 net:10.2.3.0/24 $C
10.2.1.3 10.2.2.3 10.2.3.1
host1$ weave detach net:default net:10.2.2.0/24 net:10.2.3.0/24 $C
10.2.1.3 10.2.2.3 10.2.3.1
           
host1$ weave attach net:default
10.2.1.3
host1$ weave attach net:10.2.2.0/24
10.2.2.3
           

重要:通過attach方式配置設定的IP在容器重新開機之後會丢失。

與主控端網絡內建

Weave應用網絡能夠與外部主控端的網絡內建,在主控端和應用容器之間建立連接配接。

比如你已經決定讓在HOST2上運作的容器能夠被其它主控端和容器通路。

host2$ weave expose
10.2.1.132
           

這個指令授權主控端通路所有預設網絡中的容器。為了達到這個目的weave會給weave網橋配置設定一個IP并列印出來:10.2.1.132

現在你可以在主控端中執行:

host2$ ping 10.2.1.132
           

你還可以ping另外一台機器上的容器a1:

host2$ ping $(weave dns-lookup a1)
           
  • 暴露多個網絡

網絡可以使用下面的指令被暴露或隐藏

host2$ weave expose net:default net:10.2.2.0/24
10.2.1.132 10.2.2.130
host2$ weave hide   net:default net:10.2.2.0/24
10.2.1.132 10.2.2.130           
  • 向weaveDNS添加暴露的網絡
host2$ weave expose -h exposed.weave.local
10.2.1.132           
  • 從另外的主機上路由

在暴露了IP位址後,你可以通過手工在另外沒有安裝weave的機器上添加路由來通路暴露的IP

ip route add <network-cidr> via <exposing-host>           
  • <network-cidr>

    是weave網絡的IP位址範圍,比如,

    10.2.0.0/16

    or

    10.32.0.0/12

  • <exposing-host>是你執行weave expose的機器位址,通過它來轉發

    .

管理服務-----導入,導出,綁定和路由

  • 導出服務

在weave網絡中運作在容器中的服務通過主控端可以被外部甚至是其它網絡通路,而不用管容器運作的位置。

假設有一個服務運作在HOST1上,外部網絡通過HOST2可以通路到它。

首先,在HOST2導出應用網絡

host2$ weave expose
10.2.1.132
           

然後添加NAT規則将外部網絡通路HOST1服務的流量轉發到目的容器

host2$ iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 2211 \
       -j DNAT --to-destination $(weave dns-lookup a1):4422
           

在上面的指令中,我們假設外部網絡通過eth0網卡通路HOST2,通過這個NAT,通路HOST2的2211的TCP流量将會被轉發到運作于HOST1上的a1容器的4422端口。

通過上面的配置,我們可以通過下面的指令通路

echo 'Hello, world.' | nc $HOST2 2211
           

通過類似上面的NAT指令還可以将服務暴露給内部網絡。

  • 導入服務

運作于容器中的應用可以通過weave網絡被特定的weave主機通路,而不用管實際的應用容器運作于哪兒。

如果現在你想運作第三方程式在非容器化的環境中,比如運作于HOST3,監聽2211端口,但是HOST3上沒有運作weave網絡。

另外,HOST3隻與HOST1是互通的,但是HOST2不能通路。你現在想讓HOST2能通路HOST3上的服務。

要滿足上面的需求,先在HOST1上執行

:

host1$ weave expose -h host1.weave.local
10.2.1.3
           

然後添加NAT規則,允許應用容器通過10.2.1.3:3322來通路服務。

host1$ iptables -t nat -A PREROUTING -p tcp -d 10.2.1.3 --dport 3322 \
       -j DNAT --to-destination $HOST3:2211
           

然後HOST3上:

host3$ nc -lk -p 2211
           

現在,你可以在HOST2的容器中通過下面的指令來通路HOST3上的服務:

[email protected]:/# echo 'Hello, world.' | nc host1 3322
           
  • 綁定服務

導入一個服務允許一定程度的間接性和動态綁定,與代理的功能類似。

在上面的例子中,實際的服務對應用容器全透明

,容器不知道對10.2.1.3:3322的通路實際上是

$HOST3:2211

.

你可以将應用程式通路的服務定位到另外的服務通過改變NAT規則。

  • 路由服務

你可以通過組合使用導出,導入服務來在不連續的網絡上連接配接應用和服務,甚至這些網絡被防火牆隔開和有重疊的IP位址範圍。

在網絡上導入服務到weave網絡中,同時,也可以将容器應用從weave網絡中導出服務。下面的例子中,沒有容器應用,都是在宿主環境中, weave網絡提供了位址轉換和路由服務的功能,使用容器網絡做為中介。

你可以通過weave網絡将HOST1導入另外一個運作于HOST3上的服務給HOST2。

首先在HOST2上通過暴露應用網絡導入服務:

host2$ weave expose
10.2.1.3

           

在HOST2上添加NAT規則

host2$ iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 4433 \
       -j DNAT --to-destination 10.2.1.3:3322
           

現在和HOST2在同一網絡的主機可以通路這個服務

echo 'Hello, world.' | nc $HOST2 4433
           
  • 動态遷移服務

更進一步,在上面提到的綁定服務中,實際服務的位置是可以動态變化的,而且對通路者是透明的。

比如你可以将服務遷移到

$HOST4:2211

而它仍然可以通過10.2.1.3:3322來通路。