跳轉到

任務一:認識 Docker 與容器技術

開始之前

任務目標

在這個任務中,你將學習:

  • 理解為什麼需要容器技術
  • 區分虛擬機器(VM)與容器(Container)的差異
  • 認識 Docker 的核心架構元件
  • 了解 OCI 標準與容器生態系統

為什麼需要容器

在軟體開發的世界中,我們經常遇到這樣的情況:程式在開發環境運行得很好,但一部署到測試環境或正式環境就出問題了。團隊成員可能會無奈地說:「但是在我的電腦上可以跑啊!」這個經典的問題正是容器技術要解決的核心痛點之一。

環境一致性

容器技術最大的價值在於確保環境一致性。容器會將應用程式及其所有相依套件、函式庫、設定檔打包在一起,形成一個完整的執行單元。無論這個容器在開發者的筆電、測試伺服器,還是雲端平台上執行,行為都會完全一致。

舉例來說,如果你的 Python 應用程式需要特定版本的 Django 和 PostgreSQL,容器可以將這些相依項目全部封裝起來。當其他開發者或部署環境取得這個容器時,不需要手動安裝這些套件,也不會因為版本差異而產生問題。

快速部署

傳統的部署方式通常需要在目標伺服器上安裝作業系統、設定環境變數、安裝相依套件,這個過程可能需要數小時甚至數天。容器則可以在幾秒鐘內啟動,因為容器使用的是共享的作業系統核心,不需要完整啟動一個作業系統。

這種快速啟動的特性讓開發團隊能夠更靈活地擴展服務。當流量增加時,可以迅速啟動更多容器實例來分擔負載;當流量減少時,又可以快速關閉不需要的容器,節省資源成本。

資源效率

與虛擬機器相比,容器不需要為每個應用程式執行一個完整的作業系統。多個容器可以共用同一個作業系統核心,只需要隔離應用程式的執行環境。這意味著在相同的硬體資源下,你可以執行更多的容器,而不是更少的虛擬機器。

例如,一台 16GB 記憶體的伺服器可能只能執行 3-4 個虛擬機器(每個需要配置數 GB 記憶體給作業系統),但可以輕鬆執行數十個甚至上百個容器,因為容器只需要應用程式本身所需的記憶體。

VM vs Container

為了更清楚理解容器的優勢,讓我們比較虛擬機器(VM)和容器(Container)的差異。

架構層級比較

虛擬機器架構:

graph TB
    A1[應用程式 A] --> B1[Guest OS A]
    A2[應用程式 B] --> B2[Guest OS B]
    B1 --> C1[Hypervisor]
    B2 --> C1
    C1 --> D1[Host OS]
    D1 --> E1[硬體設備]

容器架構:

graph TB
    F1[應用程式 A] --> G1[Container Engine]
    F2[應用程式 B] --> G1
    G1 --> H1[Host OS]
    H1 --> I1[硬體設備]

從架構圖可以看出,虛擬機器需要在 Hypervisor 上執行多個完整的 Guest OS(客體作業系統),而容器則直接在 Container Engine 上執行,共用 Host OS(主機作業系統)的核心。

特性比較

特性 虛擬機器(VM) 容器(Container)
啟動速度 數分鐘 數秒
資源佔用 GB 級別(包含完整 OS) MB 級別(僅應用程式)
隔離程度 完全隔離(硬體層級) 應用層級隔離
效能 有虛擬化損耗 接近原生效能
可攜性 較低(需要相容的 Hypervisor) 高(任何支援容器的平台)
啟動數量 受限於硬體資源 可啟動大量實例

何時選擇虛擬機器?

  • 需要完全隔離的環境(如多租戶 SaaS 平台)
  • 需要執行不同作業系統(如在 Linux 主機上執行 Windows)
  • 安全性要求極高的場景

何時選擇容器?

  • 微服務架構
  • CI/CD 持續整合與部署
  • 需要快速擴展的應用程式
  • 開發與測試環境

Docker 架構

Docker 是目前最流行的容器平台之一。理解 Docker 的架構可以幫助我們更有效地使用容器技術。

核心元件

Docker 採用客戶端-伺服器(Client-Server)架構,主要包含以下元件:

