目录
1、什么是pv和pvc
2、pvc的使用逻辑
3、StorageClass
4、pv和pvc相互作用
5、pv的生命周期中,一般有几种状态?
6、一个pv从创建到销毁的流程
7、nfs使用pv和pvc
7.1、配置nfs存储
7.2这里定义5个PV,并且定义挂载的路径以及访问模式,还有PV划分的大小
7.3、这里定义了pvc的访问模式为多路读写
7.4测试访问
8、搭建 StorageClass + NFS,实现 NFS 的动态 PV 创建
8.1、在stor01节点上安装nfs,并配置nfs服务
8.2、创建 Service Account,用来管理 NFS Provisioner 在 k8s 集群中运行的权限,设置 nfs-client 对 PV,PVC,StorageClass 等的规则
3、使用 Deployment 来创建 NFS Provisioner
8.4、创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联
8.5、创建 PVC 和 Pod 测试
1、什么是pv和pvc
pv是持久化存储卷,在指定的存储设备空间中创建的可持久化的存储资源
pvc是持久化存储的请求,是对Pv存储资源的请求和绑定
2、pvc的使用逻辑
在 Pod 中定义一个存储卷(该存储卷类型为 PVC),定义的时候直接指定大小,PVC 必须与对应的 PV 建立关系,PVC 会根据配置的定义去 PV 申请,而 PV 是由存储空间创建出来的。PV 和 PVC 是 Kubernetes 抽象出来的一种存储资源。
3、StorageClass
Kubernetes提供一种自动创建PV的机制,叫StorageClass,它的作用就是创建PV的模板。
4、pv和pvc相互作用
PV和PVC之间的相互作用遵循以下生命周期:
Provisioning(配置)---> Binding(绑定)---> Using(使用)---> Releasing(释放) ---> Recycling(回收)
1、Provisioning:PV 的创建,可以直接创建 PV(静态方式),也可以使用 StorageClass 动态创建
2、Binding:将 PV 分配给 PVC
3、Using:Pod 通过 PVC 使用该 Volume,并可以通过准入控制StorageProtection(1.9及以前版本为PVCProtection) 阻止删除正在使用的 PVC4、Releasing:Pod 释放 Volume 并删除 PVC
5、Reclaiming:回收 PV,可以保留 PV 以便下次使用,也可以直接从云存储中删除
5、pv的生命周期中,一般有几种状态?
Available(可用):表示可用状态,还未被任何 PVC 绑定
Bound(已绑定):表示 PV 已经绑定到 PVC
Released(已释放):表示 PVC 被删掉,但是资源尚未被集群回收
Failed(失败):表示该 PV 的自动回收失败
6、一个pv从创建到销毁的流程
1、一个PV创建完后状态会变成Available,等待被PVC绑定。
2、一旦被PVC邦定,PV的状态会变成Bound,就可以被定义了相应PVC的Pod使用。
3、Pod使用完后会释放PV,PV的状态变成Released。
4、变成Released的PV会根据定义的回收策略做相应的回收工作。有三种回收策略,Retain、Delete和Recycle。Retain就是保留现场,K8S集群什么也不做,等待用户手动去处理PV里的数据,处理完后,再手动删除PV。Delete策略,K8S会自动删除该PV及里面的数据。Recycle方式,K8S会将PV里的数据删除,然后把PV的状态变成Available,又可以被新的PVC绑定使用。
7、nfs使用pv和pvc
7.1、配置nfs存储
mkdir v{1,2,3,4,5}vim /etc/exportsexportfs -arvshowmount -e
7.2这里定义5个PV,并且定义挂载的路径以及访问模式,还有PV划分的大小
vim pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: pv001labels:name: pv001
spec:nfs:path: /data/volumes/v1server: stor01 accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv002labels:name: pv002
spec:nfs:path: /data/volumes/v2server: stor01accessModes: ["ReadWriteOnce"]capacity:storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv003labels:name: pv003
spec:nfs:path: /data/volumes/v3server: stor01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv004labels:name: pv004
spec:nfs:path: /data/volumes/v4server: stor01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv005labels:name: pv005
spec:nfs:path: /data/volumes/v5server: stor01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 5Gikubectl apply -f pv-demo.yamlkubectl get pv
7.3、这里定义了pvc的访问模式为多路读写
该访问模式必须在前面pv定义的访问模式之中。定义PVC申请的大小为2Gi,此时PVC会自动去匹配多路读写且大小为2Gi的PV,匹配成功获取PVC的状态即为Bound
vim pod-vol-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mypvcnamespace: default
spec:accessModes: ["ReadWriteMany"]resources:requests:storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:name: pod-vol-pvcnamespace: default
spec:containers:- name: myappimage: ikubernetes/myapp:v1volumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlpersistentVolumeClaim:claimName: mypvckubectl apply -f pod-vol-pvc.yamlkubectl get pvkubectl get pvc
7.4测试访问
cd /data/volumes/v3/
echo "welcome to use pv3" > index.htmlkubectl get pods -o widecurl 10.244.2.4
8、搭建 StorageClass + NFS,实现 NFS 的动态 PV 创建
8.1、在stor01节点上安装nfs,并配置nfs服务
mkdir /opt/k8s
chmod 777 /opt/k8s/vim /etc/exports
/opt/k8s 192.168.246.0/24(rw,no_root_squash,sync)systemctl restart nfs
8.2、创建 Service Account,用来管理 NFS Provisioner 在 k8s 集群中运行的权限,设置 nfs-client 对 PV,PVC,StorageClass 等的规则
vim nfs-client-rbac.yaml
#创建 Service Account 账户,用来管理 NFS Provisioner 在 k8s 集群中运行的权限
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner
---
#创建集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: nfs-client-provisioner-clusterrole
rules:- 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: ServiceAccountname: nfs-client-provisionernamespace: default
roleRef:kind: ClusterRolename: nfs-client-provisioner-clusterroleapiGroup: rbac.authorization.k8s.iokubectl apply -f nfs-client-rbac.yaml
3、使用 Deployment 来创建 NFS Provisioner
vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:containers:- command:- kube-apiserver- --feature-gates=RemoveSelfLink=false #添加这一行- --advertise-address=192.168.80.20
......kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system
kubectl get pods -n kube-system | grep apiserver#创建 NFS Provisioner
vim nfs-client-provisioner.yaml
kind: Deployment
apiVersion: apps/v1
metadata:name: nfs-client-provisioner
spec:replicas: 1selector:matchLabels:app: nfs-client-provisionerstrategy:type: Recreatetemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisioner #指定Service Account账户containers:- name: nfs-client-provisionerimage: quay.io/external_storage/nfs-client-provisioner:latestimagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: nfs-storage #配置provisioner的Name,确保该名称与StorageClass资源中的provisioner名称保持一致- name: NFS_SERVERvalue: stor01 #配置绑定的nfs服务器- name: NFS_PATHvalue: /opt/k8s #配置绑定的nfs服务器目录volumes: #申明nfs数据卷- name: nfs-client-rootnfs:server: stor01path: /opt/k8skubectl apply -f nfs-client-provisioner.yaml kubectl get pod
8.4、创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联
vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclass
provisioner: nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:archiveOnDelete: "false" #false表示在删除PVC时不会对数据进行存档,即删除数据kubectl apply -f nfs-client-storageclass.yamlkubectl get storageclass
8.5、创建 PVC 和 Pod 测试
vim test-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: test-nfs-pvc
spec:accessModes:- ReadWriteManystorageClassName: nfs-client-PROVISIONER #关联StorageClass对象resources:requests:storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:name: test-storageclass-pod
spec:containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand:- "/bin/sh"- "-c"args:- "sleep 3600"volumeMounts:- name: nfs-pvcmountPath: /mntrestartPolicy: Nevervolumes:- name: nfs-pvcpersistentVolumeClaim:claimName: test-nfs-pvc #与PVC名称保持一致kubectl apply -f test-pvc-pod.yaml//PVC 通过 StorageClass 自动申请到空间
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-nfs-pvc Bound pvc-11670f39-782d-41b8-a842-eabe1859a456 1Gi RWX nfs-client-storageclass 2s//查看 NFS 服务器上是否生成对应的目录,自动创建的 PV 会以 ${namespace}-${pvcName}-${pvName} 的目录格式放到 NFS 服务器上
ls /opt/k8s/
default-test-nfs-pvc-pvc-11670f39-782d-41b8-a842-eabe1859a456//进入 Pod 在挂载目录 /mnt 下写一个文件,然后查看 NFS 服务器上是否存在该文件
kubectl exec -it test-storageclass-pod sh
/ # cd /mnt/
/mnt # echo 'this is test file' > test.txt//发现 NFS 服务器上存在,说明验证成功
cat /opt/k8s/test.txt