Kubernetes object PersistentVolume, PersistentVolumeClaim and StorageClass concept relationship

Kubernetes container to persistent data, can not be separated volume, k8s the volume and Docker native concept of volume there are some differences, but this time do not speak of this, the secondary clear that several objects PersistentVolume k8s persistent data used , PersistentVolumeClaim and StorageClass, since this is the first clear k8s objects can be created through the API.

        k8s the volume of support There are many types, such as E mptyDir, H ostPath, nfs, etc., which is relatively easy to understand, it is that there is a time ersistentVolumeClaim, just getting started with the not quite understand how the use of this object, this introduces ersistentVolumeClaim related concepts and methods of use.

        You start to mention PersistentVolume (PV) objects, PersistentVolume and Volume as is the cluster of a storage area, but Kubernetes will become a PersistentVolume abstract cluster resources, similar to the cluster node (Node) object, which means that we PersistentVolume objects can be created using Kubernetes API. The biggest difference PV and PV Volume is independent of the Pod has a life cycle.

        The PersistentVolumeClaim (PVC) on behalf of the user requests for PV resources. When users need to use PV resources, just create a PVC objects (including specifying what kind of storage resources, how many GB, using PV and other information in what mode), Kubernetes automatically assigned PV we need for us. If PersistentVolume analogy to the cluster Node, then PersistentVolumeClaim equivalent cluster Pod, Kubernetes to allocate available Pod Node, may be understood as similar PersistentVolume PersistentVolumeClaim allocates available.

1, static objects to create PV

Can directly create a static PV object as a storage for the use of PVC, to create a PV main parameters are the following

accessModes access mode, there are three below:

  •      ReadWriteOnce (RWO): is the most basic way, readable and writable, but only a single support is mounted Pod.
  •      ReadOnlyMany (ROX): read-only mode, may be mounted a plurality of Pod.
  •      ReadWriteMany (RWX): readable and writable, and may be mounted by a plurality of Pod.
persistentVolumeReclaimPolicy recovery strategy, i.e. when the volume PV PVC release the how, there are the following three:
  •      Retain, do not clean up, when you remove PVC, PV still exists and is marked as "released" (when the need to remove the need to manually clean up)
  •      Recycle, delete data, perform cleanup (rm -rf / thevolume / *) to the volume, and it can be used again to a new index (only support NFS and HostPath)
  •      Delete, delete storage resources, it will be removed from the PV Kubernetes objects, as well as external infrastructure associated storage assets, such as AWS EBS, GCE PD, Azure disk or volume Cinder
#静态创建PV
apiVersion: v1 kind: PersistentVolume metadata: name: pv0003 spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: slow mountOptions: - hard - nfsvers=4.1 nfs: path: /tmp server: 172.17.0.2

    The definition of PV, we need to specify the type of the underlying storage, such as PV above created using nfs underlying storage, supports many types, such as awsElasticBlockStore, FC, nfs, RBD, CephFS, Hostpath, StorageOS and so on, you can view the official documents.

    You can view the current cluster of PV create objects, kubectl get PersistentVolume --all-namespaces

2, static objects to create PVC

    After creating PV, and not being used, if you want to use this you need to create PV PVC, and finally specify the use of PVC in the pod and the pod and establish a relationship of PV.

#静态创建PVC
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: myclaim spec: accessModes: - ReadWriteOnce
volumeMode: Filesystem resources: requests: storage: 8Gi storageClassName: slow selector: matchLabels: release: "stable"
#pod使用PVC
kind: Pod
apiVersion: v1
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: dockerfile/nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim

    Analyze the above code:

  • 创建PVC时指定了accessModes = ReadWriteOnce。这表明这个PVC希望使用accessModes = ReadWriteOnce的PV。
  • 创建PVC时指定了volumeMode= Filesystem。这表明这个PVC希望使用volumeMode= Filesystem的PV。
  • When you create a PVC is specified storageClassName: slow, this configuration is used to bind PVC and PV, which means that PVC want to use storageClassName=slowin PV. We can see that when you create a top PV also contains storageClassName=slowconfiguration.
  • PVC can also specify PV must meet Label, such as adding the matching selector matchLabels: release: "stable". This indicates that this PVC want to use the Label: release: "stable"the PV.
  • Finally, resources statement, a statement like pod can use a certain number of resources, storage: 8Giit indicates that this PVC want to use 8G Volume of resources.

      Through the above analysis, we can see the Binding PVC and PV, not simply be done by Label. But to comprehensive storageClassName, accessModes, matchLabels and storage to match qualified PV bind.

