Docker 介紹

什麼是 Docker?

引言

在現代軟體開發中,「一次建置,處處運行」的理想正逐漸成為現實。Docker 作為容器技術的代表,正是這股浪潮的核心之一。

Docker 是

Build and Ship any Application Anywhere (建置任何應用程式並運行在任何地方)

Docker 是一個開源的容器化平台,可以用來打包、運行和分享應用程式。Docker 通過容器化技術實現了應用程式的獨立性可移植性,這代表只要安裝 Docker,就能在不同的作業系統或平台上,毫無差異地執行相同的應用程式,讓開發者和運維人員可以更加便捷地進行應用程式的開發、部署和運維。

容器技術與虛擬機

虛擬機器

所謂的 VM,就是將「一台實體的主機」,拆分成「許多個作業系統」的技術,共享硬體資源。

VM(Virtual Machine,虛擬機) 是一種使用軟體模擬出來的電腦系統,它能在一台實體機器(宿主機,Host)上模擬出多台獨立運作的「虛擬電腦」。這些虛擬電腦彼此之間相互隔離,像是真實的電腦一樣可以安裝作業系統、應用程式、進行開發、測試或部署。

一台虛擬機的背後通常包含以下幾個核心元件:

  1. 實體硬體(Host Hardware)
    真正的電腦主機,包括 CPU、記憶體、硬碟、網卡等
  2. Hypervisor(虛擬機監控器)
    一種管理 VM 的軟體,負責將實體硬體「切分」給多個虛擬機使用
    有兩種類型:
    類型說明
    Type 1(裸機型)安裝在實體機上,例如 VMware ESXi、Microsoft Hyper-V、Xen。效率高,常見於企業伺服器環境
    Type 2(託管型)安裝在作業系統之上,例如 VMware Workstation、VirtualBox。適合開發或學習用途
  3. Guest OS(客體作業系統)
    安裝在每台 VM 裡的作業系統,可以是 Windows、Linux、macOS(受限)等
  4. 虛擬硬體(Virtual Hardware)
    包括虛擬的 CPU、RAM、硬碟、顯示卡、網卡等。從客體 OS 來看,就像真實硬體一樣

Docker 與虛擬機器不同

Docker 運行應用程式的環境被稱作 容器 (Container)。它不像虛擬機器 (virtual machine ) 需要 虛擬機器監視器 (hypervisor) 模擬出軟體、韌體或硬體,反而直接運行在宿主機(host machine)的核心。以執行應用程式的運行來說,虛擬機器需要模擬出整套作業系統才能運行應用程式,而容器則是直接運行在宿主機上。不僅如此,宿主機也可以是虛擬機器。因此,它比虛擬機器又更為輕量級、執行啟動又更快。

過去,當我們想要在不同的環境下運行同一份程式碼,我們需要使用虛擬機技術。然而,虛擬機有一些固有的問題,比如需要的資源多、啟動慢、難以移動和複製等。容器技術則為解決這些問題提供了新的方向。

容器是一種軟體技術,可以將應用程式及其全部運行環境(包括文件系統、系統庫等)打包在一起,形成一個獨立、一致的運行單元。容器之間互相隔離,但共享同一個作業系統,每個容器都像一個輕量級的虛擬機。這種技術可以讓開發者在不同的系統和環境中,輕鬆地運行和管理他們的應用程式。

