Docker篇(七): 如何實現 Docker 容器 的跨主機通訊?

大家好,我是

傑哥

之前在 Docker篇(五):容器之間該如何通訊?中,講到了執行多個容器時的網路通訊方式,但那些容器都是執行在同一臺物理機的

在實際專案中,我們往往需要部署多套軟體,比如元件需要使用

叢集化部署

,或者一個專案程式本身就依賴了很多元件,為了儲存與執行效率等方面,往往需要

跨主機部署

。那麼,

該如何實現跨主機容器之間的網路通訊呢?

哎,你想到的,

Docker

也想到啦,或者說本來就存在著一種通用的方案吧

一、理論:Docker 如何實現跨主機網路?

1、認識 Docker Overlay

Overlay 網路

是為特定目的在物理(底層)網路之上建立的邏輯網路。

Docker

可以建立容器之間的

Overlay 網路

,從而實現跨主機的容器之間的溝通

也就是說,只要幾臺物理機之間本身是可以通訊的,那麼只要在這些機器上建立好一個

Overlay 網路

把需要相互通訊的容器,直接部署在這個網路之上,最終的效果就類似於將這些容器部署在同一臺物理機一樣,進行

任意通訊

比如說我們需要實現一個

Elasticsearch

叢集,那麼我們只需要把各個節點部署在預先建立好的一個

Overlay 網路

上就可以實現通訊啦

2、稍微具體一點

你可能還會有疑惑,為什麼

Overlay 網路

就可以實現多臺物理機之間的網路互通呢?實際上它是在

Docker

叢集節點間的加入了一層虛擬網路,它有獨立的虛擬網段。

Docker

容器傳送的請求,會先發送到

虛擬子網

,再由

虛擬子網

包裝為宿主機的

真實網址

進行傳送

3、Swarm 是什麼?

而今天要介紹的

Docker Swarm

,則是

Docker Overlay

網路的一種簡易實現方式,它是

Docker

開發的容器叢集管理工具, 與

Docker API

相容性很好

並且

Linux

中安裝了

Docker

,也預設會安裝

Swarm

。因此,在這裡,我們採用

Swarm

實現 叢集間的網路通訊

接下來,讓我們透過實戰真正瞭解一下使用

Docker Swarm

如何實現Docker 容器的跨主機通訊吧

二、實戰一:實現叢集之間的通訊

還是拿那個老例子來講一下

在文章Docker篇(五):容器之間該如何通訊?中,我們分別將

Spring Boot 後端程式

druid_demo

mariadb

分別執行在不同容器中,成功實現了他們之間的通訊

那麼,接下來,我們將他們分別部署在兩臺機器上

機器配置如下:

序號節點角色ip地址容器名稱

1manager10。10。10。100druid_demo

2worker10。10。10。88mariadb

說明:使用 Swarm 建立跨主機的網路,實際上總共分為如下幾步:

manager

建立一個

Swarm

叢集

將其他叢集分別加進來

manager

建立一個

Overlay

網路

啟動各個容器時,指定這個

Overlay

網路

具體,往下看

1、在 manager 節點建立 Swarm 叢集

執行命令:

docker swarm init ——advertise-addr=10。10。10。100

效果如下:

docker swarm init ——advertise-addr=10。10。10。100[root@localhost ~]# docker swarm init ——advertise-addr=10。10。10。100Swarm initialized: current node (maw28ll7mlxuwp47z5c5vo2v1) is now a manager。 To add a worker to this swarm, run the following command: docker swarm join ——token SWMTKN-1-2bdwwlo8xvdskil05itg66l63dpi931oqnt5gvehlnf1it1auo-2uvypbiu0hpcn1e06hrhctbe8 10。10。10。100:2377 To add a manager to this swarm, run ‘docker swarm join-token manager’ and follow the instructions。

顯示了 worker節點加入到該叢集的命令,只需要執行

docker swarm join ——token SWMTKN-1-2bdwwlo8xvdskil05itg66l63dpi931oqnt5gvehlnf1it1auo-2uvypbiu0hpcn1e06hrhctbe8 10。10。10。100:2377

即可

2、在 worker 節點上執行命令,將自己加入叢集

docker swarm join ——token SWMTKN-1-2bdwwlo8xvdskil05itg66l63dpi931oqnt5gvehlnf1it1auo-2uvypbiu0hpcn1e06hrhctbe8 10。10。10。100:2377

Docker篇(七): 如何實現 Docker 容器 的跨主機通訊?

image。png

3、在 manager 節點,檢視當前網路叢集的節點情況

