Kubernetes 學習筆記之 PV 與 PVC 的建立引用

簡介

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

Kubernetes 學習筆記之 PV 與 PVC 的建立引用

生命週期

PV 是 K8S 羣集中的資源。PVC 是對這些資源的請求,而且還充當對資源的檢查。PV 和 PVC 之間的相互做用遵循如下生命週期:nginx

Provisioning ——> Binding ——> Using ——> Releasing ——> Recyclingdocker

  • 供應準備 Provisioning:經過集羣外的存儲系統或者雲平臺來提供存儲持久化支持。
    • 靜態提供 Static:集羣管理員建立多個 PV。 它們攜帶可供集羣用戶使用的真實存儲的詳細信息。 它們存在於 Kubernetes API 中,可用於消費。
    • 動態提供 Dynamic:當管理員建立的靜態 PV 都不匹配用戶的 PersistentVolumeClaim 時,集羣可能會嘗試動態地爲 PVC 建立卷。此配置基於 StorageClasses:PVC 必須請求存儲類,而且管理員必須建立並配置該類才能進行動態建立。聲明該類爲 「」 能夠有效地禁用其動態配置。
  • 綁定 Binding:用戶建立 PVC 並指定須要的資源和訪問模式。在找到可用 PV 以前,PVC 會保持未綁定狀態。
  • 使用 Using:用戶可在 Pod 中像 Volume 同樣使用 PVC。
  • 釋放 Releasing:用戶刪除 PVC 來回收存儲資源,PV 將變成 released 狀態。因爲還保留着以前的數據,這些數據須要根據不一樣的策略來處理,不然這些存儲資源沒法被其餘 PVC 使用。
  • 回收 Recycling—PV 能夠設置三種回收策略:保留(Retain)、回收(Recycle)、刪除(Delete)。
    • 保留策略:容許人工處理保留的數據。
    • 刪除策略:將刪除 PV 和外部關聯的存儲資源,須要插件支持。
    • 回收策略:將執行清除操做,以後能夠被新的 PVC 使用,須要插件支持。

注:目前只有 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

實踐操做

  1. 在 K8S master(192.168.127.133)上準備 nfs 服務器,用於提供存儲。
    # 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服務器

  1. 使用如下配置建立 PV 存儲。
    編輯 PV 資源的配置文件:
    # 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
  1. 使用如下配置建立 PVC,經過指定 storageClassName 名稱與指定 PV 進行綁定。
    編輯 PVC 資源配置文件:
    # 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>
  1. 使用如下配置建立 Job,使用 PVC 存儲。
    編輯應用資源配置文件:
    # 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

排錯

在此次實驗中出現了幾個錯誤:

  1. 使用 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 資源並從新建立。

  2. 若是 Pod 狀態是 Error 的:
    # 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
相關文章
相關標籤/搜索