返回文章列表

Kubernetes 儲存管理實戰

本文探討 Kubernetes 儲存管理機制,涵蓋永續性磁碟區(PV)、永續性磁碟區宣告(PVC)和儲存類別(StorageClass)的實務操作,並提供本地持久性儲存區與動態供應的設定步驟及案例說明,搭配圖表解析 Kubernetes 儲存架構,幫助讀者有效管理容器化應用程式的儲存需求。

容器技術 雲端原生

Kubernetes 提供了 PV、PVC 和 StorageClass 等機制,解決容器化應用程式在儲存管理方面的挑戰。本文將逐步說明如何定義和使用這些資源,包含 YAML 檔案範例和佈署指令。同時也探討本地持久性儲存區和動態供應的應用場景,並提供設定步驟和程式碼範例,讓讀者瞭解如何在 Kubernetes 環境中有效管理儲存資源,確保資料永續性、一致性和效能最佳化。最後,透過架構圖示,清楚呈現 Kubernetes 儲存管理的運作方式,幫助讀者更深入理解其核心概念。

Kubernetes 儲存管理

在應用程式發展的過程中,對於永續性和非永續性資料儲存的需求日益複雜。在動態的 Kubernetes 環境中,管理永續性儲存面臨著獨特的挑戰,例如確保資料一致性、管理儲存資源的生命週期以及最佳化效能。Kubernetes 提供了強大的儲存管理功能,包括永續性磁碟區(PV)、永續性磁碟區宣告(PVC)和儲存類別,以解決這些問題。

本章將探討 Kubernetes 中的儲存管理,提供實際步驟和見解,以有效地利用這些儲存機制。無論是處理需要資料永續性的有狀態應用程式,還是尋求自動化儲存組態以實作可擴充套件的應用程式,本章都提供了必要的指導。

容器化工作負載的儲存管理

在動態和可擴充套件的環境中,如 Kubernetes,有效地管理容器化工作負載的儲存對於確保資料永續性、一致性和最佳效能至關重要。

問題

容器化應用程式通常需要永續性儲存,以在個別容器的生命週期之外保留資料。這種永續性儲存需求在 Kubernetes 等動態和可擴充套件的環境中提出了挑戰。具體來說,管理儲存資源的生命週期、確保資料一致性和最佳化效能是常見問題。

解決方案

Kubernetes 透過永續性磁碟區(PV)、永續性磁碟區宣告(PVC)和儲存類別來管理儲存。以下是管理容器化工作負載儲存的方法:

  1. 定義永續性磁碟區(PV):建立一個 YAML 檔案來定義永續性磁碟區,例如:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-example
    spec:
      capacity:
        storage: 10Gi
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      storageClassName: standard
      hostPath:
        path: "/mnt/data"
    

    內容解密:

    • apiVersionkind 定義了 Kubernetes 資源的版本和型別。
    • metadata 包含資源的名稱和其他識別資訊。
    • spec 描述了資源的規格,包括儲存容量、存取模式和回收策略。
    • hostPath 指定了主機上的路徑,用於永續性儲存。
  2. 定義永續性磁碟區宣告(PVC):建立一個 YAML 檔案來定義 PVC,例如:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-example
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
      storageClassName: standard
    

    內容解密:

    • PVC 請求特定的儲存資源,包括存取模式和儲存大小。
    • storageClassName 指定了使用的儲存類別。
  3. 佈署使用 PVC 的應用程式:修改應用程式佈署 YAML 檔案以使用 PVC,例如:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: storage
          volumes:
          - name: storage
            persistentVolumeClaim:
              claimName: pvc-example
    

    內容解密:

    • volumeMounts 將 PVC 掛載到容器中的特定路徑。
    • volumes 定義了使用的 PVC。
  4. 應用組態:使用 kubectl 應用 PV、PVC 和應用程式佈署組態:

    kubectl apply -f pv.yaml
    kubectl apply -f pvc.yaml
    kubectl apply -f deployment.yaml
    

討論

在 Kubernetes 中管理儲存涉及正確實施永續性磁碟區、永續性磁碟區宣告和儲存類別。PV 是叢集中的儲存資源,而 PVC 是對這些資源的請求。儲存類別提供了一種定義不同型別儲存的方法,例如快速 SSD 或慢速 HDD,並指定其組態引數。

定義 StorageClass

問題

手動組態永續性磁碟區(PV)可能耗時且容易出錯,尤其是在儲存需求頻繁變化的動態環境中。這種方法缺乏彈性,可能導致資源利用效率低下。

解決方案

使用 StorageClass 啟用 PV 的動態組態。StorageClass 定義了儲存後端的引數和提供者,允許 Kubernetes 根據 PVC 請求自動建立 PV。以下是一個 StorageClass 定義示例:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
volumeBindingMode: Immediate

內容解密:

  • provisioner 指定了使用的儲存提供者,例如 AWS EBS。
  • parameters 定義了儲存提供者的引數,例如儲存型別。
  • reclaimPolicy 確定了當 PVC 被刪除時,PV 的處理方式。
  • volumeBindingMode 控制了卷的繫結模式,例如 Immediate 或 WaitForFirstConsumer。

靜態組態

問題

在 Kubernetes 上佈署有狀態應用程式(如 MySQL 資料函式庫)可能具有挑戰性,尤其是在確保資料永續性方面。

解決方案

