使用 Network 連結 container

Volume 一樣,Network 也是 Docker 的元件。正如其名,它是在管理網路相關設定的指令。

有了 Docker 後,開 server 變得容易許多。但實務上的網路架構,通常是多層式的,如三層式架構(Three-Tier)需要 Application Server 與 RDBMS 兩種 server 連結起來,才能提供完整的服務。

觀察 container log

在看完 docker run 的細節,與 Port forwarding 的說明後,相信大家可以理解下面的 docker run 在做什麼了:

# Terminal 1
docker run --rm -it --name web -p 8080:80 httpd

# Terminal 2
curl http://localhost:8080/

這次 docker run 指令範例是開著觀察 log,然後開另外一個視窗與 web container 互動。

通常先使用這樣的方法來測試 image 的功能,測完關閉就會自動移除。而當需要 -d 時,則會改用 docker logs 來觀察 log:

# Terminal 1 
docker run -d -it --name web -p 8080:80 httpd

# 加 -f 選項後,container log 只要有更新,畫面就會更新
docker logs -f web

# Terminal 2
curl http://localhost:8080/

這兩個小技巧都可以用來觀察 container 內部運作的狀況,可以視情況運用。

連結 container

想把 container 連結在一起有兩種做法:使用 --link 參數與使用 Network。

使用 --link 參數可以達成 container 連結的功能,指令也算直覺:

# wget 為 curl 的替代指令
docker run --rm busybox wget -q -O - http://web/

# 比較沒加 link 與有加 link 的差別
docker run --rm --link web busybox wget -q -O - http://web/

# 使用別名
docker run --rm --link web:alias busybox wget -q -O - http://alias/

這個範例先解釋指令的用法,docker run 可以在 IMAGE 的後面加上想在 image 裡執行的指令為何,如:

# BusyBox 裡面執行其他指令
docker run --rm busybox whoami
docker run --rm busybox ls
docker run --rm busybox wget -q -O - http://web/

# BusyBox 預設為執行 sh,因此下面兩個指令結果相同
docker run --rm busybox
docker run --rm busybox sh

執行 BusyBox 的 wget -q -O - http://web/web 對應的是 Apache container 的 --name web 設定。另外,必須要使用 container 內部的 port(本例是 80)呼叫。

--link 選項的用法:web:alias 左邊是 container name,右邊是別名。設定完後,webalias 都能通。

使用 Network

這是官方建議的做法

使用 Network 建立一個虛擬網路,container 在這個網路裡就可以使用 container name 或 hostname 互相連結。

# 建立 network
docker network create my-net

# Terminal 1 啟動 Apache
docker run --rm --name web -p 8080:80 --network my-net httpd

# Terminal 2 透過 BusyBox 連結 Apache
docker run --rm --network my-net busybox wget -q -O - web

--link 雖然在語意上是清楚的,但有個問題目前無解,因此還是建議大家使用 Network 就好了。

# Terminal 1 啟動 main container
docker run --rm -it --name main busybox

# Terminal 2 啟動 sub container
docker run --rm -it --name sub --link main busybox

# Terminal 2 ping main
ping main

# Terminal 1 ping sub
ping sub

從這個範例裡可以發現,它的 link 會有先後順序之分,被 link 的會不知道誰 link 他。如果想做到雙向呼叫 API 的機制的話,就會很麻煩。

指令補充說明

docker network create

建立網路設定,用法如下:

docker network create [OPTIONS] NETWORK

本範例並沒有帶任何參數,但需要了解的是下面這個:

  • -d|--driver 使用的 driver,預設 bridge,其他參數可以參考官網

docker run

選項補充:

  • --link 連結 container,參數為 container name 或 hostname,也可以設定 alias
  • --network 指定網路設定

今日自我回顧

瀏覽器連接 Apache 時,必須使用 8080 port,但進容器連結 Apache 時,則得改回使用 80 port。這是虛擬機與 Port Forwarding 的特性,必須要清楚了解,使用 Docker 或虛擬機才不會搞混目前要使用什麼連接埠。

  • 使用 --link 連結 container
  • 使用 --network 連結 container
  • 使用 volume 與擅長的 container 做連結,如 PHP + volume link MySQL