執行

docker node ls

Docker篇(七): 如何實現 Docker 容器 的跨主機通訊?

image。png

4、在 manager 節點,建立 overlay 網路

docker network create -d overlay ——attachable demo

說明:

——attachable

聲明當前建立的網路為:其他節點可以訪問的網路

5、在 worker 節點的網路列表,是否多了這個網路

docker network ls

說明:

正常情況,執行完第4步之後,這裡就會在原來的基礎上多一個

demo

網路

6、在 worker 節點啟動 mariadb 容器,指定該 overlay 網路

sudo docker run -itd -v /usr/local/mysqldata:/var/lib/mysql -h mariadb ——name=mariadb ——net=demo ——privileged=true mariadb:latest /sbin/init

說明:

——net=demo

:指定該叢集間的網路(overlay ):

demo

7、在 manager 節點,啟動 durid_demo 程式

接下來,在

manager

節點,啟動

Spring Boot

後端程式

druid_demo

的容器,並指定

demo

網路

docker run -it -p 8888:8080 -h druid_demo——name druid_demo ——net=demo ——privileged=true druid_demo:0。0。1-SNAPSHOT /sbin/init

此時,請求介面,驗證網路是否互通

Docker篇(七): 如何實現 Docker 容器 的跨主機通訊?

image。png

介面正常返回,說明我們已經實現了

druid_demo

應用程式容器與

mariadb

容器之間的通訊

8、退出叢集

執行

docker swarm leave

,即可實現各節點退出叢集網路的操作

那麼,現在你知道

Docker

實現跨主機通訊的步驟了

接下來,趁熱打鐵,我們再一起來進行

Elasticsearch

(後續簡稱為

ES

)叢集搭建,真正實踐一番

注意:

如果你之前沒怎麼使用過

ES

,也沒有關係,我會推出相應的文章來介紹它。在這裡,你只需要掌握

Docker

在多臺機器部署專案的方式以及實現跨主機通訊的思想,我們的目的就達到啦

三、實戰二:Elasticsearch叢集搭建

在進入叢集搭建之前,我們先來看看如何啟動一個單機

ES

1、單機方式

docker run -itd ——name elastic -v /usr/local/es/data:/var/lib/elasticsearch -v /usr/local/es/logs:/var/log/elasticsearch -p 9200:9200 -p 9300:9300 -e “discovery。type=single-node” ——restart=always elasticsearch:v7。9。1

說明:

1)

-v

:指定掛載目錄(分別將

ES

的資料目錄和日誌目錄對映到宿主機上,這樣即使容器掛掉了再重啟,日誌也不會丟失)

其中,在容器目錄的

/etc/elasticsearch/elasticsearch.yml

中分別配置了

path.data

path.logs

。分別為

/var/lib/elasticsearch/usr/local/es/logs

2)

-p

:指定對映埠(將容器中的埠對映到了宿主機上)

3)

-e

:指定配置(指定es當前是以單個節點的方式啟動)

4)

--restart=alway

:總是會自動重啟

啟動之後,登入

Es-Head

,發現可以連線上,那麼表示啟動成功

Docker篇(七): 如何實現 Docker 容器 的跨主機通訊?

image。png

單機模式很簡單,只要分別配置好掛載目錄

path.data

path.logs

,指定為單機模式啟動就好了

叢集模式相應的也不復雜,配置與單機模式基本一致。除了需要部署多臺臺物理機以外,再注意一下各節點之間的相互關聯方式就好了。而這相互關聯方式,則包括:

網路的互通

確定叢集的節點成員

2、叢集方式

我們來搭建一個叢集模式為

1 master + 3 data

節點,機器分配為:

序號節點角色ip地址

1elastic-master10。10。10。88

2elastic-data0110。10。10。76

3elastic-data0210。10。10。77

4elastic-data0310。10。10。78

1)配置叢集網路 demo

對,就是參考第一步,為三臺機器配置叢集網路

其中,網路節點角色如下:

序號節點角色ip地址

1manager10。10。10。88

2worker10。10。10。76

3worker10。10。10。77

4worker10。10。10。78

2)分別修改各節點的配置檔案 elasticsearch.yml

a. elastic-master

vi /usr/local/es/config/elastic-master/elasticsearch。yml

