Docker容器跨主機訪問

《Docker容器間互聯》一文中,我們瞭解瞭如何實現同一宿主機下的Docker容器互聯。本章將繼續之前的話題,接着介紹當容器部署在不同的主機上時,容器之間如何互聯。

使用Weave實現容器互聯

Weave是什麼?

Weave,原義爲編織。在這裏喻指建立一個虛擬網絡,用於將運行在不同主機的 Docker 容器連接起來。

官網:https://www.weave.works

Github:https://github.com/weaveworks/weave

Weave是Github上一個比較熱門的Docker容器網絡方案,具有非常良好的易用性且功能強大。Weave 的框架它包含了兩大主要組件:

1)Weave:用戶態的shell腳本,用於安裝Weave,將container連接到Weave虛擬網絡。併爲它們分配IP。

2)Weaver:運行於container內,每個Weave網絡內的主機都要運行,是一個Go語言實現的虛擬網絡路由器。不同主機之間的網絡通信依賴於Weaver路由。

Weave通過創建虛擬網絡使Docker容器能夠跨主機通信並能夠自動相互發現。

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

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

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

如上圖所示,在每一個部署Docker的主機(可能是物理機也可能是虛擬機)上都部署有一個W(即weave router,它本身也可以以一個容器的形式部署)。

weave網絡是由這些weave routers組成的對等端點(peer)構成,並且可以通過weave命令行定製網絡拓撲。

每個部署了weave router的主機之間都會建立TCP和UDP兩個連接,保證weave router之間控制面流量和數據面流量的通過。控制面由weave routers之間建立的TCP連接構成,通過它進行握手和拓撲關係信息的交換通信。控制面的通信可以被配置爲加密通信。而數據面由weave routers之間建立的UDP連接構成,這些連接大部分都會加密。這些連接都是全雙工的,並且可以穿越防火牆。

如何使用Weave?

實驗環境:

Linux:CentOS 7

Docker:1.13.1

Host1:172.16.250.234

Host2:172.16.250.239

安裝Weave

 在兩臺主機上分別執行如下命令,安裝Weave。

# 1. 下載二進制文件
[root@localhost ~]# wget -O /usr/local/bin/weave git.io/weave
# 2. 爲 weave 文件添加可執行權限
[root@localhost ~]# chmod a+x /usr/local/bin/weave
# 3. 驗證安裝版本
[root@localhost ~]# weave version
weave script 2.6.0
weave git-f43f3fc2e835

 啓動Weave網絡

啓動Weave網絡之前,請確保所以要互聯的主機上都已經正確安裝並且啓動 Docker守護進程。

在Host1(172.16.250.234)上執行如下命令:

[root@localhost ~]# weave launch
5815608f50371c4dc44ae0f58dcd80183678c9e32641d74c6bc21d1f8650672d
[root@localhost ~]# eval $(weave env)

# 再次檢查 weave 版本
[root@localhost ~]# weave version
weave script 2.6.0
weave 2.6.0

 在Host2(172.16.250.239)上執行如下命令:

[root@localhost ~]# weave launch 172.16.250.234
8353ccee1680b2249d39d0857ca44a469e3a11b67296742f2dc17d375e27ac31
[root@localhost ~]# eval $(weave env)

# 檢查 weave 連接狀態
[root@localhost ~]# weave status connections
-> 172.16.250.234:6783   established fastdp 86:c4:52:b3:cf:8b(localhost.localdomain) mtu=1376
# 查看 weave 詳細狀態
[root@localhost ~]# weave status

        Version: 2.6.0 (up to date; next check at 2019/12/09 15:38:23)

        Service: router
       Protocol: weave 1..2
           Name: d2:cf:f5:9d:9c:c7(localhost.localdomain)
     Encryption: disabled
  PeerDiscovery: enabled
        Targets: 1
    Connections: 1 (1 established)
          Peers: 2 (with 2 established connections)
 TrustedSubnets: none

        Service: ipam
         Status: ready
          Range: 10.32.0.0/12
  DefaultSubnet: 10.32.0.0/12

        Service: dns
         Domain: weave.local.
       Upstream: 172.16.0.3
            TTL: 1
        Entries: 0

        Service: proxy
        Address: unix:///var/run/weave/weave.sock

        Service: plugin (legacy)
     DriverName: weave
# 列出當前啓動的 docker 容器
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
8353ccee1680        weaveworks/weave:2.6.0       "/home/weave/weave..."   8 minutes ago       Up 8 minutes                            weave
aa5b7eac1049        weaveworks/weaveexec:2.6.0   "data-only"              50 minutes ago      Created                                 weavevolumes-2.6.0
b0129638b441        weaveworks/weavedb:latest    "data-only"              5 hours ago         Created                                 weavedb

執行 weave launch 命令常見錯誤: 

# 若出現以下錯誤
[root@localhost ~]# weave launch
WARNING: existing iptables rule

    '-A FORWARD -j REJECT --reject-with icmp-host-prohibited'

will block name resolution via weaveDNS - please reconfigure your firewall.

