PersistentVolume(PV)是 K8S 集羣中由管理員配置的一段網絡存儲。 它是集羣中的資源,就像節點是集羣資源同樣。 PV 是容量插件,如 Volumes,但其生命週期獨立於使用 PV 的任何單個 Pod。 此 API 對象捕獲存儲實現的詳細信息,包括 NFS,iSCSI 或特定於雲提供程序的存儲系統。
PersistentVolumeClaim(PVC)是 K8S 中由用戶進行存儲的請求。 它相似於 Pod。Pod 消耗節點資源,PVC 消耗 PV 資源。Pod 能夠請求特定級別的資源(CPU和內存)。聲明能夠請求特定的大小和訪問模式(例如,能夠一次讀/寫或屢次只讀)。
經過 storageClassName 參數來指定使用對應名字的 StorageClass,也就是 PVC 與 PV 具備相同的storageClassName,PVC 才能綁定到這個對應的 PV。PVC 能夠不指定storageClassName,或者將該值設置爲空,若是打開了准入控制插件,而且指定一個默認的 StorageClass,則 PVC 會使用默認的 StorageClass,不然就綁定到沒有 StorageClass 的 PV 上。node
PV 是 K8S 羣集中的資源。PVC 是對這些資源的請求,而且還充當對資源的檢查。PV 和 PVC 之間的相互做用遵循如下生命週期:nginx
Provisioning ——> Binding ——> Using ——> Releasing ——> Recyclingdocker
注:目前只有 NFS 和 HostPath 類型卷支持回收策略,AWS EBS、GCE PD、Azure Disk、Cinder 支持刪除 (Delete) 策略。vim
# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME test01 Ready master 17d v1.14.0 192.168.127.133 CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://18.9.3 test02 Ready 17d v1.14.0 192.168.127.135 CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://18.9.3
PV 支持的類型不少,好比:RBD、CephFS、Glusterfs、NFS 等,這裏使用 nfs 類型的 PV,並使用 Job 對象來驗證 PV 建立以及 PVC 資源的申請與綁定。api
# yum install nfs-utils rpcbind -y # mkdir -p /data/nfs # vim /etc/exports /data/nfs *(rw,sync) # systemctl start nfs-server.service
並在 K8S node 上安裝 nfs 客戶端:# yum install nfs-utils -y
服務器
# cat pv_nfs.yml apiVersion: v1 kind: PersistentVolume metadata: name: nfspv1 spec: # 指定 PV 的容量爲1Gi capacity: storage: 1Gi # 指定訪問模式 accessModes: # PV 能以 readwrite 模式 mount 到單個節點 - ReadWriteOnce # 指定 PV 的回收策略,即 PVC 資源釋放後的事件,recycle (不建議,使用動態供給代替)刪除 PVC 的全部文件 persistentVolumeReclaimPolicy: Recycle # 指定 PV 的 class 爲 mynfs,至關於爲 PV 分類,PVC 將指定 class 申請 PV storageClassName: mynfs # 指定 PV 爲 nfs 服務器上對應的目錄 nfs: path: /data/nfs server: 192.168.127.133
應用 PV 配置:網絡
# kubectl apply -f pv_nfs.yml persistentvolume/nfspv1 created
查看 PV 資源:app
# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE nfspv1 1Gi RWO Recycle Available
# cat pvc_nfs.yml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: nfspvc1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: mynfs
應用 PVC 配置:ide
# kubectl apply -f pvc_nfs.yml persistentvolumeclaim/nfspvc1 created
查看 PVC 資源,經過下面的結果能夠看到 nfspvc1 已經與 PV 爲 nfspv1 綁定:學習
# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE nfspvc1 Bound nfspv1 1Gi RWO mynfs 25s </pre>
# cat pvjob.yml apiVersion: batch/v1 kind: Job metadata: name: pvjob spec: template: spec: containers: - name: bbox1 image: busybox command: ["/bin/sh","-c","echo 'hello pv' > /mydata/hello"] volumeMounts: - mountPath: "/mydata" name: mydata restartPolicy: Never volumes: - name: mydata persistentVolumeClaim: claimName: nfspvc1
該 job 將在 nfs 的 volume 建立一個 hello 文件,打印 hello pv 字符串。
應用該 Job 配置文件:
# kubectl apply -f pvjob.yml job.batch/pvjob created
確認容器狀態是 Completed 狀態:
# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES deploy-nginx-684b85cd79-kv5sg 1/1 Running 2 10d 10.244.1.14 test02 pvjob-gljl7 0/1 Completed 0 39s 10.244.1.33 test02
確認 master 上 nfs 的 /data/nfs 目錄,檢查實驗結果:
# cat /data/nfs/hello hello pv
在此次實驗中出現了幾個錯誤:
使用 PVC 存儲的 Pod 一直處於 pending 狀態,沒法啓動,經過命令 kubectl describe pod podname
查看對應報錯的 Pod 的信息,部分報錯信息以下:
# dmesg | tail or so. Warning FailedMount 118s kubelet, test02 MountVolume.SetUp failed for volume "nfspv1" : mount failed: exit status 32 Mounting command: systemd-run Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/d25895f2-8220-11e9-820c-000c295ab742/volumes/kubernetes.io~nfs/nfspv1 --scope -- mount -t nfs 192.168.127.133:/data/nfs /var/lib/kubelet/pods/d25895f2-8220-11e9-820c-000c295ab742/volumes/kubernetes.io~nfs/nfspv1 Output: Running scope as unit run-15184.scope. mount: wrong fs type, bad option, bad superblock on 192.168.127.133:/data/nfs, missing codepage or helper program, or other error (for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount. helper program
注意到報錯信息:wrong fs type, bad option, bad superblock on 192.168.127.133:/data/nfs,若是沒有安裝 nfs-utils 軟件包,沒法識別 nfs 類型的文件系統,也沒法做爲 nfs 的客戶端使用。
解決方案:
安裝 nfs-utils 軟件包,刪除以前建立失敗的 Job 資源並從新建立。
# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES deploy-nginx-684b85cd79-kv5sg 1/1 Running 2 10d 10.244.1.14 test02 pvjob-4dp29 0/1 Error 0 3m10s 10.244.1.35 test02 pvjob-f6lpp 0/1 Error 0 2m33s 10.244.1.37 test02 pvjob-l8q6z 0/1 Error 0 2m13s 10.244.1.38 test02 pvjob-qbxx6 0/1 Error 0 53s 10.244.1.39 test02 pvjob-zcx6l 0/1 Error 0 2m56s 10.244.1.36 test02
經過查看執行失敗 Pod 的 log 日誌,發現是容器沒有權限寫文件到掛載的 nfs 目錄中:
# kubectl logs pvjob-4dp29 /bin/sh: can't create /mydata/hello: Permission denied
解決方案:
Permission denied 多見於普通用戶執行高權限命令失敗,不過 busybox 容器自己使用的就是 root 用戶,所以不存在這個問題。在 nfs 中,nfs 服務端沒有權限訪問掛載的目錄也會致使這個問題。
更改目錄屬主爲 nfsnobody:# chown nfsnobody /data/nfs
刪除原來 Job 並從新建立後,Job 就能執行成功:
# kubectl delete -f pvjob.yml # kubectl apply -f pvjob.yml # kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES deploy-nginx-684b85cd79-kv5sg 1/1 Running 2 10d 10.244.1.14 test02 pvjob-gljl7 0/1 Completed 0 39s 10.244.1.33 test02