目录
概念
pv:全名 Persistent volume,它是k8s虚拟化的存储资源。实际上就是存储,例如本地的硬盘。pv可以支持网络文件系统(NFS),包括可以用lvm、RAID、oss(ceph)、云存储。
pvc:全名 Persistent volume claim ,它是用户对存储资源的请求。它定义了需要存储的空间大小,以及对存储空间的访问模式。
过程:有了pvc请求之后,再和pv进行匹配,匹配到了之后绑定,绑定成功之后才能使用pv的存储功能。
流程
pv和pvc的生命周期:
配置(定义pvc请求的详细情况)——匹配pv——绑定——使用——释放——pv回收
pv的状态
1.Available 可用:就是可以被pvc匹配。pv处于未绑定状态
2. bound 已绑定 :表示pv已经被pvc绑定。pv处于正在使用状态
3. released 已释放:pvc已经被删除,但是pv的资源还没有被回收。 pv处于不可用的状态
4. failed 失败:pv自动回收失败。 pv处于不可用状态
pvc在请求的过程中支持的权限控制选项
ReadWriteOnce 简写RWO:表示存储目录权限可读、可写,但是这个目录只能被一个pod挂载
ReadOnlyMany 简写ROX:表示存储可以以只读的方式被多个pod挂载
ReadWriteMany 简写RWX:表示存储目录可以以读写的方式被多个pod挂载
注:只有NFS支持以上三种所有模式。hostPath只能支持ReadWriteOnce。云存储的对象存储可以支持动态扩容和缩容。如果存储设备是ISCSI:不支持ReadWriteMany。ISCSI是一种在网络上运行SCSI协议的网络存储技术。
pv的回收策略
Retain 保留
Retain 保留:默认策略,就是虽然pvc被删除了,但是pv还是出于released的状态,即使恢复到Available状态,上一个挂载的数据也不会丢失。(手动)
注:pv的默认策略,如果没有特殊需求,一律设置Retain
恢复:
kubectl edit pv pv002
把中间的全部删掉
保留成
此时就会恢复到Available
Delete 删除
就是虽然pvc被删除了,但是pv还是出于released的状态,即使恢复到Available状态,数据全部删除。(手动)
Recycle 回收
就是虽然pvc被删除了,但是pv还是出于released的状态,pv会自动的对资源进行回收,也就是删除数据,然后pv自动回到Available状态。(自动)
在yaml文件中指定pv的回收策略
语法:persistentVolumeReclaimPolicy:Delete
静态pv
1. 配置NFS
在另一台客户机上操作
vim /etc/exports
mkdir -p /data/v{1,2,3}
systemctl restart rpcbind
systemctl restart nfs
showmount -e
回到k8s集群,showmount -e 192.168.233.23 查看集群的节点是否能获取暴露的目录
2. 创建pv
回到master主节点
cd /opt/k8s-yaml/
kubectl explain pvc 查看pv的version和kind
vim pv.yaml
#我们定义3个pv,定义目录的路径,访问模式,pv的大小
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
labels:
name: pv001
spec:
nfs:
#定义pv使用的文件系统是nfs
server: 192.168.233.23
path: /data/v1
#如果请求匹配到这个pv,使用的是目标主机的/data/v1
accessModes: ["ReadWriteOnce"]
#定义访问模式
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
labels:
name: pv002
spec:
nfs:
server: 192.168.233.23
path: /data/v2
accessModes: ["ReadWriteMany"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
labels:
name: pv003
spec:
nfs:
server: 192.168.233.23
path: /data/v3
accessModes: ["ReadOnlyMany"]
capacity:
storage: 3Gi
kubectl apply -f pv.yaml
kubectl get pv 查看pv的状态
RECLAIM POLICY:pv的回收策略
STATUS:pv的状态
CLAIM:请求的pvc是谁
3. 创建pvc
kubectl explain pvc 查看pvc的version和kind
vim pvc-pod.yaml
#定义pvc的请求
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessMondes: ["ReadWriteMany"]
resources:
requests:
storage: 2Gi
#我需要pv的权限是ReadWriteMany,空间是2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
labels:
app: nginx1
spec:
replicas: 3
selector:
matchLabels:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
volumeMounts:
- name: xy102
mountPath: /usr/share/nginx/html
volumes:
- name: xy102
persistentVolumeClaim:
#直接使用pvc的请求把容器内目录挂载到pv请求对应的目录
claimName: mypvc
kubectl apply -f pvc-pod.yaml
kubectl get pv
kubectl get svc
然后访问 192.168.233.31:31504
动态pv
动态pv不需要人工创建pv,根据pvc的请求自动创建pv,然后实现挂载和使用。
k8s创建动态pv的机制是根据StorageClass,StorageClass相当于提供pv的模版。
我们用StorageClass+NFS来实现动态创建nfs的pv。
因为k8s本身不支持nfs创建动态pv,所以使用外部的插件Provisioner存储分配器,可以自动使用配置好的NFS自定创建pv。在k8s当中,使用Provisioner来创建动态pv。配合StorageClass一起使用。
Provisioner是用来配置信息,以及pvc的相关配置
StorageClass再根据配置信息调用模版创建pv
流程:pod里面包含pvc请求——Provisioner接受请求发送给StorageClass——StorageClass根据信息调用模版创建pv
Provisioner的类型:
nfs-client:实现与NFS网络共享的协作
aws-ebs:亚马逊云服务器的动态卷进行协作
local-storage:k8s节点的本地创建pv,一般是内部测试用的。
external-Storage:云平台支持的对象存储协作
动态pv的步骤
1. 创建角色server account,它是用来管理NFS-CLINET provisioner
2. 设定集群的角色,并赋权
3. 设定权限和server account 角色绑定
4. 创建NFS provisioner,以deployment 方式创建
在创建NFS provisioner里面声明: 存储点就是提供nfs服务的服务器、存储路径就是共享目录、挂载点
5. 创建stroageClass,作为pv的模版,和NFS provisioner 关联
6. 创建pvc请求和业务pod进行测试
7. 定义stroageclass的时候,设置pv的回收策略只能是retain,如果是delete一旦删除pvc挂载点也一起删除了数据也会没,recycle不能做动态策略。
1.配置NFS
在另一台客户机23上操作
vim /etc/exports
cd /opt/
mkdir k8s
chmod 777 k8s/
systemctl restart rpcbind
systemctl restart nfs
showmount -e
回到k8s集群,showmount -e 192.168.233.23 查看集群的节点是否能获取暴露的目录
2.创建角色、赋权、绑定角色
vim nfs-client-rbac.yaml
#创建角色:
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
#赋权:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-clusterrole
rules:
#rules规则,包含nfs provisioner权限可以新建和删除pv以及更新pvc、监听pod的变化、实时更新挂载点的变化。
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
#绑定角色:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: nfs-client-provisioner-clusterrolebinding
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-clusterrole
apiGroup: rbac.authorization.k8s.io
3.创建NFS provisioner
vim /etc/kubernetes/manifests/kube-apiserver.yaml
添加 - --feature-gates=RemoveSelfLink=false
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl get pod -n kube-system
以上就绪工作就做好了
vim nfs-client-provisioner.yaml
#创建provisioner的pod,还要声明路径和挂载点
#前面账户使用在这个pod里面
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs1
spec:
replicas: 1
selector:
matchLabels:
app: nfs1
strategy:
type: Recreate
#Recreate:每次升级容器或者更新都会将所有旧的pod停止,然后再启动新的pod
#加这个字段会导致服务暂时中断。(可加可不加)
template:
metadata:
labels:
app: nfs1
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs1
image: quay.io/external_storage/nfs-client-provisioner:latest
volumeMounts:
- name: nfs1
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-storage
#配置prosisioner的名称和值
- name: NFS_SERVER
value: 192.168.233.23
#在容器内设nfs服务器的ip地址变量
- name: NFS_PATH
value: /opt/k8s
#绑定nfs服务器的目录
volumes:
#申明nfs数据卷的类型
- name: nfs1
nfs:
server: 192.168.233.23
path: /opt/k8s
kubectl describe pod nfs1-77d76c77c4-kt68b
4.创建stroageClass
vim nfs-client-storageclass.yaml
#定义模版
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client-storageclass
provisioner: nfs-storage
parameters:
archiveOnDelete: "false"
#true表示删除pv时要进行存档,它会把pv的状态标记为archived。表示数据依然可用,但是不再对新的pvc进行绑定。
#false表示删除pvc,此时pv的状态先进入released,然后变为可用。
reclaimPolicy: Retain
#pv的回收策略
allowVolumeExpansion: true
#要想pv可以支持动态扩容,必须是true
5.创建pvc请求和业务pod
vim pvc.pod.yaml
#定义pvc的请求
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-mypvc
spec:
#定义请求的详情
accessModes: ["ReadWriteMany"]
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 2Gi
#我需要pv的权限是ReadWriteMany,空间是2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
labels:
app: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
volumeMounts:
- name: xy102
mountPath: /usr/share/nginx/html
volumes:
- name: xy102
persistentVolumeClaim:
#直接使用pvc的请求把容器内目录挂载到pv请求对应的目录
claimName: nfs-mypvc
kubectl get pv
此时回到另一台客户机
总结:动态pv的回收策略一定是Retain保留,如果是delete数据会被删除,Recycle动态不支持