當前位置:
首頁 > 知識 > Docker Machine 詳解

Docker Machine 詳解

筆者在《Docker Machine 簡介》一文中簡單介紹了 Docker Machine 及其基本用法,但是忽略的細節實在是太多了。比如 Docker 與 Docker Machine 的區別?又如當我們執行 docker-machine create 命令時,Docker Machine 都做了哪些重要的事情使得我們可以遠程操作 Docker daemon?這樣的遠程操作安全嗎?本文將試圖解讀這些問題。註:本文的演示環境為 Ubuntu16.04。


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 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 驗證功能。關於 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 驗證的標記,依此實現安全的通信。


總結

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

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 科技優家 的精彩文章:

bencode對象編碼實現
虛擬機是如何載入類的
WPF:實現 ScrollViewer 滾動到指定控制項處
ElasticSearch裡面的路由功能介紹

TAG:科技優家 |

您可能感興趣

Windows Install Docker
MacOS Install Docker
centos7 install docker-ce
Docker 小記—Compose&Swarm
Windows Docker 安裝
Docker 安裝 Tomcat
docker-compose ,docker-stack
Scrapy對接Docker
Docker 安裝 Apache
大神解說在unbuntu下Docker安裝oracle和mysql
Docker 安裝 Python
通過 Docker 實現在 Linux 容器中運行 Microsoft SQL Server 資料庫
Docker編程 Hello World
在docker for win中使用portainer管理容器
通過 Laradock學Docker——配置篇
Docker 創始人 Solomon Hykes 宣布從 Docker 離職
Docker將與MuleSoft展開合作,Salesforce坐收漁利
Docker教程:Docker Compose入門
使用gradle生成Spring Boot應用的Docker Image
如何 Docker 化 Python Django 應用程序