Docker 的核心功能在單機環境下執行良好,但實際應用中,我們需要更進階的工具來管理跨主機的容器和資料。本文將介紹 Docker 生態系中的關鍵工具,例如 Docker Machine、Docker Compose 和 Docker Swarm,並探討它們如何解決實際佈署中遇到的挑戰,例如單點故障、資料持久化和跨主機網路。我們將逐步說明如何在本地和雲端環境中使用 Docker Machine 建立和管理 Docker 主機,以及如何使用 Docker Compose 定義和執行多容器應用程式。此外,文章也涵蓋了 Docker Swarm 的基本概念,為讀者日後學習更進階的容器協調技術奠定基礎。

擴充套件 Docker 的介紹

在前面的範例中,我們啟動了兩個容器,每個容器都在我們(極為簡單)的程式碼函式庫上執行不同版本的 PHP。這雖然展示了啟動容器的簡便性,但也暴露了一些潛在的問題和單點故障。

現有的限制

首先,我們的程式碼函式庫儲存在主機的檔案系統上,這意味著我們只能在單一主機上執行容器。如果主機因任何原因宕機,會有什麼後果?

有多種方法可以解決這個問題,適用於原生的 Docker 安裝。其中一種方法是使用官方的 PHP 容器作為基礎,構建我們自己的自定義映像,以便將我們的程式碼與 PHP 一起封裝。要做到這一點,需要在 app1 目錄中新增一個名為 Dockerfile 的檔案,內容如下:

Dockerfile

FROM php:5.6-apache
MAINTAINER Russ McKendrick <russ@mckendrick.io>
ADD index.php /var/www/html/index.php

內容解密:

  1. FROM php:5.6-apache:使用官方的 PHP 5.6 Apache 映像作為基礎映像。
  2. MAINTAINER Russ McKendrick <russ@mckendrick.io>:指定維護者的資訊。
  3. ADD index.php /var/www/html/index.php:將本地的 index.php 檔案新增到容器中的 /var/www/html/index.php 位置。

我們也可以使用以下命令構建自定義映像:

docker build -t app1:php-5.6 .

執行建置命令後,您將看到以下輸出:

建置完成後,您可以將映像推播到 Docker Hub 或自己的私有倉函式庫,或者將自定義映像匯出為 .tar 檔案,然後複製到需要執行自定義 PHP 容器的每個例項上。

要匯出映像,請執行 Docker save 命令:

docker save app1:php-5.6 > ~/app1-php-56.tar

內容解密:

  1. docker save app1:php-5.6:將 app1:php-5.6 映像儲存為 tar 檔案。
  2. > ~/app1-php-56.tar:將儲存的映像輸出到 ~/app1-php-56.tar 檔案中。

現在我們有了映像的 tar 檔案,可以將其複製到其他主機。複製 tar 檔案後,需要在第二台主機上執行 Docker load 命令來匯入它:

docker load < ~/app1-php-56.tar

然後,可以透過執行以下命令啟動包含我們程式碼的容器:

docker run --name app1 -d -p 80:80 -it app1:php-5.6

內容解密:

  1. docker run:啟動一個新的容器。
  2. --name app1:將容器命名為 app1
  3. -d:在後台執行容器。
  4. -p 80:80:將主機的 80 連線埠對映到容器的 80 連線埠。
  5. -it:分配一個虛擬終端給容器。
  6. app1:php-5.6:使用 app1:php-5.6 映像啟動容器。

資料函式庫容器的挑戰

雖然我們可以輕鬆地將程式碼函式庫新增到自定義映像中,並透過各種方式傳輸映像,但對於處理不斷變化的資料的容器(如資料函式庫),我們的選擇是什麼?

假設我們正在執行來自 https://hub.docker.com/_/mysql/ 的官方 MySQL 容器,我們可以掛載主機上儲存資料函式庫的資料夾(即 /var/lib/mysql/)。然而,這可能會導致檔案許可權問題。

為瞭解決這個問題,我們可以建立一個資料卷,包含 /var/lib/mysql/ 目錄的副本。這樣,我們就可以將資料函式庫與容器分開,從而可以在不破壞資料的情況下停止、啟動甚至替換 MySQL 容器。

圖示說明

圖表翻譯: 此圖表展示了主機檔案系統如何掛載到容器中,以及如何使用資料卷來儲存 MySQL 資料函式庫的資料。

