天天看點

K8S持久化存儲方案

作者:leenhem
K8S持久化存儲方案

Kubernetes 存儲方案

介紹

Kubernetes(k8s)提供了多種存儲方案,以便在不同的場景下滿足不同的需求

  1. 空白存儲卷(EmptyDir):它是一種臨時性的存儲卷,不容器重新開機或删除時,其中的資料會被清除。适用于需要在容器内部傳遞資料的場景。
  2. 主機路徑存儲卷(HostPath):它将主機的目錄挂載到容器中,可以用來存儲一些應用程式的資料。但不适用于需要在多個節點上運作的應用程式。
  3. 持久化存儲卷(PersistentVolume & Persistent Volume Claim):它是一種動态持久性的存儲卷類型,可以在容器重新開機或遷移時自動建立和銷毀資料,以适應不同的存儲需求。可以使用多種存儲後端,如NFS、iSCSI、Ceph等。
  4. 動态存儲卷(Dynamic Volume Provisioning):它使用存儲插件動态建立存儲卷,将存儲資源與應用程式分離。可以根據需要自動建立和删除存儲資源,節約資源。

空白存儲卷(EmptyDir)

空白存儲卷(EmptyDir)它是一種臨時性的存儲卷,适用于需要在容器内部傳遞資料的場景。例如,當一個容器需要向另一個容器傳遞一些資料時,可以使用空白存儲卷來實作。下面是一個使用空白存儲卷傳遞資料的示例:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: container1
    image: my-image
    volumeMounts:
    - name: data
      mountPath: /data
  - name: container2
    image: my-image
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    emptyDir: {}           

在這個示例中,我們建立了一個 Pod,其中包含兩個容器:container1 和 container2。這兩個容器都需要通路同一個資料目錄 /data。我們使用了一個空白存儲卷來存儲這些資料。在 volumes 字段中,我們建立了一個名為 data 的空白存儲卷。在容器的 volumeMounts 字段中,我們将這個存儲卷挂載到了 /data 目錄下。

這樣,當 container1 向 /data 目錄寫入資料時,container2 可以從同一個目錄讀取資料,實作了資料的傳遞。需要注意的是,當 Pod 被删除或重新開機時,存儲在空白存儲卷中的資料也會被清除。

主機路徑存儲卷(HostPath)

主機路徑存儲卷(HostPath)将主機的目錄挂載到容器中,可以用來存儲一些應用程式的資料。例如,我們可以使用主機路徑存儲卷來存儲應用程式的日志檔案、配置檔案等。下面是一個使用主機路徑存儲卷存儲日志檔案的示例 YAML 檔案:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: container1
    image: my-image
    volumeMounts:
    - name: logs
      mountPath: /var/log/my-app
  volumes:
  - name: logs
    hostPath:
      path: /var/log/my-app           

在這個示例中,我們建立了一個 Pod,其中包含一個名為 container1 的容器。我們使用了一個主機路徑存儲卷來存儲應用程式的日志檔案。在 volumes 字段中,我們建立了一個名為 logs 的主機路徑存儲卷,并将其挂載到了 /var/log/my-app 目錄下。這個目錄在主機上已經存在,我們可以在主機上檢視和管理存儲的日志檔案。

需要注意的是,主機路徑存儲卷會将主機上的目錄直接挂載到容器中,是以可能會存在安全風險和資料共享的問題。在使用時需要注意權限控制和資料隔離。

持久化存儲卷(PersistentVolume &PersistentVolume Claim)

持久化存儲卷(PersistentVolume)持久化存儲卷。它用來描述或者說用來定義一個存儲卷,代表一個獨立的存儲資源。PV 通常代表一個存儲卷,PVC與PV是一一對應關系,通常一個PV必須被Bound到一個PVC上,才能被Pod通路和使用。下面舉例說明如何使用PV。

首先,需要在K8S中建立一個PV對象,可以使用yaml格式的配置檔案如下:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: my-storage-class
  nfs:
    path: /data/my-pv
    server: nfs-server.my-domain.com           

