返回文章列表

Kubernetes 資源管理機制深度解析

本文探討 Kubernetes 資源管理機制,包含資源請求與限制、服務品質(QoS)、汙點與容忍度、Pod 中斷預算(PDB)、資源配額(ResourceQuota)及 LimitRange 等核心概念,並提供最佳實踐建議,涵蓋 Pod 反親和性、NodeCondition 汙點及 HPA

容器技術 系統管理

Kubernetes 資源管理是確保應用程式穩定高效執行的關鍵。本文從 Pod 資源組態、QoS 等基礎概念出發,逐步探討汙點和容忍度、PDB、資源配額及 LimitRange 等機制,並結合實際案例說明如何設定和使用這些機制。最後,文章提供了一些資源管理的最佳實踐,例如利用 Pod 反親和性提高應用程式可用性、使用 NodeCondition 汙點避免將 Pod 排程到問題節點、以及使用 nodeSelectors 將 Pod 佈署到特定硬體等,幫助讀者更好地管理 Kubernetes 叢集資源。

Kubernetes 資源管理深度解析

在 Kubernetes 環境中,資源管理是確保應用程式高效執行的關鍵。本篇文章將探討 Kubernetes 中的資源管理機制,包括汙點(Taints)、資源請求(Resource Requests)、資源限制(Resource Limits)、服務品質(Quality of Service, QoS)以及 Pod 中斷預算(PodDisruptionBudgets)。

節點汙點與 Pod 排程

當 Pod 無法排程至節點時,通常是因為節點被設定了汙點,而該 Pod 沒有對應的容忍度(Tolerations)。以下是一個典型的錯誤訊息:

Warning: FailedScheduling 10s (x10 over 2m) default-scheduler 0/2 nodes are available: 2 node(s) had taints that the pod did not tolerate.

除了手動新增汙點外,Kubernetes 還提供了根據汙點的驅逐(Taint-based Eviction)機制,用於在節點異常時將 Pod 重新排程至其他健康節點。

Pod 資源管理

適當地管理 Pod 資源是 Kubernetes 叢集管理的核心任務之一。這包括 CPU 和記憶體的管理,以最佳化叢集的整體利用率。

資源請求

資源請求定義了容器執行所需的最低資源量。如果一個容器需要至少 2 GB 的記憶體才能正常執行,則需要在 Pod 的規格中定義該資源請求,以便排程器能夠正確地排程該容器。

使用 kubectl top 命令可以檢視叢集中各節點的資源使用情況:

kubectl top nodes

輸出範例:

NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
aks-nodepool1-14849087-0 524m 27% 7500Mi 33%
aks-nodepool1-14849087-1 468m 24% 3505Mi 27%
aks-nodepool1-14849087-2 406m 21% 3051Mi 24%
aks-nodepool1-14849087-3 441m 22% 2812Mi 22%

建立一個記憶體請求 Pod

apiVersion: v1
kind: Pod
metadata:
  name: memory-request
spec:
  containers:
  - name: memory-request
    image: polinux/stress
    resources:
      requests:
        memory: "8000Mi"

資源請求與限制的差異

資源請求定義了容器所需的最低資源量,而資源限制則定義了容器能夠使用的最大資源量。當 CPU 使用達到限制時,容器會被限流;而當記憶體使用達到限制時,Pod 可能會被重新啟動。

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
  namespace: cpu-example
spec:
  containers:
  - name: frontend
    image: nginx:alpine
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: "0.5"

服務品質(QoS)

Kubernetes 中的 Pod 會根據其資源請求和限制被賦予不同的 QoS 類別,包括 Guaranteed、Burstable 和 BestEffort。

  • Guaranteed:當 CPU 和記憶體的請求和限制都相同時,Pod 被賦予 Guaranteed QoS。
  • Burstable:當限制高於請求時,Pod 被賦予 Burstable QoS。
  • BestEffort:當沒有設定請求和限制時,Pod 被賦予 BestEffort QoS。
apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-ctr
    image: nginx:alpine
    resources:
      limits:
        memory: "200Mi"
        cpu: "700m"
      requests:
        memory: "200Mi"
        cpu: "700m"

Pod 中斷預算(PodDisruptionBudgets)

在進行節點維護或升級時,可能需要驅逐節點上的 Pod。PodDisruptionBudget 可以用來確保應用程式在自願中斷事件期間的可用性。

最小可用 Pod

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: frontend-pdb
spec:
  minAvailable: 5
  selector:
    matchLabels:
      app: frontend

最大不可用 Pod

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: frontend-pdb
spec:
  maxUnavailable: "20%"
  selector:
    matchLabels:
      app: frontend

Kubernetes 資源管理深度解析

在 Kubernetes 叢集管理中,資源的有效分配與管理是確保系統穩定執行的關鍵。本文將探討 PodDisruptionBudget(PDB)、Namespace 以及 ResourceQuota 的使用與組態,幫助讀者更好地理解如何在 Kubernetes 環境中進行資源管理。

PodDisruptionBudget(PDB)組態與實踐

PodDisruptionBudget 是一種用於控制應用程式在自願性幹擾(如節點維護或升級)期間可用的副本數量的機制。正確組態 PDB 可以確保應用程式在幹擾發生時仍能保持足夠的可用性。

PDB 範例解析

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: frontend-pdb
spec:
  maxUnavailable: 20%
  selector:
    matchLabels:
      app: frontend

內容解密:

  1. apiVersion 和 kind:指定了 Kubernetes API 的版本和資源型別,這裡使用的是 policy/v1 版本的 PodDisruptionBudget
  2. metadata.name:定義了 PDB 的名稱為 frontend-pdb
  3. spec.maxUnavailable:設定了最大不可用 Pod 的比例為 20%。這意味著在任何時候,不超過 20% 的副本 Pod 可以是不可用的。
  4. spec.selector.matchLabels:透過標籤選擇器指定了這個 PDB 適用的 Pod。這裡選擇了標籤 app: frontend 的 Pod。

設計考量

  • 比例設定:當 maxUnavailable 設定為百分比時,Kubernetes 會向上取整到最接近的整數。例如,如果有 7 個 Pod,20% 將被視為 2 個 Pod(因為 1.4 向上取整為 2)。
  • 叢集容量規劃:在設計叢集時,必須考慮節點故障對整體容量的影響。例如,在一個四節點叢集中,如果一個節點故障,叢集容量將損失四分之一。

Namespace 管理與資源分配

Namespace 在 Kubernetes 中提供了一種邏輯上的資源隔離方式,使得多個團隊或應用程式可以在同一個叢集中分享資源而不會相互幹擾。

Namespace 使用場景

  1. 團隊隔離:每個團隊可以使用獨立的 Namespace,以避免資源名稱衝突並實施存取控制。
  2. 應用程式隔離:對於單一團隊,可以根據不同的應用程式或服務建立不同的 Namespace。

預設 Namespace

Kubernetes 預設建立了幾個 Namespace,包括 kube-systemdefaultkube-public。建議避免在 default Namespace 中佈署應用程式,因為它缺乏資源約束,可能導致資源爭用。

使用 kubectl 管理 Namespace

kubectl create ns team-1
kubectl get pods --namespace team-1
kubectl config set-context my-context --namespace=team-1

內容解密:

  1. 建立 Namespace:使用 kubectl create ns 命令建立新的 Namespace。
  2. 查詢資源:使用 --namespace-n 引數指定 Namespace 以查詢其中的資源。
  3. 設定 Context:透過設定 kubectl 的 Context,可以避免在每個命令中重複指定 Namespace。

ResourceQuota 組態與實踐

ResourceQuota 用於限制 Namespace 中的資源使用量,確保單一 Namespace 不會消耗過多的叢集資源。

ResourceQuota 範例

apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
  namespace: team-1
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    persistentvolumeclaims: "5"
    requests.storage: "10Gi"

內容解密:

  1. 資源型別:ResourceQuota 可以限制多種型別的資源,包括計算資源(CPU 和記憶體)、儲存資源和物件數量等。
  2. 計算資源限制:可以設定 CPU 和記憶體的請求(requests)和限制(limits),以控制 Pod 的資源使用。
  3. 儲存資源限制:可以限制 PersistentVolumeClaims 的數量和儲存請求的大小。

資源管理與叢集擴充套件

在 Kubernetes 中,資源管理是確保應用程式穩定執行的關鍵。資源配額(ResourceQuotas)和限制範圍(LimitRanges)是兩個重要的工具,用於控制名稱空間中的資源使用。

資源配額(ResourceQuotas)

資源配額允許管理員限制名稱空間中的資源使用量。例如,可以設定 CPU、記憶體和儲存的配額,以防止某個名稱空間中的應用程式耗盡叢集資源。

範例:設定資源配額

首先,建立一個名稱空間 team-1

kubectl create ns team-1

接下來,套用資源配額:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
spec:
  hard:
    requests.cpu: 2
    requests.memory: 2Gi
    limits.cpu: 2
    limits.memory: 2Gi

將上述組態儲存到 resourcequota.yaml 檔案中,然後執行:

kubectl apply -f resourcequota.yaml -n team-1

驗證資源配額

嘗試佈署一個應用程式,以測試資源配額的效果:

kubectl run nginx-quotatest --image=nginx --restart=Never --replicas=1 --port=80 --requests='cpu=500m,memory=4Gi' --limits='cpu=500m,memory=4Gi' -n team-1

由於記憶體請求超過了設定的 2 Gi 配額,佈署將會失敗,並出現錯誤訊息:

Error from server (Forbidden): pods "nginx-quotatest" is forbidden: exceeded quota: mem-cpu-demo

資源配額的重要性

資源配額可以有效地防止某個名稱空間中的應用程式耗盡叢集資源,從而確保其他名稱空間中的應用程式能夠穩定執行。

限制範圍(LimitRanges)

限制範圍允許管理員為容器設定預設的請求和限制。如果容器沒有指定請求和限制,LimitRange 將會自動套用預設值。

範例:設定 LimitRange

建立一個 LimitRange 組態檔:

apiVersion: v1
kind: LimitRange
metadata:
  name: team-1-limit-range
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256Mi
    type: Container

將上述組態儲存到 limitranger.yaml 檔案中,然後執行:

kubectl apply -f limitranger.yaml -n team-1

驗證 LimitRange

建立一個 Pod 以測試 LimitRange 的效果:

kubectl run team-1-pod --image=nginx -n team-1

然後,檢視 Pod 的詳細資訊:

kubectl describe pod team-1-pod -n team-1

你應該會看到以下請求和限制被設定在 Pod 上:

Limits:
  memory: 512Mi
Requests:
  memory: 256Mi

LimitRange 的重要性

LimitRange 可以確保容器具有合理的請求和限制,從而避免因資源不足而導致的佈署失敗。

叢集擴充套件

Kubernetes 提供了多種方式來擴充套件叢集,包括手動擴充套件和自動擴充套件。

手動擴充套件

手動擴充套件叢集通常涉及選擇新的節點數量,並將新的節點新增到叢集中。可以使用 Kops 或受管理的 Kubernetes 服務等工具來簡化此過程。

自動擴充套件

Kubernetes 提供了一個 Cluster Autoscaler 外掛,可以根據需要自動新增或移除節點。當 Pod 因資源不足而處於 Pending 狀態時,Cluster Autoscaler 將會新增新的節點。

範例:Cluster Autoscaler

Cluster Autoscaler 可以根據 Pod 的需求自動調整叢集大小。例如,如果一個 Pod 需要 4,000 MiB 的記憶體,但叢集中只有 2,000 MiB 可用,Pod 將會進入 Pending 狀態。此時,Cluster Autoscaler 將會新增新的節點,以滿足 Pod 的需求。

