初學者指南:Docker 服務 (Service) 與容器 (Container) 的區別

更新日期: 2025 年 3 月 13 日

如果你是剛接觸 Docker 的新手,可能會被 Docker 中各種名詞搞得頭暈目眩,特別是「服務 (Service)」和「容器 (Container)」這兩個詞,經常在文件和教學中反覆出現,卻又似乎有些不同。

理解這兩者的區別,不僅能幫助你更好地使用 Docker,還能讓你的開發和部署流程變得更加流暢。

本篇文章將從概念、用途和應用場景多角度深入介紹 Docker 服務與容器,讓你快速上手,避免踩坑。


Docker 容器 (Container) 是什麼?

概念

Docker 容器 (Container) 是一個輕量級、獨立的運行環境,它將應用程式及其所有依賴項(如程式碼、庫、配置文件等)打包在一起,使應用程式能夠在任何環境中保持一致的運行效果。

容器類似於虛擬機 (VM),但不同的是,容器不需要整個操作系統 (OS) 的開銷,而是與宿主系統 (Host) 共享操作系統核心 (Kernel),這使得容器比虛擬機更輕量、啟動更快速。

主要特點

  • 輕量化:容器啟動速度通常在秒級,佔用資源也較少,允許在同一台伺服器上運行更多的應用程式實例。
  • 便於移植:只要 Docker 環境一致,容器能夠在不同的開發、測試、運行環境中保持相同的效果,消除了「在我這裡可以運行,但在伺服器上不行」的問題。
  • 獨立性:每個容器擁有自己的文件系統、網路、進程空間 (Process Space),互不干擾,這有助於提高應用的安全性和穩定性。

如何創建與管理 Docker 容器?

在 Docker 中,管理容器的基本操作包括創建、查看、停止和刪除容器。

1️⃣ 從映像檔啟動一個新的容器

docker run -d --name my-container nginx

這個指令在做什麼?

  • docker run 是創建並啟動容器的指令。
  • -d (Detached mode) 讓容器在後台運行,而不是佔用你的終端 (Terminal)。
  • --name my-container 為容器指定名稱 “my-container”,這樣你之後可以用這個名稱管理容器,而不需要使用自動生成的隨機名稱或容器 ID。
  • nginx 是映像檔的名稱,表示從 Docker Hub 下載並使用官方的 Nginx 映像檔。如果本地沒有這個映像檔,Docker 會自動從遠端倉庫拉取 (Pull) 下來。

這個指令運行後會發生什麼?

  • Docker 會下載 Nginx 映像檔(如果本地沒有)。
  • 創建一個新的容器,並在裡面啟動 Nginx Web 伺服器。
  • 容器會在後台運行,你可以繼續在終端中輸入其他命令。

如何確認容器已經成功運行?

你可以通過接下來的 docker ps 指令來查看運行中的容器,並確認 “my-container” 是否已啟動。

2️⃣ 查看運行中的容器

docker ps

這個指令在做什麼?

  • docker ps 是用來查看目前正在運行的所有容器的指令。
  • 這個指令會列出所有處於 “運行中” (Up) 狀態的容器,而不會顯示已經停止 (Exited) 的容器。

輸出結果包含哪些信息?

執行後你會看到類似這樣的輸出:

CONTAINER ID   IMAGE    COMMAND                  CREATED         STATUS         PORTS                  NAMES
f3a123456789   nginx    "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->80/tcp     my-container
  • CONTAINER ID:容器的唯一識別碼 (ID),你可以用這個 ID 進行管理操作(如停止、刪除等)。
  • IMAGE:容器使用的映像檔名稱,在這裡是 nginx
  • COMMAND:容器啟動時執行的命令,這裡是 "/docker-entrypoint.…"(Nginx 默認啟動命令)。
  • CREATED:容器創建的時間,例如 “2 minutes ago”。
  • STATUS:容器的運行狀態,”Up 2 minutes” 表示已運行了兩分鐘。
  • PORTS:容器內的服務與宿主機之間的端口映射,例如 0.0.0.0:80->80/tcp 表示容器的 80 埠映射到宿主機的 80 埠。
  • NAMES:容器名稱,這裡是 my-container,如果沒有用 --name 指定,這裡會顯示一個自動生成的隨機名稱。

3️⃣ 停止並刪除容器

docker stop my-container
docker rm my-container

這些指令在做什麼?

  1. 停止容器 (docker stop)
docker stop my-container
  • docker stop 會將指定的容器優雅地關閉 (Gracefully Stop),讓容器內的應用程式有機會處理未完成的任務 (如保存數據或安全退出)。
  • my-container 是容器名稱(也可以使用容器 ID 代替名稱)。
  • 停止容器後,你可以再用 docker ps 檢查,容器將不再顯示在運行中的列表中,但 docker ps -a 還是可以看到它處於 Exited 狀態。
  1. 刪除容器 (docker rm)
