轉載請注明出處:點我
由於Docker自身的網絡的原因,想要在多主機間的容器之間進行通信是比較麻煩的事情。可以利用Ambassador容器來實現這一功能。
基本原理:
利用Ambassador來實現主機間容器進行通信時,需要在兩台需要通信的容器的主機上都啟動Ambassador容器。由Ambassador容器提供數據轉發服務。
當客戶端主機上的容器client_container想要同服務器端主機上的容器server_container通信時,client_container容器直接訪問同一台主機上運行的client_ambassador容器,請求會被client_ambassador容器轉發出去,達到服務端主機。服務端Ambassador容器server_ambassador監聽在對應的端口,收到請求后再轉發給服務器容器server_container。
下面是一個示例:
主機A為服務器端,上面運行了一個運行Flask程序的容器server_container,主機B為客戶端,上面運行一個容器client_container來訪問主機A上面的Flask程序。先來看看主機A上面的啟動server_container的image的Dockerfile文件:
1 FROM ubuntu 2 MAINTAINER rio_2607 j_huang@126.com 3 4 RUN apt-get update 5 RUN apt-get install -y python-pip 6 RUN pip install flask 7 8 ADD app.py /app 9 WORKDIR /app 10 EXPOSE 5002 11 CMD ["python'","app.py"]
從上面的代碼可以看到,我們把app.py文件復制到了/app目錄下,在把工作目錄切換到了/app目錄下面,之后開放了5002端口,這一點很重要,開放的端口會影響后面的命令,然后在容器啟動的時候會執行app.py文件。現在來看下app.py文件中的代碼:
1 from flask import Flask 2 3 app = Flask(__name__) 4 5 @app.route('/') 6 def hello(): 7 return "Hello World" 8 9 if "__main__" == __name__: 10 app.run(host="0.0.0.0",port=5002,debug=True)
代碼很簡單,不用解釋。啟動容器server_container:
sudo docker run -d --name flask rio_2607/flask
現在在主機A上面啟動ambassador容器,並把flask容器link到這個ambassador容器上面去:
sudo docker run -d --name server_ambassador --link flask:flask_f -p 5002:5002 svendowideit/ambassador
上面命令中可以看到flask link后的別名是flask_f,這一點很重要,因為這會影響到server_ambassador的環境變量名字,也就會影響之后的命令。現在進入這個server_ambassador里面看下環境變量:
sudo docker exec -it server_ambassador /bin/sh
進入之后使用env命令可以查看到下面的環境變量當前容器的環境變量:
可以看到環境變量軍事以FLASK_F開頭的,我們接下來會使用FLASK_F_PORT_5002_TCP這個環境變量。
接下來我們在主機B上面啟動ambassador容器,命令如下:
sudo docker run -d --name client_ambassador --expose 5002 -e FLASK_F_PORT_5002_TCP=tcp://10.31.181.84:5002 svendowideit/ambassador
在上面這條命令中,我們傳入了FLASK_F_PORT_TCP這個環境變量,這個變量就是之前使用env命令看到的,這里要把IP地址替換成運行改容器的主機,也就是主機A的IP地址。
接下來我們要啟動一個容器client_container來訪問主機A上面的Flask程序。這里我們僅僅是啟動一個ubuntu容器,安裝curl程序,啟動容器時,要把之前啟動的client_ambassador容器掛接過來。命令如下:
sudo docker run -it --rm --link client_ambassador:am ubuntu /bin/bash
上面的命令中,我們把ambassador掛接到client_container容器中,別名為am。現在,我們已經進入到了這個client_container中,安裝curl
apt-get update
apt-get install -y curl
安裝完curl之后,使用curl來訪問主機A上面的Flask程序,這是通過使用別名am來實現的
curl am:5002
命令執行完成之后,可以看到結果如下:
可以看到curl命令返回了Hello World,表明主機B上面的client_container容器成功的訪問到了主機A上面的flask容器。
注意:在使用Ambassador容器實現容器跨主機通信的時候,Ambassador暴露出的端口最好要跟服務器端容器(本文中是flask容器,暴露出5002端口)暴露一致。我在實驗的過程中把--expose 5002端口改成了其他的端口,curl命令連接失敗,跨主機通信失敗,原因暫時還沒有查明。
使用Ambassador只能實現一對多的容器跨主機通信,也就是說一台機器A充當服務器,其他的機器統一訪問機器A,無法實現多對多的通信。
集群的話可以使用Docker公司的swarm來進行管理,接下來准備研究下swarm。