應用程式擴充套件

Kubernetes 提供了多種方式來擴充套件應用程式,包括手動擴充套件和自動擴充套件。

手動擴充套件

手動擴充套件應用程式涉及變更 Deployment 中的副本數量。可以使用以下 Deployment 清單來示範:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      name: frontend
      labels:
        app: frontend
    spec:
      containers:
      - image: nginx:alpine
        name: frontend
        resources:
          requests:
            cpu: 100m

自動擴充套件

Kubernetes 提供了一個 Horizontal Pod Autoscaler(HPA),可以根據需要自動調整應用程式的副本數量。

範例:HPA

HPA 可以根據 CPU 使用率或其他自定義指標來調整應用程式的副本數量。例如,可以建立一個 HPA 物件,以根據 CPU 使用率調整前端 Deployment 的副本數量。

Kubernetes 資源管理最佳實踐

在 Kubernetes 中,資源管理是確保叢集可靠、高效運作的關鍵。本章將探討如何最佳化管理 Kubernetes 和應用程式資源。

佈署與擴充套件

首先,我們來看看如何佈署和擴充套件前端服務。以下是一個簡單的佈署範例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: frontend:latest
        ports:
        - containerPort: 80

內容解密:

  • apiVersionkind 定義了 Kubernetes 資源的型別。
  • metadata 包含了資源的中繼資料,如名稱。
  • spec 定義了資源的規格,包括副本數量、選擇器和範本。
  • replicas 指定了初始的副本數量。
  • selectortemplate 定義瞭如何選擇和建立 Pod。

使用 kubectl scale 命令可以輕鬆擴充套件佈署:

kubectl scale deployment frontend --replicas 5

這將前端服務的副本數量擴充套件到 5 個。

使用 HPA 自動擴充套件

Kubernetes 的 Horizontal Pod Autoscaler(HPA)允許根據 CPU、記憶體或自定義指標自動擴充套件佈署。以下是一個 HPA 的設定範例:

kubectl expose deployment frontend --port 80
kubectl autoscale deployment frontend --cpu-percent=50 --min=1 --max=10

內容解密:

  • kubectl expose 命令將佈署暴露為服務。
  • kubectl autoscale 命令設定 HPA 策略,根據 CPU 使用率進行擴充套件。
  • --cpu-percent=50 表示當 CPU 使用率達到 50% 時觸發擴充套件。
  • --min=1--max=10 分別設定了最小和最大副本數量。

使用自定義指標進行 HPA

除了基本的 CPU 和記憶體指標外,HPA 還支援自定義指標。透過 Custom Metrics API 和 Metrics Aggregator,可以擴充套件指標來源,實作更靈活的自動擴充套件。

垂直 Pod 自動擴充套件器(VPA)

VPA 與 HPA 不同,它不是透過增加副本數量來擴充套件,而是自動調整 Pod 的資源請求。VPA 由三個元件組成:Recommender、Updater 和 Admission Plugin。

資源管理最佳實踐

  1. 使用 Pod 反親和性 將工作負載分散到多個可用區域,以確保高用性。
  2. 使用汙點(Taints)和容忍度(Tolerations) 確保只有需要特殊硬體(如 GPU)的 Pod 被排程到相應的節點上。
  3. 使用 NodeCondition 汙點 主動避免排程到故障或降級的節點。
  4. 使用 nodeSelectors 將 Pod 排程到特定的硬體上。
  5. 實驗不同的節點大小 以找到成本和效能的最佳平衡。
  6. 使用資源配額(ResourceQuotas) 確保多個團隊或應用程式公平分享叢集資源。
  7. 實施 LimitRange 為未設定限制或請求的 Pod 設定預設值。
  8. 使用 HPA 處理具有變異性和意外峰值的工作負載。