在容器化應用普及的背景下,高效的資源管理成為維運的關鍵挑戰。本文從實務操作出發,系統性地介紹 Docker 容器與映像檔的完整生命週期管理策略。從外部網路存取驗證,到運行中容器的停止與移除,再到磁碟空間的清理,這些操作不僅是日常維運的基本功,更是建構穩健、可擴展容器化架構的基礎。掌握這些進階管理技巧,有助於開發者與維運團隊優化資源利用率,並維持開發環境的敏捷性與潔淨度。

容器化應用的進階管理:從瀏覽器存取到資源清理

透過瀏覽器存取容器化應用

雖然 curl 工具能夠從命令列驗證容器內應用程式的響應,但對於生成 HTML 輸出的 Web 應用程式,透過瀏覽器進行視覺化存取是更直觀且常用的方式。

使用 EC2 實例的公用 DNS

當運行 Docker 容器的 EC2 實例與我們本地的瀏覽器不在同一台機器上時,我們需要使用 EC2 實例的公用 DNS 名稱來存取應用程式。

  1. 獲取公用 DNS:在 AWS 管理控制台中,找到已啟動的 EC2 實例,其詳細資訊中會包含一個「公用 IPv4 DNS」欄位。這個 DNS 名稱類似於 ec2-xx-xx-xx-xx.compute-1.amazonaws.com
  2. 在瀏覽器中訪問:將獲取的公用 DNS 名稱,結合之前映射到主機的外部埠號(例如 32768),輸入到瀏覽器的網址列中。
    http://<PUBLIC_DNS_NAME>:<EXTERNAL_PORT>
    
    例如:http://ec2-xx-xx-xx-xx.compute-1.amazonaws.com:32768

這樣,我們就可以在本地的瀏覽器中看到由 helloapp 容器生成的 HTML 輸出,這與之前使用 curl 在命令列看到的內容應該是一致的。這也驗證了應用程式不僅能在容器內運行,還能透過網路從外部被成功訪問。

Docker 容器的生命週期管理:停止與移除

容器的生命週期管理是 Docker 操作的重要部分,包括停止不再需要的容器以及完全移除它們以釋放資源。

停止 Docker 容器

當我們不再需要一個正在運行的容器時,可以使用 docker stop 命令來停止它。

sudo docker stop <CONTAINER_NAME_OR_ID>

例如,要停止名為 helloapp 的容器:

sudo docker stop helloapp

執行此命令後,Docker 會向容器內的應用程式發送一個終止信號(SIGTERM),並等待一段時間。如果應用程式在規定時間內沒有自行終止,Docker 會發送一個強制終止信號(SIGKILL)。

停止後,如果再次運行 docker ps 命令,將不再看到 helloapp 容器,因為它已經不再運行。

移除 Docker 容器

停止的容器仍然會佔用磁碟空間(用於儲存其日誌和寫入層)。要完全釋放這些資源,需要使用 docker rm 命令來移除容器。

重要提示:移除容器前,必須先停止它。

sudo docker rm <CONTAINER_NAME_OR_ID>

例如,要移除已停止的 helloapp 容器:

sudo docker rm helloapp

執行此命令後,該容器及其相關的日誌和寫入層將被徹底刪除。

Docker 映像檔的清理與管理

隨著時間推移,本地可能會積累大量的 Docker 映像檔,其中一些可能不再被使用,或者是不完整的下載產物(稱為「懸空映像檔」或「dangling images」)。定期清理這些映像檔對於節省磁碟空間至關重要。

移除 Docker 映像檔

可以使用 docker rmi 命令來移除指定的 Docker 映像檔。

sudo docker rmi <IMAGE_NAME_OR_ID>

例如,要移除 tutum/hello-world 映像檔:

sudo docker rmi tutum/hello-world

重要提示:一個映像檔只有在沒有任何容器(無論是運行中還是已停止)依賴它的情況下,才能被成功移除。如果存在依賴,Docker 會報錯提示。

清理懸空映像檔

有時,在映像檔構建過程中,某些層級可能下載不完整,或者舊版本的映像檔被替換後,其不再被任何標籤引用的層級會變成懸空映像檔。這些映像檔通常沒有名稱和標籤,在 docker images 的輸出中會顯示為 <none>

可以使用以下命令來批量移除所有懸空映像檔:

sudo docker rmi $(sudo docker images -f "dangling=true" -q)
  • sudo docker images -f "dangling=true" -q:這個命令會列出所有懸空映像檔的 Image ID(-q 選項只輸出 ID)。
  • $(...):命令替換,將前面命令的輸出作為參數傳遞給 docker rmi

執行此命令後,所有懸空的映像檔層級都會被移除。

停止 Docker 服務

在某些維護或關閉伺服器的場景下,可能需要停止 Docker 服務本身。

sudo service docker stop

或者使用 systemctl

sudo systemctl stop docker

停止 Docker 服務會導致所有正在運行的 Docker 容器也隨之停止。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

object "使用者" as User
object "Docker CLI" as DockerCLI
object "Docker Daemon" as DockerDaemon
object "Docker Container (helloapp)" as HelloappContainer
object "Docker Image (tutum/hello-world)" as TutumImage

