Docker Machine 詳解

Docker 與 Docker Machine 的區別

Docker 是一個 Client-Server 架構的應用,人家是有官稱的:Docker Engine。Docker 只是你們對 Docker Engine 的暱稱,固然 Docker 還有其餘的意思,好比一家公司的名稱。簡單起見,本文中的 Docker 等同於 Docker Engine。docker

提到 Docker 咱們必需要知道它包含了三部份內容:安全

  1. Docker daemon網絡

  2. 一套與 Docker daemon 交互的 REST API架構

  3. 一個命令行客戶端socket

下圖很清晰的展現了它們之間的關係:tcp

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

Docker daemon socket

既然 Docker 客戶端要和 Docker daemon 經過 REST API 通訊,那就讓咱們看看它們能夠採用的方法有哪些:工具

  1. Unix socket加密

  2. Systemd socket activationspa

  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 驗證功能。關於 TLS,筆者在《局域網內部署 Docker Registry》一文中略有涉及,當時是手動配置的證書,感興趣的朋友能夠參考一下。

如今讓咱們回到安裝了 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 驗證的標記,依此實現安全的通訊。

相關文章
相關標籤/搜索