Kubernetes 存儲方案
介紹
Kubernetes(k8s)提供了多種存儲方案,以便在不同的場景下滿足不同的需求
- 空白存儲卷(EmptyDir):它是一種臨時性的存儲卷,不容器重新開機或删除時,其中的資料會被清除。适用于需要在容器内部傳遞資料的場景。
- 主機路徑存儲卷(HostPath):它将主機的目錄挂載到容器中,可以用來存儲一些應用程式的資料。但不适用于需要在多個節點上運作的應用程式。
- 持久化存儲卷(PersistentVolume & Persistent Volume Claim):它是一種動态持久性的存儲卷類型,可以在容器重新開機或遷移時自動建立和銷毀資料,以适應不同的存儲需求。可以使用多種存儲後端,如NFS、iSCSI、Ceph等。
- 動态存儲卷(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的聲明式存儲卷進行綁定,實作自動化的存儲管理和排程。動态存儲可以通過統一的接口和控制器進行管理和監控,避免了手動管理的繁瑣和複雜性。同時,也可以通過自動化的方式實作存儲資源的自愈和優化,降低了管理成本和風險。