# ======================== Elasticsearch Configuration =========================## NOTE: Elasticsearch comes with reasonable defaults for most settings。# Before you set out to tweak and tune the configuration, make sure you# understand what are you trying to accomplish and the consequences。## The primary way of configuring a node is via this file。 This template lists# the most important settings you may want to configure for a production cluster。## Please consult the documentation for further information on configuration options:# https://www。elastic。co/guide/en/elasticsearch/reference/index。html## —————————————————— Cluster ——————————————————-## Use a descriptive name for your cluster:#cluster。name: my-application## —————————————————— Node ——————————————————## Use a descriptive name for the node:#node。name: elastic-masternode。master: truenode。data: fasle## Add custom attributes to the node:##node。attr。rack: r1## ——————————————————- Paths ——————————————————## Path to directory where to store the data (separate multiple locations by comma):#path。data: /var/lib/elasticsearch## Path to log files:#path。logs: /var/log/elasticsearch## ——————————————————- Memory ——————————————————-## Lock the memory on startup:##bootstrap。memory_lock: true## Make sure that the heap size is set to about half the memory available# on the system and that the owner of the process is allowed to use this# limit。## Elasticsearch performs poorly when the system is swapping the memory。## —————————————————— Network ——————————————————-## Set the bind address to a specific IP (IPv4 or IPv6):#network。host: 0。0。0。0## Set a custom port for HTTP:##http。port: 9200## For more information, consult the network module documentation。## ————————————————- Discovery ——————————————————## Pass an initial list of hosts to perform discovery when this node is started:# The default list of hosts is [“127。0。0。1”, “[::1]”]#discovery。seed_hosts: [“elastic-master”, “elastic-data01”,“elastic-data02”,“elastic-data03”]## Bootstrap the cluster using an initial set of master-eligible nodes:#cluster。initial_master_nodes: [“elastic-master”]## For more information, consult the discovery and cluster formation module documentation。## —————————————————— Gateway ——————————————————-## Block initial recovery after a full cluster restart until N nodes are started:##gateway。recover_after_nodes: 3## For more information, consult the gateway module documentation。## —————————————————— Various ——————————————————-## Require explicit names when deleting indices:##action。destructive_requihttp。cors。enabled: truehttp。cors。allow-origin: “*”

說明:

cluster.name

my-application

#叢集名稱,各個節點保持一致即可

node.name

elastic-master

#節點名稱,各個節點必須獨一無二

node.master

demo

#是master節點

node.data

: demo #不是data節點

path.data

/var/lib/elasticsearch

#data儲存目錄(無特殊需求,直接使用預設的即可)

path.logs

/var/log/elasticsearch

#日誌儲存目錄(無特殊需求,直接使用預設的即可)

discovery.seed_hosts

["elastic-master", "elastic-data01","elastic-data02","elastic-data03"]

#可發現的節點(配置四個節點的主機名稱或者ip即可,docker部署,建議直接配置主機名稱)

cluster.initial_master_nodes

: [“elastic-master”] #初始化叢集節點,直接配置master節點的主機名即可

b.elastic-data01

vi /usr/local/es/config/elastic-data01/elasticsearch。yml

# ======================== Elasticsearch Configuration =========================## NOTE: Elasticsearch comes with reasonable defaults for most settings。# Before you set out to tweak and tune the configuration, make sure you# understand what are you trying to accomplish and the consequences。## The primary way of configuring a node is via this file。 This template lists# the most important settings you may want to configure for a production cluster。## Please consult the documentation for further information on configuration options:# https://www。elastic。co/guide/en/elasticsearch/reference/index。html## —————————————————— Cluster ——————————————————-## Use a descriptive name for your cluster:#cluster。name: my-application## —————————————————— Node ——————————————————## Use a descriptive name for the node:#node。name: elastic-data01node。master: falsenode。data: true## Add custom attributes to the node:##node。attr。rack: r1## ——————————————————- Paths ——————————————————## Path to directory where to store the data (separate multiple locations by comma):#path。data: /var/lib/elasticsearch## Path to log files:#path。logs: /var/log/elasticsearch## ——————————————————- Memory ——————————————————-## Lock the memory on startup:##bootstrap。memory_lock: true## Make sure that the heap size is set to about half the memory available# on the system and that the owner of the process is allowed to use this# limit。## Elasticsearch performs poorly when the system is swapping the memory。## —————————————————— Network ——————————————————-## Set the bind address to a specific IP (IPv4 or IPv6):#network。host: 0。0。0。0## Set a custom port for HTTP:##http。port: 9200## For more information, consult the network module documentation。## ————————————————- Discovery ——————————————————## Pass an initial list of hosts to perform discovery when this node is started:# The default list of hosts is [“127。0。0。1”, “[::1]”]#discovery。seed_hosts: [“elastic-master”, “elastic-data01”,“elastic-data02”,“elastic-data03”]## Bootstrap the cluster using an initial set of master-eligible nodes:#cluster。initial_master_nodes: [“elastic-master”]## For more information, consult the discovery and cluster formation module documentation。## —————————————————— Gateway ——————————————————-## Block initial recovery after a full cluster restart until N nodes are started:##gateway。recover_after_nodes: 3## For more information, consult the gateway module documentation。## —————————————————— Various ——————————————————-## Require explicit names when deleting indices:##action。destructive_requihttp。cors。enabled: truehttp。cors。allow-origin: “*”