解決方案涉及使用 PersistentVolumeClaim(PVC)物件。以下是逐步:

  1. 建立 PVC 請求:準備一個 YAML 清單(data.yaml)來請求儲存,例如 1 GB。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: data
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    

    內容解密:

    • PVC 請求特定的儲存資源,包括存取模式和儲存大小。
  2. 應用清單:使用 Kubernetes 命令列工具應用此清單:

    $ kubectl apply -f data.yaml
    

圖表說明:Kubernetes 儲存架構圖示

圖表翻譯: 此圖示展示了 Kubernetes 中的儲存架構。Kubernetes 叢集包含永續性磁碟區(PV)、永續性磁碟區宣告(PVC)和儲存類別(Storage Class)。PV 代表叢集中的實際儲存資源,而 PVC 是對這些資源的請求。Storage Class 定義了不同的儲存型別及其組態引數,並與底層的儲存後端相關聯。PVC 請求特定的 PV,而 Storage Class 定義了 PV 的特性。

Kubernetes 中的儲存管理

驗證 PVC 和 PV 的建立

要檢查 Persistent Volume Claim (PVC) 和對應的 Persistent Volume (PV) 狀態,可以使用以下命令:

$ kubectl get pvc
$ kubectl get pv

這些命令會顯示 PV 的詳細資訊,包括其狀態、存取模式和回收策略。預設情況下,PersistentVolume 的回收策略是 “Delete”,這意味著當 PVC 被刪除時,PV 及其資料也會被刪除。若要確保資料在 PVC 的生命週期之外仍然存在,需要在 PV 清單中將 persistentVolumeReclaimPolicy 設定為 “Retain”。使用 “describe” 引數可以獲得更多資訊:

kubectl describe PersistentVolume data

我們應該會看到 PV 的狀態變為 “Bound”,這表示宣告成功。

在 Pod 中使用 PVC

在 Pod 的 YAML 檔案中,需要在 volumes 區段中參考 PVC,並將該卷掛載到容器內。例如,對於 MySQL,可以掛載到 /var/lib/mysql

apiVersion: v1
kind: Pod
metadata:
  name: db
spec:
  containers:
  - image: mysql:8.3.0
    name: db
    volumeMounts:
    - mountPath: /var/lib/mysql
      name: data
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: root
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: data

內容解密:

  • apiVersionkind 定義了 Kubernetes 物件的版本和型別。
  • metadata 區段包含了 Pod 的名稱。
  • spec 區段定義了 Pod 的規格,包括容器、卷掛載和環境變數。
  • volumeMounts 將 PVC 掛載到容器內的指定路徑。
  • persistentVolumeClaim 參考了名為 “data” 的 PVC。

本地持久性儲存區(Local Persistent Volumes)

問題

需要在單一 Kubernetes 節點上直接掛載本地磁碟作為持久性儲存區,以滿足高效能、低延遲的儲存需求。

解決方案

步驟 1:建立 StorageClass

定義一個 StorageClass,使用 kubernetes.io/no-provisioner 提供者,表示卷不會被動態建立,必須手動建立。

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: sc-local
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

內容解密:

  • provisioner 指定了不進行動態建立。
  • volumeBindingMode 設定為 “WaitForFirstConsumer”,確保 PVC 只在被 Pod 使用時才會被繫結到 PV。
步驟 2:建立本地 PersistentVolume

建立一個 PersistentVolume,參考節點上的本地路徑,並設定節點親和性,以確保卷只被特定節點上的 Pod 使用。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-local
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: sc-local
  local:
    path: /data/volume1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - worker-01

內容解密:

  • capacity 指定了 PV 的儲存容量。
  • accessModes 設定為 “ReadWriteOnce”,表示該卷可以被單個節點以讀寫模式掛載。
  • persistentVolumeReclaimPolicy 設定為 “Retain”,確保資料在 PVC 被刪除後仍然保留。
  • local 指定了本地路徑。
  • nodeAffinity 設定了節點親和性,以限制 PV 只能被特定節點使用。
步驟 3:建立 PersistentVolumeClaim

建立一個 PVC,以請求本地儲存。

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc-local
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: sc-local
  resources:
    requests:
      storage: 10Gi

內容解密:

  • accessModesstorageClassName 與 PV 相匹配。
  • resources.requests.storage 指定了所需的儲存容量。

動態建立卷(Dynamic Provisioning Volumes)

問題

在 Kubernetes 環境中,應用程式經常需要持久儲存,以在 Pod 重啟和失敗時保持資料的完整性。手動建立儲存卷並將其繫結到特定的 Pod 上非常耗時。

本地持久性儲存區的使用場景

本地持久性儲存區適用於需要高效能和低延遲存取儲存的工作負載。這些卷在物理上與 Kubernetes 節點相連,因此受限於節點的生命週期。如果節點故障,本地 PV 上的資料可能會變得不可用。

此設定中的關鍵元件包括:

  • StorageClass:定義儲存類別並指定不進行動態建立。
  • PersistentVolume:代表叢集中手動建立並可用的儲存資源,包括節點親和性設定以限制卷的使用範圍。
  • PersistentVolumeClaim:使用者對儲存資源的請求,消耗由 PersistentVolume 提供的資源。

圖表說明

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Kubernetes 儲存管理實戰

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

圖表翻譯: 此圖表呈現了 Kubernetes 中儲存資源的提供與請求流程。首先,StorageClass 定義了儲存類別,接著 PersistentVolume 提供具體的儲存資源。PersistentVolumeClaim 請求這些資源,並最終由 Pod 使用。整個流程體現了 Kubernetes 中動態儲存管理的機制。