返回文章列表

Docker容器基礎與資料持久化

本文探討 Docker 容器技術,解析容器的短暫性以及資料持久化的重要性。同時,文章也提供 Docker 安裝步驟及常用 CLI 指令教學,讓讀者快速掌握 Docker 的基本操作與核心概念,為後續學習 Kubernetes 等容器協調技術奠定基礎。

容器化 DevOps

Docker 容器的短暫特性決定了容器內資料的非永續性,理解此特性對於正確使用 Docker 至關重要。容器啟動時,根據基礎映像建立,所有變更儲存在與容器 ID 關聯的暫存層中,容器刪除時,變更也隨之消失。Docker 提供了卷等機制實作資料持久化,將資料儲存在容器外部,確保資料的永續性。Docker 映像採用分層結構,利用複製即寫機制管理變更,提升效率。文章也提供 Docker 安裝和常用 CLI 指令,方便讀者快速上手。

Docker幾乎可以安裝在所有硬體平台上,不同平台的Docker版本操作方式一致,簡化了跨平台應用程式的開發流程。由於不同架構的映像檔無法跨平台執行,需注意映像檔的架構相容性。Docker 提供多種安裝方式,推薦使用軟體倉函式庫安裝,方便更新和維護。安裝過程中需注意儲存驅動程式的選擇,一般使用預設即可。安裝完成後,需將使用者新增到 docker 群組,以避免每次執行 Docker 命令都需要 root 許可權。最後,透過執行 hello-world 映像檔驗證安裝成功。

第一節:Docker和容器基礎

在本文中,我們將回顧重要的Docker和容器概念,以及Docker為開發人員帶來的益處。在快速回顧Docker之後,我們將繼續討論如何為容器新增持久資料,以及如何使用Docker網路將容器暴露給外部世界。這些基本概念對於完全理解Kubernetes以及瞭解容器如何在叢集中執行至關重要。

本部分包括以下章節:

  • 第1章:瞭解Docker和容器基礎知識
  • 第2章:使用持久資料
  • 第3章:瞭解Docker網路

第1章:Docker和容器基礎知識

容器是近年來最具變革性的技術之一。科技公司、企業和終端使用者都採用了它來處理日常工作負載。越來越多的現成應用程式(COTS)正在從傳統安裝轉變為完全容器化的佈署。隨著如此重大的技術變革,IT領域的任何人都必須學習有關容器的知識。

在本章中,我們將介紹容器所解決的問題。在介紹了容器的重要性之後,我們將介紹啟動現代容器熱潮的執行時——Docker。在本章結束時,您將瞭解如何安裝Docker以及如何使用最常見的Docker CLI命令。

在本章中,我們將涵蓋以下主題:

  • 瞭解容器化的需求
  • 瞭解Docker
  • 安裝Docker
  • 使用Docker CLI

讓我們開始吧!

內容解密:

本章主要介紹了容器的基本概念及其重要性,並引出了Docker這一現代容器執行時。透過本章的學習,讀者將能夠瞭解容器的基本原理,並掌握Docker的基本使用方法。

容器化技術的需求與 Docker 簡介

在軟體開發與佈署的過程中,「它在我的機器上可以運作」是個令人沮喪的問題。開發者需要確保應用程式在不同環境中的相容性,而容器化技術正是為瞭解決這一難題而誕生。

為何需要容器化?

開發者交付應用程式時常會遇到依賴性問題。開發者的機器上可能安裝了某些函式庫,而這些函式庫並未包含在應用程式的釋出包中。將所有依賴的函式庫與應用程式一起封裝似乎是個解決方案,但這可能會導致版本衝突,進而影響其他應用程式的運作。

過去,業界嘗試過各種解決方案,如應用程式虛擬化技術(例如 VMware 的 Thinapp)。這種技術將應用程式及其依賴項封裝成單一的可執行檔,避免了依賴性衝突的問題,同時也提升了安全性,並簡化了作業系統遷移的流程。

Docker 的登場

Docker 將容器化技術帶給了廣大的開發者。它提供了一個抽象層,讓開發者能夠輕鬆地封裝應用程式及其依賴項,而不需要為每個應用程式準備一個乾淨的系統環境。Docker 的出現降低了使用門檻,並且是免費的,因此迅速成為許多開源專案的首選。

