k8s的pv和pvc概念


存儲卷

  同一個pod內的所有容器共享存儲 網絡 用戶等空間     pod內的容器都是以pause鏡像為基礎鏡像來運行的
   k8s.gcr.io/pause 3.1 da86e6ba6ca1 17 mon 742 kB

emptyDir
     臨時存儲目錄 pod刪除 存儲卷也隨即會被刪除

hostPath 主機目錄
     pod所在主機上的目錄

搭建NFS網絡存儲

nfs搭建
   yum install nfs-utils
   mkdir -pv /data/volumes
   vi /etc/exports
     /data/volumes 192.168.11.0/16(rw,no_root_squash)
   systemctl start nfs
  1.確保k8s集群中的所有節點都能驅動nfs 
    yum install nfs-utils
  2.[root@node2 ~]# mount -t nfs 192.168.11.157:/data/volumnes/ /mnt
mount.nfs: access denied by server while mounting 192.168.11.157:/data/volumnes/
  3.在nfs服務器查看/var/log/messages查看 volumnes單詞拼寫錯誤

  [root@node2 ~]# mount -t nfs 192.168.11.157:/data/volumes  /mnt

  [root@localhost ~]# vi /etc/exports
   /data/volumes/ 192.168.11.0/16(insecure,rw,async,no_root_squash)

  [root@localhost ~]# exportfs -r
  exportfs: Invalid prefix `24*' for 192.168.11.0/24*
  [root@localhost ~]# showmount -e
  Export list for localhost.localdomain:
  /data/volumes 192.168.11.0/16
nfs搭建
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-hostpath
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: html
    hostPath:
      path: /data/pod/volume1
      type: DirectoryOrCreate
hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-nfs
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: html
    nfs:
      path: /data/volumes
      server: 192.168.11.157
nfs.yaml

  nfs遠程文件存儲並沒有一個“存儲設備”需要掛載在宿主機上 所以不需要attach階段

  直接將遠端 NFS 服務器的目錄(比如:“/”目錄)掛載到Volume的宿主機目錄上即可 

  mount -t nfs <NFS服務器地址>:/ /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume類型>/<Volume名字> 

  通過掛載操作,Volume的宿主機目錄就成為了一個遠程NFS目錄的掛載點,后面你在這個目錄里寫入的所有文件,都會被保存在遠程NFS服務器

  所以,我們也就完成了對這個Volume宿主機目錄的“持久化”

pv和pvc的使用

       存儲工程師把分布式存儲系統上的總空間划分成一個一個小的存儲塊

       k8s管理員根據存儲塊創建與之一一對應的pv資源

       pv屬於集群級別資源  不屬於任何名稱空間 定義的時候不能指定名稱空間

       用戶在創建pod的時候同時創建與pv一一對應的pvc資源

       創建Pod的時候,系統里並沒有合適的PV跟它定義的PVC綁定 也就是說此時容器想要使用的Volume不存在.這時候Pod的啟動就會報錯

[root@localhost volumes]# mkdir v{1,2,3,4,5}
[root@localhost volumes]# ls
index.html  v1  v2  v3  v4  v5
[root@localhost volumes]# vi /etc/exports

/data/volumes/v1 192.168.11.0/16(insecure,rw,async,no_root_squash)
/data/volumes/v2 192.168.11.0/16(insecure,rw,async,no_root_squash)
/data/volumes/v3 192.168.11.0/16(insecure,rw,async,no_root_squash)
/data/volumes/v4 192.168.11.0/16(insecure,rw,async,no_root_squash)
/data/volumes/v5 192.168.11.0/16(insecure,rw,async,no_root_squash)


[root@localhost volumes]# exportfs -r
[root@localhost volumes]# showmount -e
Export list for localhost.localdomain:
/data/volumes/v5 192.168.11.0/16
/data/volumes/v4 192.168.11.0/16
/data/volumes/v3 192.168.11.0/16
/data/volumes/v2 192.168.11.0/16
/data/volumes/v1 192.168.11.0/16
創建小的存儲塊
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
   path: /data/volumes/v1
   server: 192.168.11.158
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
   path: /data/volumes/v2
   server: 192.168.11.158
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
   path: /data/volumes/v3
   server: 192.168.11.158
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
   path: /data/volumes/v4
   server: 192.168.11.158
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
   path: /data/volumes/v5
   server: 192.168.11.158
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
創建pv資源
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
  namespace: default
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 4Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-pvc
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    persistentVolumeClaim:
      claimName: mypvc
創建pod和pvc資源
[root@k8s-master ~]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON    AGE
pv001     2Gi        RWO,RWX        Retain           Available                                            8m
pv002     5Gi        RWO,RWX        Retain           Bound       default/mypvc                            8m
pv003     2Gi        RWO,RWX        Retain           Available                                            8m
pv004     2Gi        RWO,RWX        Retain           Available                                            8m
pv005     2Gi        RWO,RWX        Retain           Available                                            8m


[root@k8s-master ~]# kubectl get pvc
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc     Bound     pv002     5Gi        RWO,RWX                       8m


[root@k8s-master ~]# kubectl get pods
NAME                             READY     STATUS    RESTARTS   AGE
myapp-deploy-67f6f6b4dc-2986w    1/1       Running   0          4h
myapp-deploy-67f6f6b4dc-czvq4    1/1       Running   0          4h
myapp-deploy-67f6f6b4dc-tpggj    1/1       Running   0          10d
pod-vol-pvc                      1/1       Running   0          9m
tomcat-deploy-588c79d48d-mdgml   1/1       Running   0          10d
tomcat-deploy-588c79d48d-mvttj   1/1       Running   0          4h
tomcat-deploy-588c79d48d-w2mxb   1/1       Running   0          10d


在創建pvc的時候如果后端沒有合適的pv 那么掛載此pvc的pod將會一致處於等待狀態直到pvc匹配到一個符合條件的pv
演示結果

 

pv和pvc的機制

pv和pvc綁定要求
     1.PV和PVC的spec字段.比如PV的存儲(storage)大小
     2.PV和PVC的storageClassName字段必須一樣

     3. PV描述的是持久化存儲卷 這個API對象主要定義的是一個持久化存儲在宿主機上的目錄,如一個NFS的掛載目錄

         PVC可以理解為持久化存儲的 它提供了對某種持久化存儲的描述,但不提供具體的實現

     4. 持久化存儲的實現部分則由PV負責完成

     5.PV與PVC進行綁定,其實就是將這個PV對象的名字,填在了PVC對象的spec.volumeName字段上

       當PV和PVC成功綁定后 Pod就能像使用hostPath等常規類型的Volume一樣 在YAML文件中使用PVC

     pv對象轉換成持久化volume的原理

          所謂容器的Volume,其實就是將一個宿主機上的目錄跟一個容器里的目錄綁定掛載在了一起

持久化宿主機目錄

       遠程存儲服務,比如:遠程文件存儲(比如,NFS、GlusterFS),遠程塊存儲(比如,公有雲提供的遠程磁盤)

      “持久化”宿主機目錄的過程,我們可以形象地稱為“兩階段處理”

       先把遠程存儲設備附加到指定節點上  然后在節點上格式化存儲設備再掛載到節點上的具體目錄下  這樣才能通過節點目錄訪問遠程存儲設備

     Attach階段
         為虛擬機掛載遠程磁盤的操作
         當一個Pod調度到一個節點上之后,kubelet就要負責為這個Pod創建它的 Volume 目錄.默認情況下,kubelet為Volume創建的目錄是一個宿主機上的路徑如
         /var/lib/kubelet/pods/volumes/kubernetes.io~/   這個目錄是宿主機后面用來和遠程存儲服務mount的關聯目錄

         Kubernetes提供的可用參數是nodeName,即宿主機的名字

    Mount階段
       將磁盤設備格式化並掛載到Volume宿主機目錄的操作
       把格式化的磁盤mount到/var/lib/kubelet/pods/volumes/kubernetes.io~/

       Kubernetes提供的可用參數是dir   即Volume的宿主機目錄

    經過了“兩階段處理” 我們就得到了一個“持久化”的 Volume 宿主機目錄 但是還沒有關聯到docker容器

    接下來 kubelet 只要把這個 Volume目錄通過 CRI 里的 Mounts 參數,傳遞給 Docker 然后就可以為 Pod 里的容器掛載這個“持久化”的 Volume 

   docker run -v /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume類型>/<Volume名字>:/<容器內的目標目錄> 我的鏡像 

   上面是Kubernetes 處理 PV 的具體原理

StorageClass自動創建pv 

      Kubernetes只會將StorageClass相同的PVC和PV綁定起來

      自動創建PV的機制Dynamic Provisioning
     人工管理PV的方式就叫作Static Provisioning
     StorageClass對象就是創建PV的模板

    定義StorageClass一般包含Name,后端使用存儲插件類型,存儲插件需要使用到的參數等信息 定義好之后相當於定義了一塊巨大的存儲磁盤

    當pvc中定義的storageClassName和StorageClass的Name相同的時候那么StorageClass會自動從巨大的存儲磁盤創建一個指定storage大小的pv,創建的pv和pvc進行綁定

 StorageClass對象會定義如下兩個部分內容
    第一   PV的屬性.  比如,存儲類型
    第二   創建這種PV需要用到的存儲插件.   比如Ceph等等

    k8s根據用戶提交的PVC中指定的storageClassName的屬性值找到對應的StorageClass.然后調用該StorageClass聲明的存儲插件創建出需要的PV

   有了Dynamic Provisioning機制,運維人員只需要在Kubernetes集群里創建出數量有限的StorageClass對象就可以了

   當開發人員提交了包含StorageClass字段的PVC之后,Kubernetes就會根據這個StorageClass創建出對應的PV

   在沒有StorageClass的情況下運維人員對開發人員定義的每一個pvc都要手動創建一個對應的pv與其進行綁定 這樣就會大大的增加創建pv的工作量

 


免責聲明!

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



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