背景
在Pod级别定义存储卷有两个弊端
- 卷对象的生命周期无法独立于Pod而存在, pod删除后 卷就没了, 卷是二等公民
- 例如ceph 用户必须要足够熟悉可用的存储及其详情才能在Pod上配置和使用卷
nfs存储卷的问题
- server的地址
- 哪些存储目录可以使用
- 对client的要求太高了
pod和pvc pv的关系
- 用户只管用
- pv的定义交给专业的人去维护和管理
PV(Persistent Volume)介绍
是集群级别的资源,负责将存储空间引入到集群中,通常由管理员定义
PV是标准的资源类型,除了负责关联至后端存储系统外,它通常还需要定义支持的存储特性
- Volume Mode:当前PV卷提供的存储空间模型,分为块设备和文件系统两种
- StorageClassName:当前PV隶属的存储类;
- AccessMode:支持的访问模型,
- 单路读写 ReadWriteOnce
- 多路读写 ReadWriteMany
- 多路只读 ReadOnlyMany
- 单pod读写
- Size:当前PV允许使用的空间上限
在对象元数据上,还能够根据需要定义标签
各种访问模式的详细介绍:
- ReadWriteOnce (RWO):这种模式支持被单个节点读写挂载。换句话说,任何时候只有一个节点可以对该存储卷进行写入操作。
- ReadOnlyMany (ROX):这个模式允许多个节点对存储卷进行只读挂载。也就是说,多个节点可以同时读取该存储卷的内容,但只能有一个节点进行写入操作。
- ReadWriteMany (RWX):这是最常见的模式,它允许多个节点对存储卷进行读写挂载。这意味着多个节点可以同时读取和写入该存储卷的内容。
- ReadWriteOncePod:这是Kubernetes在v1.22中引入的一种新的访问模式,适用于PersistentVolume (PVs) 和 PersistentVolumeClaim (PVCs)。这种模式确保一次只有一个Pod可以写入存储卷,对于有状态工作负载特别有用,因为它们可能需要单一写入者访问存储。
pv回收策略
pvc删除后 pv的保留策略
- Retain 不能被其他pvc复用
- Recycle 只清空pv中的数据 重新给其他pvc复用 可以通俗的认为是格式化磁盘(生产中用的少)
- Delete 删除资源
PVC(Persistent Volume Claim) 介绍
是名称空间级别的资源,由用户定义。
用于在空闲的PV中申请使用符合过滤条件的PV之一,与选定的PV是 “一对一”的关系。
用户在Pod上通过pvc插件请求绑定使用定义好的PVC资源
PVC也是标准的资源类型,它允许用户按需指定期望的存储特性,并以之为条件,按特定的条件顺序进行PV筛选
支持动态预配的存储类,还可以根据PVC的条件按需完成PV创建
PVC 筛选PV 的workflow:
VolumeMode -> LabelSelector -> StorageClassName -> AccessMode -> Size
- VolumeMode 确保访问模式(设备和文件系统两种)
- LabelSelector 标签选择器 过滤不符合的
- 静态置备也可以指定StorageClassName 同一个StorageClassName的pv pvc才能绑定,
- pv pvc要么都不隶属存储类, 要么属于同一个StorageClassName
- AccessMode 访问模式
- Size 符合大小的
StorageClass 存储类
支持PV的动态预配(Provision) pv的创建模版(接口)
一般由集群管理员定义,隶属集群级别
Kubernetes支持的标准资源类型之一
为管理PV资源之便而按需创建的存储资源类别(逻辑组)
是PVC筛选PV时的过滤条件之一
为动态创建PV提供“模板”
- 需要存储服务提供管理API
- StorageClass资源上配置接入API的各种参数
- 定义在parameters字段中
- 还需要使用provisioner字段指明存储服务类型
配置规范
这个资源没有spec 不需要控制器控制
创建StorageClass流程
- step1 接收请求
- step2 按照要求 创建storage对象(文件系统 或者 块存储)
- step3 创建pv
- step4 将存储对象和pv进行联动
StorageClass 创建pv的方式
静态置备
提前手工创建好pv
动态置备
通过模版去动态的创建pv, StorageClass去请求storage 创建符合要求的pv
PVC 和动态 PV 示例 --动态置备
存储插件 支持的情况
一些存储插件不支持动态PV
但是多数CSI存储都支持动态PV,且支持卷扩展和卷快照等功能
静态PV(NFS存储) 和 PVC配置步骤 --静态置备
流程
- 配置NFS网络存储
- 配置PV
- 配置PVC
- 使用PVC创建pod
step1配置nfs
nfs配置文档 juejin.cn/post/720614…
nfsserver配置存储目录
mkdir /data/redis02 -p
chmod 777 /data/redis02 #一定要改权限 不然client端无法写数据
vim /etc/exports
/data/redis02 *(rw,sync,subtree_check,no_root_squash)
exportfs -ar
step2 定义pv
yaml示例
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs-demo
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: "/data/redis02"
server: 192.168.0.44
创建pv
root@k8s-master01:~/pratice# kubectl apply -f volums-pv-demo.yml
persistentvolume/pv-nfs-demo created
检查创建的pv
root@k8s-node01:~/practice-pv# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs-demo 1Gi RWO,RWX Retain Available 4s
step3 定义pvc
yaml示例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo-0001
namespace: default
spec:
accessModes: [ "ReadWriteMany" ]
volumeMode: Filesystem
resources:
requests:
storage: "1Gi"
limits:
storage: "1Gi"
创建pvc
root@k8s-master01:~/pratice# kubectl apply -f volums-pvc-demo.yml
persistentvolumeclaim/pvc-demo-0001 created
发现pv已经绑定了pvc
step4 定义pod使用pvc
yaml示例
apiVersion: v1
kind: Pod
metadata:
name: redis-pv-pod
labels:
app: redis
spec:
containers:
- name: redisusepv
image: redis:alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data
name: nfspvdata
volumes:
- name: nfspvdata
persistentVolumeClaim:
claimName: pvc-demo-0001
数据可以成功写入到nfs 存储设备中