docker rm my-container
  • docker rm 會將指定的容器從 Docker 系統中永久刪除。
  • 這個指令僅能刪除處於停止 (Exited) 狀態的容器,無法直接刪除正在運行的容器。
  • 刪除後,容器的所有數據和狀態都會消失,無法恢復。

什麼是 Docker 服務 (Service)?

概念

簡單來說,Docker 服務 (Service) 就是一個能幫你自動管理多個容器的工具。

如果你的應用程式只需要一個容器運行,直接用 docker run 就行了,但當你的應用程式需要多個容器一起工作,還要確保它們一直正常運行,這時候 Docker 服務就很有用了。

🚦 舉個例子

想像你有個網站,平時 100 人訪問時,一個容器足夠應付,但如果突然有 1000 人同時上線,一個容器就撐不住了。

這時 Docker 服務會自動幫你開啟更多容器,讓訪問量平均分配到每個容器上,確保網站不卡不掛。

而且,如果某個容器崩潰了,服務還會自動重啟一個新容器,讓服務保持在線,這就是「高可用性 (High Availability)」。

什麼是 Docker Swarm?

Docker Swarm 可以理解為一個「容器管理的大腦」,它把多台裝有 Docker 的伺服器 (Host) 組成一個「團隊 (集群, Cluster)」。

Swarm 會自動把應用程式的容器分配到不同的伺服器 (也叫節點, Node) 上,實現負載平衡和資源最佳化。

  • 管理節點 (Manager Node):大腦角色,負責分配工作、管理容器和服務設定。
  • 工作節點 (Worker Node):執行角色,實際運行容器,處理應用程式的任務。

Docker 服務的四大特點

  1. 自動擴展 (Scalability)
    只需一條命令就能調整容器的數量,應對流量變化。例如,當網站流量暴增時,可以快速把容器數量從 3 個擴展到 10 個,不需要手動啟動容器。
  2. 負載平衡 (Load Balancing)
    Swarm 會把用戶的請求平均分配到所有容器,避免某個容器超載而其他容器閒置。
  3. 容錯機制 (Fault Tolerance)
    如果某個容器崩潰,Swarm 會自動在其他節點上啟動新的容器,保持服務的穩定運行。
  4. 滾動更新 (Rolling Update)
    當需要更新應用程式時,Swarm 會逐個重啟容器,讓應用程式在不影響用戶體驗的情況下完成升級。

應用範例

flowchart LR
    subgraph Docker_Swarm_集群
        direction LR
        
        %% 服務 (Service) 節點
        S1[服務: 網站服務<br/>3個 Nginx 容器]
        
        %% Swarm 節點 (Nodes)
        N1[節點 1]
        N2[節點 2]
        N3[節點 3]
        
        %% 服務與節點連線
        S1 --> N1
        S1 --> N2
        S1 --> N3
        
        %% 容器 (Containers) - Nginx
        N1 --> C1[容器 1: Nginx]
        N2 --> C2[容器 2: Nginx]
        N3 --> C3[容器 3: Nginx]
    end
    
    %% 用戶請求進入服務
    用戶[用戶請求] -->|自動負載平衡| S1
  1. 網站服務 (web-service)
    • 這是一個 Nginx 靜態網站服務,設定了 3 個副本 (Replicas)。
    • 也就是說,這個服務會自動啟動 3 個 Nginx 容器。
  2. Swarm 節點 (Nodes)
    • 有 3 個節點 (伺服器),每個節點上運行 1 個 Nginx 容器。
    • Swarm 會自動把 3 個容器分配到不同的節點上,這樣即使有一台伺服器出現故障,網站服務仍然能運行。
  3. 用戶請求的流向
    • 用戶的請求會進入「網站服務」(Service)。
    • Swarm 會自動把請求平均分配到 3 個 Nginx 容器中的一個,實現負載平衡
    • 例如:第一個請求到容器 1,第二個請求到容器 2,第三個請求到容器 3,第四個請求再回到容器 1…依此類推。

💡 為什麼要用多個容器?

  • 負載平衡 (Load Balancing)
    • 3 個容器能同時處理更多請求,避免單一容器超載。
  • 高可用性 (High Availability)
    • 如果某個容器或伺服器宕機 (Down),服務仍然可用,因為還有其他容器在運行。
  • 彈性擴展 (Scalability)
    • 當網站流量增加時,可以透過簡單的指令把「網站服務」的容器數量從 3 個擴展到 5 個、10 個,Swarm 會自動幫你分配資源。

