Docker Machine深入詳解

Docker 與 Docker Machine 的區別

Docker 是一個 Client-Server 架構的應用,人傢是有官稱的:Docker Engine。Docker 隻是大傢對 Docker Engine 的昵稱,當然 Docker 還有其他的意思,比如一傢公司的名稱。簡單起見,本文中的 Docker 等同於 Docker Engine。

提到 Docker 我們必須要知道它包含瞭三部分內容:

  1. Docker daemon
  2. 一套與 Docker daemon 交互的 REST API
  3. 一個命令行客戶端

下圖很清晰的展示瞭它們之間的關系:

Docker Machine 則是一個安裝和管理 Docker 的工具。它有自己的命令行工具:docker-machine。

Docker daemon socket

既然 Docker 客戶端要和 Docker daemon 通過 REST API 通信,那就讓我們看看它們可以采用的方法有哪些:

  1. Unix socket
  2. Systemd socket activation
  3. Tcp

我們可以簡單的把 1 和 2 理解成一種方式,就是同一臺主機上的進程間通信。至於 3 則很好理解:通過 tcp 協議進行跨網絡的通信。

既然 1 和 2 用於同一臺機器上的進程間通信,那麼我們可以猜想:安裝在同一主機上的 Docker 客戶端和 Docker daemon 就是通過這種方式來通信的。事實也正是如此,我們可以查看安裝 Docker 時默認添加的 Docker daemon 啟動配置,打開文件 /etc/systemd/system/multi-user.target.wants/docker.service:

圖中的 -H 用來指定 Docker Daemon 監聽的 socket,此處指定的類型為 system socket activation。使用類型 1 和 2 進行通信需要進程具有 root 權限。這也是 Docker 安裝過程中會自動創建一個具有 root 權限的用戶和用戶組的主要原因。新創建的用戶和用戶組名稱為 docker,建議大傢把需要操作 Docker 的用戶都加入到這個組中,否則當你執行命令時就會碰到下圖顯示的問題:

我們還可以同時指定多個 -H 參數讓 Docker daemon 同時監聽不同的 socket 類型。比如要添加對 TCP 端口 2376 的監聽就可以使用下面的命令行參數:

$ sudo dockerd -H fd:// -H tcp://0.0.0.0:2376

運行上面的命令,然後查看本機監聽的端口:

此時我們就可以從遠程主機上的 Docker 客戶端訪問這部主機的 2376 端口瞭。

DOCKER_HOST 環境變量

Docker 客戶端默認的配置是訪問本機的 Docker daemon,當你指定瞭 DOCKER_HOST 變量後,Docker 客戶端會訪問這個變量中指定的 Docker daemon。讓我們回顧一下 docker-machine env 命令:

執行的 $ eval $(docker-machine env krdevdb) 命令就是在設置 DOCKER_HOST 環境變量。

解決安全問題

我們的 Docker daemon 監聽瞭 tcp 端口,糟糕的是此時我們沒有做任何的保護措施。因此任何 Docker 客戶端都可以通過 tcp 端口與我們的 Docker daemon 交互,這顯然是無法接受的。解決方案是同時啟用 Docker daemon 和 Docker 客戶端的 TLS 證書認證機制。這樣 Docker daemon 和 Docker 客戶端之間的通信會被加密,並且隻有安裝瞭特定證書的客戶端才能夠與對應的 Docker daemon 交互。

至此本文的鋪墊部分終於結束瞭,接下來我們將討論 Docker Machine 相關的內容。

Docker Machine create 命令

根據 Docker Machine 驅動的不同,create 命令執行的操作也不太一樣,但其中有兩步是我們在這裡比較關心的:

docker-machine 會在您指定的主機上執行下面的操作:

  1. 安裝 Docker,並進行配置。
  2. 生成證書保護 Docker 服務的安全。

配置 Docker daemon

Docker 的安裝過程並沒有什麼秘密,這裡不再贅述。我們重點關註 Docker daemon 的配置。仔細觀察我們會發現,通過 docker-machine 安裝的 Docker 在 /etc/systemd/system 目錄下多出瞭一個 Docker 相關的目錄:docker.service.d。這個目錄中隻有一個文件 10-machine.conf:

好吧,-H tcp://0.0.0.0:2376 出現在這裡並沒有讓我們太吃驚。在我們做瞭巨多的鋪墊之後,你應該覺得這是理所當然才是。–tls 開頭的幾個參數主要和證書相關,我們會在後面的安全設置中詳細的介紹它們。讓人多少有些疑惑的地方是上圖中的 /usr/bin/docker。當前最新版本的 Docker Machine 還在使用舊的方式設置 Docker daemon,希望在接下來的版本中會有所更新。

這個配置文件至關重要,因為它會覆蓋 Docker 默認安裝時的配置文件,從而以 Docker Machine 指定的方式啟動 Docker daemon。至此我們有瞭一個可以被遠程訪問的 Docker daemon。

生成證書

我們在 Docker daemon 的配置文件中看到四個以 –tls 開頭的參數,分別是 –tlsverify、–tlscacert、–tlscert和 –tlskey。其中的 –tlsverify 告訴 Docker daemon 需要通過 TLS 來驗證遠程客戶端。其它三個參數分別指定瞭一個 pem 格式文件的路徑,按照它們指定的文件路徑去查看一下:

對比一下手動安裝的 Docker,會發現 /etc/docker 目錄下並沒有這三個文件。毫無疑問它們是 Docker Machine 生成的,主要是為瞭啟用 Docker daemon 的 TLS 驗證功能。

現在讓我們回到安裝瞭 Docker Machine 的主機上。

查看 /home/nick/.docker/machines/krdevdb 目錄,發現瞭一些同名的文件(ca.pem、server-key.pem 和 server.pem),和主機 drdevdb 上的文件對比一下,發現它們是一樣的!

讓我們再來觀察一下這幅圖:

除瞭我們關註過的 DOCKER_HOST,還有另外三個環境變量。其中的 DOCKER_TLS_VERIFY 告訴 Docker 客戶端需要啟用 TLS 驗證。DOCKER_CERT_PATH 則指定瞭 TLS 驗證所依賴文件的目錄,這個目錄正是我們前面查看的 /home/nick/.docker/machines/krdevdb 目錄。

行文至此,困擾我們的安全問題終於得到瞭解釋:Docker Machine 在執行 create 命令的過程中,生成瞭一系列保證安全性的秘鑰和數字證書(*.pem)文件。這些文件在本地和遠程 Docker 主機上各存一份,本地的用於配置 Docker 客戶端,遠程主機上的用於配置 Docker daemon,讓兩邊都設置 TLS 驗證的標記,依此實現安全的通信。

總結

從本文的前一部分可以看到,Docker 其實把該提供的都提供瞭,隻是配置起來比較麻煩!但是對用戶來說,需要的總是更簡單,更容易的配置。因此從使用者的角度來看,Docker Machine 確實很酷,一個命令下去不僅能夠安裝虛機和 Docker,還完成瞭很多手動搞起來令人生畏的配置。然後帶來幾個清晰、簡單的命令。再然後,同學們就可以開心愉快的玩耍瞭!

到此這篇關於Docker Machine深入詳解的文章就介紹到這瞭,更多相關Docker Machine內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: