1. 程式人生 > 其它 >k8s儲存卷,pv和pvc

k8s儲存卷,pv和pvc

儲存卷

容器磁碟上的檔案的生命週期是短暫的,這就使得在容器中執行重要應用時會出現一些問題。首先, 當容器崩潰時,kubelet會重啟它,但是容器中的檔案將丟失容器以乾淨的狀態 (映象最初的狀態)重新啟動。其次,在Pod中同時執行多個容器時,這些容器之間通常需要共享檔案。Kubernetes 中的Volume抽象就很好的解決了這些問題。Pod中的容器通過Pause容器共享Volume。

emptyDir儲存卷

當Pod被分配給節點時,首先建立emptyDir卷,並且只要該Pod在該節點上執行,該卷就會存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以讀取和寫入emptyDir卷中的相同檔案,儘管該卷可以掛載到每個容器中的相同或不同路徑上。當出於任何原因從節點中刪除 Pod 時,emptyDir中的資料將被永久刪除。

mkdir shiyan
cd /shiyan
vim pod4.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx1
    image: nginx
    ports:
    - name: http
      containerPort: 80
    volumeMounts:                                                     #定義容器掛載內容
    - name: html                                    #使用儲存卷名稱,如果跟下面volume欄位name值相同,則表示使用volume的這個儲存卷
      mountPath: /usr/share/nginx/html/                              #掛載至容器中哪個目錄
  - name: nginx2
    image: nginx
    volumeMounts:
    - name: html
      mountPath: /data/
    command: ['/bin/bash','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
  volumes:
  - name: html
    emptyDir: {}

kubectl exec -it nginx -c nginx2 sh                                 #-c指定pod裡面的容器名進入

hostPath儲存卷

hostPath卷將 node 節點的檔案系統中的檔案或目錄掛載到叢集中。
hostPath可以實現持久儲存,但是在node節點故障時,也會導致資料的丟失。

在 node01 節點上建立掛載目錄
mkdir -p /data/pod/
echo 'node1.com' > /data/pod/index.html

在 node02 節點上建立掛載目錄
mkdir -p /data/pod/
echo 'node2.com' > /data/pod/index.html

建立 Pod 資源
vim pod5.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:                                           #定義容器掛載內容
    - name: html                                               #使用儲存卷名稱於volume定義 的name相同
      mountPath: /usr/share/nginx/html/      #定義容器內的掛載目錄
      readOnly: false                                         #讀寫掛載方式,預設為讀寫模式false             
  volumes: 
    - name: html                                               #定義儲存卷名稱
      hostPath:                                                   #路徑,宿主機儲存路徑
        path: /data/pod/                                    #在宿主機上目錄的路徑
        type: DirectoryOrCreate                        #定義型別,如果宿主機沒有此目錄會自動建立
kubectl get pods -o wide

curl 10.244.2.6                                               #刪除pod重建檔案內容依然存在,直接修改主機內的目錄也可以

nfs共享儲存卷

在新節點(node3)安裝nfs並配置服務
mkdir /data/pod -p
chmod 777 /data/pod/
echo 'node3' > /data/pod/index.html

vim /etc/exports
/data/pod 192.168.150.0/24(rw,no_root_squash)
                                         
systemctl start rpcbind
systemctl start nfs

showmount -e
Export list for localhost.localdomain:
/data/pod 192.168.150.0/24

master節點操作,k8s叢集需要新增主機名對映
vim pod6.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
    - name: html
      nfs:                                                            #指定掛載型別為nfs
        path: /data/pod/                                         
        server: stor03                                     #指定nfs伺服器名,只能是主機名不能為IP地址

PVC和 PV

PersistentVolume(PV)是叢集中已由管理員配置的一段網路儲存。叢集中的資源就像一個節點是一個叢集資源。

PV是諸如卷之類的卷外掛,但是具有獨立於使用PV的任何單個pod的生命週期。

該API物件捕獲儲存的實現細節,即NFSiSCSI或雲提供商特定的儲存系統。

PersistentVolumeclaim(PVC)是使用者儲存的請求。PVC的使用邏輯∶在pod中定義一個儲存卷(該儲存卷型別為PVC),定義的時候直接指定大小,pvc必須與對應的pv建立關係,pvc會根據定義去pv申請,而pv是由儲存空間創建出來的。pv和pvc是kubernetes抽象出來的一種儲存資源。

雖然PersistentVolumeClaims允許使用者使用抽象儲存資源,但是常見的需求是,使用者需要根據不同的需求去建立PV,用於不同的場景。而此時需要叢集管理員提供不同需求的PV,而不僅僅是PV的大小和訪問模式,但又不需要使用者瞭解這些卷的實現細節。對於這樣的需求,此時可以採用StorageClass資源動態

PV是叢集中的資源。 PVC是對這些資源的請求,也是對資源的索引檢查。PV和PVC之間的相互作用遵循這個生命週期∶

Provisioning(配置)---> Binding(繫結)--->Using(使用)---> Releasing(釋放)---> Recycling(回收)

這裡有兩種PV的提供方式∶靜態或者動態

靜態-->直接固定儲存空間∶

叢集管理員建立一些 PV。它們攜帶可供叢集使用者使用的真實儲存的詳細資訊。它們存在於Kubernetes API中,可用於消費。

動態-->通過儲存類進行動態建立儲存空間∶

當管理員建立的靜態 PV 都不匹配使用者的PVC時,叢集可能會嘗試動態地為 PVC 配置卷。此配置基於 storageClasses:PVC必須請求儲存類,並且管理員必須已建立並配置該類才能進行動態配置。要求該類的宣告有效地為自已禁用動態配置。

格式

kubectl explain pv                                   #檢視pv的定義方式
FIELDS:
    apiVersion 
    kind 
    metadata 
    spec

kubectl explain pv.spec                               #檢視pv定義的規格
spec:
  nfs(定義儲存型別)
    path(定義掛載卷路徑)
    server(定義伺服器名稱)
  accessModes(定義訪問模型,有以下三種訪問模型,以列表的方式存在,也就是說可以定義多個訪
問模式)
ReadWriteOnce(RWO) 單節點讀寫    
ReadOnlyMany(ROX)多節點只讀    
ReadWriteMany(RWX)多節點讀寫
  persistentVolumeReclaimPolicy: Retain               #可以定義回收策略
  capacity(定義PV空間的大小)
    storage(指定大小)
kubectl explain pvc                                  #檢視PVC的定義方式
KIND: PersistentVolumeClaim
VERSION: v1 
FIELDS:
   apiVersion <string>
   kind <string>
   metadata <Object>
   spec <Object>

kubectl explain pvc.spec 
spec:
  accessModes(定義訪問模式,必須是P的訪問模式的子集)
  resources (定義申請資源的大小)
requests:       
storage:

NFS使用PV和PVC

1、單獨一臺機器配置nfs儲存

mkdir -p /data/v{1,2,3,4,5}
chmod 777 /data/v{1,2,3,4,5}

vim /etc/exports
/data/v1 192.168.10.0/24(rw,no_root_squash)
/data/v2 192.168.10.0/24(rw,no_root_squash)
/data/v3 192.168.10.0/24(rw,no_root_squash)
/data/v4 192.168.10.0/24(rw,no_root_squash)
/data/v5 192.168.10.0/24(rw,no_root_squash)
exportfs -arv 
showmount -e

2、定義PV

這裡定義5個PV,並且定義掛載的路徑以及訪問模式,還有PV劃分的大小。

vim pv.yaml

apiVersion: v1

kind: PersistentVolume

metadata:

name: pv01

labels:

name: pv01

spec:

nfs:

path: /data/v1

server: nfs01

accessModes: ["ReadWriteMany","ReadWriteOnce"]

capacity:

storage: 1Gi

---

apiVersion: v1

kind: PersistentVolume

metadata:

name: pv02

labels:

name: pv02

spec:

nfs:

path: /data/v2

server: nfs01

accessModes: ["ReadWriteOnce"]

capacity:

storage: 2Gi

---

apiVersion: v1

kind: PersistentVolume

metadata:

name: pv03

labels:

name: pv03

spec:

nfs:

path: /data/v3

server: nfs01

accessModes: ["ReadWriteMany","ReadWriteOnce"]

capacity:

storage: 2Gi

---

apiVersion: v1

kind: PersistentVolume

metadata:

name: pv04

labels:

name: pv04

spec:

nfs:

path: /data/v4

server: nfs01

accessModes: ["ReadWriteMany","ReadWriteOnce"]

capacity:

storage: 4Gi

---

apiVersion: v1

kind: PersistentVolume

metadata:

name: pv05

labels:

name: pv05

spec:

nfs:

path: /data/v5

server: nfs01

accessModes: ["ReadWriteMany","ReadWriteOnce"]

capacity:

storage: 5Gi

kubectl create -f pv.yaml

kubectl get pv

3、定義PVC

這裡定義了pvc的訪問模式為多路讀寫,該訪問模式必須在前面pv定義的訪問模式之中。定義PVc申請的大小為2Gi,此時PVC會自動去匹配多路讀寫且大小為2Gi的PV,匹配成功獲取PVC的狀態即為Bound(需要做好node節點和nfs伺服器的對映)
vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginxpvc
spec:
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx01
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
    - name: html
      persistentVolumeClaim:
        claimName: nginxpvc

StorageClass

在pv和pvc使用過程中存在的問題,在pvc申請儲存空間時,未必就有現成的py符合pvc申請的需求,上面nfs在做pvc可以成功的因素是因為我們做了指定的需求處理。那麼當PvC申請的儲存空間不一定有滿足PVC要求的PV時,又該如何處理呢為此,Kubernetes為管理員提供了描述儲存"class(類)"的方法(storageClass)。舉個例子,在儲存系統中劃分一個1TB的儲存空間提供給Kubernetes使用,當用戶需要個10G的pvc時,會立即通過restful傳送請求,從而讓儲存空間建立一個10G的image,之後在我們的叢集中定義成10G的Pv供給給當前的PVC作為掛載使用。在此之前我們的儲存系統必須支援restful介面,比如ceph分散式儲存,而glusterfs則需要藉助第三方介面完成這樣的請求。

kubectl explapin storageclass                           #storageclass也是k8s上的資源
KIND:     StorageClass
VERSION:  storage.k8s.io/v1
FIELDS:
  allowVolumeExpansion <boolean>
  allowedTopologies    <[]Object>
  apiVersion           <string>
  kind                 <string>
  metadata             <Object>
  mountOptions         <[]string>           #掛載選項
  parameters           <map[string]string>   #引數,取決於分配器,可以接受不同的引數。例如引數 type 的值 iol 和引數 iopsPerGB 特定於EBS PV。當引數被省略時,會使用預設值。
  provisioner          <string>-required-      #儲存分配器,用來決定使用哪個卷外掛分配 PV。該欄位必須指定。
  reclaimPolicy        <string>              #回收策略,可以是 Delete 或者 Retain。如果 storageclass 物件被建立時沒有指定 reclaimPolicy,它將
預設為 Delete。
  volumeBindingMode   <string>   #卷的繫結模式