partition "Docker 容器與映像檔清理流程" {
  User --> DockerCLI : 執行 docker stop helloapp
  DockerCLI --> DockerDaemon : 請求停止容器
  DockerDaemon --> HelloappContainer : 發送終止信號並停止容器
  User --> DockerCLI : 執行 docker rm helloapp
  DockerCLI --> DockerDaemon : 請求移除容器
  DockerDaemon --> HelloappContainer : 徹底刪除容器及其資源
  User --> DockerCLI : 執行 docker rmi tutum/hello-world
  DockerCLI --> DockerDaemon : 請求移除映像檔
  DockerDaemon --> TutumImage : 移除映像檔 (若無容器依賴)
  User --> DockerCLI : 執行 docker images -f "dangling=true" -q
  DockerCLI --> DockerDaemon : 請求列出懸空映像檔 ID
  DockerDaemon --> User : 回傳懸空映像檔 ID 列表
  User --> DockerCLI : 執行 docker rmi <Dangling_Image_IDs>
  DockerCLI --> DockerDaemon : 請求批量移除映像檔
  DockerDaemon --> User : 回傳移除狀態
  User --> DockerCLI : 執行 service docker stop
  DockerCLI --> DockerDaemon : 請求停止 Docker 服務
  DockerDaemon --> User : 停止 Docker 服務
}

@enduml

看圖說話:

此圖示展示了 Docker 容器和映像檔的清理流程。首先,使用者希望停止一個名為 helloapp 的容器,於是執行 docker stop helloapp 命令。Docker CLI 將此請求傳送給 Docker Daemon,Daemon 會向 helloapp 容器發送終止信號,使其停止運行。接著,如果使用者決定永久移除該容器,則執行 docker rm helloapp 命令。Docker Daemon 會接收請求,並徹底刪除 helloapp 容器及其相關的日誌和寫入層。隨後,使用者可能需要清理不再使用的映像檔,例如 tutum/hello-world,執行 docker rmi tutum/hello-world 命令。Docker Daemon 在移除映像檔前會檢查是否有容器依賴該映像檔,若無則將其刪除。對於下載過程中產生的懸空映像檔(即沒有被任何標籤引用的映像檔層),使用者可以透過執行 docker images -f "dangling=true" -q 命令來獲取這些懸空映像檔的 ID,然後再將這些 ID 傳遞給 docker rmi 命令進行批量移除。最後,如果需要關閉整個 Docker 服務,使用者可以執行 service docker stop 命令,Docker Daemon 會停止所有與 Docker 相關的進程和服務。

Docker 環境建置與核心操作回顧

本章節深入探討了 Docker 的基本概念與實踐,涵蓋了從環境準備到應用程式容器化的完整流程。我們在兩種主流的 Linux 發行版上成功安裝並配置了 Docker:

  • Red Hat Enterprise Linux 7:透過官方安裝腳本,簡潔高效地完成了 Docker Engine 的部署,並學習了如何調整服務啟動超時設定,以確保服務的穩定運行。
  • Ubuntu (多個 LTS 版本):遵循 APT 套件管理系統的流程,更新了套件來源,安裝了必要的 Linux 核心更新,並最終成功部署了 Docker Engine。

在完成 Docker 環境的建置後,我們實際操作了 Docker 的核心功能,包括:

  • 下載 Docker 映像檔:使用 docker pull 命令從 Docker Hub 等倉庫獲取預先構建好的應用程式藍圖。
  • 運行 Docker 容器:透過 docker run 命令,基於映像檔創建並啟動容器,包括在前台和後台(detached mode)模式下運行。
  • 容器應用程式存取:學習了如何將容器內的應用程式埠號映射到主機,並透過 curl 工具或遠端瀏覽器存取容器中的 Web 應用程式。
  • 容器與映像檔管理:掌握了使用 docker psdocker stopdocker rmdocker imagesdocker rmi 等命令來管理容器的生命週期和清理本地映像檔,確保系統資源的有效利用。

這些基礎操作為後續更複雜的容器化應用開發和部署奠定了堅實的基礎。

下一階段的探索:Linux 容器化

在掌握了 Docker 的基本操作後,下一階段的學習將聚焦於更深入的應用場景。第二章將引導我們學習如何在 Docker 容器內部運行一個完整的 Linux 作業系統。這不僅僅是運行一個簡單的應用程式,而是將整個 Linux 發行版封裝到容器中。

Linux 安裝的多樣化途徑

在傳統的伺服器管理中,安裝 Linux 作業系統有多種方式,例如:

  • 使用雲端供應商提供的 AMI:如 Amazon EC2 提供的 Amazon Linux AMI。
  • 從 ISO 映像檔安裝:這是最常見的物理機或虛擬機安裝方式。
  • 使用虛擬機映像檔:例如預先配置好的 VirtualBox 或 VMware 映像檔。

