开篇先总结一下三个存储相关的概念:
PersistentVolume(PV) 是对具体存储资源的描述,比如NFS、Ceph、GlusterFS等,通过PV可以访问到具体的存储资源; PersistentVolumeClaim(PVC) Pod想要使用具体的存储资源需要对接到PVC,PVC里会定义好Pod希望使用存储的属性,通过PVC再去申请合适的存储资源(PV),匹配到合适的资源后PVC和PV会进行绑定,它们两者是一一对应的; StorageClass(SC) PV可以手动创建,也可以自动创建,当PV需求量非常大时,如果靠手动创建PV就非常麻烦了,SC可以实现自动创建PV,并且会将PVC和PV绑定。
SC会定义两部分内容:
① pv的属性,比如存储类型、大小;
② 创建该PV需要用到的存储插件(provisioner),这个provisioner是实现自动创建PV的关键。
API资源对象PV和PVC
1)PV YAML示例:
vi testpv.yaml #内容如下
apiVersion: v1 kind: PersistentVolume metadata: name: testpv spec: storageClassName: test-storage accessModes: - ReadWriteOnce capacity: storage: 500Mi ##提供500Mi空间 hostPath: path: /tmp/testpv/
说明:
storageClassName: 定义存储类名称,PV和PVC中都会有该字段,目的是为了方便两者匹配绑定在一起
accessModes定义该pv的访问权限模式,有三种:
ReadWriteOnce:存储卷可读可写,但只能被一个节点上的 Pod 挂载;
ReadOnlyMany:存储卷只读不可写,可以被任意节点上的 Pod 多次挂载;
ReadWriteMany:存储卷可读可写,也可以被任意节点上的 Pod 多次挂载;
capacity 定义该存储大小。
hostPath 定义该存储访问路径,这里指的是本地的磁盘。
2)PVC YAML示例:
vi testpvc.yaml #内容如下
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: testpvc spec: storageClassName: test-storage accessModes: - ReadWriteOnce resources: requests: storage: 100Mi ##期望申请100Mi空间
应用pv和pvc的YAML
kubectl apply -f testpv.yaml -f testpvc.yaml
查看状态
kubectl get pv,pvc
3)PV和PVC匹配规则
PV创建好后,会等待PVC与其进行绑定,PVC一旦找到合适的PV就会绑定。如果有多个PV时,PVC又是如何匹配PV的呢?它有如下一些规则:
① 访问模式和存储类匹配:Kubernetes会筛选出访问模式(accessModes)和存储类(storageClassName)与PVC相匹配的PV。如果没有匹配的PV,PVC将保持未绑定状态。
② 资源大小:在满足访问模式和存储类匹配的PV中,Kubernetes会选择资源大小大于或等于PVC请求大小的PV。
③ 最佳匹配:在满足访问模式、存储类和资源大小的PV中,Kubernetes会选择资源大小最接近PVC请求大小的PV。如果有多个PV具有相同的资源大小,Kubernetes会选择其中一个进行绑定。
④ 避免重复绑定:一个PV在任何时候只能被一个PVC绑定。一旦PV被绑定到一个PVC,它将不再可用于其他PVC。
API资源对象StorageClass
SC的主要作用在于,自动创建PV,从而实现PVC按需自动绑定PV。
下面我们通过创建一个基于NFS的SC来演示SC的作用。
要想使用NFS的SC,还需要安装一个NFS provisioner,provisioner里会定义NFS相关的信息(服务器IP、共享目录等)
修改yaml,并创建rbac授权
cd nfs-subdir-external-provisioner/deploy sed -i 's/namespace: default/namespace: kube-system/' rbac.yaml ##修改命名空间为kube-system kubectl apply -f rbac.yaml ##创建rbac授权修改deployment.yaml
sed -i 's/namespace: default/namespace: kube-system/' deployment.yaml ##修改命名空间为kube-system ##另外,你还需要手动修改下面内容 spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: chronolaw/nfs-subdir-external-provisioner:v4.0.2 ##改为dockerhub地址 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: k8s-sigs.io/nfs-subdir-external-provisioner - name: NFS_SERVER value: 192.168.222.99 ##改为你自己的nfs服务器地址 - name: NFS_PATH value: /data/nfs ##改为你自己的nfs共享目录 volumes: - name: nfs-client-root nfs: server: 192.168.222.99 ##改为你自己的nfs服务器地址 path: /data/nfs ##改为你自己的nfs共享目录应用yaml
kubectl apply -f deployment.yaml kubectl apply -f class.yaml ##创建storageclassSC YAML示例 如下是class.yaml文件内容:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME' parameters: archiveOnDelete: "false" ##自动回收存储空间有了SC,还需要一个PVC vi nfsPvc.yaml #增加如下内容
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfsPvc spec: storageClassName: nfs-client accessModes: - ReadWriteMany resources: requests: storage: 500Mi下面创建一个Pod,来使用PVC vi nfsPod.yaml #内容如下
apiVersion: v1 kind: Pod metadata: name: nfsPod spec: containers: - name: nfsPod image: nginx:1.23.2 volumeMounts: - name: nfspv mountPath: "/usr/share/nginx/html" volumes: - name: nfspv persistentVolumeClaim: claimName: nfsPvc
审核编辑:刘清
评论
查看更多