pod数据持久化-pv与pvc资源及动态存储StorageClass
一、pc与pvc的概念
在传统的存储卷挂载,比如说nfs,它虽然能够实现我们大多数的生产场景,但是,耦合性比较高;
举例:假设,我们要将集群从“阿里云”迁移到我们私有云服务器上,并改变存储卷挂在的类型,就无法实现,必须使用原有的存储卷类型;比如我们阿里云的存储卷是nfs,我们线下服务器的存储卷是ceph,就无法迁移成功;
那么此时,我们来通过pv与pvc,就可以解决这个耦合性问题了;
二、pvc与pv初体验
我们先按照这个架构图搭建一遍,在来梳理内在的逻辑问题;
1,准别nfs环境
· 所有节点安装nfs工具
harbor安装nfs:是为了作为外部存储卷使用;
k8s231、k8s232、k8s233安装nfs:是为了,自动挂载nfs的时候,使用nfs命令;
yum -y install nfs-utils
harbor节点编辑nfs配置文件
[root@harbor ~]# vim /etc/exports /data/kubernetes *(rw,no_root_squash)
[root@harbor ~]# systemctl enable --now nfs [root@harbor ~]# exportfs /data/kubernetes <world>
2,创建3个pv资源
[root@k8s231 pv-pvc]# cat pc.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv01 labels: k8s: xinjizhiwa spec: #声明访问模式 accessModes: #ReadWriteOnce: 【RWO】 允许单个节点【读写】这个存储卷; #ReadOnlyMany: 【ROX】 允许多个节点【只读】这个存储卷; #ReadWriteMany: 【RWX】 允许多个节点【读写】这个存储卷; #ReadWriteOncePod:【RWOP】允许单个 pod【读写】这个存储卷;1.22版本后新功能; - ReadOnlyMany #声明pv的挂载类型 nfs: path: /data/kubernetes/pv/pv01 server: 10.0.0.230 #声明数据的回收策略 #Retain: 删除PVC时,PV不被删除,状态:已释放,需要手动回收,其他pod否则无法直接使用 #Delete: 删除PVC时,PV和数据都将被删除; #Recycle:官方已经弃用;(删除PVC时,自动清理对应数据,其他pod可以继续使用) persistentVolumeReclaimPolicy: Retain #声明存储卷的容量(给你存多少东西的容量控制) capacity: storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv02 labels: k8s: xinjizhiwa spec: accessModes: - ReadWriteMany nfs: path: /data/kubernetes/pv/pv02 server: 10.0.0.230 persistentVolumeReclaimPolicy: Retain capacity: storage: 5Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv03 labels: k8s: xinjizhiwa spec: accessModes: - ReadWriteMany nfs: path: /data/kubernetes/pv/pv03 server: 10.0.0.230 persistentVolumeReclaimPolicy: Retain capacity: storage: 10Gi
[root@k8s231 pv-pvc]# kubectl apply -f pc.yaml
查看创建好的pc资源
[root@k8s231 pv-pvc]# kubectl get pv
3,harbor节点创建pv对应的nfs存储路径
[root@harbor ~]# mkdir -pv /data/kubernetes/pv/pv0{1..3}
4,创建pvc关联pv
pvc链接pv的方式有两种:
第一种:是指定使用哪个pv;
另一种:是不写使用哪个pv,pvc会自动去寻找系统中存在的所有pv,从中匹配一个合适的,进行自动化存储;
[root@k8s231 pv-pvc]# vim pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc01 spec: # 声明要是用的pv;PVC会根据资源限制自动选择pv存储卷; # volumeName: pv03 #不写volumeName就会自动根据资源限制自动选择; # 声明资源的访问模式 accessModes: - ReadWriteMany # 声明资源的使用量 resources: limits: storage: 4Gi requests: storage: 3Gi
[root@k8s231 pv-pvc]# kubectl apply -f pvc.yaml
查看pvc
因为,我们三个存储卷的pv分别设置了2g、5g、10g的存储容量;
此时我们配置pvc的时候,要求期望是3g,最大值为4g,那么最优的pv选择一定是5g最合适,创建pvc后,我们可以验证查看,自动匹配的pv,就是pv02,存储容量为5g的这个;
[root@k8s231 pv-pvc]# kubectl get pvc
5,创建pod引入pvc
[root@k8s231 pv-pvc]# cat pod.yaml apiVersion: apps/v1 kind: Deployment metadata: name: dm-pv spec: replicas: 5 selector: matchLabels: k8s: xinjizhiwa template: metadata: labels: k8s: xinjizhiwa spec: volumes: - name: pvc-vol #声明pvc存储类型 persistentVolumeClaim: #引用pvc的名称 claimName: pvc01 containers: - name: c1 image: nginx:1.20.1-alpine volumeMounts: - name: pvc-vol mountPath: /usr/share/nginx/html/ ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: svc-pv-pvc spec: type: NodePort selector: k8s: xinjizhiwa ports: - port: 80 targetPort: 80 nodePort: 8080
[root@k8s231 pv-pvc]# kubectl apply -f pod.yaml
6,编辑index访问文件到harbor存储目录下
[root@harbor ~]# echo xinjizhiwa-hahahahah > /data/kubernetes/pv/pv02/index.html
我们也可以通过查看pv的详细信息,看到存储路径
[root@k8s231 pv-pvc]# kubectl describe pv pv02
7,浏览器访问测试
三、StorageClass动态存储资源
StorageClass动态存储资源:简称sc资源;
动态存储类,它自动创建pv;不再需要手动创建pv;
但是,我们的存储卷系统nfs本身不支持这个sc动态存储,所以,我们需要借助一个插件来实现nfs配合sc资源实现动态自动存储;
整体流程规划汇总;
1,部署nfs环境(存储nfs,和集群的nfs命令) 2,配置nfs动态存储插件; 3,创建StorageClass动态存储资源; 4,创建pvc适配StorageClass动态存储资源 5,创建业务pod引用pvc
1,准备nfs环境
· 所有节点安装nfs
yum -y install nfs-utils
· harbor存储节点配置nfs
[root@harbor ~]# vim /etc/exports /data/kubernetes *(rw,no_root_squash)
[root@harbor ~]# systemctl enable --now nfs [root@harbor ~]# exportfs /data/kubernetes <world>
· harbor节点创建nfs挂载目录
[root@harbor ~]# mkdir -p /data/kubernetes/storageclass
2,部署配置nfs动态存储插件
注意,nfs的这个插件包中,包含了创建部署服务pod清单,pvc清单和nfs插件清单(deployment.yaml)、storageclass清单(class.yaml);
所以,这个插件包,满足了一切要求了;当然,除了deploymengt.yaml文件外,其他的都不算是插件,都是我们要创建的资源,只是这个插件的构建者,帮助我们把资源清单汇总了;
你也可以自己单独去创建;
· 修改集群api-server,为适配插件中镜像
不设置这一步,nfs的插件镜像无法启动
[root@k8s231 deploy]# vim /etc/kubernetes/manifests/kube-apiserver.yaml ........... containers: - command: - kube-apiserver - --service-node-port-range=3000-50000 # 就是加下面这句代码 - --feature-gates=RemoveSelfLink=false .............
插件地址链接:
百度网盘:https://pan.baidu.com/s/106FXTyxJLNWfDStvRqBL1w?pwd=7a91
提取码:7a91
· 上传解压插件压缩包
[root@k8s231 storageclass]# rz -E [root@k8s231 storageclass]# tar xf k8s-external-storage.tar.gz [root@k8s231 storageclass]# ll drwxr-xr-x 17 root root 4096 Jan 7 07:15 k8s-external-storage -rw-r--r-- 1 root root 17618638 Jan 7 07:17 k8s-external-storage.tar.gz
· 进入nfs动态配置文件目录
这个插件保重包含很多存储类的动态配置,我们需要进入到nfs动态配置的目录下;
[root@k8s231 storageclass]# cd k8s-external-storage/nfs-client/deploy/
[root@k8s231 deploy]# ll
创建sa用户
[root@k8s231 deploy]# kubectl apply -f rbac.yaml
· 修改插件文件deployment.yaml
[root@k8s231 deploy]# cat deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: #执行程序的sa用户 serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: quay.io/external_storage/nfs-client-provisioner:latest volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME #对应的StorageClass资源里的provisioner字段值 value: xinjizhiwa-provisioner - name: NFS_SERVER value: 10.0.0.230 - name: NFS_PATH value: /data/kubernetes/storageclass volumes: - name: nfs-client-root nfs: server: 10.0.0.230 # path: /ifs/kubernetes path: /data/kubernetes/storageclass
· 创建插件的deployment.yaml文件资源
[root@k8s231 deploy]# kubectl apply -f deployment.yaml
查看是否创建成功
· 修改nfs插件中class.yaml文件
nfs自带的sc资源模板文件,这个文件就是storageclass资源文件;
[root@k8s231 deploy]# vim class.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: managed-nfs-storage #这个值,对应nfs插件的deploymengt.yaml文件中env下的name是PROVISIONER_NAME的value值 provisioner: xinjizhiwa-provisioner parameters: #是否删除里面的数据; #注意:仅对“回收策略是Retain”的值时生效,如果回收策略是delete,则这个参数无效; #删除数据后,会在存储卷路径创建“archived-*”前缀的目录; archiveOnDelete: "true" #在这里设置pv的回收策略(如果不设置,默认是delete) recalaimPolicy: Retain
[root@k8s231 deploy]# kubectl apply -f class.yaml
查看sc资源是否成功;
· 创建pvc资源
nfs自带的pvc文件模板
[root@k8s231 deploy]# vim test-claim.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test-claim #annotations: #volume.beta.kubernetes.io/storage-class: "managed-nfs-storage" spec: #指定storageclass资源名称,pvc向哪个storageclass申请pv?? storageClassName: managed-nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 1Mi
[root@k8s231 deploy]# kubectl apply -f test-claim.yaml
· 验证storageclass是否自动创建了pv?
[root@k8s231 deploy]# kubectl get pv
· 此时查看harbor节点的存储路径
可以看到,创建了pvc之后,nfs挂载目录,就通过sc资源自动创建了一个目录,用于pvc使用;
· 创建pod引用pvc
nfs插件中自带的模板文件
[root@k8s231 deploy]# vim test-pod.yaml kind: Pod apiVersion: v1 metadata: name: test-pod spec: containers: - name: test-pod #咱们就修改了这个镜像而已; image: alpine:latest command: - "/bin/sh" args: - "-c" - "touch /mnt/SUCCESS && exit 0 || exit 1" volumeMounts: - name: nfs-pvc mountPath: "/mnt" restartPolicy: "Never" volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test-claim
[root@k8s231 deploy]# kubectl apply -f test-pod.yaml
· pod运行结束后查看挂载卷路径
证明,动态存储验证成功
1,在创建pvc的时候,sc资源自动创建了pv
2,在创建pvc之后,插卡nfs路径,发现自动创建了pv
3,pod容器运行命令,产生存储数据后,查看nfs存储路径,发现文件生成了;
因此、可以证明,动态存储验证成功;