Docker容器跨主機通訊之:直接路由方式

Desktop



概述

就目前Docker自身默認的網絡來講,單臺主機上的不一樣Docker容器能夠藉助docker0網橋直接通訊,這沒毛病,而不一樣主機上的Docker容器之間只能經過在主機上用映射端口的方法來進行通訊,有時這種方式會很不方便,甚至達不到咱們的要求,所以位於不一樣物理機上的Docker容器之間直接使用自己的IP地址進行通訊頗有必要。再者說,若是將Docker容器起在不一樣的物理主機上,咱們不可避免的會遭遇到Docker容器的跨主機通訊問題。本文就來嘗試一下。docker

注: 本文首發於 My 公衆號 CodeSheep ,可 長按掃描 下面的 當心心 來訂閱 ↓ ↓ ↓

CodeSheep · 程序羊



情景構造

以下圖所示,咱們有兩個物理主機1和主機2,咱們在各自宿主機上啓動一個centos容器,啓動成功以後,兩個容器分別運行在兩個宿主機之上,默認的IP地址分配如圖所示,這也是Docker自身默認的網絡。編程

兩臺主機上的容器如何通訊?

此時兩臺主機上的Docker容器如何直接經過IP地址進行通訊?json

一種直接想到的方案即是經過分別在各自主機中 添加路由 來實現兩個centos容器之間的直接通訊。咱們來試試吧c#



方案原理分析

因爲使用容器的IP進行路由,就須要避免不一樣主機上的容器使用了相同的IP,爲此咱們應該爲不一樣的主機分配不一樣的子網來保證。因而咱們構造一下兩個容器之間通訊的路由方案,以下圖所示。centos

容器間通訊

各項配置以下:bash

  • 主機1的IP地址爲:192.168.145.128
  • 主機2的IP地址爲:192.168.145.129
  • 爲主機1上的Docker容器分配的子網:172.17.1.0/24
  • 爲主機2上的Docker容器分配的子網:172.17.2.0/24

這樣配置以後,兩個主機上的Docker容器就確定不會使用相同的IP地址從而避免了IP衝突。服務器

咱們接下來 定義兩條路由規則 便可:網絡

  • 全部目的地址爲172.17.1.0/24的包都被轉發到主機1上
  • 全部目的地址爲172.17.2.0/24的包都被轉發到主機2上

綜上所述,數據包在兩個容器間的傳遞過程以下:框架

  • 從container1 發往 container2 的數據包,首先發往container1的「網關」docker0,而後經過查找主機1的路由得知須要將數據包發給主機2,數據包到達主機2後再轉發給主機2的docker0,最後由其將數據包轉到container2中;反向原理相同,再也不贅述。

咱們內心方案想的是這樣,接下來實踐一下看看是否可行。微服務



實際試驗

  • 0x01. 分別對主機1和主機2上的docker0進行配置

編輯主機1上的 /etc/docker/daemon.json 文件,添加內容:"bip" : "ip/netmask"

{ "bip", "172.17.1.252/24" }

編輯主機2上的 /etc/docker/daemon.json 文件,添加內容:"bip" : "ip/netmask"

{ "bip", "172.17.2.252/24" }
  • 0x02. 重啓docker服務

主機1和主機2上均執行以下命令重啓docker服務以使修改後的docker0網段生效

systemctl restart docker
  • 0x03. 添加路由規則

主機1上添加路由規則以下:

route add -net 172.17.2.0 netmask 255.255.255.0 gw 192.168.145.129

主機2上添加路由規則以下:

route add -net 172.17.1.0 netmask 255.255.255.0 gw 192.168.145.128
  • 0x04. 配置iptables規則

主機1上添加以下規則:

iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -s 172.17.1.0/24 ! -d 172.17.0.0/16 -j MASQUERADE

主機2上添加以下規則:

iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -s 172.17.2.0/24 ! -d 172.17.0.0/16 -j MASQUERADE
  • 0x05. 啓動容器

主機1上啓動centos容器:

docker run -it --name container1 centos /bin/bash

主機2上啓動centos容器:

docker run -it --name container2 centos /bin/bash
  • 0x06. 容器間直接通訊

好了,如今兩容器能夠互ping了

container1 ping container2

container2 ping container1



後記

本文探討了局域網中不一樣宿主機間Docker容器直接通訊的一種可能方案。固然如今實現跨主機容器間通訊的現成方案也不少,典型的好比flannel這種,個人 我的私有云 也用的是這種方案。

做者更多的SpringBt實踐文章在此:


若是有興趣,也能夠抽點時間看看做者一些關於容器化、微服務化方面的文章:


CodeSheep · 程序羊

相關文章
相關標籤/搜索