iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Kubernetes

都什麼年代了,還在學 Kubernetes系列 第 28

學 Kubernetes 的第二十八天 - Resource - Pod 層級的資源管理

  • 分享至 

  • xImage
  •  

Kubernetes 資源管理概述

前言

在現代的微服務架構中,我們經常使用容器技術來封裝和運行應用程序。這種方法雖然使部署變得更加便捷和一致,但也帶來了資源管理的挑戰:如何有效地控制和分配執行應用程序所需的計算資源?這是一個需要仔細權衡的問題,因為資源分配不足可能導致服務性能下降或無法正常運行,而過度分配則會造成資源浪費和成本增加。

Kubernetes Resources

在 Kubernetes (K8s) 中,Resources 是用於管理和分配叢集資源的核心概念。這些資源主要包括 CPU 和記憶體(RAM),但也可能涉及其他計算資源如 GPU 或存儲空間。Kubernetes 提供了一套完整的機制來配置、監控和自動調整這些資源,以確保應用程序能夠高效穩定地運行。

Pod 中的資源

當我們定義 Pod 時,可以為每個容器設定所需要的資源數量。最常見的資源是 CPU 和記憶體(RAM),也有其他類型的資源。

當你為 Pod 中的容器指定了 request(請求) 時,kube-scheduler 會根據這些資訊決定將 Pod 調度到哪個節點上。當你指定了 limit(限制) 時,kubelet 會確保容器不會使用超過這個限制的資源。kubelet 也會為容器預留 request(請求) 的資源,讓容器使用。

資源請求(Requests)和資源限制(Limits)

如果 Pod 運行的節點有足夠的可用資源,容器可以使用超過 request 設定的資源量,但不能使用超過 limit 設定的資源量。

例如:如果容器的 memory 請求是 256 MiB,且節點有足夠的記憶體(比如 8 GiB),那麼容器可以使用更多的記憶體。

如果我們將容器的 memory 限制設為 4 GiB,kubeletContainer Runtimes 會確保容器不會使用超過這個限制。如果容器中的程序嘗試使用超過允許的記憶體,系統核心會終止這些程序並引發記憶體不足(OOM)錯誤。

總結來說: request <= Pod/Container 實際使用的資源量 <= limit

資源單位

CPU 資源用 millicpu 來表示,1000m 代表 1 個 CPU 核心。

範例

  • cpu: "500m" 表示使用 0.5 個 CPU 核心。
  • cpu: "1" 表示使用 1 個 CPU 核心。
  • cpu: "2" 表示使用 2 個 CPU 核心。

記憶體資源使用基於 2 的次方的單位,包括:

  • 1 Ki = 1024 B
  • 1 Mi = 1024 Ki
  • 1 Gi = 1024 Mi
  • 1 Ti = 1024 Gi

範例

  • memory: "512Mi" 表示 512 兆字節(MiB)的記憶體。
  • memory: "1Gi" 表示 1 千兆字節(GiB)的記憶體。
  • memory: "2Gi" 表示 2 千兆字節(GiB)的記憶體。

服務質量 (QoS)

Kubernetes 會對每個 Pod 進行分類,並分配到特定的 QoS 類。這些分類影響 Pod 的處理方式,並基於容器的資源請求和資源限制來決定。這些分類稱為服務質量(QoS)類,Kubernetes 使用 QoS 類來決定當節點資源不足時,哪些 Pod 會被驅逐。

QoS 類型可以幫助決定 Pod 在節點資源不足時的優先級。QoS 類型有 GuaranteedBurstableBestEffort。當一個節點資源不足時,Kubernetes 會首先驅逐 BestEffort 類型的 Pod,接著是 Burstable 類型,最後才是 Guaranteed 類型。當驅逐是因為資源壓力時,只有超出資源請求的 Pod 才會被驅逐。

簡單來說,Pod 被驅逐的順序是: Guaranteed < Burstable < BestEffort

