iT邦幫忙

2025 iThome 鐵人賽

DAY 7
1
DevOps

賢者大叔的容器修煉手札系列 第 7

Kubernetes 資源管理 - 讓你的 Pod 不再餓肚子

  • 分享至 

  • xImage
  •  

賢者大叔的容器修煉手札:Kubernetes 資源管理 - 讓你的 Pod 不再餓肚子 🍱

還記得我們之前聊過的 Pod 生命週期嗎?我們學會了如何讓 Pod 健康地啟動和運行。但是各位,有沒有想過一個問題:當你的 Pod 在 cluster 中運行時,它到底需要多少 CPU記憶體?如果資源不夠用會發生什麼事?
就像你去餐廳用餐,如果沒有事先預約,可能就要等位子;如果點了太多菜,可能會撐死;如果餐廳食材不夠,可能就要請你離開。K8s 的資源管理就是要解決這些問題!

今日學習目標 🎯

✅ 理解資源請求與限制的概念:學會為 Pod 「訂位」和「設限」

✅ 掌握 QoS 服務品質分類:了解 Pod 的「VIP 等級」

✅ 實作資源管理配置:動手配置不同等級的資源策略

✅ 培養架構思維:從功能導向轉為可靠性導向的思考模式

為什麼需要 Resource Management?🤔

沒有資源管理的災難現場
想像一下,你是一家餐廳的老闆,如果你不控制客人數量會發生什麼?

# 災難場景一:資源搶奪大戰
Pod A: "我要用完所有 CPU!" 💪
Pod B: "我也要!" 💪  
Pod C: "等等我!" 😵
結果:大家都卡住了... 🔴

在 Docker Compose 時代,我們通常只關心「功能能不能跑」,但在 K8s cluster 中,資源就是生存的關鍵!

真實世界的問題

# 沒有資源限制的 Pod
apiVersion: v1
kind: Pod
metadata:
  name: greedy-pod
spec:
  containers:
  - name: app
    image: nginx
    # 沒有任何資源設定 ⚠️

這個 Pod 就像一個不知節制的食客,可能會:

  • 🔴 吃光所有 CPU,讓其他 Pod 餓死
  • 🔴 佔用過多記憶體,導致節點崩潰
  • 🔴 讓調度器無法做出明智決策

資源單位快速參考

📏 資源單位快速參考:
CPU:
  - 1000m = 1 CPU 核心
  - 500m = 0.5 CPU 核心  
  - 100m = 0.1 CPU 核心

Memory:
  - Ki = 1024 bytes (二進制)
  - Mi = 1024 Ki = 1,048,576 bytes
  - Gi = 1024 Mi = 1,073,741,824 bytes
  - K = 1000 bytes (十進制)
  - M = 1000 K = 1,000,000 bytes

資源管理的兩大支柱 🏛️

1. Requests(資源請求)- 「我至少需要這麼多」
就像去餐廳預約座位,你告訴餐廳「我們有 4 個人」,餐廳就會為你保留 4 人桌。

resources:
  requests:
    memory: "200Mi"  # 我至少需要 200MB 記憶體
    cpu: "100m"      # 我至少需要 0.1 個 CPU 核心

Requests 的作用:

  • 🎯 調度依據:k8s 調度器用這個決定把 Pod 放在哪個節點
  • 🛡️ 資源保證:系統保證你至少有這麼多資源可用
  • 📊 計費基準:雲端服務商通常以 requests 計費

2. Limits(資源限制)- 「你最多只能用這麼多」
就像餐廳的用餐時間限制,不能讓你無限制地佔著位子。

resources:
  limits:
    memory: "400Mi"  # 你最多只能用 400MB 記憶體
    cpu: "200m"      # 你最多只能用 0.2 個 CPU 核心

Limits 的作用:

  • 🚫 防止資源濫用:避免單一 Pod 影響整個節點
  • ⚡ 觸發限制機制:超過限制會被節流或終止
  • 🔄 允許突發使用:在限制內可以使用超過 requests 的資源

https://ithelp.ithome.com.tw/upload/images/20250822/20104930kxw05uYB7c.png

完整的資源配置實戰 🛠️

場景一:Web 應用程式(Burstable QoS)
web-app.yaml

# web-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        resources:
          requests:
            memory: "128Mi"   # 平時需要 128MB
            cpu: "50m"        # 平時需要 0.05 CPU
          limits:
            memory: "256Mi"   # 高峰時最多用 256MB
            cpu: "100m"       # 高峰時最多用 0.1 CPU
        ports:
        - containerPort: 80

為什麼這樣設計?

  • 🌊 Web 應用流量有波峰波谷,或者潮汐現象
  • 💰 平時用較少資源節省成本
  • 🚀 高峰時可以突發使用更多資源

場景二:資料庫(Guaranteed QoS)
pg-db.yaml

# pg-db.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: pg-db
spec:
  serviceName: pg
  replicas: 1
  selector:
    matchLabels:
      app: pg
  template:
    metadata:
      labels:
        app: pg
    spec:
      containers:
      - name: pg
        image: postgres:15
        resources:
          requests:
            memory: "1Gi"     # 需要 1GB 記憶體
            cpu: "500m"       # 需要 0.5 CPU
          limits:
            memory: "1Gi"     # 限制也是 1GB(相同)
            cpu: "500m"       # 限制也是 0.5 CPU(相同)
        env:
        - name: POSTGRES_PASSWORD
          value: "password123"

為什麼 requests = limits?

  • 🎯 穩定性優先:資料庫需要穩定的效能
  • 🛡️ 最高優先級:獲得 Guaranteed QoS 等級
  • 📊 可預測性:資源使用量相對固定

