Kubernetes PV與PVC

一、PV和PVC

PV的全稱是: PersistentVolume (持久化卷),是對底層的共享存儲的一種抽象,PV由管理員進行創建和配置,它和具體的底層的共享存儲技術的實現方式有關,比如Ceph、GlusterFS、NFS等,都是通過插件機制完成與共享存儲的對接

PVC的全稱是: PersistenVolumeClaim (持久化卷聲明),PVC是用戶存儲的一種聲明,PVC和Pod比較類型,Pod是消耗節點,PVC消耗的是PV資源,Pod可以請求CPU的內存,而PVC可以請求特定的存儲空間和訪問模式。對於真正存儲的用戶不需要關心底層的存儲實現細節,只需要直接使用PVC即可

二、PV和PVC的生命週期

PV可以看作可用的存儲資源,PVC則是對存儲資源的需求,PV和PVC的互相關係遵循如下圖

在這裏插入圖片描述

2.1 資源供應 (Provisioning)

Kubernetes支持兩種資源的供應模式:靜態模式(Staic)和動態模式(Dynamic)。資源供應的結果就是創建好的PV。

  • 靜態模式:集羣管理員手工創建許多PV,在定義PV時需要將後端存儲的特性進行設置
  • 動態模式:集羣管理員無須手工創建PV,而是通過StorageClass的設置對後端存儲進行描述,標記爲某種 “類型(Class)”。此時要求PVC對存儲的類型進行聲明,系統將自動完成PV的創建及PVC的綁定。PVC可以聲明Class爲””,說明該PVC禁止使用動態模式

2.2 資源綁定 (Binding)

在用戶定義好PVC後,系統將根據PVC對存儲資源的請求 (存儲空間和訪問模式)在已存在的PV中選擇一個滿足PVC要求的PV,一旦找到,就將該PV與用戶定義的PVC進行綁定,然後用戶的應用就可以使用這個PVC了。如果系統中沒有滿足PVC要求的PV,PVC則會無限期處於Pending狀態,直到等到系統管理員創建了一個符合要求的PV。PV一旦綁定在某個PVC上,就被這個PVC獨佔,不能再與其他PVC進行綁定了。在這種情況下,當PVC申請的存儲空間比PV的少時,整個PV的空間都能夠爲PVC所用,可能會造成資源的浪費。如果資源供應使用的是動態模式,則系統在PVC找到合適的StorageClass後,將會自動創建PV並完成PVC的綁定

2.3 資源使用 (Using)

Pod 使用volume的定義,將PVC掛載到容器內的某個路徑進行使用。volume的類型爲persistentVoulumeClaim,在容器應用掛載了一個PVC後,就能被持續獨佔使用。不過,多個Pod可以掛載同一個PVC,應用程序需要考慮多個實例共同訪問一塊存儲空間的問題

2.4 資源釋放 (Releasing)

當用戶對存儲資源使用哪個完畢後,用戶可以刪除PVC,與該PVC綁定的PV將會被標記爲已釋放,但還不能立刻與其他PVC進行綁定。通過之前PVC寫入的數據可能還留在存儲設備上,只有在清除之後該PV才能繼續使用

2.5 資源回收 (Reclaiming)

對於PV,管理員可以設定回收策略(Reclaim Policy)用於設置與之綁定的PVC釋放資源之後,對於遺留數據如何處理。只有PV的存儲空間完成回收,才能供新的PVC綁定和使用。

靜態資源下,通過PV和PVC完成綁定,並供Pod使用的存儲管理機制
在這裏插入圖片描述

動態資源下,通過StorageClass和PVC完成資源動態綁定 (系統自動生成PV,並供Pod使用的存儲管理機制)

三、使用NFS進行演示

3.1 首先我們需要安裝NFS服務

