cover

概念概覽

flowchart LR
    A[Dockerfile 定義] -->|docker build| B[Image 映像檔]
    B -->|docker run| C[Container 容器]
    C --> D[應用程式運行]
    B -->|docker push| E[Registry 倉庫]
    E -->|docker pull| B
    C --> F[網路/Port 對應]
    C --> G[Volume 資料掛載]
    H[Docker Compose] -->|編排多容器| C
    I[Kubernetes] -->|大規模編排| C

什麼是容器化?

「可是在我的電腦上明明可以跑啊!」——如果你寫過程式,一定聽過(或說過)這句話。環境不一致是開發者的日常惡夢:你的 Node.js 版本跟同事不一樣、你裝了某個系統套件但伺服器上沒有、或是測試環境跟正式環境的設定差了一點點就爆了。容器化技術的出現,基本上就是為了終結這個問題——把你的程式連同它需要的「整個環境」一起打包,走到哪裡都能跑。

容器化(Containerization)是一種將應用程式與其運行所需的所有依賴項(程式庫、設定檔、環境變數等)打包在一起的技術。容器提供了一個隔離的運行環境,確保應用程式在任何環境中都能一致地運行。

容器 vs 虛擬機器

特性容器虛擬機器 (VM)
啟動時間秒級分鐘級
資源佔用輕量(MB 級)重量(GB 級)
隔離程度進程級隔離完整 OS 隔離
效能接近原生有虛擬化開銷
可移植性極高較低

Docker 基礎

Docker 是目前最流行的容器化平台,它讓開發者可以輕鬆地建立、部署和運行容器。

核心概念

  • Image(映像檔):容器的藍圖,包含應用程式和所有依賴項
  • Container(容器):從映像檔建立的運行實例
  • Dockerfile:定義如何建立映像檔的腳本
  • Registry(倉庫):存放和分發映像檔的服務(如 Docker Hub)

Dockerfile 範例

# 使用 Node.js 官方映像檔作為基礎
FROM node:18-alpine
 
# 設定工作目錄
WORKDIR /app
 
# 複製 package.json 並安裝依賴
COPY package*.json ./
RUN npm install
 
# 複製應用程式碼
COPY . .
 
# 暴露應用程式埠
EXPOSE 3000
 
# 啟動應用程式
CMD ["npm", "start"]

常用 Docker 指令

# 建立映像檔
docker build -t my-app .
 
# 運行容器
docker run -d -p 3000:3000 my-app
 
# 查看運行中的容器
docker ps
 
# 停止容器
docker stop <container_id>
 
# 進入容器
docker exec -it <container_id> /bin/sh

學會用 Docker 跑一個容器之後,你很快就會遇到下一個問題:實際的專案通常不只一個服務——前端、後端、資料庫,總不能一個一個手動 docker run 吧?

Docker Compose

當應用程式需要多個服務(如前端、後端、資料庫)時,Docker Compose 可以協調管理這些容器。

# docker-compose.yml
version: '3.8'
services:
  web:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - api
 
  api:
    build: ./backend
    ports:
      - "8080:8080"
    environment:
      - DB_HOST=db
    depends_on:
      - db
 
  db:
    image: postgres:14
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=secret
 
volumes:
  postgres_data:

Kubernetes 簡介

當容器數量增加,需要在多台機器上運行時,Kubernetes(K8s)提供了容器編排的解決方案。

K8s 核心概念

  • Pod:最小部署單位,可包含一個或多個容器
  • Deployment:管理 Pod 的副本數量和更新策略
  • Service:為 Pod 提供穩定的網路存取點
  • Ingress:管理外部流量進入叢集

簡單的 K8s 部署

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app:latest
        ports:
        - containerPort: 3000

容器化的優點

  1. 環境一致性:「在我電腦上可以跑」的問題不再發生
  2. 快速部署:秒級啟動,支援 CI/CD 流程
  3. 資源效率:比虛擬機器更輕量,提高硬體利用率
  4. 微服務架構:每個服務獨立容器化,便於擴展和維護
  5. 版本控制:映像檔可版本化管理,輕鬆回滾

延伸閱讀

Docker 官方文件 Kubernetes 官方文件 Docker — 從入門到實踐 架構 CD