pic

  1. 啟動速度:
    Docker 屬於作業系統層級的虛擬化,啟動極快,通常在秒級甚至毫秒等級即可完成。相比之下,傳統虛擬機需啟動完整作業系統,常見情況下需要數十秒至數分鐘。
  2. 資源效率:
    Docker 相對虛擬機更節省資源,容器共用宿主機的核心,不需要像虛擬機那樣為每台虛擬作業系統配置獨立的資源。這種架構大幅減少了 CPU、記憶體等的開銷,也提升了效能。不過,仍有部分系統資源競爭或隔離上的考量,並非毫無性能損耗。
  3. 輕量與可擴展性:
    Docker 容器架構支援共用核心與分層式映像(image layer)技術,使其相較虛擬機更輕量、更容易快速部署。在相同的硬體環境下,通常可以部署更多的容器來服務不同應用。但要注意,容器數量一多,也會對系統資源管理提出挑戰,例如記憶體、PID、網路等限制。
  4. 安全性:
    相較虛擬機,Docker 的安全性較弱。容器的使用者(尤其是 root)若未經妥善限制,可能直接存取宿主機的資源。虛擬機則有完整的硬體與作業系統隔離,搭配如 Intel VT-d、VT-x 等技術,即使其中一台虛擬機被攻破,也較難波及宿主機或其他虛擬機。容器則必須透過額外機制(如 AppArmor、Seccomp、user namespace)強化安全隔離。
  5. 可管理性:
    早期 Docker 的管理工具確實不夠成熟,但如今已有完整的容器管理生態系統,如 Kubernetes、Docker Compose、Portainer 等,可實現集中式部署、監控與資源管理。雖然和 VMware vCenter 等虛擬機管理工具相比,在某些使用體驗上仍有差異,但不可再簡單認為 Docker 管理能力不足。
  6. 高可用與容錯性:
    Docker 本身雖不具備這些機制,但可透過 Kubernetes 等容器編排工具,實現自動故障恢復、滾動升級與副本擴展等功能,達成應用層級的高可用性。虛擬機透過成熟的架構如 VMotion、HA、高可用集群等,在業界經過多年驗證,具備高度的業務連續性保證。
  7. 部署與交付:
    Docker 透過 Dockerfile 記錄應用構建流程,能完整還原映像並實現一致性的交付與自動化部署,極適合 DevOps 流程整合。而傳統虛擬機雖可透過映像實現環境封裝,但缺乏標準化的構建過程與分發機制,難以支援大規模快速部署。
虛擬機 (VM)容器 (Docker)
啟動速度較慢非常快
系統資源占用
是否需完整 OS
可攜性較差
應用隔離性中~高

Docker 的優勢與應用場景

  • 環境一致
    Docker 可以將應用程式及其所有依賴項打包在一個容器中,確保了從開發到測試到生產的整個生命週期中,環境的一致性。這解決了「在我的機器上運行得好好的」這種常見問題,讓開發和發佈有統一的標準環境,也有利於持續整合(CI, Continuous Integration)與持續交付(CD, Continuous Delivery)流程的建立,讓應用程式從寫好程式碼到部署上線都能自動化完成。 例如,開發者在 macOS 上開發的 Node.js 應用,使用 Docker 打包後可以直接部署到 Ubuntu 的生產環境中,不會因為 Node.js 版本不同而出錯。
  • 輕量級和性能優越
    容器提供輕量級的沙盒環境,與傳統的虛擬機相比,Docker 容器不需要運行一整套操作系統,而是直接使用主機的操作系統,這使得容器變得非常輕量且啟動速度快
  • 應用程式隔離
    容器提供輕量級的沙盒環境,每個容器都在自己的空間中運行,並有其自己的網路和文件系統,互不干擾。這提供了額外的安全層,也使得各種應用程式可以在同一台機器上共存
  • 可移植
    由於容器包含了所有需要的依賴項,因此它可以在任何安裝了 Docker 的系統上運行,無論這個系統是物理機還是虛擬機,是在數據中心還是在雲端
  • 易於管理和擴展
    Docker 提供了豐富的工具和平台,用於管理容器、服務和集群,使應用程式的部署、擴展和運維變得簡單

Docker 可以做什麼?

  • 容器管理
    使用 Docker CLI 建立、啟動、停止、搬移和刪除容器
  • 映像管理
    可以從容器建立映像,並推送至映像倉庫以供分享與部署。這是實現快速應用程式部署和擴展的基礎
  • 映像版本控制
    透過 tag 機制追蹤映像變化,可回溯特定版本。開發者可以追蹤映像的改變,並在需要的時候回退至先前的版本
  • 系統資源隔離
    使用 Linux 的 cgroups 和 namespaces 技術,將每個容器的 CPU、記憶體、網路等與其他容器隔離
  • 資源掛載與整合
    容器可掛載的資源如磁盤、網路和檔案系統,使容器可以像真實的獨立系統一樣運行

這些功能構成了 Docker 作為開發、測試與部署平台的基礎。

Docker 是如何運作的?

