Kubernetes 持久化存储 PV PVC
kubernetes存储管理按照发展的历程,涉及到有Volume,PV(Persistent Volume)和PVC(PersistentVolumeClaims),和StorageClass,Volume是最早提出的存储卷,主要解决容器和数据存储的依赖关系,抽象底层驱动以支持不同的存储类型;使用Volume需要了解底层存储细节,因此提出了PV,Persistent Volume是由k8s管理员定义的存储单元,应用端使用PersistentVolumeClaims声明去调用PV存储,进一步抽象了底层存储;随着PV数量的增加,管理员需要不停的定义PV的数量,衍生了通过StorageClass动态生成PV,StorageClass通过PVC中声明存储的容量,会调用底层的提供商生成PV。本文介绍Volume的使用,下篇文章介绍PV,PVC和StorageClass。
- Volume 存储卷,独立于容器,后端和不同的存储驱动对接
- PV Persistent Volume持久化存储卷,和node类似,是一种集群资源,由管理员定义,对接不同的存储
- PVC PersistentVolumeClaims持久化存储声明,和pod类似,作为PV的使用者
- StorageClass 动态存储类型,分为静态和动态两种类型,通过在PVC中定义存储类型,自动创建所需PV
持久卷概述
K8s将存储当作资源管理,这样我们不需要知道存储具体的实现,我们不需要知道具体的细节,只需要关心使用多大的容量。
存储概述
kubernetes容器中的数据是临时的,即当重启重启或crash后容器的数据将会丢失,此外容器之间有共享存储的需求,所以kubernetes中提供了volume存储的抽象,volume后端能够支持多种不同的plugin驱动,通过.spec.volumes中定义一个存储,然后在容器中.spec.containers.volumeMounts调用,最终在容器内部以目录的形式呈现。
kubernetes内置能支持多种不同的驱动类型,大体上可以分为四种类型:
1. 公/私有云驱动接口,如awsElasticBlockStore实现与aws EBS集成,
2. 开源存储驱动接口,如ceph rbd,实现与ceph rb块存储对接,
3. 本地临时存储,如hostPath,
4. kubernetes对象API驱动接口,实现其他对象调用,如configmap,每种存储支持不同的驱动,如下介绍:
- 公/私有云驱动接口
- awsElasticBlockStore AWS的EBS云盘
- azureDisk 微软azure云盘
- azureFile 微软NAS存储
- gcePersistentDisk google云盘
- cinder openstack cinder云盘
- vsphereVolume VMware的VMFS存储
- scaleIO EMC分布式存储
- 开源存储驱动接口
- ceph rbd ceph块存储
- cephfs ceph文件存储
- glusterfs glusterfs存储
- nfs nfs文件
- iscsi
- flexvolume
- csi 社区标准化驱动
- flocker
- 本地临时存储
- hostpath 宿主机文件
- emptyDir 临时目录
- kubernetes对象API驱动接口
- configMap 调用configmap对象,注入配置文件
- secrets 调用secrets对象,注入秘文配置文件
- persistentVolumeClaim 通过pvc调用存储
- downloadAPI 下载URL
- projected
Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足。
拿前面 AWS EBS 的例子来说,要使用 Volume,Pod 必须事先知道如下信息:
-
当前 Volume 来自 AWS EBS。
-
EBS Volume 已经提前创建,并且知道确切的 volume-id。
Pod 通常是由应用的开发人员维护,而 Volume 则通常是由存储系统的管理员维护。开发人员要获得上面的信息:
-
要么询问管理员。
-
要么自己就是管理员。
这样就带来一个管理上的问题:应用开发人员和系统管理员的职责耦合在一起了。如果系统规模较小或者对于开发环境这样的情况还可以接受。但当集群规模变大,特别是对于生成环境,考虑到效率和安全性,这就成了必须要解决的问题。
Kubernetes 给出的解决方案是 PersistentVolume 和 PersistentVolumeClaim。
PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。
PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。
有了 PersistentVolumeClaim,用户只需要告诉 Kubernetes 需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息。这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心创建 PersistentVolume 的细节信息。
Kubernetes 支持多种类型的 PersistentVolume,比如 AWS EBS、Ceph、NFS 等,完整列表请参考 https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes
下面我们用 NFS 来体会 PersistentVolume 的使用方法。 p
[root@k8s-master ~]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /ifs/kubernetes
server: 192.168.179.102
[root@k8s-master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv 5Gi RWX Retain Available 8s
[root@k8s-master ~]# kubectl describe pv my-pv
Name: my-pv
Labels: <none>
Annotations: Finalizers: [kubernetes.io/pv-protection]
StorageClass:
Status: Available
Claim:
Reclaim Policy: Retain
Access Modes: RWX
VolumeMode: Filesystem
Capacity: 5Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 192.168.179.102
Path: /ifs/kubernetes
ReadOnly: false
Events: <none>
pvc定义要使用多大的存储就行
[root@k8s-master ~]# cat my-pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 7Gi
[root@k8s-master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pvc Pending 21s
[root@k8s-master ~]# kubectl describe pvc my-pvc
Name: my-pvc
Namespace: default
StorageClass:
Status: Pending
Volume:
Labels: <none>
Annotations: Finalizers: [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode: Filesystem
Mounted By: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal FailedBinding 4s (x4 over 46s) persistentvolume-controller no persistent volumes available for this claim and no storage class is set
修改为5G,可以看到和Pv绑定了
[root@k8s-master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pvc Bound my-pv 5Gi RWX 38s
删除pvc那么pv状态relase 后面就不能再绑定了
[root@k8s-master ~]# kubectl delete -f my-pvc.yml
persistentvolumeclaim "my-pvc" deleted
[root@k8s-master ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/my-pv 5Gi RWX Retain Released default/my-pvc 30m
[root@k8s-master ~]# kubectl apply -f my-pvc.yml
persistentvolumeclaim/my-pvc created
[root@k8s-master ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/my-pv 5Gi RWX Retain Released default/my-pvc 31m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/my-pvc Pending 3s
PV 生命周期
[root@k8s-master ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/nfs-pv 5Gi RWX Recycle Bound default/my-pv 35s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/my-pv Bound nfs-pv 5Gi RWX 12s
[root@localhost ~]# ls /opt/k8s-pods/data/
index.html
[root@k8s-master ~]# kubectl delete -f my-pvc.yml
persistentvolumeclaim "my-pv" deleted
[root@k8s-master ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/nfs-pv 5Gi RWX Recycle Released default/my-pv 115s
[root@localhost ~]# ls /opt/k8s-pods/data/
[root@k8s-master ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/nfs-pv 5Gi RWX Recycle Available 4m19s
[root@k8s-master ~]# kubectl apply -f my-pvc.yml
persistentvolumeclaim/my-pvc created
[root@k8s-master ~]# kubectl apply -f pv.yaml
persistentvolume/my-pv created
[root@k8s-master ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/my-pv 5Gi RWX Retain Bound default/my-pvc 16s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/my-pvc Bound my-pv 5Gi RWX 21s
[root@k8s-master ~]#
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl apply -f deployment-pvc.yaml
deployment.apps/deployment-pvc created
[root@k8s-master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-pvc-679bc8746f-ftwp8 1/1 Running 0 81s 10.244.0.22 k8s-master <none> <none>
deployment-pvc-679bc8746f-h6zp7 1/1 Running 0 81s 10.244.0.21 k8s-master <none> <none>
deployment-pvc-679bc8746f-r9bk8 1/1 Running 0 81s 10.244.0.20 k8s-master <none> <none>
[root@k8s-master ~]# curl 10.244.0.22
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.19.6</center>
</body>
</html>
[root@k8s-master ~]# cat deployment-pvc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-pvc
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pvc
template:
metadata:
labels:
app: nginx-pvc
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
persistentVolumeClaim: # 引用Pvc
claimName: my-pvc
PV 生命周期
目录 返回
首页