說明:

a.

elastic-data01

的配置檔案,與

elastic-master

的配置檔案中,只有以下三項內容不同,其餘均相同

node.name: elastic-data01

#節點名稱,各個節點必須獨一無二

node.master: false

#不是master節點

node.data: true

#是data節點

b.

elastic-data02

elastic-data03

的配置,與

elastic-data01

的配置,除了

node.name

的值不一致以外,其餘均相同

3)啟動

分別在各個主機上,執行

docker

啟動命令,進行各個節點的啟動

docker run -itd ——name elastic-master -h elastic-master ——net=demo -v /usr/local/es/data:/var/lib/elasticsearch -v /usr/local/es/logs:/var/log/elasticsearch -v /usr/local/es/plugins:/usr/share/elasticsearch/plugins -v /usr/local/es/config/elastic-master/elasticsearch。yml:/etc/elasticsearch/elasticsearch。yml:ro -p 9200:9200 -p 9300:9300 -e cluster。initial_master_nodes=elastic-master ——restart=always elasticsearch:v7。9。1 /sbin/init

docker run -itd ——name elastic-data01 -h elastic-data01 ——net=demo -v /usr/local/es/data:/var/lib/elasticsearch -v /usr/local/es/logs:/var/log/elasticsearch -v /usr/local/es/plugins:/usr/share/elasticsearch/plugins -v /usr/local/es/config/elastic-data01/elasticsearch。yml:/etc/elasticsearch/elasticsearch。yml:ro -p 9200:9200 -p 9300:9300 -e cluster。initial_master_nodes=elastic-master ——restart=always elasticsearch:v7。9。1 /sbin/init

docker run -itd ——name elastic-data02 -h elastic-data02 ——net=demo -v /usr/local/es/data:/var/lib/elasticsearch -v /usr/local/es/logs:/var/log/elasticsearch -v /usr/local/es/plugins:/usr/share/elasticsearch/plugins -v /usr/local/es/config/elastic-data02/elasticsearch。yml:/etc/elasticsearch/elasticsearch。yml:ro -p 9200:9200 -p 9300:9300 -e cluster。initial_master_nodes=elastic-master ——restart=always elasticsearch:v7。9。1 /sbin/init

docker run -itd ——name elastic-data03 -h elastic-data03 ——net=demo -v /usr/local/es/data:/var/lib/elasticsearch -v /usr/local/es/logs:/var/log/elasticsearch -v /usr/local/es/plugins:/usr/share/elasticsearch/plugins -v /usr/local/es/config/elastic-data03/elasticsearch。yml:/etc/elasticsearch/elasticsearch。yml:ro -p 9200:9200 -p 9300:9300 -e cluster。initial_master_nodes=elastic-master ——restart=always relasticsearch:v7。9。1 /sbin/init

4)驗證

請求地址:

http://10。10。10。88:9200/_cat/nodes

檢視節點列表

Docker篇(七): 如何實現 Docker 容器 的跨主機通訊?

image。png

可以看到,叢集中,如期展示了

4

個節點,其中

1

master

節點和

3

data

節點(帶 * 號的為

master

節點)

叢集成功搭建完畢!可喜可賀!

5)專案中整合 ES 配置

經測試,只需要配置一個

master

節點的地址即可

spring。elasticsearch。rest。uris=http://10。10。10。88:9200

注:這裡只是說明了如何搭建一個

ES

叢集,實現叢集間網路通訊的方式。後面會專門有文章,介紹

ES

的理論知識,與具體實戰知識,敬請期待

四、總結

好了,總得來說,

Docker

是透過搭建

Overlay

網橋,然後把各個主機的容器都統一放在這個網橋上就實現了

Docker

容器的跨主機通訊

恭喜你又掌握了一個新技能。當然,如果想要真正掌握的話,也建議大家真正實戰一次,畢竟實戰與理解是不同階段,對於知識的掌握程度也是不同級別的哦

嗯,就這樣。每天學習一點,時間會見證你的強大~