# 安裝nfs、rpcbind
yum install nfs-utils -y rpcbind
# 設置nfs存儲目錄
mkdir -p /data/k8s-volume
chmod 755 /data/k8s-volume/
# 編輯nfs配置文件
vim /etc/exports
# 存儲目錄,*允許所有人連接,rw讀寫權限,sync文件同時寫入硬盤及內存,no_root_squash 使用者root用戶自動修改爲普通用戶
/data/k8s-volume *(rw,no_root_squash,sync)
# 啓動rpcbind
systemctl start rpcbind && systemctl enable rpcbind
# 啓動NFS
systemctl restart nfs && systemctl enable nfs
# 查看nfs目錄掛載權限
cat /var/lib/nfs/etab
/data/k8s-volume	*(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,no_root_squash,no_all_squash)

3.2 nfs server端安裝完畢,然後所有需要nfs掛載的集羣節點安裝nfs

yum install -y nfs-utils rpcbind \
  && systemctl start rpcbind \
  && systemctl enable rpcbind \
  && systemctl start nfs \
  && systemctl enable nfs

3.3 客戶端掛載測試

# 首先檢查nfs掛載目錄是否正常
[root@所有節點 ~]# showmount -e 192.168.1.40 # 服務端的IP
Export list for 192.168.1.40:
/data/k8s-volume *

# 現在進行節點掛載
# 先在客戶端創建數據目錄(掛載點位置)
[root@所有節點 ~]# mkdir -p /data/k8s/
#現在進行掛載 分別是ip:nfs目錄 節點存儲目錄
[root@所有節點 ~]# mount -t nfs 192.168.1.40:/data/k8s-volume /data/k8s
#掛在完成後我們使用df -h 就可以看到掛載點
[root@所有節點 ~]# df -Th|grep /data/k8s-volume
文件系統                       類型  容量  已用 可用 已用% 掛載點
192.168.1.40:/data/k8s-volume nfs4  50G  5.0G 46G  10%  /data/k8s
#所有需要nfs節點這樣掛載就可以

四、創建PV

有了我們NFS共享存儲,下面就可以來使用PV和PVC。PV作爲存儲資源,主要包括存儲能力、訪問模式、存儲類型、回收策略等關鍵信息。這裏使用nfs類型的後端存儲,1g存儲空間,訪問模式爲ReadWriteOnce,回收策略爲Recyle,對應文件如下

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1         #pv名稱
spec:
  capacity:         #存儲能力,一個pv對象都要指定一個存儲能力,目前僅支持存儲空間的設置
    storage: 1Gi    #存儲空間
  accessModes:
  - ReadWriteOnce   #訪問模式
  persistentVolumeReclaimPolicy: Recycle     #回收策略
  nfs:              #服務模式 (nfs、ceph、hostpath等)
    path: /data/k8s-volume     #共享數據目錄掛載點
    server: 192.168.1.40         #nfs服務器地址

創建pv

[root@harbor ~]# kubectl apply -f pv.yaml 
persistentvolume/pv1 created

查看pv

[root@harbor ~]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    1Gi        RWO            Recycle          Available                                   5s

參數解釋

pv1 名稱
1Gi 代表存儲空間大小
RWO 訪問模式(ReadWriteOnce縮寫)
Recycle 回收策略
Available PV狀態

PV相關配置說明

  1. Capacity 存儲能力
  • 通過PV的capacity屬性來設置存儲空間,目前僅支持storage=數據大小,未來可能會加入IOPS、吞吐量等指標配置
  1. AccessModes 訪問模式,AccessModes 是用來對PV進行訪問模式的設置,用於描述用戶應用對存儲資源的訪問權限
  • ReadWriteOnce (RWO) 讀寫權限,但是隻能被單個節點掛載
  • ReadOnlyMany (ROX) 只讀權限,可能被多個節點掛載
  • ReadWriteMany (RWX) 讀寫權限,可以被多個節點掛載
  1. persistentVolumeReclaimPolicy 回收策略
  • Retain (保留) 保留數據,需要管理員手動清理
  • Recycle (回收) 清除PV中的數據,效果相當於執行刪除命令
  • Delete (刪除) 與PV相連的後端存儲完成volume的刪除操作,常見於雲服務商的存儲服務

