PV与PVC

• PersistentVolume(PV):持久数据卷,对存储资源的抽象,使得存储作为集群中的资源管理。
• PersistentVolumeClaim(PVC):持久数据卷申请,用户定义使用的存储容量,使得用户不需要关心后端存储实现。
Pod申请PVC作为卷来使用,Kubernetes通过PVC查找绑定的PV,并挂载到Pod中供程序使用
他是出于安全性与专业性以及专业职业逻辑分离的考虑
他的一般逻辑如下
其中,容器应用内的引用与卷需求模板由开发提供,数据卷定义由k8s管理员安排

示例:

创建一个deployment并创建对应pvc请求,如下
vi deployment-pvc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-pvc
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
      volumes:
      - name: wwwroot
        persistentVolumeClaim:
          claimName: web-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: web-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
此yaml创建了三个pod并申请了pvc,他们靠name关联
执行并查看pvc
kubectl apply -f deployment-pvc.yaml
kubectl get pvc
他是pending状态,pod也是
原因是因为pod绑定的pvc还没有绑定到pv
此时为集群创建存储pv
创建pv
vi pv.yaml
标红处分别为挂载目录权限,nfs挂载路径以及nfs服务器ip
apiVersion: v1
kind: PersistentVolume
metadata:
  name: web-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /ifs/kubernetes
    server: 192.168.209.112
执行
kubectl apply -f pv.yaml
kubectl get pv
现在在查看刚刚创建的pvc与pod,可以看见都处于绑定运行状态
通过测试他们数据共享与持久化无问题
注意:本质上讲,其实还是pod直接挂载的nfs,

测试pv与pvc的关联规则

测试创建多pvc,每一个路径不一样,互相独立
现在nfs挂载路径下创建多个文件
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /ifs/kubernetes/pv0001
    server: 192.168.209.112
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0002
spec:
  capacity:
    storage: 30Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /ifs/kubernetes/pv0002
    server: 192.168.209.112
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 60Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /ifs/kubernetes/pv0003
    server: 192.168.209.112
kubectl get pv
创建一个需求为15G的pvc
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-pvc2
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
      volumes:
      - name: wwwroot
        persistentVolumeClaim:
          claimName: web-pvc2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: web-pvc2
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 15Gi
他被分配到30G的pv中,
所以,pvc与pv的绑定是自动的,他们的关联关系是pvc的申请存储空间大小与访问模式,,这个存储大小没有实际限制作用,只做匹配作用,向上兼容匹配
如果不满足条件则pod处于pending状态,无法得到匹配,pvc与pv是一对一关系

pv生命周期

ACCESS MODES(访问模式):
AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
• ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
• ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
• ReadWriteMany(RWX):读写权限,可以被多个节点挂载
RECLAIM POLICY(回收策略):
目前 PV 支持的策略有三种:
• Retain(保留): 保留数据,需要管理员手工清理数据
• Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/kuberneres/*,PV改变为Available状态
• Delete(删除):与 PV 相连的后端存储同时删除
修改回收策略:persistentVolumeReclaimPolicy: Retain
STATUS(状态):
一个 PV 的生命周期中,可能会处于4中不同的阶段:
• Available(可用):表示可用状态,还未被任何 PVC 绑定
• Bound(已绑定):表示 PV 已经被 PVC 绑定
• Released(已释放):PVC 被删除,但是资源还未被集群重新声明
• Failed(失败): 表示该 PV 的自动回收失败

PV与PVC动态供给

现在PV使用方式称为静态供给,需要K8s运维工程师提前创 建一堆PV,供开发者使用。
PV静态供给明显的缺点是维护成本太高了! 因此,K8s开始支持PV动态供给,使用StorageClass对象实现。
K8s默认不支持NFS动态供给,需要单独部署社区开发的插件。
部署动态供给的pod
上传nfs-external-provisioner.zip到master节点
解压
修改deployment.yaml的ip和存储目录为自己nfs对应的
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:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: lizhenliang/nfs-subdir-external-provisioner:v4.0.1
          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.209.112
            - name: NFS_PATH
              value: /ifs/kubernetes
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.209.112
            path: /ifs/kubernetes
执行三个yaml并查看
kubectl apply -f .
查看存储
kubectl get sc

使用动态供给

创建一个示例yaml
vi deployment-sc.yaml
与普通创建pvc不同的是,在创建pvc是要加一个storageClassName参数,它对应上面存储类的name
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-sc
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
      volumes:
      - name: wwwroot
        persistentVolumeClaim:
          claimName: web-sc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: web-sc
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
创建
kubectl apply -f deployment-sc.yaml
查看pvc,pv,他会自己新建一个pv并绑定申请的pvc,他就是动态供给产生的pv
注意:自动供给的pv创建是delete类型的,也就是pod删除后他所在的持久卷也会默认删除,可以通过修改创建动态供给时的class.yaml中的参数,将flase改为ture
因为这个yaml不支持apply更新,所以要先删除在新建
kubectl delete -f class.yaml
kubectl apply -f class.yaml
此时我环境中还有一个sc2是动态添加的pv
删除这个pod
可以看到这个pv也被跟着删除了
进入nfs服务器 ,发现他持久化的目录还在,加了default前缀归档,,即他状态虽然为delete,在删除pod后pv也会被删除,但在class.yaml中加入了启用归档的配置后,虽然pv会被删除,但在nfs服务器中不会删除这个目录,而会归档
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