QoS 的分類標準

  • Guaranteed
    • Pod 中的每個容器 必須 定義記憶體和 CPU 的限制(limit)和請求(request)。
    • 限制和請求的值 相等
  • Burstable
    • 不滿足 Guaranteed 的條件。
    • 至少有一個容器定義了記憶體或 CPU 的限制(limit)或請求(request)。
  • BestEffort
    • 不滿足 GuaranteedBurstable 的條件。
    • 只有當所有容器都沒有定義記憶體或 CPU 的限制和請求時,Pod 才屬於 BestEffort 類型。

實作: 資源請求限制 + QoS 判定

建立 Namespace

建立一個名字空間,以便將本練習所建立的資源與叢集的其餘資源相隔離。

  • 建立 Namespace
kubectl create namespace qos-example

組態檔案: qos.yaml

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-ctr
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "700m"
      requests:
        memory: "200Mi"
        cpu: "700m"
---
apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-2
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-2-ctr
    image: nginx
    resources:
      limits:
        memory: "200Mi"
      requests:
        memory: "100Mi"
---
apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-3
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-3-ctr
    image: nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-4
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-4-ctr-1
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "700m"
      requests:
        memory: "200Mi"
        cpu: "700m"
  - name: qos-demo-4-ctr-2
    image: redis

這個組態檔案裡,包含四個 Pod:

  • qos-demo: 指定 cpu, memory 的 limit, request,並且 limit = request
  • qos-demo-2: 指定 memory 的 limit, request
  • qos-demo-3: 沒有指定
  • qos-demo-4: 有兩個 container,一個指定 cpu, memory 的 limit, request,並且 limit = request,一個什麼都沒指定

依照之前學過的內容,我們期望 Pod QoS 的結果是:

  • qos-demo=Guaranteed

  • qos-demo-2=Burstable

  • qos-demo-3=BestEffort

  • qos-demo-4=Burstable

  • 驗證 qos 資訊

kubectl get pods --namespace=qos-example -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.qosClass}{"\n"}{end}'
---
qos-demo        Guaranteed
qos-demo-2      Burstable
qos-demo-3      BestEffort
qos-demo-4      Burstable

清理

kubectl delete namespace qos-example

實作: 設定超過節點能力的請求

在本練習中,你將建立一個 Pod,該 Pod 的 CPU 請求對於叢集中任何節點的容量而言都會過大。 下面是 Pod 的組態檔案,其中有一個容器。容器請求 100 個 CPU,這可能會超出叢集中任何節點的容量。

建立 Namespace

建立一個名字空間,以便將本練習所建立的資源與叢集的其餘資源相隔離。

kubectl create namespace cpu-example

組態檔案: example.yaml

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo-2
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr-2
    image: vish/stress
    resources:
      limits:
        cpu: "100"
      requests:
        cpu: "100"
    args:
    - -cpus
    - "2"

  • 建立 Pod
kubectl apply -f examply.yaml
  • 查看 Pod 狀態
kubectl -n cpu-example get pod cpu-demo
---
NAME       READY   STATUS    RESTARTS   AGE
cpu-demo   0/1     Pending   0          19s

輸出顯示 Pod 狀態為 Pending。也就是說,Pod 未被調度到任何節點上運行, 並且 Pod 將無限期地處於 Pending 狀態。

  • 查看有關 Pod 的詳細資訊,包含事件
kubectl -n cpu-example describe pod cpu-demo
---
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  10s   default-scheduler  0/3 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 2 Insufficient cpu. preemption: 0/3 nodes are available: 1 Preemption is not helpful for scheduling, 2 No preemption victims found for incoming pod.

輸出顯示由於節點上的 CPU 資源不足,無法調度容器。

清理

kubectl delete namespace cpu-example

小結

Kubernetes 的資源管理機制為微服務架構提供了強大的支持。通過合理設置資源請求和限制,結合 QoS 類別,我們可以有效控制應用程序的資源使用,確保系統穩定性和資源利用效率。

然而,有效的資源管理不僅依賴於 Kubernetes 的機制,還需要深入理解應用程序的需求和行為。持續監控、分析和優化是確保資源管理效果的關鍵。


參考


上一篇
學 Kubernetes 的第二十七天 - Scheduling - Taints 和 Tolerations
下一篇
學 Kubernetes 的第二十九天 - Resource - Namespace 層級的資源管理
系列文
都什麼年代了,還在學 Kubernetes32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言