Docker 的架構主要由以下三個部分組成:

  • docker daemon (dockerd)
    Docker 的核心服務程式,稱為 dockerd 或 docker 引擎,是常駐在背景的守護行程(daemon process),負責處理容器的建立管理、控制映像、配置網路與儲存空間等工作,幾乎所有背後的魔法,都是它在操控
  • REST API
    dockerd 暴露出一組 RESTful API,讓用戶或工具可以程式化地控制、操控 Docker,例如管理 Images、containers、networks 和 volumes 等資源
  • Docker CLI (Command-Line Interface)
    相較於 REST API,使用者更常透過命令列來操作 Docker。這個 CLI 是與 Docker Daemon 互動的主要方式。CLI 會呼叫 REST API 與 dockerd 溝通

容器的物件

Container(容器):映像檔的執行物件

Container 是 Docker 的核心技術,運行於 Docker Engine 之上,且在各種作業系統上皆有對應版本。

容器是映像檔 (Image) 的實際執行物件,用 docker + run / start / restart / stop / rm 指令可以管理容器。當容器建立時,容器執行於隔離的沙箱環境中,可視為擁有獨立的檔案系統。另外,我們還可以為 Container 設定 networkvolume 等資源,讓其具備通訊與持久化資料的能力:

  • volume 是容器與別人共享的資料區,我們把資料放在裡面,可以:
    1. Host 共同存取
    2. 提供其它 Container 掛載 (mount) 使用,共享同樣的資料區
    3. 獨立於 container,當 Container 移除時,volume 裡的資料可以保留下來
  • network 讓我們可以與別的容器和主機通訊,像是:從外部存取容器內的服務,可能是從 Host,也可能是來自別的 Container

Image(映像檔):容器建立的範本

Image 是容器建立的範本,它打包著相關程式碼、函式庫、環境配置檔。簡而言之,就是一群檔案集合。Image 常常是基於別的 Image 建立的,像是我們可以基於 nginx:1.18.0 加入客制的 Nginx 設定組態或加入你自己的檔案再重新建置 (build) 一個新的 Image。

當要建立並執行 Container 時一定要指定「唯一」的一個映像檔,如 docker run <Image>

Volume:獨立於容器的檔案空間

在實際應用中,我們常需要容器擁有「持久化資料」或「跨容器共用資料」的能力,以下是常見使用場景:

  1. 資料在容器刪除後仍需保留(例如:資料庫)
  2. 容器與宿主機 (Host) 共享資料夾或檔案
  3. 多個容器共用設定檔或資料集

簡單來說當我們需要「資料共用」或「資料保留」,此時就會用到 Volume

docker run -v (–volume) 來掛載 volume,格式是:-v <source>:<target>:其中 source 可以是宿主機路徑(bind mount)或 volume 名稱,兩者都不會因為容器移除而被自動刪除。;目標 (target) 是指定要掛入容器內的位置。

Docker 提供三種掛載類型(mount types):

  1. bind mount:掛入現有的 Host 檔案系統 (filesystem),用在容器與 Host 共享資料夾或檔案
  2. volume:掛入 volume 物件
  3. tmpfs mount:從 memory 掛載

Network:與容器通訊

網路是 Docker 物件中重要的一環,它可以讓其它人存取容器中的應用程式,也可以讓各個 Docker daemons (dockerd) 串接起來,使容器在它們之間擴張 (scale) 複製,而容器不會察覺它目前運行在哪台主機。

docker 支援許多模式,但我們只考慮本機常遇到的 bridgeHost 使用情境。

  • Bridge mode:分離容器和本機的網路
    這是容器預設的網路模式。當我們 docker run 時,容器會使用一個預設的 network,名稱為 bridge 的網路物件 (不同的作業系統可能名稱會有差異,mac 叫 bridge, linux 叫 docker0)。容器接上那個預設的 network 並配給一個 IP。
  • Host mode:直接使用本機的網路
    這是最簡單的模式,容器會共用主機的網路堆疊與 IP,可視為在主機上執行的「本地行程(local process)」,不再有獨立的網路介面。它監聽什麼 port ,那麼 Hostport 就會被使用,所以連 -p 都不用設定。此外,有個小細節要注意,一個 port 只有一個 process 能監聽,同理,一個 port 也只能給一個容器物件監聽。

參考

docker学习笔记