然而,這種方法仍然將我們繫結在單一主機上執行 MySQL 容器,這是一個很大的單點故障。

未來解決方案

為瞭解決這個問題,我們需要擴充套件 Docker 的功能。雖然 Docker 原生不支援在主機之間移動卷,但我們可以插入檔案系統擴充套件,以便在主機之間遷移卷或從共用檔案系統(如 NFS)掛載卷。

如果我們為 MySQL 容器組態了這種功能,那麼即使主機出現問題,我們也可以輕鬆地將資料卷掛載到另一台主機上,從而實作無縫切換。

同樣,對於網路組態,我們也可以新增網路擴充套件,將容器的網路解除安裝到軟體定義網路(SDN),而不是讓 Docker 的核心使用 NAT 和主機上的 iptables 中的橋接介面來管理網路。

一旦我們在 Docker 的核心中引入了這種級別的功能,管理容器就會變得更加複雜。在理想情況下,我們不應該擔心容器在哪個主機上執行,或者如果容器/主機停止回應,容器是否會自動在容器網路中的其他主機上啟動並繼續執行。

擴充套件 Docker 的介紹

在接下來的章節中,我們將探討如何實作本章所討論的一些概念,並介紹由 Docker 開發的工具,這些工具旨在與核心 Docker 引擎一起執行。雖然這些工具的功能可能不如我們稍後將要討論的工具那麼全面,但它們為我們介紹了一些核心概念,這些概念將在建立 Docker 主機叢集和協調容器時發揮重要作用。

在探討了這些工具之後,我們將介紹卷和網路外掛。我們將涵蓋一些更為人所知的外掛,這些外掛為 Docker 核心增加了功能,使我們的平台更具冗餘性。

在親手操作了預先編寫的外掛之後,我們將探討編寫自己的外掛的最佳方法。

在本文的最後幾章中,我們將開始探討第三方工具,這些工具允許您組態、佈署和管理容器的整個生命週期。

介紹第一方工具

Docker 提供了多種工具來擴充套件核心 Docker 引擎的功能。在本章中,您將逐步瞭解如何安裝、組態和執行以下工具:

  • Docker Toolbox
  • Docker Machine
  • Docker Swarm
  • Docker Compose

這些工具雖然不像我們即將使用的一些更先進的工具那樣功能全面,但它們將為我們介紹如何為核心 Docker 引擎新增額外功能,以及如何佈署和協調容器等概念,這些內容將在本文的後面部分進行更深入的探討。

Docker Toolbox

在開始使用這三種其他工具之前,我們應該先看看如何在本地機器上安裝它們。在前一章中,我們下載了 Docker 提供的指令碼,並透過 bash 管道快速組態了官方的 Docker YUM 或 APT 儲存函式庫(取決於您執行的作業系統),我們執行的命令如下:

curl -sSL https://get.docker.com/ | sh

內容解密:

這條命令的作用是從 Docker 的官方網站下載一個指令碼,並透過管道傳遞給 sh 命令以執行該指令碼,從而快速安裝 Docker。這個指令碼會根據您的作業系統組態相應的軟體源(YUM 或 APT),並安裝 Docker。這種安裝方式適合已經擁有 Linux 伺服器的使用者。

這很有用,如果你已經在眾多的雲端服務之一或本地虛擬機器上執行了根據 Linux 的伺服器;然而,如果你想在非 Linux 的作業系統上安裝 Docker,例如 Mac OSX 或 Windows,該怎麼辦?

在我們檢視 Docker 提供的工具之前,我們應該回答一個問題:為什麼?

為什麼要在本地安裝 Docker?

