Use A Remote Docker Host
前言
Docker 為 server-client 架構的服務,雖然通常習慣安裝在同一台機器使用,但實際上是可以從別台機器使用 docker-cli 對遠端 docker engine 進行控制。
在開發過程中,開發者通常會在自己的電腦上裝 Docker 以利驗證包裝的過程以及運行的結果。但若是同一個開發團隊每個人都在電腦中安裝的話,無形中其實造成了一些資源的浪費,像是 layer cache 不能共用使得每個開發人員電腦中可能都會有一份相同的 layer cache。
此時若是能使用同一 Docker Engine 的話,便可省下建構過程中拉取相依套件的網路用量、layer cache 的儲存空間等等。
示範環境 |
|
Docker Engine |
chi-tools |
Docker CLI |
chi-vm |
設定遠端 Docker Server
一般預設的情況下,裝好的 docker.service 可能會如下圖,只是單純的以 dockerd 運行:
此時只能夠使用 unix socket 在本機上進行呼叫。
為了要能夠透過網路來呼叫,我們需要啟用 docker 的 tcp socket。具體配置方式為透過修改 docker.service 的 ExecStart 所使用的指令。
## Modify /usr/lib/systemd/system/docker.service
[Service]
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
接著使用以下兩條指令重啟 docker.service:
sudo systemctl daemon-reload
sudo systemctl restart docker
應該就可以看到 docker.service 的運行指令變了:
設定本地端的 Docker CLI
這邊示範的是 linux 系統下的設定方式,有兩種做法可以達到這個目的。
使用環境變數 DOCKER_HOST
第一種作法是在下 docker 指令前宣告環境變數 DOCKER_HOST
:
DOCKER_HOST=tcp://chi-tools:2375 docker info
下圖為有無宣告環境變數的差異比較:
**注意上圖範例中黃色底線標註的 hostname 為 chi-vm 而非我們的 docker server 所在的 chi-tools。
可以看到給環境變數前由於主機上 docker engine 沒有運行,所以會失敗。 (紅色底線)
當給了環境變數後就會去呼叫剛剛設定的遠端 docker server。 (綠色底線)
使用 docker context
使用環境變數是很方便也很簡單的做法,但若是有多個遠端的 docker server 要操作,在管理上就有點麻煩了。
Docker CLI 本身有提供管理多個連線的工具,即 docker context
。這邊就不詳細介紹了,有興趣的話可以用以下指令去看使用方式:
docker context --help
使用 docker context
的方法很簡單,使用以下指令便可新增一個名為 chi-tools-tcp 的 context 並完成相關連線設定:
docker context create chi-tools-tcp \
--docker host=tcp://chi-tools:2375 \
--description "Connect to chi-tools through tcp"
接著便可以用以下指令看到剛剛新增的 context:
docker context ls
* 表示當前正在使用的,比如說途中可看出目前使用的 default 其 Docker Endpoint 為本機上面的 docker socket。
最後以下指令切換 context 成剛剛設定好的 chi-tools-tcp:
docker context use chi-tools-tcp
注意事項
雖然把 server 跟 client 分開讓團隊共用有諸多好處,但使用這可能會因為已經習慣使用單機架構而有一些地方覺得有些奇怪。其中最明顯的就是 docker run
跑起來的容器並非位於自己的電腦上,而是在 server 端。這會導致當你需要把外部的檔案掛載進容器時,docker 會在遠端的 server 路徑下找檔案而非自己電腦的路徑。
要解決這個問題你可以每次要跑容器時都先把檔案 copy 到 docker server 上,但這是個非常惱人的臨時作法。比較好的方式是透過 nfs 或 nas 這類的服務,讓 client 端與 server 端能共用一個檔案空間,這麼一來在檔案傳輸以及掛載路徑的選擇都可以固定下來,多少可以節省一些時間~