2018年5月23日 星期三

Docker container 互相連接 (link, network)


Container如何互相溝通呢?


Container建立後使用者只要未指定nework都是預設 bridge網路,彼此在同個網段
可透過Container的IP位址去調用Container內的服務
假設有兩個Container, c1與c2,ip位址個別為172.17.0.10與172.17.0.11
c1若要調用c2的api(假設80Port),則透過http://172.17.0.11/api/resource?user=1

就算我知道了所有Container的ip address,那麼ip address不會變動嗎?
如果把image交付給別人,且另外在新的docker環境上運行,ip address的豈不是一定要重新設定

解決辦法

透過link或network讓container可使用container name呼叫對方的服務

實驗步驟

步驟1:建立兩個container並互相PING對方IP/Container name已檢測網路是否互通
步驟2:Docker run時透過參數--link連接另一個container
步驟3:設定container network,讓Docker run時就綁定network,即運行中的container綁定network

1.建立數個container


建立第一個container
sudo docker run -itd --name c1 sfoubert/iputils

建立第二個container
sudo docker run -itd --name c2 sfoubert/iputils

查看container
sudo docker ps

結果:
CONTAINER ID  
IMAGE
COMMAND
CREATED 
STATUS
PORTS
NAMES
5f138cd86469       
sfoubert/iputils 
"ping 127.0.0.1" 
 10 seconds ago
Up 9 seconds 

c2

sfoubert/iputils 
"ping 127.0.0.1" 
 10 seconds ago
Up 9 seconds 

c1

進入c1 container再透過ping指令 檢查是否可互通
sudo docker exec -it c1 bash

ping c2 的IP位置
root@f258c58882b2:/# ping 172.17.0.11
PING 172.17.0.11 (172.17.0.11) 56(84) bytes of data.
64 bytes from 172.17.0.11: icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from 172.17.0.11: icmp_seq=2 ttl=64 time=0.071 ms


c1 Container內執行ping c2 container name
root@f258c58882b2:/# ping c2
ping: unknown host c2

雖然可透過private IP 檢視兩個容器網路互通,但是如果是服務(API)要互相調用,若使用private IP呼叫雖然是沒問題
但是,若private IP改變呢? Hard Code IP Address似乎不是很好的做法

2.Link 目標 Container


先把原先的c1, c2 Container移除再重新建立
sudo docker run -itd --name c1 sfoubert/iputils

c2 Container 透過link連接c1 Container
sudo docker run -itd --name c2 --link c1 sfoubert/iputils

進入c1 container再透過ping指令 檢查是否可互通

sudo docker exec -it c1 bash

ping c2 的IP位置
root@30d6f21c774b:/# ping c2
ping: unknown host c2



進入c2 container再透過ping指令 檢查是否可互通

sudo docker exec -it c2 bash

ping c1 的IP位置

root@be813b7e517f:/# ping c1
PING c1 (172.17.0.10) 56(84) bytes of data.
64 bytes from c1 (172.17.0.10): icmp_seq=1 ttl=64 time=0.138 ms
64 bytes from c1 (172.17.0.10): icmp_seq=2 ttl=64 time=0.067 ms


由上述範例可看到一件事情,c1無法解析c2,是不是一開始應該執行以下指令
讓兩個container互相連結?
sudo docker run -itd --name c1 --link c2 sfoubert/iputils
sudo docker run -itd --name c2 --link c1 sfoubert/iputils

很遺憾這樣做會出現以下訊息
docker: Error response from daemon: could not get container for c2: No such container: c2.
See 'docker run --help'.

可以看出link的目標必須是已運行的container,那這樣link參數又有何用呢?

適用情境:
有個兩個Container,c1是Database,不會有主動聯外的需求,c2是tomcat,需要連接Database
上述情境符合link的使用

sudo docker run -itd --name c1  -p 3306:3306 -e MYSQL_ROOT_PASSWORD=yourpassword  -e MYSQL_ROOT_HOST=%  mysql/mysql-server

sudo docker run -itd --name c2 -p 8080:8080 --link c1 tomcat:8.0-jre8


除了link對象必須是已運行的container外,若自身要再新增多的link對象則必須重新run,
諸如上述問題可使用Network方式取代link

3.設定Network


先建立netwotk
docker network create --net test-network

查看network
root@pc:~$ sudo docker network ls
NETWORK ID          NAME                 DRIVER              SCOPE
8f90553e7117        bridge                   bridge                local
c303fe138a8f         host                      host                   local
b6d646370841       none                     null                    local
cac27a945c8b        test-network         bridge                local


建立container
sudo docker run --name c1 --net test-network -itd sfoubert/iputils
sudo docker run --name c2 --net test-network -itd sfoubert/iputils

如果是正在運行的container,則可加入network
sudo docker run --name c1 -itd sfoubert/iputils
sudo docker run --name c2 -itd sfoubert/iputils


進入c1 container再透過ping指令 檢查是否可互通

sudo docker exec -it c1 bash

ping c2 的IP位置
root@d1884f96ae20:/# ping c2
PING c2 (172.20.0.3) 56(84) bytes of data.
64 bytes from c2.test-network (172.20.0.3): icmp_seq=1 ttl=64 time=0.076 ms


進入c2 container再透過ping指令 檢查是否可互通

sudo docker exec -it c2 bash

ping c1 的IP位置
root@166260e4dea3:/# ping c1
PING c1 (172.20.0.2) 56(84) bytes of data.
64 bytes from c1.test-network (172.20.0.2): icmp_seq=1 ttl=64 time=0.100 ms





Tags: Docker, IFTTT-SYNC
May 23, 2018 at 05:53PM
Open in Evernote

沒有留言:

張貼留言