任務一:認識 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 run 或 docker 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 時,背後的流程是這樣的:
- Docker Client 接收指令,並透過 API 發送請求給 Docker Daemon
- Docker Daemon 檢查本地是否有
hello-world映像檔 - 如果本地沒有,Docker Daemon 會從 Docker Registry(預設是 Docker Hub)拉取映像檔
- Docker Daemon 根據映像檔建立一個新的容器
- Docker Daemon 啟動容器並執行其中的程式
- 程式的輸出會透過 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,並執行第一個容器。準備好了嗎?讓我們繼續前進!