不過需要注意的是,目前只有NFS和HostPath兩類支持回收策略,一般設置Retain比較保險

  1. 狀態
  • Available (可用): 表示可用狀態,還未被任何PVC綁定
  • Bound (已綁定):已經綁定到某個PVC
  • Released (已釋放):對應的PVC已經刪除,但資源還沒有被集羣收回
  • Failed:PV自動回收失敗

五、創建PVC

#前面我們已經在集羣上都安裝nfs客戶端,並且進行掛載了。下面進行創建pvc
[root@harbor ~]# kubectl get node
NAME    STATUS   ROLES                      AGE   VERSION
node1   Ready    controlplane,etcd,worker   42d   v1.17.5
node2   Ready    controlplane,etcd,worker   42d   v1.17.5
node3   Ready    controlplane,etcd,worker   42d   v1.17.5
node4   Ready    worker                     37d   v1.17.5
node5   Ready    worker                     37d   v1.17.5
node6   Ready    worker                     30d   v1.17.5

新建pvc同樣需要建立一個數據卷聲明

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

在Kubernetes中會自動幫我們查看pv狀態爲Available並且根據聲明pvc容量storage的大小進行篩選匹配,同時還會根據AccessMode進行匹配。如果pvc匹配不到pv會一直處於pending狀態。

[root@harbor ~]# kubectl apply -f pv.yaml 
persistentvolume/pv1 created

[root@harbor ~]# kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-nfs   Bound    pv1      1Gi        RWO                           71s

[root@harbor ~]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
pv1    1Gi        RWO            Recycle          Bound    default/pvc-nfs                           4m35s

# 這裏我們可以看到,當我們創建pvc之後,pv的狀態變成了Bound綁定狀態,並且和pvc的狀態相同。並且可以看到pvc已經綁定到名稱爲pv1的volume上,同時在pv上可以看到綁定到名稱爲pvc-nfs的pvc中

六、使用Labels匹配PV與PVC

pv與pvc中間還可以通過label標籤進行匹配,配置如下

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv2
  labels:           #這裏將pv設置一個labels
    app: nfs
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/k8s-volume
    server: 192.168.1.40
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2-nfs
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  selector:         ##pvc匹配標籤爲app=nfs的pv
    matchLabels:
      app: nfs

應用

[root@harbor ~]# kubectl apply -f pvc-pv.yaml 
persistentvolume/pv2 created
persistentvolumeclaim/pvc2-nfs created

注意:當我們申請pvc的容量大於pv的容量是無法進行綁定的。

七、Deployment引用pvc

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pv-nfs-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: pv-nfs-nginx
  template:
    metadata:
      labels:
        app: pv-nfs-nginx
    spec:
      containers:
      - name: pv-nfs-nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:           #掛載,首先添加需要掛載的目錄
        - name: pv-nginx        #掛載點的名稱
          mountPath: /usr/share/nginx/html   #掛載點的路徑
      volumes:    #綁定
      - name: pv-nginx
        persistentVolumeClaim:    #將鏡像中的nginx目錄掛載到下面名稱的pvc中
          claimName: pvc2-nfs   #pvc名稱
---
apiVersion: v1
kind: Service
metadata:
  name: nfs-pvc
  labels:
    app: pv-nfs-nginx
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 32334
  selector:
    app: pv-nfs-nginx

接下來我們到nfs掛載點創建一個index.html

echo "I am tester" > /data/k8s/index.html

nginx可以顯示該內容

注意:如果我們直接刪除或者有pod在使用pv或者pvc是無法直接刪除的,當我們使用Recycle模式時,刪除所有pv和pvc後,數據也會進行刪除。所以刪除pv和pvc請謹慎操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章