怎麼創建和管理 Docker 服務?

接下來讓我一步步帶你用 Docker 指令操作服務吧!

1️⃣ 初始化 Swarm 模式(只需做一次)

docker swarm init

這條指令會把你的 Docker 主機變成 管理節點 (Manager Node),就像是把你的伺服器升級成「容器管理員」,準備好管理多個容器和服務。

如果你有多台伺服器,這條命令還會生成一條 docker swarm join 指令,讓其他伺服器也能加入這個 Swarm 集群 (Cluster),變成新的節點 (Node)。

2️⃣ 創建一個服務,啟動 3 個容器

docker service create --name my-service --replicas 3 -p 8080:80 nginx

👉 這條指令的意思是:創建一個名叫 my-service 的服務,啟動 3 個 Nginx 容器,並把宿主機的 8080 埠 (Port) 連接到容器的 80 埠。

  • --name my-service:設定服務名稱,方便後續管理。
  • --replicas 3:設定運行 3 個容器副本。
  • -p 8080:80:將 8080 埠對應到容器的 80 埠,這樣通過 http://localhost:8080 就能訪問服務。
  • nginx:指定使用的 Nginx 映像檔 (Image)。

當這個服務啟動後,Swarm 會自動把這 3 個容器分配到不同的節點上 (如果有多台伺服器),並自動幫你進行負載平衡。

3️⃣ 查看服務運行狀態

docker service ls

這條指令會列出所有正在運行的服務,例如:

ID            NAME        MODE        REPLICAS  IMAGE    PORTS
a1b2c3d4e5f6  my-service  replicated  3/3       nginx    *:8080->80/tcp
  • REPLICAS 3/3:表示預期有 3 個容器,實際也有 3 個容器在運行,說明服務運行正常。
  • 如果看到 2/3,就說明有一個容器出了問題,Swarm 會自動補上新的容器保持 3/3 的狀態。

4️⃣ 快速擴展服務,增加容器數量

docker service scale my-service=5

這個命令會把 my-service 服務的容器副本數量從 3 個擴展到 5 個,Swarm 會自動在不同的節點上啟動新容器,不需要你手動操作每個容器。

5️⃣ 刪除服務

docker service rm my-service

當你不再需要這個服務時,用這條命令可以把服務和所有相關的容器一併刪除,清理系統資源。


Docker Compose 是在定義什麼?

在 Docker Compose 的設定檔 (docker-compose.yml) 中,你定義的是一組「服務 (Services)」,每個服務對應到一個應用程式或容器的設定。

這裡的「服務」類似於 Swarm 中的服務概念,但是用在單一主機或多容器應用場景中。

📝 範例:docker-compose.yml

version: '3.9'
services:
  web:
    image: nginx
    ports:
      - "8080:80"
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example

在這個例子中,你定義了兩個服務 (webdb):

  • web 服務會啟動一個 Nginx 容器,並將本機的 8080 埠對應到容器的 80 埠。
  • db 服務會啟動一個 MySQL 容器,並設置了資料庫的環境變數。

🚦 這裡的「服務 (Service)」是什麼意思?

  • webdb 是兩個服務,分別負責運行不同的應用程式(Nginx 和 MySQL)。
  • 當你啟動服務時,Docker Compose 會根據每個服務的設定,自動幫你創建和運行對應的容器。

🚀 那當你執行 docker compose up 時,發生了什麼?

docker compose up
  1. 讀取 Compose 檔案 (docker-compose.yml):Docker Compose 會讀取設定檔中的所有服務定義。
  2. 創建服務
    • 為每個服務創建一個或多個容器(依據 scaledeploy 設置來決定容器數量)。
    • 自動處理網路、資料夾掛載 (Volumes)、環境變數等設定。
  3. 啟動容器
    • 實際運行的是「容器」,但這些容器是透過「服務」的設定自動生成的。
    • 例如,web 服務會啟動一個 Nginx 容器,db 服務會啟動一個 MySQL 容器。

docker compose up vs. docker run

功能docker compose updocker run
管理對象服務 (Service)單一容器 (Container)
行為創建和啟動多個容器,根據 docker-compose.yml 中定義的多個服務直接啟動一個容器,從映像檔 (Image) 執行應用程式
擴展性支援多服務、多容器,內建網路、數據卷 (Volume)、依賴關係管理一次只能啟動單個容器,需要手動配置網路和資料卷
用例用於多容器應用 (例如,Web + 資料庫),提供自動管理適合快速測試單個映像檔,或簡單場景

1️⃣ docker run:單一容器管理與手動配置示範

