1. 程式人生 > 其它 >k8s 持久化儲存 PV 和 PVC 的簡單使用

k8s 持久化儲存 PV 和 PVC 的簡單使用

概述

Kubernetes 對於有狀態的容器應用或者對資料需要持久化的應用,可以通過 hostPath 或者 emptyDir 的方式來持久化我們的資料,但是我們需要更加可靠的儲存來儲存應用的持久化資料。不過儲存資源和 CPU 資源以及記憶體資源有很大不同,為了遮蔽底層的技術實現細節,讓使用者更加方便的使用,Kubernetes 便引入了 PVPVC 兩個重要的資源物件來實現對儲存的管理。

概念

PV (PersistentVolume) 是對底層網路共享儲存的抽象,將共享儲存定義為一種 “資源”。PV 一般由K8S的管理員所建立和配置,它和具體的底層的共享儲存技術的實現方式有關,比如 Ceph

GlusterFSNFS 等,都是通過外掛機制完成與共享儲存的對接。

PVC (PersistentVolumeClaim) 是使用者對儲存資源的一個 “申請”。就像 Pod消費 Node 資源一樣,PVC 能夠消費 PV 的資源。Pod 可以請求節點的CPU和記憶體,而 PVC 可以請求特定的儲存空間和訪問模式。對於使用者來說,不需要關心底層的儲存實現細節,只需要直接使用 PVC 即可。

實戰:基於NFS共享儲存建立PV和PVC

示例:基於NFS儲存來建立PV和PVC

本次共享儲存資源選擇本地自建的NFS,關於搭建NFS的教程參考之前寫的博文:centos7搭建NFS服務

試驗環境如下,注意所有k8s節點都要安裝nfs,yum install -y nfs-tools

主機名hostname IP地址 說明
master 192.168.18.10 k8s主節點
node1 192.168.18.11 k8s的node1節點
node2 192.168.18.12 k8snode2節點
db 192.168.18.7 NFS伺服器,共享目錄/data/nfs/test-pv

PV

PV 作為儲存資源,主要包括儲存能力、訪問模式、儲存型別、回收策略、後端儲存型別等關鍵資訊的設定。PV 是沒有名稱空間的隔離性的。下面來建立一個PV 資源物件:

apiVersion: v1
kind: PersistentVolume
metadata:
  name:  pv001
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs-slow
  nfs:
    path: /data/nfs/test-pv
    server: 192.168.18.7

上面yaml檔案表明:建立了一個名字是pv001的PV,使用NFS型別的後端儲存,宣告5G的儲存空間,訪問模式是 ReadWriteMany ,回收策略為 Recyle。有了yaml檔案後,直接建立即可。

# 建立pv
[root@master k8s-yaml]# kubectl create -f pv.yaml
# 檢視pv
[root@master k8s-yaml]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   5Gi        RWX            Recycle          Available           nfs-slow                5s

PV的常用配置引數

1. 儲存能力(Capacity)

一個 PV 物件一般都要指定一個儲存能力,通過 PV 的 capacity 屬性來設定的,比如這裡的 storage: 5Gi,目前只支援對儲存空間的設定,未來可能加入IOIPS、吞吐量等指標的設定。

2. 訪問模式(Access Modes)

對 PV 進行訪問模式的設定,用於描述使用者的應用對儲存資源的訪問許可權。分為三種:

  • ReadWriteOnce:讀寫許可權,並且只能被單個 Node 掛載;
  • ReadOnlyMany:只讀許可權,允許被多個 Node 掛載;
  • ReadWriteMany:讀寫許可權,允許被多個 Node 掛載

一些 PV 可能支援多種訪問模式,但是在掛載的時候只能使用一種訪問模式,多種訪問模式是不會生效的。

3. 儲存類別(Class)

PV 可以設定其儲存的類別,通過 storageClassName 引數指定一個 StorageClass 資源物件的名稱。具有特定類別的 PV 只能與請求了該類別的 PVC 進行繫結。未設定類別的 PV 則只能與不請求任何類別的 PVC 進行繫結。

4. 回收策略

回收策略是通過 persistentVolumeReclaimPolicy 引數進行設定,可選性如下:

  • Retain:保留,需要手動清理資料
  • Recycle:回收,清楚PV中的資料,相當於 rm -rf /thevolume/* 命令
  • Delete:刪除,與 PV 相連的後端儲存完成volume的刪除操作,刪除 PVC 後,PV也會被刪掉。這一類的PV,需要支援刪除功能,是動態儲存的預設方式。

PV 的生命週期

一個 PV 在生命週期可能處於下面四個階段之一:

  • Available:可用狀態,還沒有於某個PVC進行繫結
  • Bound:已跟某個PVC繫結
  • Released:繫結的PVC已經刪除,資源已經釋放,但是沒有被叢集回收
  • Failed:自動資源回收失敗

上面建立了PV之後,由於還沒有任何PVC跟PV繫結,所以PV的狀態還是 Available

PVC

PVC 作為使用者對儲存資源的需求申請,主要包括儲存空間請求、訪問模式、PV選擇條件和儲存類別的資訊的設定。如下,新建一個PVC,跟上面建立的PV進行繫結。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 3Gi
  storageClassName: nfs-slow

該PVC申請了與儲存類別名稱為 nfs-slow 的 PV 進行繫結,請求3G的儲存容量,訪問模式是 ReadWriteMany,建立該PVC:

[root@master k8s-yaml]# kubectl create -f pvc.yaml

# 檢視default名稱空間下的PVC
[root@master k8s-yaml]# kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim   Bound    pv001    5Gi        RWX            nfs-slow       6s

# 注意,PVC有名稱空間的隔離性
[root@master k8s-yaml]# kubectl get pvc -n kube-system
No resources found in kube-system namespace.

# 檢視PV狀態
[root@master k8s-yaml]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
pv001   5Gi        RWX            Recycle          Bound    default/myclaim   nfs-slow                3h29m

可以看到,在PVC與PV進行繫結之後,PV的狀態變成了 Bound。但是從上面也看出,我的 PVC 裡面宣告的容量是3G,而PV裡面宣告的容量是5G,結果創建出來的PVC容量卻是5G,說明,PV的容量是多少,PVC的容量就是多少。

如果PVC裡面設定的容量超過PV裡面定義的容量,那麼PVC是建立不成功的,會一直處於Pending狀態。

使用PVC

上面建立了PV和PVC,接下來就可以使用它們了,使用下面nginx-pvc.yaml 進行測試:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-pvc
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.18.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: my-pvc-volume

      volumes:
      - name: my-pvc-volume
        persistentVolumeClaim:
          claimName: myclaim

然後在nfs的共享目錄裡面建立個html檔案:

[root@db ]# cd /data/nfs/test-pv/
[root@db test-pv]# echo "hello k8s pvc" > index.html

建立Deployment

[root@master k8s-yaml]# kubectl create -f nginx-pvc.yaml 

檢視Pod:

[root@master k8s-yaml]# kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
nginx-pvc-78c9859d7-94lxn   1/1     Running   0          38s   10.244.166.165   node1   <none>           <none>

訪問Pod:

[root@master k8s-yaml]# curl 10.244.166.165
hello k8s pvc

可以看到,Pod內部的容器已經成功掛載nfs的後端儲存。

參考資料