Docker 容器基礎概念

Docker 容器具有短暫性(ephemeral)的特性,這意味著容器可以在任何時候被銷毀並重新啟動,而不會影響到使用者的體驗。然而,這也意味著在容器中對檔案系統所做的任何修改,都不會被儲存下來。

舉例來說:

  1. 啟動一個執行 NGINX 網頁伺服器的容器,但不包含任何網頁內容。
  2. 使用 Docker 命令將網頁檔案複製到容器的檔案系統中。
  3. 瀏覽網頁,確認網頁內容正確顯示。
  4. 停止並刪除容器。稍後重新啟動容器,再次瀏覽網頁時,卻發現出現了 404 錯誤。
# 建立並執行 NGINX 容器
docker run --name my-nginx -d nginx

# 將網頁檔案複製到容器中
docker cp ./webfiles my-nginx:/usr/share/nginx/html/

# 瀏覽網頁,確認內容正確

# 停止並刪除容器
docker stop my-nginx
docker rm my-nginx

# 重新建立並執行容器
docker run --name my-nginx -d nginx

# 再次瀏覽網頁,出現 404 錯誤

內容解密:

  • docker run --name my-nginx -d nginx:建立並在背景執行一個名為 my-nginx 的 NGINX 容器。
  • docker cp ./webfiles my-nginx:/usr/share/nginx/html/:將本地端的 webfiles 目錄複製到容器內的 /usr/share/nginx/html/ 目錄。
  • 當容器被刪除後,所有在容器檔案系統中的修改都會丟失,因此重新啟動的容器無法找到之前複製的網頁檔案。

Docker 容器本質與資料持久化解析

Docker 容器的本質是短暫且非持久的,這意味著當容器停止或被刪除時,所有在容器內部所做的變更預設都會丟失。瞭解這一特性對於有效使用 Docker 技術至關重要。

為什麼容器內的檔案會消失?

當你啟動一個 Docker 容器時,它是根據一個基礎映像(base image)執行個體化的。任何對容器檔案系統的修改都會被寫入一個稱為容器層(container layer)的暫存層中。這個容器層與容器的 ID 相關聯,並且會在容器被刪除時一併移除。因此,當你停止並刪除一個容器後,所有在該容器內上傳的檔案都會丟失。

容器的短暫性與資料持久化需求

雖然容器是短暫的,但這並不意味著你不能在執行中的容器內進行修改。任何變更都會被寫入容器層,並儲存在主機的檔案系統中,直到容器被刪除。然而,為了實作資料的持久化,Docker 提供了多種方法,例如使用 Docker 卷(Docker volumes)將資料儲存在容器外部,從而確保即使在容器被刪除後,資料仍然得以保留。

Docker 映像層與複製即寫(Copy-on-Write)機制

Docker 映像是由多個映像層(image layers)堆積疊而成,每一層都包含著檔案系統的變更記錄。當你執行一個容器時,Docker 會在這些唯讀的映像層之上新增一個可寫的容器層。Docker 採用複製即寫(copy-on-write)機制來有效管理這些層之間的互動。當你需要修改一個檔案時,Docker 會將該檔案複製到容器層,並在那裡進行修改,而原始的映像層保持不變。

如何實作資料持久化?

為了克服容器短暫性的限制,Docker 提供了資料持久化的解決方案,例如 Docker 卷。透過將 Docker 卷掛載到容器內,你可以將資料儲存在容器的外部,從而實作資料的持久化。這樣,即使容器被刪除或重新啟動,儲存在 Docker 卷中的資料仍然得以保留。

Docker 安裝

本文的實作練習需要一台可用的 Docker 主機。你可以按照本文中的步驟進行安裝,或者執行本文 GitHub 儲存函式庫中 chapter1 目錄下的 install-docker.sh 指令碼。

Docker 映像層結構

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Docker容器基礎與資料持久化

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

圖表翻譯: 此圖示展示了 Docker 映像層的結構,從基礎映像層開始,逐層疊加,最上層為可寫的容器層。