讓我們部署並觀察

# 部署 Web 應用
kubectl apply -f web-app.yaml

# 部署資料庫
kubectl apply -f pg-db.yaml


# 查看節點資源總量
kubectl describe nodes

# 查看 Pod 實際資源使用
kubectl top pods --all-namespaces

# 查看資源配額
kubectl describe resourcequota

# 檢查 Pod 的 QoS 等級
kubectl get pods -o custom-columns=NAME:.metadata.name,QOS:.status.qosClass

輸出結果:

NAME                       QOS
web-app-5d8c6cc7c4-7fghb          Burstable
web-app-5d8c6cc7c4-96mmm          Burstable
web-app-5d8c6cc7c4-hb2dl          Burstable
pg-db-0                 Guaranteed

QoS 服務品質分類深度解析 🏆

1. Guaranteed(保證級)- VIP 包廂 👑
特徵:requests = limits

resources:
  requests:
    memory: "400Mi"
    cpu: "200m"
  limits:
    memory: "400Mi"  # 完全相同
    cpu: "200m"      # 完全相同

就像餐廳的 VIP 包廂:

  • 🥇 最高優先級:資源不足時最後才被驅逐
  • 🎯 資源保證:100% 獲得所需資源
  • 💎 適用場景:關鍵業務、資料庫、有狀態服務

2. Burstable(突發級)- 彈性座位 🎢
特徵:有 requests,但 limits > requests

resources:
  requests:
    memory: "200Mi"  # 保證有 200MB
    cpu: "100m"      # 保證有 0.1 CPU
  limits:
    memory: "400Mi"  # 最多可用 400MB
    cpu: "200m"      # 最多可用 0.2 CPU

就像餐廳的彈性座位:

  • 🥈 中等優先級:資源不足時第二順位被驅逐
  • 🚀 彈性使用:可以突發使用更多資源
  • 💰 成本效益:平時用少一點,需要時用多一點
  • 🎯 適用場景:Web 應用、微服務、批次處理

3. BestEffort(盡力級)- 候位區 ⏳
特徵:沒有設定任何 requests 和 limits

# 沒有 resources 設定
spec:
  containers:
  - name: app
    image: nginx
    # 完全沒有資源設定

就像餐廳的候位區:

  • 🥉 最低優先級:資源不足時第一個被驅逐
  • 🎲 隨機資源:能用多少算多少
  • 🆓 零成本:不佔用預留資源
  • 🎯 適用場景:測試環境、非關鍵任務

https://ithelp.ithome.com.tw/upload/images/20250822/201049302dO6nCJKe0.png

資源管理的實戰演練 🎮

模擬記憶體超限情況

# 創建會超出記憶體限制的 Pod
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: real-oom-test
spec:
  restartPolicy: Always
  containers:
  - name: stress
    image: polinux/stress
    resources:
      requests:
        memory: "100Mi"
      limits:
        memory: "200Mi"
    command: ["stress"]
    args: ["--timeout", "5s", "--vm", "1", "--vm-bytes", "300M", "--verbose"]
EOF

觀察資源使用情況

> kubectl get pods real-oom-test

NAME            READY   STATUS             RESTARTS     AGE
real-oom-test   0/1     CrashLoopBackOff   1 (5s ago)   9s
✅ 容器因為重複失敗而被限制重啟

> kubectl get pod real-oom-test -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'

137

# 退出碼 137 = 128 + 9 (SIGKILL)
Exit Code: 137 ✅ OOM Kill 確認!

https://ithelp.ithome.com.tw/upload/images/20250822/20104930W7MOVQekOf.png

https://ithelp.ithome.com.tw/upload/images/20250822/20104930tG4rmpjN9Q.png

資源管理的雙面性思考 ⚖️

優點 ✅
1. 可預測性

# 你知道這個 Pod 至少有這些資源
resources:
  requests:
    memory: "256Mi"
    cpu: "100m"

2. 公平性

  • 防止資源霸凌
  • 保證每個 Pod 都有基本資源

3. 穩定性

  • 避免節點過載
  • 提供服務品質保證

挑戰與風險 ⚠️
** 1. 資源浪費**

# 如果設定過高,可能造成浪費
resources:
  requests:
    memory: "2Gi"    # 實際只用 500Mi
    cpu: "1000m"     # 實際只用 100m

** 2. 配置複雜性**

  • 需要了解應用程式的資源特性
  • 需要持續監控和調整

** 3. 調度困難**

  • 資源請求過高可能導致無法調度
  • 需要平衡資源利用率和可用性

🎓 總結

架構思維的轉變

  • 從功能導向到可靠性導向:

    ❌ 以前:「能跑就好」
    ✅ 現在:「穩定可靠地跑」

  • 從單機思維到叢集思維:

    ❌ 以前:「我的應用程式」
    ✅ 現在:「我們的叢集資源」

運維思維的培養

  • 關注使用者體驗:

    🎯 確保關鍵服務獲得足夠資源
    ⚡ 允許非關鍵服務彈性使用資源
    🛡️ 防止單一故障影響整體服務

微服務架構的理解
在微服務架構中,資源管理不只是技術問題,更是架構設計問題:

  • 服務分級:哪些服務是關鍵的?
  • 資源隔離:如何避免服務間相互影響?
  • 彈性設計:如何應對流量波動?
  • 成本優化:如何在性能和成本間平衡?

https://ithelp.ithome.com.tw/upload/images/20250822/201049306AKpywAwM2.png


上一篇
Health Probe 健康探針
下一篇
ConfigMap - 讓你的應用配置不再寫死在程式碼裡 ⚙️
系列文
賢者大叔的容器修煉手札17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言