# 解決辦法:關閉防火牆
[root@localhost ~]# systemctl stop firewalld.service # 停止firewall
[root@localhost ~]# systemctl disable firewalld.service # 禁止firewall開機啓動
# 若出現以下錯誤
[root@localhost ~]# weave launch
cannot locate running docker daemon
Warning: unable to detect proxy TLS configuration. To enable TLS, launch the proxy with 'weave launch' and supply TLS options. To suppress this warning, supply the '--no-detect-tls' option.
The weave container has died. Consult the container logs for further details.

# 解決辦法:啓動時增加 --no-detect-tls 選項
[root@localhost ~]# weave launch --no-detect-tls

host clock skew of -6124s exceeds 900s limit,時鐘偏差超過限制的解決方案:  

# 若出現以下錯誤
[root@localhost ~]# weave status connections
-> 172.16.250.234:6783   failed      host clock skew of -6124s exceeds 900s limit, retry: 2019-12-09 08:26:45.12313254 +0000 UTC m=+451.600743522

# 解決辦法:重新設置時間和時區
[root@localhost ~]# tzselect # 選擇時區
[root@localhost ~]# date -s "20191209 16:31:01" # 設置時間

容器連通性檢查

同一宿主機下容器的連通性

在同一太宿主機上的容器默認情況下就可以相互連接,所以在此需要先將 Docker的 icc 選項設置爲 false,避免干擾。

在Host2(172.16.250.239)上創建兩個容器,查看其連通性。

# 啓動容器
[root@localhost ~]# docker run -itd --name container1 centos:7.6.1810
61cd0cf587da7b328ee552531bde1a4fd044d48dcfb2091293430c5414bceb23
[root@localhost ~]# docker run -itd --name container2 centos:7.6.1810
5ca25464cb372230eb0e551eeda54c1553f9e90bf1abac12fb9fcaa3015e4e09
[root@localhost ~]# docker exec -it container1 /bin/bash
# 附加到 container1
[root@localhost ~]# docker exec -it container1 /bin/bash
# 查看 container1 的ip地址
[root@61cd0cf587da /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 3947  bytes 13317093 (12.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3801  bytes 301864 (294.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

# 附加到 container2
[root@localhost ~]# docker exec -it container2 /bin/bash
# 查看是否能夠 ping 通 container1
[root@5ca25464cb37 /]# ping 172.16.0.2
PING 172.16.0.2 (172.16.0.2) 56(84) bytes of data.
64 bytes from 172.16.0.2: icmp_seq=1 ttl=126 time=0.811 ms
64 bytes from 172.16.0.2: icmp_seq=2 ttl=126 time=0.777 ms
64 bytes from 172.16.0.2: icmp_seq=3 ttl=126 time=0.836 ms
^C
--- 172.16.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.777/0.808/0.836/0.024 ms

不同宿主機下容器的連通性 

在Host1(172.16.250.234)上創建一個容器,查看其是否能夠ping 通在 Host2(172.16.250.239)中創建的 container1(172.17.0.2)。

[root@localhost ~]# docker run -itd --name container3 centos:7.6.1810
5fa9f0dc34272c7dada392e5c0e74a527439f0ea71dada0b464c9dfe856ced72
[root@localhost ~]# docker exec -it container3 /bin/bash
# 附加到 container3
[root@localhost ~]# docker exec -it container3 /bin/bash
# 查看是否能夠 ping 同 container1
[root@5fa9f0dc3427 /]# ping 172.16.0.2
PING 172.16.0.2 (172.16.0.2) 56(84) bytes of data.
64 bytes from 172.16.0.2: icmp_seq=1 ttl=126 time=0.634 ms
64 bytes from 172.16.0.2: icmp_seq=2 ttl=126 time=0.735 ms
64 bytes from 172.16.0.2: icmp_seq=3 ttl=126 time=0.749 ms
64 bytes from 172.16.0.2: icmp_seq=4 ttl=126 time=0.730 ms
^C
--- 172.16.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.634/0.712/0.749/0.045 ms 

由此可見,不同宿主機下的各容器也能正常相互訪問。

Open-vSwitch是什麼?

Open vSwitch 是一個高質量的、多層虛擬交換機,使用開源 Apache 2.0 許可協議,由 Nicira Networks 開發,主要實現代碼爲可移植的C代碼。它的目的是讓大規模網絡自動化可以通過編程擴展,同時仍然支持標準的管理接口和協議(例如:NetFlow,sFlow,SPAN,RSPAN,CLI,LACP,802.lag)。

什麼是GRE隧道?

GRE (Generic Routing Encapsulation,通用路由協議封裝),是一種通過使用互聯網絡的基礎設施在網絡之間傳遞數據的方式。使用隧道傳遞的數據(或負載)可以是不同協議的數據幀或包。隧道協議將其他協議的數據幀或包重新封裝然後通過隧道發送。新的幀頭提供路由信息,以便通過互聯網傳遞被封裝的負載數據。

使用Open-vSwitch實現跨主機容器互聯

使用 Open vSwitch 實現跨主機容器互聯的網絡拓撲圖如下:

由於系統資源有限,使用Open-vSwitch實現跨主機容器互聯的具體過程就不再具體示例了。

發佈了247 篇原創文章 · 獲贊 512 · 訪問量 1255萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章