內容解密:

  • 圖中展示了 Docker 的分層結構,從底層的基礎映像層到頂層的可寫容器層。
  • 每個映像層都是唯讀的,而容器層是可寫的,用於儲存執行中的容器的變更。

程式碼範例:Dockerfile 編寫

# 使用官方 Nginx 映像作為基礎映像
FROM nginx:latest

# 複製自定義網頁到容器內的預設 Nginx 網頁目錄
COPY index.html /usr/share/nginx/html/index.html

# 暴露容器的 80 連線埠
EXPOSE 80

內容解密:

  • FROM nginx:latest:使用最新的官方 Nginx 映像作為基礎映像。
  • COPY index.html /usr/share/nginx/html/index.html:將當前目錄下的 index.html 複製到容器內的 Nginx 網頁目錄,取代預設的首頁。
  • EXPOSE 80:宣告容器監聽的連線埠號碼為 80,以便外部可以透過此連線埠存取 Nginx 服務。

總之,透過瞭解 Docker 的基本原理和操作,你可以更有效地使用 Docker 來開發、佈署和管理應用程式。接下來的章節將進一步探討 Docker 的進階功能,包括如何使用 Docker 卷和網路設定來增強容器的功能性和靈活性。

Docker 與容器基礎知識

現今,Docker 可安裝於幾乎所有硬體平台上。每個版本的 Docker 在各平台上的運作方式和外觀都相同,使得需要開發跨平台應用程式的人員能夠輕鬆使用 Docker。透過使不同平台之間的功能和命令保持一致,開發人員無需學習不同的容器執行環境即可執行映像檔。

下表列出了 Docker 可用的平台。如您所見,有多個作業系統以及多個 CPU 架構的安裝選項:

Docker 的可用平台

由於不同架構的映像檔無法在不同的架構上執行,因此無法在 x86 硬體上建立映像檔並期望該映像檔能在搭載 ARM 處理器的 Raspberry Pi 上執行。同樣需要注意的是,雖然可以在 Windows 機器上執行 Linux 容器,但無法在 Linux 機器上執行 Windows 容器。

用於安裝 Docker 的安裝步驟會因平台而異。幸運的是,Docker 已在其網站上記錄了許多安裝步驟:https://docs.docker.com/install/。

在本章中,我們將在 Ubuntu 18.04 系統上安裝 Docker。如果您沒有可供安裝的 Ubuntu 機器,您仍然可以閱讀有關安裝步驟的內容,因為每個步驟都將被詳細解釋,您無需實際執行的系統即可理解該過程。如果您有不同的 Linux 安裝,您可以使用 Docker 網站上提供的安裝步驟:https://docs.docker.com/。該網站提供了 CentOS、Debian、Fedora、Ubuntu 的安裝步驟,以及其他 Linux 發行版的通用安裝步驟。

準備安裝 Docker

在開始安裝之前,我們需要考慮要使用的儲存驅動程式。儲存驅動程式提供了聯合檔案系統,用於管理容器的層以及如何存取容器的可寫入層。

在大多數安裝中,您不需要更改預設的儲存驅動程式,因為會自動選擇預設選項。如果您執行的 Linux 核心版本至少為 4.0 或更高版本,您的 Docker 安裝將使用 overlay2 儲存驅動程式;較早的核心版本將安裝 AUFS 儲存驅動程式。

除了 overlay2AUFS 驅動程式之外,Docker 還支援 devicemapperbtrfszfsvfs 儲存驅動程式。但是,這些驅動程式很少在新系統中使用,此處僅作為參考。

如果您想了解每個儲存驅動程式,請參閱以下 Docker 網頁,該網頁詳細介紹了每個驅動程式及其使用案例:https://docs.docker.com/storage/storagedriver/select-storage-driver/。

現在您瞭解了儲存驅動程式的需求,下一步是選擇安裝方法。您可以透過以下三種方法之一來安裝 Docker:

  1. 將 Docker 軟體倉函式庫新增到您的主機系統。
  2. 手動安裝套件。
  3. 使用 Docker 提供的安裝指令碼。

