iT邦幫忙

2025 iThome 鐵人賽

DAY 4
0
Cloud Native

從 Docker 到 K8s:我的 30 天雲原生筆記系列 第 4

Day 4: Docker 核心三劍客:Image, Container 與 Registry

  • 分享至 

  • xImage
  •  

哈囉,大家好!歡迎來到第四天的旅程。

在昨天的 Day 3,我們成功地安裝了 Docker Desktop,並且用 docker run 這個神奇的指令,啟動了 hello-worldnginx 兩個容器。看著終端機的輸出和瀏覽器的歡迎頁面,是不是很有成就感?

但你心中可能還留著一些疑問:

  • 當我輸入 docker run nginx 時,那個 nginx 到底是什麼?它從哪裡來?
  • 為什麼下載下來的東西叫 Image,但跑起來的東西又叫 Container?這兩者到底有什麼區別?

今天,我們就要來解開這些謎團。我們的目標是深入理解 Docker 世界中最重要的三個核心概念,我喜歡稱它們為「Docker 核心三劍客」:

  1. 容器 (Container)
  2. 映像檔 (Image)
  3. 倉庫 (Registry)

搞懂了它們的關係,你就掌握了 Docker 運作的精髓。

Part 1:容器 (Container)

讓我們先從最熟悉的開始。在 Day 3,你已經親手「運行」了一個 Container。所以,它到底是什麼?

我們可以用「小套房」來比喻。Container 就是一個真正提供服務、正在運行中的、被隔離的獨立空間。它是動態的、活生生的。

Docker 官方文件 給了一個更精確的定義:

Simply put, containers are isolated processes... Each component... runs in its own isolated environment, completely isolated from everything else on your machine.
(簡單來說,容器就是被隔離的行程... 每個組件都在其專屬的隔離環境中運行,與你機器上的其他任何東西完全隔離。)

神奇的「隔離牆」是怎麼來的?

這段話的關鍵字是 isolated processes (被隔離的行程)。Docker 很巧妙地用一層「隔離牆」把行程包了起來,讓它彷彿活在一個平行時空。這層牆,其實是基於 Linux 核心 (Kernel) 的兩項強大技術:

https://ithelp.ithome.com.tw/upload/images/20250911/20178656OcNf55QFSx.png

  1. Namespaces (命名空間):這是實現「隔離」的關鍵。它為容器提供了獨立的視角。例如:
    • PID Namespace (Process ID Namespace):容器有自己獨立的行程樹,它以為自己是系統裡唯一的行程 (PID 1),看不到主機上或其他容器的行程。容器內的 PID 是「局部世界編號」,主機上才有全局唯一 PID。
    • Network Namespace:容器有自己獨立的網路堆疊(IP 位址、路由表、網路埠),看不到別人的網路設定。就像你有自己獨立的衛浴,不用跟別人搶。
    • 還有 Mount、UTS、IPC、User 等命名空間,共同打造了一個幾近完美的隔離環境。
  2. cgroups (Control Groups):如果說 Namespace 讓你看不到別人,那 cgroups 就是防止你用太多資源,就像飯店幫你的房間設定了水電用量的上限,防止你一個人把整棟樓的資源都用光,例如:
    • 可以使用的 CPU 核心數量與時間。
    • 可以使用的記憶體 (RAM) 上限。
    • 可以使用的磁碟 I/O 速度。

https://ithelp.ithome.com.tw/upload/images/20250911/20178656rb3SfgbD9a.png

既然 Docker 的底層技術源自 Linux 核心,那為什麼它能在 Windows 和 macOS 上運行呢?

答案是:Docker Desktop 很巧妙地在你的電腦背景中,運行了一個輕量級的 Linux 虛擬機 (VM)。

  • Windows 上,它利用了 WSL 2 (Windows Subsystem for Linux) 技術,這是一個深度整合在 Windows 中的完整 Linux 核心。
  • macOS 上,它利用了蘋果的虛擬化框架。

所以,當你在 Windows 或 Mac 上執行 docker run 時,你其實是透過 Docker Desktop,將指令傳送到這個幕後的 Linux VM 中去執行。對我們使用者來說,這一切都是無感的、自動化的,讓我們可以在任何平台上享受到原生 Linux 容器的強大威力。

Part 2:映像檔 (Image)

既然 Container 是「正在運行的小套房」,那這間套房是怎麼蓋出來的呢?答案就是 映像檔 (Image)

