為什麼深入了解 Docker 的內部運作很重要?
Docker 是現代容器技術的基石,其方便的指令和快速的容器啟動能力,讓開發者與運維工程師能快速上手。然而,當應用程式進入生產環境,或系統遇到性能瓶頸與故障時,深入理解 Docker 的內部架構和運作流程便相當重要。
在本文教學中,我們將聚焦於 Docker 的核心組件(EX: Docker Client、Docker Daemon、Containerd、OCI Runtime…等)及其之間的互動關係,並帶你探索從下載 Image 檔到啟動 Container 的完整流程,幫助你掌握 Docker 的內部邏輯。
核心組件與角色
Docker Client
用戶與 Docker 互動的入口,通過命令 (如
docker run
、docker build
) 向 Docker Daemon 發送請求。
- 互動對象:與 Docker Daemon 通訊 (通常通過 REST API 或 UNIX Socket)。
- 位置:用戶本地環境。
Docker Daemon
Docker 的核心服務 process ,負責接收 Client 請求並執行具體操作,EX: 拉取 Image、創建 Container,並協調後續所有 Container 生命週期、Image 管理、網路、儲存…等工作。
早期 Docker Daemon 自己直接管理 Container,但後來將 Container 執行的部分抽象化給Containerd
去處理。
- 內部構成:
- Containerd:Container 管理層,負責++管理容器的生命周期++ (EX: 啟動、停止)。
- Containerd-shim:中介層,確保 Container 與 Containerd 的解耦,讓 Container 在 Containerd 崩潰後仍能運行。
- **OCI Runtime (EX: runc)**:執行層,負責啟動和管理容器的隔離 process 。
Registry
Image 儲存庫,用於保存和分發 Docker Image。
可以是 Public(EX: Docker Hub)或 Private(公司內部架設)。
- 互動對象:Docker Daemon 通過拉取或推送操作與 Registry 互動。
- 常見:Docker Hub、privete Registry。
Image
Container 的靜態模板,包含應用程式及其運行所需的依賴和配置。
- 特性:
- 使用分層文件系統 (UnionFS),每層代表 Image 的一部分 (EX: 基礎 OS、應用依賴)。
- 不可變,可以被多個容器共享。
- 互動對象:由 Docker Daemon 從 Registry 中拉取,並交付給 Containerd 啟動 Container。
Container
Image 的運行實例,是一個輕量級、隔離的應用運行環境。
- 運作基礎:依賴 Linux 的 Namespace 和 Cgroups 技術實現隔離與資源限制。
- 互動對象:由 Containerd 調用 OCI Runtime 創建,並由 Containerd-shim 管理。
Containerd
管理層,負責 Container 的整體生命周期管理,是 Docker Daemon 的核心子系統。
- 功能:
- 拉取與管理 Image。
- 創建與刪除 Container。
- 調用 OCI Runtime 啟動容器。
- 互動對象:通過 Docker Daemon 接收指令,並向 OCI Runtime 傳遞容器配置。
Containerd-shim
中介層 (中間代理) ,管理 Container 的生命周期,確保 Container 在 Containerd 崩潰後依然運行。
功能:
- 管理 Container 與父 process 的互動。
- 解耦作用:確保容器的執行不依賴於 Containerd 的狀態 (狀態相互獨立)。
- 資源管理:監控 Container 的 process 狀態。
- I/O 管理:處理 Container 的輸入/輸出數據,方便用戶與 Container 互動。
- Container 生命周期管理:處理 Container 的啟動、停止及 process 監控(不因 containerd daemon 本身的重啟而中斷)。
互動對象:
- 作為 Containerd 與容器之間的橋接,解耦 Container 與 Containerd。
- 與底層的 OCI Runtime 溝通,啟動 Container process。
- shim 就像是「轉接器」或「支架(shim)」的概念,一個 Container 對應一個 shim。
- Container 啟動後,
Containerd-shim
會取代Containerd
成為 Container 的父 process,確保即使Containerd
崩潰,Container 仍然能持續運行。
OCI Runtime (EX: runc)
執行層,基於 OCI (Open Container Initiative) 規範的運行時工具,負責實際啟動 Container。
- 功能:
- 設置 Container 的++隔離環境++ (Namespace、Cgroups…等)。
- 啟動 Container 內的應用 process 。
- 互動對象:由 Containerd 呼叫,執行容器啟動的具體邏輯。
最常見的 OCI Runtime 是 runc,它是 OCI Runtime 的一個具體實現,專門處理容器的低層操作。
OCI Spec (規範)
一套 Container 運行時的標準規範,定義 Container 的配置文件格式和行為。
- 功能:
- 描述 Container 的資源設置 (EX: CPU、Memory)。
- 定義 Container 的文件系統掛載點。
- 設置 process 的啟動命令和參數。
- 配置 Namespace 隔離(EX: 網路、PID、用戶等)。
- 內容:
- Container 的資源配置 (EX: CPU、Memory)。
- Namespace 和檔案系統的隔離規則。
- 主要構成:
config.json
:定義 Container 的配置,EX: 環境變量、文件系統、資源限制。runtime-spec
:描述 Container 的行為規範,OCI Runtime 依此實現運行時行為。
- 互動對象:OCI Runtime 根據 OCI Spec 配置 Container 環境。
運作流程
以下是執行 docker run
指令的完整過程:
發送指令
- 步驟:使用者執行
docker run hello-world
。 - 互動對象:Docker Client 將請求發送給 Docker Daemon。
拉取 Image
- 步驟:Docker Daemon 檢查本地是否存在 Image ,若無則從 Registry 拉取。
- 互動對象:Docker Daemon 與 Registry 通訊,下載 Image 後存儲於本地。
創建 Container
- 步驟:
- Docker Daemon 通過 Containerd 請求創建容器。
- Containerd 調用 OCI Runtime (如 runc),基於 OCI Spec 配置容器環境。
- 互動對象:
- Docker Daemon → Containerd → OCI Runtime。
啟動容器
- 步驟:
- OCI Runtime 配置命名空間、Cgroups,並啟動 Container process。
- Containerd-shim 接管 Container process 的管理,與父 process 解耦。
- 互動對象:
- OCI Runtime → Containerd-shim。
運行與管理
- 步驟:容器進入運行狀態,Docker Client 可通過命令與容器互動。
- 互動對象:
- Docker Client → Docker Daemon → Containerd。
架構圖
1 | +-----------------------------------+ |
總結
組件名稱 | 作用 | 互動對象 |
---|---|---|
Docker Client | 接收用戶指令,發送給 Docker Daemon | Docker Daemon |
Docker Daemon | 管理 Container 的核心服務,處理 Image 與 Container 操作 | Docker Client、Registry、Containerd |
Registry | 儲存與分發 Image | Docker Daemon |
Image | Container 的靜態模板 | Docker Daemon |
Container | Image 的運行實例 | Containerd |
Containerd | 管理 Container 的生命周期 | Docker Daemon、OCI Runtime |
Containerd-shim | 確保 Container 與 Containerd 解耦 | Containerd、Container、OCI Runtime |
OCI Runtime (runc) | 實際執行Container | Containerd、作業系統 |
OCI Spec | Container 配置的標準規範 | OCI Runtime |