然而,在 Docker 的世界裡,安裝 Linux 作業系統將呈現出全新的維度:

  • 透過 Docker 映像檔安裝 Linux 發行版:這意味著我們可以利用 Docker Hub 上提供的各種 Linux 發行版(如 Oracle Linux, Ubuntu, Red Hat 等)的映像檔,快速啟動一個隔離的 Linux 環境。這將極大地簡化環境配置和測試流程。

第二章的核心內容預覽

在第二章中,我們將會探索以下關鍵主題:

  • 設定環境:準備 Docker 主機以運行 Linux 容器。
  • 下載 Linux 發行版的 Docker 映像檔:獲取如 Oracle Linux 等發行版的映像檔。
  • 管理 Docker 映像檔:列出和檢查已下載的映像檔。
  • 在後台模式運行 Linux 容器:啟動一個隔離的 Linux 環境,使其在後台持續運行。
  • 在前台模式運行 Linux 容器:以交互式方式啟動一個 Linux 環境,以便直接操作。
  • 列出 Docker 容器:查看所有正在運行的 Linux 容器。
  • 獲取 Oracle Linux 容器資訊:深入了解特定容器的詳細配置和狀態。
  • 列出容器內部的進程:查看在 Linux 容器中運行哪些進程。

透過這些學習,我們將能夠更靈活地利用 Docker 來構建、測試和部署各種應用程式,無論它們是簡單的 Web 服務還是完整的作業系統環境。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

object "使用者" as User
object "Docker CLI" as DockerCLI
object "Docker Daemon" as DockerDaemon
object "Docker Image (Linux Distro)" as LinuxImage
object "Docker Container (Linux OS)" as LinuxContainer

partition "Docker 基礎總結與下一階段展望" {
  note as N1
    本章節回顧了 Docker 的安裝、
    映像檔下載、容器運行、
    埠號映射、應用存取、
    以及容器與映像檔的清理管理。
    涵蓋了 Red Hat 7 和 Ubuntu 上的部署實踐。
  end note

  User --> DockerCLI : 執行 Docker 操作 (pull, run, ps, stop, rm, rmi)
  DockerCLI --> DockerDaemon : 協調映像檔下載與容器生命週期
  DockerDaemon --> LinuxImage : 管理本地 Docker 映像檔
  DockerDaemon --> LinuxContainer : 管理容器運行狀態與資源

  note as N2
    下一章節將聚焦於:
    在 Docker 容器中運行完整的 Linux 作業系統。
    學習安裝 Linux 發行版(如 Oracle Linux)的 Docker 映像檔,
    並進行容器化部署與管理。
  end note

  User --> DockerCLI : 準備進入下一階段學習
  DockerCLI --> User : 提示下一章節主題:Linux 容器化
}

@enduml

看圖說話:

此圖示總結了本章節 Docker 基礎知識的學習內容,並展望了下一階段的學習方向。圖中的「使用者」透過「Docker CLI」與「Docker Daemon」互動,執行了諸如 docker pull(下載映像檔)、docker run(運行容器)、docker ps(列出容器)、docker stop(停止容器)、docker rm(移除容器)和 docker rmi(移除映像檔)等核心操作。這些操作共同構成了 Docker 的基礎應用框架,涵蓋了從映像檔的獲取到容器的運行、管理與清理的全過程。圖中特別標註了「Docker Image (Linux Distro)」和「Docker Container (Linux OS)」,暗示了本章節雖然涵蓋了基礎的應用容器運行,但下一階段將深入到將整個 Linux 作業系統本身容器化的層面。下方的「下一章節將聚焦於…」的註解,清晰地指出了下一階段的學習重點:如何在 Docker 容器內運行完整的 Linux 作業系統,例如 Oracle Linux,並進行相關的部署與管理。這表明了從單一應用容器化到作業系統級別容器化的進階過程。

好的,這是一篇針對該技術文章,採用「玄貓風格」撰寫的結論。


結論

視角: 績效與成就視角

縱觀容器化應用的完整生命週期,從部署驗證到資源回收的每個環節,都深刻影響著系統的長期效能與穩定性。本章節的探討,不僅展示了從指令列 curl 驗證到瀏覽器視覺化存取的實務跨越,其更核心的價值在於揭示了資源管理的紀律性。

docker stoprmrmi 等指令,看似基礎,實則構成了防止資源洩漏與維持系統健康的治理框架。許多團隊在初期僅專注於「運行」,卻忽略了已停止容器與懸空映像檔(dangling images)對磁碟空間的持續侵蝕,這正是從入門者邁向專業維運人員必須跨越的認知瓶頸。將這些清理指令整合為系統化的管理流程,是確保資源利用率最佳化的關鍵實踐。

精通此類管理技術,不僅是提升系統效能的直接手段,更象徵著工程師從「功能實現者」轉變為「系統管理者」的思維升級。這種對資源生命週期的掌控力,是未來駕馭更複雜部署(如在容器中運行完整作業系統)的必要基礎。

玄貓認為,將這種系統性的資源治理內化為日常開發與維運的標準作業流程,是確保容器化環境長期穩定、高效與可擴展的基石,也代表了技術專業成熟度的關鍵指標。