2024-05-10 渥太华微生活
从一个例子入手PV、PVC
Kubernetes 项目引入了一组叫作 Persistent Volume Claim(PVC)和 Persistent Volume(PV)的 API 对象用于管理存储卷。
下面举个例子看看,这个例子来自《k8s in Action》:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mongodb-pvcspec: resources: requests: storage: 1Gi accessModes: - ReadWriteOnce storageClassName: ""
yaml文件中定义了storage为1 GiB表示PVC需要的容量;
Access Modes表示需要的volume存储类型,ReadWriteOnce表示只能在一个node节点上进行读写操作,其他的Access Modes详见
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes;
storageClassName为空,表示的是storageClass的名称,我们下面会说到。
然后获取一下PVC的状态:
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mongodb-pvc Available mongodb-pv 1Gi RWO,ROX 2m25s
此时可以看到,我们的PVC处于可用状态。
然后再定义一个PV:
apiVersion: v1 kind: PersistentVolume metadata: name: mongodb-pvspec: capacity: storage: 1Gi accessModes: - ReadWriteOnce - ReadOnlyMany persistentVolumeReclaimPolicy: Retain gcePersistentDisk: pdName: mongodb fsType: ext4
这个 PV 对象中会详细定义存储的类型是GCE,以及大小是1 GiB,这里没有声明storageClassName,是因为storageClassName默认就为空。
然后我们看一下PV和PVC的状态:
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mongodb-pv 1Gi RWO,ROX Retain Bound default/mongodb-pvc 77m $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mongodb-pvc Bound mongodb-pv 1Gi RWO,ROX 7m7s
可以看到PV和PVC已经相互绑定了。
PVC和PV相当于“接口”和“实现”,所以我们需要将PVC和PV绑定起来才可以使用。
而PVC和PV绑定的时候需要满足:
PV 和 PVC 的 spec 字段要匹配,比如PV 的存储(storage)大小,就必须满足 PVC 的要求。
PV 和 PVC 的 storageClassName 字段必须一样才能进行绑定。storageClassName表示的是StorageClass的name属性。
如果我们想要在Pod中使用这个PVC,那么我们可以这么做:
apiVersion: v1 kind: Pod metadata: name: mongodb spec: containers: - image: mongo name: mongodb volumeMounts: - name: mongodb-data mountPath: /data/db ports: - containerPort: 27017 protocol: TCP volumes: - name: mongodb-data persistentVolumeClaim: claimName: mongodb-pvc
在Pod中只需要声明PVC的名字,等Pod创建后kubelet 就会把这个 PVC 所对应的 PV,也就是一个 GCE类型的 Volume,挂载在这个 Pod 容器内的目录上。
PersistentVolumeController会不断地查看当前每一个 PVC,是不是已经处于 Bound(已绑定)状态。如果不是,那它就会遍历所有的、可用的 PV,并尝试将其与这个“单身”的 PVC 进行绑定。
那么问题来了,k8s为什么要将一个存储卷分成两部分呢?
因为实际上,我们项目当中,研发人员和集群的管理人员是分开的,研发人员只管使用,但是并不关心底层到底用的是什么存储技术,所以研发人员只要声明一个PVC,表示我需要多大的一个存储,以及读写类型就可以了。
StorageClass 的 Dynamic Provisioning
在上面我们说的PV和PVC绑定的过程称为Static Provisioning,需要手动的创建PV。
我们在研发中可能有这样的情况,就是管理员没有及时给我们创建对应的PV,难道一直等着吗?
所以这个时候就需要用到StorageClass了,StorageClass提供了Dynamic Provisioning机制,可以根据模板创建PV。
StorageClass 对象会定义如下两个部分内容:
PV 的属性。比如,存储类型、Volume 的大小等等。
创建这种 PV 需要用到的存储插件。比如,Ceph 等等。
这样k8s就能够根据用户提交的 PVC,找到一个对应的 StorageClass ,然后调用该 StorageClass 声明的存储插件,创建出需要的 PV。
例如声明如下StorageClass:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: block-service provisioner: kubernetes.io/gce-pd parameters: type: pd-ssd
这里定义了名叫 block-service 的 StorageClass,provisioner 字段的值是:kubernetes.io/gce-pd,这是k8s内置的存储插件,type字段也是跟着provisioner定义的,官方默认支持 Dynamic Provisioning 的内置存储插件:https://kubernetes.io/docs/concepts/storage/storage-classes/。
然后就可以在PVC中声明storageClassName为block-service,当创建好PVC 对象之后,k8s就会调用相应的存储插件API创建一个PV对象。
如下:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: claim1 spec: accessModes: - ReadWriteOnce storageClassName: block-service resources: requests: storage: 30Gi
这种自动创建PV的机制就是Dynamic Provisioning,Kubernetes 就能够根据用户提交的 PVC,找到一个对应的 StorageClass ,然后会调用StorageClass 声明的存储插件,创建出需要的 PV。
需要注意的是,如果没有声明StorageClassName在PVC中,PVC 的 storageClassName 的值就是"",这也意味着它只能够跟 storageClassName 也是""的 PV 进行绑定。
PV和PVC 的生命周期
PV和PVC之间的相互作用遵循这个生命周期:
Provisioning —>Binding —>Using —>Reclaiming
Provisioning
k8s提供了两种PV生成方式: statically or dynamically
statically:由管理员创建PV,它们携带可供集群用户使用的真实存储的详细信息。 它们存在于Kubernetes API中,可用于消费。
dynamically:当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试为PVC动态配置卷。 此配置基于StorageClasses,PVC必须请求一个StorageClasses,并且管理员必须已创建并配置该类才能进行动态配置。
Binding
由用户创建好PersistentVolumeClaim 后,PersistentVolumeController会不断地查看当前每一个 PVC,是不是已经处于 Bound(已绑定)状态。如果不是,那它就会遍历所有的、可用的 PV,并尝试将其与这个“单身”的 PVC 进行绑定。
Using
Pods声明并使用PVC作为volume后,集群会找到该PVC,如果该PVC已经绑定了PV,那么会将该volume挂载到Pod中。
Reclaiming
当用户已经不再使用该volume,可以将该PVC删除,以便让资源得以回收。相应的在PVC删除后,PV的回收策略可以是Retained, Recycled, or Deleted,这个策略可以在字段spec.persistentVolumeReclaimPolicy中设置。
Retain:这个策略允许手动回收资源,当PVC被删除后,PV仍然可以存在,管理员可以手动的执行删除PV,并且和PV绑定的存储资源也不会被删除,如果想要删除相应的存储资源的数据,需要手动删除对应存储资源的数据。
Delete:这个策略会在PVC被删除之后,连带将PV以及PV管理的存储资源也删除。
Recycle:相当于在volume中执行rm -rf /thevolume/*命令,以便让volume可以重复利用。
一般的情况下,我们遵循这个删除流程:
删除使用这个 PV 的 Pod (kubectl delete pod my-pod);
从宿主机移除本地磁盘(比如,umount 它);
删除 PVC (kubectl delete pvc my-pvc);
删除 PV (kubectl delete pv my-pv)。
编者注:新闻取自各大新闻媒体,新闻内容并不代表本网立场!文字和图片来自网络,版权归原作者所有。如有侵权,请速联系小编,立即删除。
全部评论 (0) |
---|