k8s存儲持久化(nfs用例)


在k8s中對於存儲的資源抽象了兩個概念,分別是PersistentVolume(PV)、PersistentVolumeClaim(PVC)。

  • PV是集群中的資源
  • PVC是對這些資源的請求。

PV和PVC都只是抽象的概念,在k8s中是通過插件的方式提供具體的存儲實現,目前包含有NFS、ceph、iSCSI和雲提供商指定的存儲系統,

一、認識PV/PVC/StorageClass

1、概念介紹

  管理存儲是管理計算的一個明顯問題。該PersistentVolume子系統為用戶和管理員提供了一個API,用於抽象如何根據消費方式提供存儲的詳細信息。為此,我們引入了兩個新的API資源:PersistentVolume和PersistentVolumeClaim

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

  PersistentVolumeClaim(PVC)是由用戶進行存儲的請求。 它類似於pod。 Pod消耗節點資源,PVC消耗PV資源。Pod可以請求特定級別的資源(CPU和內存)。聲明可以請求特定的大小和訪問模式(例如,可以一次讀/寫或多次只讀)。

  雖然PersistentVolumeClaims允許用戶使用抽象存儲資源,但是PersistentVolumes對於不同的問題,用戶通常需要具有不同屬性(例如性能)。群集管理員需要能夠提供各種PersistentVolumes不同的方式,而不僅僅是大小和訪問模式,而不會讓用戶了解這些卷的實現方式。對於這些需求,有StorageClass 資源。

  StorageClass為管理員提供了一種描述他們提供的存儲的“類”的方法。 不同的類可能映射到服務質量級別,或備份策略,或者由群集管理員確定的任意策略。 Kubernetes本身對於什么類別代表是不言而喻的。 這個概念有時在其他存儲系統中稱為“配置文件”。

       PV是運維人員來創建的,開發操作PVC,可是大規模集群中可能會有很多PV,如果這些PV都需要運維手動來處理這也是一件很繁瑣的事情,所以就有了動態供給概念,也就是Dynamic Provisioning,動態供給的關鍵就是StorageClass,它的作用就是創建PV模板。創建StorageClass里面需要定義PV屬性比如存儲類型、大小等;另外創建這種PV需要用到存儲插件。最終效果是,用戶提交PVC,里面指定存儲類型,如果符合我們定義的StorageClass,則會為其自動創建PV並進行綁定。

  PVC和PV是一一對應的。

PV和PVC中的spec關鍵字段要匹配,比如存儲(storage)大小。

PV和PVC中的storageClassName字段必須一致。

2、生命周期

  PV是群集中的資源。PVC是對這些資源的請求,並且還充當對資源的檢查。PV和PVC之間的相互作用遵循以下生命周期:

Provisioning ——-> Binding ——–>Using——>Releasing——>Recycling

  •  供應准備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)策略。

3、PV類型

  •  GCEPersistentDisk
  •  AWSElasticBlockStore
  •  AzureFile
  •  AzureDisk
  •  FC (Fibre Channel)
  •  Flexvolume
  •  Flocker
  •  NFS
  •  iSCSI
  •  RBD (Ceph Block Device)
  •  CephFS
  •  Cinder (OpenStack block storage)
  •  Glusterfs
  •  VsphereVolume
  •  Quobyte Volumes
  •  HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
  •  Portworx Volumes
  •  ScaleIO Volumes
  •  StorageOS

4、PV卷階段狀態

  •  Available – 資源尚未被claim使用
  •  Bound – 卷已經被綁定到claim了
  •  Released – claim被刪除,卷處於釋放狀態,但未被集群回收。
  •  Failed – 卷自動回收失敗

二、創建PV演示

1、准備nfs服務

  在nfs服務器上先建立存儲卷對應的目錄

[root@nfs ~]# cd /data/volumes/
[root@nfs volumes]# mkdir v{1,2,3,4,5}
[root@nfs volumes]# ls
index.html  v1  v2  v3  v4  v5
[root@nfs volumes]# echo "<h1>NFS stor 01</h1>" > v1/index.html
[root@nfs volumes]# echo "<h1>NFS stor 02</h1>" > v2/index.html
[root@nfs volumes]# echo "<h1>NFS stor 03</h1>" > v3/index.html
[root@nfs volumes]# echo "<h1>NFS stor 04</h1>" > v4/index.html
[root@nfs volumes]# echo "<h1>NFS stor 05</h1>" > v5/index.html

  修改nfs的配置

[root@nfs volumes]# vim /etc/exports
/data/volumes/v1        192.168.130.0/24(rw,no_root_squash)
/data/volumes/v2        192.168.130.0/24(rw,no_root_squash)
/data/volumes/v3        192.168.130.0/24(rw,no_root_squash)
/data/volumes/v4        192.168.130.0/24(rw,no_root_squash)
/data/volumes/v5        192.168.130.0/24(rw,no_root_squash)

  查看nfs的配置

[root@nfs volumes]# exportfs -arv
exporting 192.168.130.0/24:/data/volumes/v5
exporting 192.168.130.0/24:/data/volumes/v4
exporting 192.168.130.0/24:/data/volumes/v3
exporting 192.168.130.0/24:/data/volumes/v2
exporting 192.168.130.0/24:/data/volumes/v1

  配置生效

[root@nfs volumes]# showmount -e
Export list for nfs:
/data/volumes/v5 192.168.130.0/24
/data/volumes/v4 192.168.130.0/24
/data/volumes/v3 192.168.130.0/24
/data/volumes/v2 192.168.130.0/24
/data/volumes/v1 192.168.130.0/24

