持久化存储之 PV、PVC、StorageClass

容器化一个应用比较麻烦的地方,就是对于有状态的服务的管理,最常见的状态就是存储状态

pv、pvc 存储体系

  1. PV 描述的是持久化存储数据卷,这个API对象主要定义的是一个持久化存储在宿主机上的目录。
    通常情况下,PV由运维人员负责创建,如下例(NFS为例):

     apiVersion: v1
     kind: PersistentVolume
     metadata:
       name: nfs
     spec:
       storageClassName: manual
       capacity:
         storage: 1Gi
       accessModes:
         - ReadWriteMany
       nfs:
         server: 10.244.1.4
         path: "/"
    
  2. PVC描述的是Pod希望使用的持久化存储的属性,比如,Volume 存储的大小,可读写权限等。
    PVC通常是由开发人员创建;或者以 PVC 模版的方式成为 StatefulSet 的一部分, 然后由 StatefulSet 控制器负责创建带编号的 PVC。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: nfs
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: manual
      resources:
        requests:
          storage: 1Gi
    

创建的PVC只有和对应的PV绑定才可以使用
绑定条件:

  • PV 的存储大小和权限必须满足 PVC 的要求。
  • PV 和 PVC 的 storageClassName 必须一致。如果没有指定 storageClassName 则默认是 "default" 或者 ""。

    如果PVC没有绑定,则声明使用该PVC的Pod无法启动。

成功绑定之后,Pod 就是声明PVC绑定的持久化存储了,使用方法如下:

apiVersion: v1
kind: Pod
metadata:
  labels:
    role: web-frontend
spec:
  containers:
  - name: web
    image: nginx
    ports:
      - name: web
        containerPort: 80
    volumeMounts:
        - name: nfs
          mountPath: "/usr/share/nginx/html"
  volumes:
  - name: nfs
    persistentVolumeClaim:
      claimName: nfs

Pod 只需要在 volumes 字段里声明要使用的 PVC 的name,等Pod创建后,Kubelet会将 PVC 绑定的 PV, 例如上面的 NFS 类型的 volume 挂载到容器内目录。

PVC 和 PV 的设计,其实跟“面向对象”的思想完全一致

PVC 可以理解为持久化存储的接口,提供了对存储的描述,但不提供具体实现;而PV来负责存储的具体实现。


StorageClass

问题

当每次创建 PVC 声明使用存储时,都需要去手动的创建 PV,来满足 PVC 的使用。

解决方法

可以用一种机制来根据用户声明的存储使用量(PVC)来动态的创建对应的持久化存储卷(PV)。k8s 用 StorageClass 来实现动态创建 持久化存储。

实现原理:

存储控制器 Volume Controller,是用来专门处理持久化存储的控制器,其一个子控制循环 PersistentVolumeController 负责实现 PV 和 PVC 的绑定。
PersistentVolumeController 会 watch kube-apiserver 的 PVC 对象。如果发现有 PVC对象创建,则会查看所有可用的 PV, 如果有则绑定,若没有,则会使用 StorageClass 的配置和 PVC 的描述创建 PV 进行绑定。

所谓将一个 PV 与 PVC 进行“绑定”,其实就是将这个PV对象的名字,填在了 PVC 对象的 spec.volumeName 字段上

你可能感兴趣的:(持久化存储之 PV、PVC、StorageClass)