Kubernetes Pod 資源限制與 QoS

Kubernetes Pod Resource Limits and QoS Classes

資源管理概述

在 Kubernetes 叢集中,資源管理是確保應用程式穩定運行的關鍵要素。每個 Pod 都需要消耗一定的運算資源,包括 CPU 和記憶體。透過適當的資源配置,我們可以:

  • 確保應用程式獲得足夠的資源來正常運作
  • 防止單一應用程式過度消耗資源影響其他服務
  • 提升叢集整體的資源利用效率
  • 實現更好的成本控制

Requests 與 Limits 差異

Kubernetes 提供兩種資源控制機制:

類型說明用途
requestsPod 啟動時保證獲得的最小資源量用於排程決策
limitsPod 可使用的最大資源量防止資源過度使用

基本配置範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
  name: resource-demo
spec:
  containers:
  - name: app
    image: nginx:1.24
    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
      limits:
        memory: "256Mi"
        cpu: "500m"

CPU 資源設定

CPU 資源以「核心數」為單位,支援小數表示。常見的表示方式:

  • 1 = 1 個 CPU 核心
  • 500m = 0.5 個 CPU 核心(m 代表 millicore)
  • 100m = 0.1 個 CPU 核心

當 Pod 超過 CPU limits 時,會被節流(throttled),但不會被終止。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
spec:
  containers:
  - name: cpu-intensive-app
    image: python:3.11-slim
    command: ["python", "-c", "while True: pass"]
    resources:
      requests:
        cpu: "100m"
      limits:
        cpu: "200m"

記憶體資源設定

記憶體資源以位元組為單位,支援多種表示方式:

  • 128Mi = 128 MiB(Mebibyte,1024 為基數)
  • 1Gi = 1 GiB
  • 128M = 128 MB(Megabyte,1000 為基數)

當 Pod 超過記憶體 limits 時,會被 OOM Killer 終止。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
spec:
  containers:
  - name: memory-app
    image: redis:7.0
    resources:
      requests:
        memory: "256Mi"
      limits:
        memory: "512Mi"

QoS 類別

Kubernetes 根據 requests 和 limits 的設定,自動將 Pod 分為三種服務品質(QoS)類別:

1. Guaranteed(保證等級)

條件:所有容器都必須設定 requests 和 limits,且兩者相等。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
  name: qos-guaranteed
spec:
  containers:
  - name: app
    image: nginx:1.24
    resources:
      requests:
        memory: "256Mi"
        cpu: "500m"
      limits:
        memory: "256Mi"
        cpu: "500m"

特點:最高優先級,資源緊張時最後被驅逐。

2. Burstable(可突發等級)

條件:至少有一個容器設定了 requests 或 limits,但不符合 Guaranteed 條件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
  name: qos-burstable
spec:
  containers:
  - name: app
    image: nginx:1.24
    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
      limits:
        memory: "256Mi"
        cpu: "500m"

特點:中等優先級,可使用額外可用資源。

3. BestEffort(盡力等級)

條件:所有容器都沒有設定任何 requests 或 limits。

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Pod
metadata:
  name: qos-besteffort
spec:
  containers:
  - name: app
    image: nginx:1.24

特點:最低優先級,資源緊張時最先被驅逐。

LimitRange 設定

LimitRange 用於在 Namespace 層級設定預設資源限制和範圍約束。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: v1
kind: LimitRange
metadata:
  name: resource-limits
  namespace: production
spec:
  limits:
  - type: Container
    default:
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    min:
      cpu: "50m"
      memory: "64Mi"
    max:
      cpu: "2"
      memory: "2Gi"
  - type: Pod
    max:
      cpu: "4"
      memory: "4Gi"

ResourceQuota 設定

ResourceQuota 用於限制整個 Namespace 的總資源使用量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    pods: "50"
    persistentvolumeclaims: "10"
    services: "20"
    secrets: "100"
    configmaps: "100"

查看配額使用情況:

1
kubectl describe resourcequota compute-quota -n production

資源監控

使用 kubectl top 監控資源

1
2
3
4
5
6
7
8
# 查看節點資源使用情況
kubectl top nodes

# 查看 Pod 資源使用情況
kubectl top pods -n production

# 查看特定 Pod 的容器資源
kubectl top pod my-pod --containers -n production

完整的 Deployment 資源配置範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-application
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx:1.24
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "250m"
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
        livenessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3

最佳實踐

  1. 始終設定 requests 和 limits:避免使用 BestEffort 類別,確保應用程式有基本的資源保障。

  2. 根據實際使用量設定:先監控應用程式的實際資源消耗,再據此調整配置。

  3. 考慮 QoS 等級:關鍵服務使用 Guaranteed,一般服務使用 Burstable。

  4. 使用 LimitRange 設定預設值:防止開發者忘記設定資源限制。

  5. 使用 ResourceQuota 控制總量:防止單一團隊或專案過度消耗叢集資源。

  6. 定期審查資源配置:隨著應用程式演進,及時調整資源設定。

  7. 設定合理的 limits/requests 比例:建議 limits 不超過 requests 的 2 倍。

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy