如果有多个PV时,PVC又是如何匹配PV的呢?

存储技术

606人已加入

描述

开篇先总结一下三个存储相关的概念:

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 ##创建storageclass
SC 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




审核编辑:刘清

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分