Image 就是用來創建 Container 的唯讀範本。它就像是一份「套房設計藍圖」。它是靜態的、不可變的。

Docker 官方文件 是這樣描述 Image 的:

A container image is a standardized package that includes all of the files, binaries, libraries, and configurations to run a container.
(容器映像檔是一個標準化的包裹,其中包含了運行一個容器所需的所有檔案、執行檔、函式庫和配置。)

Image 最重要的兩個特性是:

1. 不可變性 (Immutable)

一旦一個 Image 被建立,它就不能被修改。

  • 一旦製作完成,就不能修改:當一個 Image (例如 my-app:1.0) 被 build 出來後,它的內容就被固定下來了。你無法對這個 Image 本身進行任何修改。
  • 想改變?只能做一個新的:如果你想更新程式碼,你必須重新執行 docker build,這會產生一個全新的 Image (例如 my-app:1.1)。舊的 my-app:1.0 依然保持原樣,不受影響。
  • 好處:絕對的一致性:這確保了不論何時、何地,只要你使用的是同一個 Image,得到的運行環境就保證 100% 相同,這也是 Docker 能解決「在我電腦上可以跑」問題的根本原因。

2. 分層結構 (Composed of layers)

Image 是由一層層的檔案系統變更堆疊而成的。

https://ithelp.ithome.com.tw/upload/images/20250911/20178656k54QS84Bt3.jpg

  • 層層堆疊:Dockerfile 中的每一行指令(例如 COPY, RUN)都會在前一層的基礎上,新增一個唯讀 (Read-only) 的圖層。
  • 共享與重用:這是分層結構最聰明的地方!如果你的電腦上已經有了 node:18-alpine 這個基礎圖層,當你下載另一個也基於 node:18-alpine 的 Image 時,Docker 不需要重新下載這個基礎層,它會在你本機共用它。這大大節省了儲存空間和下載時間。
  • 高效的建置快取 (Build Cache):同樣地,當你修改了檔案並重新 build Image 時,Docker 會發現 FROM, COPY package.json, RUN npm ci 這幾層完全沒變,於是它會直接使用快取,只重新建立 COPY . . 這一層,讓建置過程飛快。

這個「分層」的設計非常聰明!這讓 Image 的建立和傳輸變得極度高效。

總結一下 Image vs. Container 的關係:

  • Image (映像檔):是靜態的設計藍圖
  • Container (容器):是 Image 的運行實例

你可以用同一張設計藍圖 (Image),蓋出好幾棟一模一樣的房子 (Container)。

Part 3:倉庫 (Registry)

好了,我們現在知道需要用 nginx 這張「設計藍圖」(Image) 來蓋房子 (Container)。但問題來了,當我們在 Day 3 第一次執行 docker run nginx 時,我們電腦上明明沒有這張圖,Docker 是從哪裡把它變出來的?

答案就是 倉庫 (Registry)

Registry 是一個集中儲存和分發 Image 的服務。你可以把它想像成一個存放各種設計藍圖的倉庫,而最有名也最常用的就是 Docker Hub

Registry vs. Repository

在官方文件中,你會看到兩個很像的詞:RegistryRepository。它們的關係就像是「圖書館」和「書架」。

https://ithelp.ithome.com.tw/upload/images/20250911/20178656DToCRs6tmj.png

  • Registry (圖書館):例如 Docker Hub。
  • Repository (書架):在 Docker Hub 這個倉庫裡,有一個叫做 nginx 的書架,上面放了各種不同版本(tag)的 Nginx Image (書)。

結論

今天我們深入探討了 Docker 的核心三劍客,並揭開了背後的技術面紗。

既然我們已經知道 Image 是什麼,也知道它是由一層層堆疊起來的,那下一個問題就是:我們該如何親手製作一個專屬於我們自己應用程式的 Image 呢? 製作時,有沒有辦法讓 Image 像 alpine 版本那樣,既輕巧又強大?

這就要請出我們的「建造說明書」—— Dockerfile 了。在明天的文章中,我們將學習如何撰寫 Dockerfile,為我們的應用程式量身打造一個家!明天見!


上一篇
Day 3: 初探 Docker:安裝與你的第一個 Hello World 容器
下一篇
Day 5: Dockerfile:為你的應用程式量身打造 Image
系列文
從 Docker 到 K8s:我的 30 天雲原生筆記6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言