Docker client 與 Docker daemon

在上一篇的文章最後: Docker Certified Associate(DCA)認證考試學習-準備環境

有一段話提到: Docker client 與 Docker daemon 建立連線
那麼這句話是甚麼意思呢

從官方文檔Docker architecture中可以了解到Docker背後是client-server架構, 也就是說當我們下命令時背後會透過某種方式交由其他服務幫忙執行,而這個背後的服務就是Docker daemon
並且Docker client 與 Docker daemon 中間的連線可以透過網路來互相溝通,所以並沒有強制Docker client 與 Docker daemon需要裝在同一台機器

那麼根據以上的結論我們可以來做一些小的測試

  • 建立兩台Instance, Node1與 Node2
  • 我想在Node1下命令但背後轉交給Node2來執行

首先我們建立二台機器以下為範例

192.168.0.27 ssh ip172-18-0-41-cfjp9t60qau000e82i8g@direct.labs.play-with-docker.com
192.168.0.28 ssh ip172-18-0-37-cfjp9t60qau000e82i8g@direct.labs.play-with-docker.com

所以最終結果我需要在192.168.0.27下命令,但背後轉交給192.168.0.28運行

在開始之前先測試二台是否能透過ssh來連線,這部分PWD已經幫我們準備好命令了我們直接複製後運行即可

[node1] (local) root@192.168.0.27 ~
$ ssh ip172-18-0-55-cfjosl60qau000e82hkg@direct.labs.play-with-docker.com
The authenticity of host 'direct.labs.play-with-docker.com (40.121.45.0)' can't be established.
RSA key fingerprint is SHA256:vCbhEjmYQhtNzuuuh7TmGAPfe9T+JdGnGaVquQJUphY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'direct.labs.play-with-docker.com' (RSA) to the list of known hosts.
Connecting to 52.188.144.191:8022
###############################################################
#                          WARNING!!!!                        #
# This is a sandbox environment. Using personal credentials   #
# is HIGHLY! discouraged. Any consequences of doing so are    #
# completely the user's responsibilites.                      #
#                                                             #
# The PWD team.                                               #
###############################################################
[node2] (local) root@192.168.0.28 ~
$ 

我們在192.168.0.27透過ssh連線192.168.0.28,第一次連線的機器會自動在~/.ssh/產生known_hosts檔案
想要手動生成可以使用工具ssh-keyscan指定要連線到的機器,兩種方法是一樣的,以下為範例

ssh-keyscan direct.labs.play-with-docker.com >> ~/.ssh/known_hosts

確定能正常連線後要記得使用exit命令返回一開始的機器
終端機會顯示現在在什麼環境之中[node1] (local) root@192.168.0.27

首先先認識幾個docker命令

docker context list   #查詢現在有哪些運行環境可以使用,預設只會有本機default環境可以使用
docker context create #建立新的運行環境,可以創建一個遠程環境多人共用一個docker daemon(背景服務)
docker context use    #使用指定的環境

那麼先在192.168.0.27運行 docker context list 執行完畢會會輸出以下資訊,目前只包含一個本機環境

NAME        DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm

接下來在192.168.0.27運行 docker context create 此命令會搭配設定endpoint,Docker才會知道要連線到哪台遠程機器,需要替換成自己的ssh網址

docker context create \
    --docker host=ssh://ip172-18-0-37-cfjp9t60qau000e82i8g@direct.labs.play-with-docker.com \
    --description="remote-docker-28" \
    remote-docker-28

成功建立會輸出以下提示

remote-docker-28
Successfully created context "remote-docker-28"

接下來在192.168.0.27運行 docker context list 檢查使否有新的環境可以使用

NAME               DESCRIPTION                               DOCKER ENDPOINT                                                              KUBERNETES ENDPOINT   ORCHESTRATOR
default *          Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                                                                        swarm
remote-docker-28   remote-docker-28                          ssh://ip172-18-0-120-cfj3gon91rrg00cciijg@direct.labs.play-with-docker.com                         

確實現在在清單中多了一個環境可以用,但是要注意default後面有一個星字號(*)代表現在正在使用的環境
所以雖然我們創建了一個新的環境但是還沒有切換過去之前還是會在舊的環境中運行
切換的方式也很簡單只要指定環境的name就可以了

docker context use remote-docker-28

成功切換後會輸出以下提示

remote-docker-28
Current context is now "remote-docker-28"

最後再192.168.0.27檢查一次 docker context list 是否有切換成功

NAME               DESCRIPTION                               DOCKER ENDPOINT                                                              KUBERNETES ENDPOINT   ORCHESTRATOR
default *          Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                                                                        swarm
remote-docker-28   remote-docker-28                          ssh://ip172-18-0-120-cfj3gon91rrg00cciijg@direct.labs.play-with-docker.com                         

奇怪,星號還是在default上,看來沒有切換過去
稍微翻了一下文檔docker context use 發現有提到環境變數DOCKER_HOST, DOCKER_CONTEXT如果有設定的話會直接讀取值,所以會忽略docker context use

那麼檢查一下192.168.0.27是否有DOCKER的環境變數

$ env | grep DOCKER

DOCKER_VERSION=20.10.17
DOCKER_TLSENABLE=false
DOCKER_BUILDX_VERSION=0.8.2
DOCKER_TLS_CERTDIR=
DOCKER_CLI_EXPERIMENTAL=enabled
DOCKER_COMPOSE_VERSION=2.6.1
DOCKER_HOST=

確實有設定DOCKER_HOST參數,那麼直接把他移除,再切換一次環境看看

unset DOCKER_HOST
docker context use remote-docker-28
docker context ls

NAME                 DESCRIPTION                               DOCKER ENDPOINT                                                              KUBERNETES ENDPOINT   ORCHESTRATOR
default              Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                                                                        swarm
remote-docker-28 *   remote-docker-28                          ssh://ip172-18-0-120-cfj3gon91rrg00cciijg@direct.labs.play-with-docker.com                         

終於切換過去了,那麼再來下幾個命令實際測試看看,看會不會照我們當初想的一樣轉交給192.168.0.28執行

docker run --name nginx28 -p 8080:80 nginx #這邊指定name參數設定容器名稱並開放8080 port
docker ps -a #列出daemon中所有執行中的容器

以上命令執行後會在192.168.0.28建立一個nginx container並且對外開放8080 port,現在我們只要連線到192.168.0.28的8080 port就可以看到nginx的預設頁面了

這邊很方便的是PWD會自動檢測開放的端口,並在頁面上顯示連結方便我們可以直接連結到頁面

如果沒有出現的話可以按下 OPEN PORT按鈕,網頁會跳出一個彈窗只要在彈窗書入8080 port也可以達到同樣的效果

DCAContext-nginx28 DCAContext-nginxdefault

Summary

今天我們學習到了如何使用docker context命令,方便我們指定運行的環境
當我們的電腦不方便安裝完整的Docker時,我們可以考慮只安裝Docker cli再搭配設定context
例如可以在雲端機器安裝Docker engine之後團隊都連線到同一台機器來共享環境。