那麼,為什麼我們要在非 Linux 機器上安裝 Docker Toolbox、Compose、Machine 和 Swarm?首先,你需要記住,Docker 在其核心是一個 API,用於根據 Linux 核心的技術,例如 run(https://github.com/opencontainers/runc)和 LXC(https://linuxcontainers.org),所以雖然你不能在 Mac OS X 或 Windows 機器上啟動容器,但你將能夠與 Linux 機器上的 Docker 安裝進行互動。

能夠從本地機器與 Docker 互動意味著你可以跨多個主機啟動和互動容器,這些主機可以託管在公共雲/託管服務上,也可以託管在本地虛擬機器上。

幸運的是,Docker 為在本地機器上安裝 Docker 和我們即將在本章中檢視的其他三個服務提供了支援。

安裝 Docker Toolbox

Docker 提供了一個全域安裝程式,稱為 Docker Toolbox,它使安裝以下軟體盡可能無痛:

  • Docker Client
  • Docker Machine
  • Docker Compose
  • Docker Kitematic
  • VM VirtualBox

內容解密:

Docker Toolbox 提供了一套完整的工具,使得在非 Linux 平台(如 Mac OS X 和 Windows)上安裝和組態 Docker 相關工具變得簡單。這些工具包括用於與 Docker 互動的客戶端、建立和管理虛擬機器的 Machine、用於定義和執行多容器應用程式的 Compose,以及用於管理容器的圖形介面 Kitematic。最後,它還包括 VirtualBox,用於執行虛擬機器。

要開始,你需要在執行 Mac OS X 10.8+ 或 Windows 7+ 的機器上。首先,你需要從 Docker 網站下載安裝程式。你可以在 https://www.docker.com/docker-toolbox/ 找到適合你作業系統的可執行檔下載連結。

下載安裝程式後,可以透過雙擊它來啟動。然後,你將看到一系列螢幕和安裝選項。第一個螢幕是歡迎頁面,它確認了你正在執行的 Toolbox 版本。如果你從前面的截圖中的頁面下載,那麼你總是會有最新版本。

點選「繼續」以進入安裝的下一步。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Docker 工具深入解析與實務應用

package "Docker 架構" {
    actor "開發者" as dev

    package "Docker Engine" {
        component [Docker Daemon] as daemon
        component [Docker CLI] as cli
        component [REST API] as api
    }

    package "容器運行時" {
        component [containerd] as containerd
        component [runc] as runc
    }

    package "儲存" {
        database [Images] as images
        database [Volumes] as volumes
        database [Networks] as networks
    }

    cloud "Registry" as registry
}

dev --> cli : 命令操作
cli --> api : API 呼叫
api --> daemon : 處理請求
daemon --> containerd : 容器管理
containerd --> runc : 執行容器
daemon --> images : 映像檔管理
daemon --> registry : 拉取/推送
daemon --> volumes : 資料持久化
daemon --> networks : 網路配置

@enduml

圖表翻譯: 此圖示展示了安裝 Docker Toolbox 的基本流程。首先需要下載安裝程式,接著雙擊執行它。在歡迎頁面確認版本後,點選「繼續」以進入下一步。

下一螢幕會更詳細地介紹將要安裝的軟體包,以及它們將被安裝的位置。還有一個選項框,如果選中,將收集有關你正在安裝 Docker Toolbox 的機器的資訊,對其進行匿名處理,然後將其提交回 Docker。

點選「繼續」以進入下一步。對於大多數人來說,標準安裝就足夠了;然而,如果你不想安裝其中一個工具,可以點選「自定義」按鈕。唯一必須安裝的兩個工具是 Docker Client 和 Docker Machine。

Docker 工具安裝與設定

在安裝 Docker 工具時,您可以選擇標準安裝或自定義安裝。標準安裝將安裝所有必要的工具,而自定義安裝允許您選擇特定的工具。

執行安裝

  1. 選擇安裝型別後,點選「Install」按鈕以開始安裝。
  2. 安裝過程需要幾分鐘,並會顯示安裝進度。
  3. 安裝完成後,點選「Continue」按鈕。

設定 Docker Agent

在開始使用 Docker 工具之前,需要設定 Docker Agent。執行以下步驟:

  1. 執行 Docker Quickstart Terminal 應用程式。
  2. 如果有多個終端模擬器安裝,將彈出提示詢問要使用哪一個終端模擬器。
  3. 選擇偏好的終端模擬器後,將開啟新的終端視窗並設定 Docker。

Docker Machine

Docker Quickstart Terminal 應用程式使用 Docker Machine 建立虛擬機器並設定 Docker 環境。您可以檢查虛擬機器的狀態:

docker-machine active
docker-machine status default

連線虛擬機器

您可以使用以下命令 SSH 連線到虛擬機器:

docker-machine ssh default

這將連線到正在執行 Boot2Docker 發行版的虛擬機器。Boot2Docker 是一個極為輕量級的 Linux 發行版,專為執行 Docker 而設計。

測試 Docker

在虛擬機器上執行 Docker 命令:

docker run hello-world

內容解密:

此命令將下載並執行 hello-world 映象,驗證 Docker 是否正確安裝和設定。

Docker Machine 的雲端支援

Docker Machine 不僅可以用於本地虛擬機器,還支援多個雲端服務提供商,包括:

  • Amazon Web Services (AWS)
  • DigitalOcean
  • Microsoft Azure
  • Google Compute Engine
  • Rackspace
  • IBM SoftLayer
  • Exoscale
  • VMware vCloud Air

以及自託管平台,如:

  • OpenStack
  • Microsoft Hyper-V
  • VMware vSphere

在 DigitalOcean 上建立例項

要在 DigitalOcean 上建立例項,需要:

  1. 註冊 DigitalOcean 帳戶。
  2. 生成 API Token。

使用以下命令建立例項:

docker-machine create \
--driver digitalocean \
--digitalocean-access-token sdnjkjdfgkjb345kjdgljknqwetkjwhgoih314rjkwergoiyu34rjkherglkhrg0 \
dotest

內容解密:

此命令使用 Docker Machine 在 DigitalOcean 上建立名為 dotest 的例項。請將 sdnjkjdfgkjb345kjdgljknqwetkjwhgoih314rjkwergoiyu34rjkherglkhrg0 替換為您的實際 API Token。

使用Docker Machine管理雲端例項

Docker Machine是一個強大的工具,允許使用者在本地或雲端環境中建立、管理和維護Docker主機。本章節將介紹如何使用Docker Machine在DigitalOcean和Amazon Web Services(AWS)上佈署和管理Docker例項。

啟動和管理例項

首先,我們使用Docker Machine在本地和DigitalOcean上啟動了兩個例項。我們可以透過執行以下命令來確認這兩個例項的狀態:

docker-machine ls

這個命令將列出所有正在執行的機器,並確認它們的狀態、IP地址、Docker版本和名稱。同時,它還會顯示當前本地環境組態為與哪個例項進行通訊。

切換活動例項

預設情況下,本地Docker客戶端組態為與本地執行的default例項進行通訊。要切換到DigitalOcean上的dotest例項,我們需要更改一些本地環境變數。Docker Machine提供了一個簡單的方法來查詢和更改這些變數:

docker-machine env dotest
eval $(docker-machine env dotest)

執行上述命令後,本地Docker客戶端將組態為與dotest例項進行通訊。

測試例項連線

為了測試連線是否成功,我們可以執行一個hello-world容器:

docker run hello-world

然後,透過以下命令檢視容器的執行狀態:

docker ps -a

驗證命令執行位置

為了驗證我們在本地執行的Docker命令是否在DigitalOcean例項上執行,我們可以透過SSH登入到DigitalOcean例項並執行相同的docker ps -adocker images命令。

Docker Machine的預設組態

Docker Machine有一些預設組態,例如:

  • digitalocean-image = ubuntu-15-10-x64
  • digitalocean-region = nyc3
  • digitalocean-size = 512mb

這些預設組態使得使用者可以快速啟動例項,而無需指定過多的引數。

自定義例項組態

如果需要更改例項的組態,例如更改地區或規格,可以透過新增額外的標誌來實作。首先,需要刪除舊的例項:

docker-machine rm dotest

然後,使用自定義的引數建立新的例項:

docker-machine create \
--driver digitalocean \
--digitalocean-access-token sdnjkjdfgkjb345kjdgljknqwetkjwhgoih314rjkwergoiyu34rjkherglkhrg0 \
--digitalocean-region lon1 \
--digitalocean-size 1gb \
douktest

查詢可用地區和規格

使用者可以透過查詢DigitalOcean API來取得各個地區的資訊和可用的機器型別:

curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer sdnjkjdfgkjb345kjdgljknqwetkjwhgoih314rjkwergoiyu34rjkherglkhrg0" "https://api.digitalocean.com/v2/regions" | python -mjson.tool

SSH金鑰管理

每次執行Docker Machine時,都會為新啟動的例項建立並上傳一個新的SSH金鑰。這些金鑰儲存在使用者主目錄下的.docker資料夾中。

Amazon Web Services(AWS)驅動程式

除了DigitalOcean之外,Docker Machine還支援AWS等其他雲端服務提供商。要使用AWS驅動程式,需要先註冊一個AWS帳戶,並閱讀AWS的入門。

使用AWS驅動程式建立例項

建立AWS例項的過程與DigitalOcean類別似,需要指定AWS存取金鑰和其他必要的引數。