docker run 是 Docker 中用於啟動單一容器的指令。從映像檔 (Image) 中創建一個新的容器,並可以自訂各種配置,例如:

  • 容器命名 (--name)
  • 網路設定 (--network)
  • 資料卷掛載 (-v)
  • 環境變數 (-e)
  • 埠映射 (-p)

示例:啟動一個 Nginx 容器

假設你需要啟動一個 Nginx 伺服器,並滿足以下需求:

  • 在本地端口 8080 提供服務。
  • 使用本地資料夾 ./html 作為靜態頁面的來源。
  • 設定環境變數 (例如 Nginx 日誌級別)。
  • 容器連接到指定的 Docker 網路 my_network
# 1. 創建 Docker 網路
docker network create my_network

# 2. 啟動 Nginx 容器
docker run -d \
  --name nginx-container \
  -p 8080:80 \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  -e NGINX_LOG_LEVEL=info \
  --network my_network \
  nginx

指令解釋:

  • -d:在背景 (detached) 模式下運行容器。
  • --name nginx-container:給容器命名,方便管理。
  • -p 8080:80:將本地端口 8080 映射到容器的 80 端口。
  • -v $(pwd)/html:/usr/share/nginx/html:ro:將本地資料夾掛載到容器的靜態頁面目錄(只讀模式)。
  • -e NGINX_LOG_LEVEL=info:設定環境變數,調整 Nginx 的日誌級別。
  • --network my_network:將容器連接到之前創建的 Docker 網路 my_network

手動操作的挑戰:

  1. 多容器協作麻煩: 如果需要增加資料庫(例如 MySQL),還需要額外的命令:
# 啟動 MySQL 容器
docker run -d \
  --name mysql-container \
  -e MYSQL_ROOT_PASSWORD=example \
  -v mysql_data:/var/lib/mysql \
  --network my_network \
  mysql:5.7
  1. 無法自動管理依賴關係: Nginx 可能在 MySQL 準備好之前啟動,導致應用服務錯誤。
  2. 擴展性差: 如果想啟動多個 Nginx 容器(例如負載均衡),需要手動多次執行 docker run,而且難以同步管理。

2️⃣ docker compose up:用配置文件簡化操作

docker compose up 是 Docker Compose 中用於啟動多個容器的指令。

通過編寫 docker-compose.yml 文件,可以將所有配置統一管理,實現:

  • 自動創建和啟動多個容器。
  • 自動處理網路、資料卷和依賴關係。
  • 方便進行服務擴展 (Scaling)。

將上面的手動配置轉換成 docker-compose.yml 文件

version: '3.9'

services:
  nginx:
    image: nginx
    container_name: nginx-container
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    environment:
      - NGINX_LOG_LEVEL=info
    networks:
      - my_network
    depends_on:
      - db

  db:
    image: mysql:5.7
    container_name: mysql-container
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - my_network

volumes:
  db_data:

networks:
  my_network:

docker-compose.yml 文件的優勢:

  1. 集中管理: 將所有配置統一寫在文件中,版本控制更方便。
  2. 自動化啟動順序: depends_on 確保資料庫 (db) 在 Nginx 之前啟動。
  3. 簡化指令: 只需一條指令就能啟動整個應用程式:
docker compose up -d
  • 停止與清理:
docker compose down

擴展多容器更方便:

如果需要啟動多個 Nginx 副本,支援簡單的擴展指令:

docker compose up --scale nginx=3 -d

這比手動執行多次 docker run 簡單得多,並且所有容器都會自動加入相同網路。

3️⃣ 什麼時候該用哪個指令?

  • docker run 適用於:
    • 簡單場景,例如測試單一容器或執行臨時工具: docker run -it --rm alpine sh
    • 只需要單個容器,不涉及多容器協作的場景。
  • docker compose up 適用於:
    • 複雜應用程式,包括多個相互依賴的服務 (例如 Web + 資料庫 + 緩存系統)。
    • 開發、測試和生產環境,特別是需要自動化部署和管理的情況。
    • 需要擴展 (Scaling) 和服務更新 (Rolling Update) 的場景。

小結與建議

對於初學者來說,理解 Docker 容器和服務的區別是一個重要的基礎。

在日常開發中,你可能更多地與「容器」打交道,因為它簡單、直觀、適合測試和本地開發。

而當你的應用需要進入生產環境,特別是需要應對流量波動或實現高可用性時,使用 Docker 服務能讓你事半功倍。

在開始使用 Docker 時,建議先從容器入手,熟悉基礎操作,然後逐步學習 Docker Swarm 或 Kubernetes 等容器編排工具。

這樣你將能夠更從容地應對各種應用場景,讓你的開發流程更專業、更高效。

Similar Posts