3, PV dynamically created objects

    Above we create static objects by describing file PV finalized and pod binding, PV created this way is called a static directly from a description file, so there are drawbacks to create a way to specify the size of 50G when if we create PV, and PVC requests of PV 80G, then the PVC will not be able to find a suitable PV to bind. Therefore, the actual production of more use to dynamically create the PV.

    PV depends on StorageClass dynamically created objects. We do not need to manually create any PV, all the work is done by StorageClass for us, you can view information StorageClass cluster, kubectl get StorageClass --all-namespaces

 

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: kubernetes.io/glusterfs
parameters:
  resturl: "http://192.168.10.100:8080"
  restuser: ""
  secretNamespace: ""
  secretName: ""
reclaimPolicy: Retain
allowVolumeExpansion: true

 

 This example uses creates a distributed storage based on glusterfs StorageClass, only when allowVolumeExpansion = teue, in order to expand PVC, to request larger volumes as PVC, PVC edit the object and specify a larger size, which triggers the underlying PersistentVolume extend the volume. Never create a new, but adjust the size of an existing volume.

StorageClass definition consists of four parts:

  • provisioner: Volume specified widget types, including built-ins (e.g. kubernetes.io/glusterfs, kubernetes.io/aws-ebs) and external (ceph.com/cephfs provided as external-storage) plug.
  • parameters: Specifies the provisioner options, such as glusterfs support resturl, restuser and other parameters.
  • mountOptions: Specifies the mount options, when the PV specified option is not supported directly fail. Such as NFS support hard and nfsvers = 4.1 and other options.
  • reclaimPolicy: Specifies the recovery strategy, with PV recycling strategy.

        手动创建的PV时,我们指定了storageClassName=slow的配置项,然后Pod定义中也通过指定storageClassName=slow,从而完成绑定。而通过StorageClass实现动态PV时,我们只需要指定StorageClass的metadata.name即可,这个名称非常重要,用户通过名称类请求特定的存储类,储类的对象一旦被创建,name将不能再更改。
        回到上文中创建PVC的例子,此时PVC指定了storageClassName=slow。那么Kubernetes会在集群中寻找是否存在metadata.name=slow的StorageClass,如果存在,此StorageClass会自动为此PVC创建一个accessModes = ReadWriteOnce,并且大小为8GB的PV。

 

或者直接写到一起

#上面的部分省略了
        volumeMounts:
        - name: data-dir
          mountPath: /var/mysql/data
      #volumes:
      #- name: data-dir
      #  hostPath:
      #    path: /opt/mysql

  volumeClaimTemplates:
  - metadata:
#annotations: volume.alpha.kubernetes.io/storage-class: xxxx creationTimestamp: null name: data-dir spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: slow volumeMode: Filesystem status: phase: Pending

 

        下面是参考官方的一种比较通用的写法,基于helm的,直接将PVC的代码写到volumes的后面,根据values.yaml中的参数生成是挂载PVC的存储还是其他存储,可以作为以后自己写脚本的参考

      volumes:
      - name: config
        configMap:
          name: {{ template "redis-ha.fullname" . }}-configmap
      - name: probes
        configMap:
          name: {{ template "redis-ha.fullname" . }}-probes
      {{- if .Values.sysctlImage.mountHostSys }}
      - name: host-sys
        hostPath:
          path: /sys
      {{- end }}
{{- if .Values.persistentVolume.enabled }}
  volumeClaimTemplates:
  - metadata:
      name: data
      annotations:
      {{- range $key, $value := .Values.persistentVolume.annotations }}
        {{ $key }}: {{ $value }}
      {{- end }}
    spec:
      accessModes:
      {{- range .Values.persistentVolume.accessModes }}
        - {{ . | quote }}
      {{- end }}
      resources:
        requests:
          storage: {{ .Values.persistentVolume.size | quote }}
    {{- if .Values.persistentVolume.storageClass }}
    {{- if (eq "-" .Values.persistentVolume.storageClass) }}
      storageClassName: ""
    {{- else }}
      storageClassName: "{{ .Values.persistentVolume.storageClass }}"
    {{- end }}
    {{- end }}
{{- else if .Values.hostPath.path }}
      - name: data
        hostPath:
          path: {{ tpl .Values.hostPath.path .}}
{{- else }}
      - name: data
        emptyDir: {}
{{- end }}

 

总结一下整个过程

1)集群管理员预先创建存储类(StorageClass);

2)用户创建使用存储类的持久化存储声明(PVC:PersistentVolumeClaim);

3)存储持久化声明通知系统,它需要一个持久化存储(PV: PersistentVolume);

4)系统读取存储类的信息;

5)系统基于存储类的信息,在后台自动创建PVC需要的PV;

6)用户创建一个使用PVC的Pod;

7)Pod中的应用通过PVC进行数据的持久化;

8)而PVC使用PV进行数据的最终持久化处理。

 

官方文档 https://kubernetes.io/docs/concepts/storage/persistent-volumes/

 

Guess you like

Origin www.cnblogs.com/yanh0606/p/11269142.html