文章目录
- 一、相关概念
- 二、创建pv
- 二、创建pvc
- 三、创建pod调用pvc
- 四、StorageClass动态制备pv
一、相关概念
-
关系
-
生命周期相关概念
2.1 静态构建:集群管理员创建若干PV卷。这些卷对象带有真实存储的细节信息,并且对集群用户可用(可见)。PV卷对象存在于Kubernetes API中,可供用户消费使用。
2.2动态构建:如果集群中已经有的PV无法满足PVC的需求,那么集群会根据PVC自动构建一个PV,该操作是通过Storageclass 实现的。想要实现这个操作,前提是PVC必须设置StorageClass,否则会无法动态构建该PV,可以通过启用DefaultstorageClass来实现PV的构建。
2.3 绑定:当用户创建一个 PVC对象后,主节点会监测新的 PVC对象,并且寻找与之匹配的PV卷,找到PV卷后将二者绑定在一起。如果找不到对应的PV,则需要看PVC是否设置StqrageClass来决定是否动态创建PV,若没有配置,PVC就会—致处于未绑定状态,直到有与之匹配的PV后才会申领绑定关系。
2.4 使用:Pod 将PVC当作存储卷来使用,集群会通过PVC找到绑定的PV,并为Pod挂载该卷。Pod 一旦使用PVC绑定PV后,为了保护数据,避免数据丢失问题,PV对象会受到保护,在系统中无法被删除。
2.5 回收策略:当用户不再使用其存储卷时,他们可以从API中将PVC对象删除,从而允许该资源被回收再利用。Persistentvolume对象的回收策略告诉集群,当其被从申领中释放时如何处理该数据卷。目前,数据卷可以被 Retained(保留)、Recyced(回收)或Deleted(删除)。
2.6 保留:回收策略Retain 使得用户可以手动回收资源。当Persistentvolumeclaim对象被删除时,Persistentvolume卷仍然存在,对应的数据卷被视为"已释放(released) "。由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领。管理员可以通过下面的步骤来手动回收该卷:
1)删除 Persistentvolume对象。与之相关的、位于外部基础设施中的存储资产(如AWS EBS、GCE PD、Azure Disk或 Cinder卷)在PV删除之后仍然存在。
2)根据情况,手动清除所关联的存储资产上的数据。
3)手动删除所关联的存储资产。如果你希望重用该存储资产,可以基于存储资产的定义创建新的Persistentvolume卷对象。
4)删除:对于支持Delete回收策略的插件,删除动作会将Persistentvolume对象从Kubernetes中移除,同时也会从外部基础设施(如AwS EBS、GCE PD、Azure Disk 或 Cinder卷)中移除所关联的存储资产。动态制备的卷会继承基StorageClass中设置的回收策略,该策略默认为Delete。管理员需要根据用户的期望来配置StorageClass;否则PV卷被创建之后必须要被编辑或者修补。
5)回收:动态制备。如果下层卷插件支持,回收策略Recycle会在卷上执行一些基本的擦除(rm -rf /thevolume/*)操作,之后允许该卷用于新的PVC申领。
-
生命周期相关概念
Available:空闲,未被绑定 Bound:已经被PVC绑定 Released : PVC被册删除,资源已回收,俚是PV未被重新使用 Failed:自动回收失败
二、创建pv
-
创建pv文件:vi /opt/pv.yaml
apiVersion: v1 kind: PersistentVolume #描述资源对象为PV类型 metadata: name : pv0001 #PV的名字 spec: capacity: #容量配置 storage: 5Gi # pv的容量 volumeMode: Filesystem #存储类型为文件系统 accessModes: #访问模式:ReadWriteOnce、ReadWriteMany、ReadOnlyMany - ReadWriteMany #可被单节点独写 persistentVolumeReclaimPolicy: Retain #回收策略 storageClassName: sc0001 # 创建PV的存储类名,需要与 pvc 的相同 mountOptions: #加载配置l - hard #使用硬挂载方式 - nfsvers=4.1 #使用NFSv4.1版本 nfs: #连接到nfs path: /root/data/nfs #存储路径 server: 192.168.248.11 # nfs服务地址
-
创建资源:kubectl apply -f /opt/pv.yaml
-
查看: kubectl get pv
-
查看详情:kubectl describe pv pv0001
二、创建pvc
-
创建pvc文件:vi /opt/pvc.yaml
apiVersion: v1 kind: PersistentVolumeClaim #资源类型为 PVC metadata: name: pvc0001 spec: accessModes: - ReadWriteMany #权限需要与对应的pv相同 volumeMode: Filesystem resources: requests: storage: 5Gi #资源可以小于 pv 的,但是不能大于,如果大于就会匹配不到 pv storageClassName: sc0001 #名字需要与对应的pv相同
-
创建资源:kubectl apply -f /opt/pvc.yaml
-
查看:kubectl get pvc
-
查看详情:kubectl describe pvc pvc0001
三、创建pod调用pvc
-
创建pod:vi /opt/testpvc.yaml
apiVersion: v1 kind : Pod metadata: name: test-pvc-pd spec: containers: - image: nginx name: nginx-volume volumeMounts: - mountPath: /usr/share/nginx/html #挂载到容器的哪个目录 name: test-volume #挂载哪个volume volumes: - name: test-volume persistentVolumeClaim: claimName: pvc0001 #要关联到哪个pvc
-
创建资源:kubectl apply -f /opt/testpvc.yaml
-
进入:vi /root/data/nfs/index.html
111
-
进入pod并且查看
kubectl exec -it test-pvc-pd sh cd /usr/share/nginx/html cat index.html
四、StorageClass动态制备pv
-
什么是StorageClass
StorageClass又称为PV动态供给,是k8s1.4之后引入的一个新资源,StorageClass主要实现了存储卷PV按需创建,动态创建,当Pod需要使用PVC时,StorageClass会自动创建一个PV,并与PVC进行绑定,相比于传统的PV、PVC,管理员不再需要创建PV,PV由StorageClass自动创建。
1.PV的属性。比如,存储类型,Volume的大小等。 2.创建这种PV需要用到的存储插件,即存储制备器。有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass,之后Kubernetes就会调用该StorageClass声明的存储插件,进而创建出需要的PV。
-
为什么需要StorageClass
传统的PV和PVC属于静态的,静态的PV和PVC都需要运维手动来创建,如果有很多个Pod需要同时使用PVC,而一个PV只能挂载到一个Pod中,这时运维的工作量将会很大。
而且不同的应用程序对于存储性能的要求可能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes 又为我们引入了一个新的资源对象:StorageClass,通过 StorageClass 的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据 StorageClass 的描述就可以非常直观的知道各种存储资源的具体特性了,这样就可以根据应用的特性去申请合适的存储资源了。
-
运行原理
要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner(制备器),这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。
1. 自动创建的 PV 以${namespace}-${pvcName}-${pvName}这样的命名格式创建在 NFS 服务器上的共享数据目录中 2. 而当这个 PV 被回收后会以archieved-${namespace}-${pvcName}-${pvName}这样的命名格式存在 NFS 服务器上。
-
逻辑图
-
实操StorageClass步骤
1.创建nfs-client-provisioner程序的rbac授权角色账号,以及角色,然后将账户与rbac账号进行绑定,使nfs-client-provisioner对pv、pvc有增删改查权限 2.创建制备器nfs-client-provisioner,同时指定操作用户为前面创建的rbac授权角色账号 3.创建StorageClass存储类并且指定外部制备器,自动创建PV时,就将PV存储到了nfs-client对应的nfs存储上 4.创建一个pod,并且指向StorageClass存储类,验证是否能自动创建PV
-
编写账号权限创建脚本:vi /opt/nfs-provisioner-rbac.yaml
ps:定义了一个
ServiceAccount
,然后定义了两个ClusterRole
,在分别在ClusterRoleBinding中进行绑定apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner namespace: kube-system --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner namespace: kube-system 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: ["create", "update", "patch"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: run-nfs-client-provisioner namespace: kube-system subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: kube-system roleRef: kind: ClusterRole name: nfs-client-provisioner-runner apiGroup: rbac.authorization.k8s.io --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner namespace: kube-system rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner namespace: kube-system subjects: - kind: ServiceAccount name: nfs-client-provisioner roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io
-
创建资源:kubectl apply -f /opt/nfs-provisioner-rbac.yaml
-
编写制备器创建脚本:vi /opt/sc-nfs-storage.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner namespace: kube-system labels: app: nfs-client-provisioner spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: fuseim.pri/ifs - name: NFS_SERVER value: 192.168.248.10 - name: NFS_PATH value: /root/data/nfs volumes: - name: nfs-client-root nfs: server: 192.168.248.10 path: /root/data/nfs
-
创建资源:kubectl apply -f /opt/sc-nfs-storage.yaml
-
编写StorageClass创建脚本:vi /opt/storageClass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: fuseim.pri/ifs #外部制备器提供者,编写为提供者的名称
parameters:
archiveOnDelete: "false" #是否存档,false 表示不存档,会删除 oldPath下面的数据,true 表示存档,会重命名路径
reclaimPolicy: Retain #回收策略,默认为Delete可以配置为 Retain I
volumeBindingMode: Immediate #默认为Imediate,表示创建PVC立即进行绑定,只有 azuredisk和AuSelasticblockstore支持其他值
-
创建资源:kubectl apply -f /opt/storageClass.yaml
-
编写nginx应用创建脚本:vi /opt/sc-nginx.yaml
--- apiVersion: v1 kind: Service metadata: name: nginx-sc labels: app: nginx-sc spec: type: NodePort ports: - name: web port: 80 protocol: TCP selector: app: nginx-sc --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx-sc spec: replicas: 1 serviceName: "nginx-sc" selector: matchLabels: app: nginx-sc template: metadata: labels: app: nginx-sc spec: containers: - image: nginx name: nginx-sc imagePullPolicy: IfNotPresent volumeMounts: - mountPath: /usr/share/nginx/html name: nginx-sc-test-pvc volumeClaimTemplates: - metadata: name: nginx-sc-test-pvc spec: storageClassName: managed-nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 1Gi
-
创建资源:kubectl apply -f /opt/sc-nginx.yaml
-
查看:kubectl get pvc
-
kubectl get pv
ps:如果失败可以查看日志kubectl logs nfs-client-provisioner-6db49949bf-txqvl -n kube-system
-
也可以手动创建pvc,同时将storageClassName指向当前StorageClass,即第三大点的yaml的storageClassName属性