Docker Engine

Docker Engine 是 Docker 的核心,負責建立和執行容器。它是一個輕量級的容器執行環境,提供容器生命週期管理的所有功能。

Docker Daemon (dockerd)

Docker Daemon 是一個背景服務程式,負責管理 Docker 物件,如映像檔(Images)、容器(Containers)、網路(Networks)和儲存卷(Volumes)。它監聽來自 Docker Client 的 API 請求並執行相應的操作。

Docker Client (docker)

Docker Client 是我們與 Docker 互動的主要介面。當你在終端機輸入 docker rundocker build 等指令時,Docker Client 會將這些指令轉換為 API 請求,並發送給 Docker Daemon 執行。

Docker Registry

Docker Registry 是儲存 Docker 映像檔的倉庫。最常見的公開 Registry 是 Docker Hub,你可以在上面找到數以萬計的官方和社群提供的映像檔。企業也可以架設私有的 Registry 來存放內部使用的映像檔。

架構圖

graph LR
    A[Docker Client<br/>docker CLI] -->|API 請求| B[Docker Daemon<br/>dockerd]
    B -->|拉取映像檔| C[Docker Registry<br/>Docker Hub]
    B -->|管理| D[Images<br/>映像檔]
    B -->|管理| E[Containers<br/>容器]
    B -->|管理| F[Networks<br/>網路]
    B -->|管理| G[Volumes<br/>儲存卷]

    style A fill:#e1f5ff
    style B fill:#fff4e1
    style C fill:#f0f0f0
    style D fill:#e8f5e9
    style E fill:#e8f5e9
    style F fill:#e8f5e9
    style G fill:#e8f5e9

運作流程

當你執行 docker run hello-world 時,背後的流程是這樣的:

  1. Docker Client 接收指令,並透過 API 發送請求給 Docker Daemon
  2. Docker Daemon 檢查本地是否有 hello-world 映像檔
  3. 如果本地沒有,Docker Daemon 會從 Docker Registry(預設是 Docker Hub)拉取映像檔
  4. Docker Daemon 根據映像檔建立一個新的容器
  5. Docker Daemon 啟動容器並執行其中的程式
  6. 程式的輸出會透過 Docker Daemon 傳回給 Docker Client,顯示在終端機上

OCI 標準與容器生態

什麼是 OCI?

OCI(Open Container Initiative,開放容器計畫)是由 Linux 基金會於 2015 年成立的開放性治理組織,目標是建立容器格式和執行時期的產業標準。

為什麼需要標準化?

在 OCI 成立之前,不同的容器技術(如 Docker、rkt)使用各自的格式和規範,導致容器生態系統的碎片化。開發者必須針對不同的容器平台調整應用程式,增加了學習成本和維護負擔。

OCI 定義了兩個主要規範:

  • 映像檔規範(Image Specification):定義容器映像檔的格式,確保映像檔可以在不同的執行環境中使用
  • 執行時期規範(Runtime Specification):定義如何執行容器的標準,包括容器的生命週期、配置格式等

容器生態系統

有了 OCI 標準,容器生態系統變得更加開放和多元。除了 Docker,還有許多符合 OCI 標準的容器工具:

  • containerd:Docker 的核心容器執行環境,也被 Kubernetes 廣泛採用
  • Podman:Red Hat 推出的容器工具,特色是不需要 Daemon 就能執行容器
  • CRI-O:專為 Kubernetes 設計的輕量級容器執行環境
  • runc:OCI 標準的參考實作,是 Docker 和 containerd 的底層執行時期

這些工具雖然各有特色,但因為遵循 OCI 標準,它們可以互相搭配使用。例如,你可以用 Docker 建立映像檔,再用 Podman 執行;或者在 Kubernetes 中使用 containerd 執行 Docker 建立的容器。

任務結束

完成!

恭喜你完成了這個任務!現在你已經學會:

  • 理解為什麼需要容器技術
  • 區分虛擬機器(VM)與容器(Container)的差異
  • 認識 Docker 的核心架構元件
  • 了解 OCI 標準與容器生態系統

在下一個任務中,我們將開始動手安裝 Docker,並執行第一個容器。準備好了嗎?讓我們繼續前進!