2、在master上創建PV

  編寫yaml文件,並創建pv。創建5個pv,存儲大小各不相同,是否可讀也不相同

# vim pv-damo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/volumes/v1
    server: nfs
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/volumes/v2
    server: nfs
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/volumes/v3
    server: nfs
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 20Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/volumes/v4
    server: nfs
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 10Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/volumes/v5
    server: nfs
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 15Gi

注:accessModes:支持三種類型
ReadWriteMany 多路讀寫,卷能被集群多個節點掛載並讀寫
ReadWriteOnce 單路讀寫,卷只能被單一集群節點掛載讀寫
ReadOnlyMany 多路只讀,卷能被多個集群節點掛載且只能讀
nfs,它支持全部三種。但是ISCI就不支持ReadWriteMany;HostPath就不支持ReadOnlyMany和ReadWriteMany

# kubectl apply -f pv-damo.yaml
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
persistentvolume/pv004 created
persistentvolume/pv005 created

  查看pv狀態

kubectl  get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
pv001     5Gi        RWO,RWX        Retain           Available                                      9s
pv002     5Gi        RWO            Retain           Available                                      9s
pv003     5Gi        RWO,RWX        Retain           Available                                      9s
pv004     10Gi       RWO,RWX        Retain           Available                                      9s
pv005     15Gi       RWO,RWX        Retain           Available                                      9s

3、創建PVC,綁定PV

  編寫yaml文件,並創建pvc。創建一個pvc,需要6G存儲;所以不會匹配pv001、pv002、pv003

vim vol-pvc-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
  namespace: default
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 6Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: vol-pvc
  namespace: default
spec:
  volumes:
  - name: html
    persistentVolumeClaim:
      claimName: mypvc
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/


kubectl apply -f vol-pvc-demo.yaml
persistentvolumeclaim/mypvc created
pod/vol-pvc created

  查詢驗證:pvc已經綁定到pv004上

# kubectl get pvc
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc     Bound     pv004     10Gi       RWO,RWX                       24s

# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON    AGE
pv001     5Gi        RWO,RWX        Retain           Available                                            1m
pv002     5Gi        RWO            Retain           Available                                            1m
pv003     5Gi        RWO,RWX        Retain           Available                                            1m
pv004     10Gi       RWO,RWX        Retain           Bound       default/mypvc                            1m
pv005     15Gi       RWO,RWX        Retain           Available                                            1m

  查詢業務驗證

# kubectl get pods -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP             NODE
vol-pvc   1/1       Running   0          59s       10.244.2.117   node2

# curl 10.244.2.117
<h1>NFS stor 04</h1>

三、動態存儲StorageClass

 nfs默認不支持動態存儲,使用了第三方的NFS插件 external-storagenfs-client-provisioner

1、流程圖

2、創建rbac授權

# cat  rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

3、創建nfs的nfs-client-provisioner

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 10.10.10.60
            - name: NFS_PATH
              value: /ifs/kubernetes
      volumes:
        - name: nfs-client-root
          nfs:
            server: 10.10.10.60  
            path: /ifs/kubernetes

注:

-value: 10.10.10.60 、server: 10.10.10.60    #換成自己nfs的ip

- name:

NFS_PATH value: /xxx/xxxx   ##nfs共享的目錄。

4、創建客戶端

kubectl apply -f deployment.yaml

5、創建storage class

kubectl apply -f  class.yaml

reclaimPolicy:有兩種策略:Delete、Retain。默認是Delet

fuseim.pri/ifs為上面deployment上創建的PROVISIONER_NAM(在“3、創建nfs的nfs-client-provisioner”)

6、查看 nfs 客戶端 和 storage class

客戶端
# kubectl  get pod
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-7695c66c6b-56sbw   1/1     Running   0          10m

storage class
# kubectl  get sc
NAME                  PROVISIONER      AGE
managed-nfs-storage   fuseim.pri/ifs   10m

7、創建PVC

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
  annotations:
    volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
  accessModes: # 策略
    - ReadWriteMany
  resources: 
    requests:
      storage: 1Mi # 請求空間大小

創建PersistenetVolumeClaim

kubectl  apply -f test-claim.yaml

查看 pvc

# kubectl  get pvc
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
test-claim   Bound    pvc-2febc25a-d2b0-11e9-9623-000c29b3776e   1Mi        RWX            managed-nfs-storage   14s

8、部署測試pod

kind: Pod
apiVersion: v1
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod
    image: nginx
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/SUCCESS && exit 0 || exit 1"
    volumeMounts:
      - name: nfs-pvc # 綁定pvc
        mountPath: "/mnt"
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc #pvc 通過pvc 動態創建pv
      persistentVolumeClaim:
        claimName: test-claim

創建 測試 pod

kubectl  apply -f test-pod.yaml

kubectl  get pod | grep pod
test-pod                                  0/1     Completed   0          81s

kubectl  get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS          REASON   AGE
pvc-e78d0817-d2b0-11e9-9623-000c29b3776e   1Mi        RWX            Delete           Bound    default/test-claim   managed-nfs-storage            22m

 

 

https://github.com/kubernetes-retired/external-storage   github項目地址external-storage

https://www.cnblogs.com/panwenbin-logs/p/12196286.html    實戰,分析案例詳細

https://blog.csdn.net/weixin_30119911/article/details/112337003 實戰,tomcat使用storageclass


免責聲明!

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



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