這個配置檔案定義了一個名為my-pv的PV對象,使用NFS存儲後端,在伺服器nfs-server.my-domain.com上,挂載在/data/my-pv路徑下,容量為1GB。它的通路模式為ReadWriteOnce,即隻能被一個Pod挂載為讀寫模式。另外,它的持久化存儲政策為Retain,即在PV對象被删除時,保留其存儲内容。最後,它的存儲類别為my-storage-class。

接下來,可以在K8S中建立一個Persistent Volume Claim(PVC)對象,例如:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi
  storageClassName: my-storage-class           

這個配置檔案定義了一個名為my-pvc的PVC對象,請求500MB的存儲空間,通路模式為ReadWriteOnce,存儲類别為my-storage-class。 最後,在Pod的配置檔案中,可以使用volumeMounts和volumes字段,将PVC挂載為一個持久化存儲卷,例如:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    volumeMounts:
    - mountPath: /data
      name: my-pv-volume
  volumes:
  - name: my-pv-volume
    persistentVolumeClaim:
      claimName: my-pvc           

這個配置檔案定義了一個名為my-pod的Pod對象,使用名為my-pv-volume的持久化存儲卷,将PVC my-pvc挂載到/data路徑下。這樣,Pod中的應用程式就可以使用/data路徑下的持久化存儲了。

動态存儲卷(Dynamic Volume Provisioning)

一個大規模的 Kubernetes 叢集裡很可能有成千上萬個 PVC,這就意味着運維人員必須得事先建立出成千上萬個 PV。更麻煩的是,随着新的 PVC 不斷被送出,運維人員就不得不繼續添加新的、能滿足條件的 PV,否則新的 Pod 就會因為 PVC 綁定不到 PV 而失敗。在實際操作中,這幾乎沒辦法靠人工做到。

是以,Kubernetes 為我們提供了一套可以自動建立 PV 的機制,即:Dynamic Provisioning。相比之下,前面人工管理 PV 的方式就叫作 Static Provisioning。Dynamic Provisioning 機制工作的核心,在于一個名叫 StorageClass 的 API資源對象。

StorageClass是Kubernetes中一種動态存儲類型,它可以根據不同的存儲需求,自動選擇不同的存儲方案。下面舉個例子說明如何使用StorageClass。

首先,需要在Kubernetes中建立一個StorageClass對象,可以使用yaml格式的配置檔案,例如:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: my-storage-class
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2           

這個配置檔案定義了一個名為my-storage-class的StorageClass對象,使用AWS EBS存儲後端,并使用gp2類型的存儲。provisioner字段指定了存儲後端的名稱,parameters字段指定了存儲參數。

接下來,可以在Kubernetes中建立一個PersistentVolumeClaim(PVC)對象,例如:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: my-storage-class           

這個配置檔案定義了一個名為my-pvc的PVC對象,請求1GB的存儲空間,通路模式為ReadWriteOnce,存儲類别為my-storage-class。

最後,在Pod的配置檔案中,可以使用volumeMounts和volumes字段,将PVC挂載為一個持久化存儲卷,例如:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    volumeMounts:
    - mountPath: /data
      name: my-pv-volume
  volumes:
  - name: my-pv-volume
    persistentVolumeClaim:
      claimName: my-pvc           

這個配置檔案定義了一個名為my-pod的Pod對象,使用名為my-pv-volume的持久化存儲卷,将PVC my-pvc挂載到/data路徑下。這樣,Pod中的應用程式就可以使用/data路徑下的持久化存儲了。使用StorageClass和PVC,可以友善地管理和使用Kubernetes中的持久化存儲。

總結

Storage Class是一種抽象的存儲層,用于定義動态存儲的政策和屬性。它可以友善地管理和配置設定存儲資源,支援多種存儲類型和配置選項,提高了存儲的靈活性和可靠性。同時,Storage Class也可以與Pod的聲明式存儲卷進行綁定,實作自動化的存儲管理和排程。動态存儲可以通過統一的接口和控制器進行管理和監控,避免了手動管理的繁瑣和複雜性。同時,也可以通過自動化的方式實作存儲資源的自愈和優化,降低了管理成本和風險。

繼續閱讀