第一種方法被認為是最佳選擇,因為它允許輕鬆安裝和更新 Docker 引擎。第二種方法對於沒有網際網路存取權的企業伺服器(即「隔離」伺服器)非常有用。第三種方法用於安裝 edge 和測試版本的 Docker,不建議用於生產環境。

由於首選方法是將 Docker 的軟體倉函式庫新增到我們的宿主機,因此我們將使用該選項並解釋新增軟體倉函式庫和安裝 Docker 的過程。

在 Ubuntu 上安裝 Docker

既然我們已經完成了所有準備工作,讓我們開始安裝 Docker:

  1. 第一步是透過執行 apt-get update 更新套件索引:
sudo apt-get update

內容解密:

此命令用於更新本地套件索引,以確保我們擁有最新的套件資訊。sudo 用於以管理員許可權執行命令。

  1. 接下來,我們需要新增可能在宿主機系統上遺失的套件,以允許 HTTPS apt 存取:
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

內容解密:

此命令安裝必要的套件,以允許系統透過 HTTPS 存取軟體倉函式庫,並安裝其他必要的工具,如 curlgnupg-agent

  1. 要從 Docker 的軟體倉函式庫中提取套件,我們需要新增其金鑰。您可以使用以下命令新增金鑰,該命令將下載 gpg 金鑰並將其新增到您的系統中:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

內容解密:

此命令下載 Docker 的 GPG 金鑰並將其新增到系統的金鑰圈中,以驗證 Docker 套件的真實性。

  1. 現在,將 Docker 的軟體倉函式庫新增到您的宿主機系統:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

內容解密:

此命令新增 Docker 的 APT 軟體倉函式庫到系統中,使我們能夠從該倉函式庫安裝 Docker。

  1. 完成所有先決條件後,您可以在伺服器上安裝 Docker:
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

內容解密:

第一個命令更新套件索引,以反映新新增的 Docker 軟體倉函式庫。第二個命令安裝 Docker 社群版(docker-ce)、Docker CLI(docker-ce-cli)和容器執行環境(containerd.io)。

  1. 現在,Docker 已安裝在您的宿主機上,但與大多數新服務一樣,Docker 目前未執行,也未組態為隨系統啟動。要啟動 Docker 並使其在啟動時啟用,請使用以下命令:
sudo systemctl enable docker && systemctl start docker

內容解密:

此命令啟用 Docker 服務,使其在系統啟動時自動啟動,並立即啟動 Docker 服務。

給予 Docker 許可權

在預設安裝中,Docker 需要 root 存取許可權,因此您需要以 root 身份執行所有 Docker 命令。與其在每個 Docker 命令前使用 sudo,您可以將您的使用者帳戶新增到伺服器上的一個新群組,該群組提供無需 sudo 的 Docker 存取許可權。

如果您以標準使用者身份登入並嘗試執行 Docker 命令,您將收到錯誤訊息:

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/images/json: dial unix /var/run/docker.sock: connect: permission denied

要允許您的使用者或其他您可能想要新增的使用者執行 Docker 命令,您需要建立一個新群組並將使用者新增到該群組。以下是您可以使用的範例命令,用於新增目前登入的使用者:

sudo groupadd docker
sudo usermod -aG docker $USER

內容解密:

第一個命令建立一個名為 docker 的新群組。第二個命令將目前登入的使用者帳戶新增到 docker 群組。

要使新的成員資格對您的帳戶生效,您需要登出系統並重新登入,這將更新您的群組。

最後,您可以透過執行標準的 hello-world 映像檔來測試它是否有效(注意,我們不需要使用 sudo 來執行 Docker 命令):

docker run hello-world

內容解密:

此命令下載並執行 hello-world 映像檔,用於測試 Docker 安裝是否成功以及目前使用者是否有許可權執行 Docker 命令。

使用 Docker CLI

當您執行 hello-world 容器來測試您的安裝時,您使用了 Docker CLI。Docker 命令是用於與 Docker daemon 互動的工具。使用這個單一的可執行檔,您可以執行以下操作,以及更多:

  • 啟動和停止容器
  • 提取和推播映像檔
  • 在活動容器中執行 shell
  • 檢視容器日誌
  • 建立 Docker 磁碟區
  • 建立 Docker 網路
  • 清理舊映像檔和磁碟區