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


概述

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

概念

PV (PersistentVolume) 是對底層網絡共享存儲的抽象,將共享存儲定義為一種 “資源”。PV 一般由K8S的管理員所創建和配置,它和具體的底層的共享存儲技術的實現方式有關,比如 CephGlusterFSNFS 等,都是通過插件機制完成與共享存儲的對接。

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的后端存儲。

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM