存储之PV与PVC

一.概述

PersistentVolume子系统为用户和管理员提供的一组API,将存储如何供应的细节从其如何被使用中抽象出来,为了实现这一点,引入了两个新的API资源
  • 持久卷(PersistentVolume,PV):集群中的一块存储,可以由管理员事先供应,或者使用存储类(storage class)来动态供应,持久卷是集群资源,就像节点也是集群资源一样。
    • PV持久卷和普通Volume一样,也是使用卷插件来实现的,只是他们拥有独立于任何使用PV的Pod的生命周期
    • 对存储资源创建和使用的抽象,使得存储作为集中的资源进行管理

 

  • 持久卷的申领(PersistentVolumeClaim,PVC):表达的是用户对存储的请求。概念上与Pod类似。用户无需关心具体的volume实现细节
    • Pod会耗用节点资源,而PVC申领会耗用PV资源
    • Pod可以请求特定数量的资源(CPU、内存),同样PVC申领也可以请求特定大小和访问模式     

二.静态PV/PVC的创建和使用

创建PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: game-pv                   
  namespace: volume       # 指定默认在default命名空间  
spec:
  capacity:
    storage: 5Gi          # 此处的5Gi并不是真正只能使用5Gi,而是为了创建pvc是能匹配到这块pv
  accessModes:
  - ReadWriteMany          
  nfs:
    path: /ifs/kubernetes/game-pv
    server: 192.168.11.130
# 查案pv状态  
[root@k8s-master volume]# kubectl get pv  -n volume 
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
game-pv   5Gi        RWX            Retain           Available                                   3s

# 查看pv的详细状态
[root@k8s-master volume]# kubectl describe pv game-pv 
Name:            game-pv
Labels:          <none>
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    
Status:          Available
Claim:           
Reclaim Policy:  Retain
Access Modes:    RWX
VolumeMode:      Filesystem
Capacity:        5Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    192.168.11.130
    Path:      /ifs/kubernetes/game-pv
    ReadOnly:  false
Events:        <none>

创建pvc 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wot-pvc
  namespace: volume
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5Gi           # 如果集群中刚好有5Gi的一块pv,则绑定这块 如果刚好没有,但是有8Gi和10Gi的两块pv,则匹配到8Gi这块(向上接近),而不会匹配给10Gi,如果都没有,则会一直处于pending状态  
# 查看pvc状态
[root@k8s-master volume]# kubectl get pvc -n volume 
NAME      STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
wot-pvc   Bound    game-pv   5Gi        RWX                           10s

# 查看pvc的详细状态
[root@k8s-master volume]# kubectl describe pvc wot-pvc -n volume
Name:          wot-pvc
Namespace:     volume
StorageClass:  
Status:        Bound
Volume:        game-pv
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      5Gi
Access Modes:  RWX
VolumeMode:    Filesystem
Mounted By:    <none>
Events:        <none>

# 此时查看pv,显示已经绑定到刚才创建的pvc了
[root@k8s-master volume]# kubectl get pv  -n volume 
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
game-pv   5Gi        RWX            Retain           Bound    volume/wot-pvc                           6m7s

应用程序使用pvc

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: volume
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: www
 
  volumes:
  - name: www
    persistentVolumeClaim:
      claimName: wot-pvc          # pvc的name

三.访问模式

AccessModes是用来对PV进行访问模式的设置,用于描述应用程序对存储资源的访问权限,包括以下几种模式:
  • ReadWriteOnce(RWO):读写权限,但只能被单个节点挂载 应用场景:mysql的数据目录持久化
  • ReadOnlyMany(ROX):只读权限,可以被多个节点挂载 应用场景:多个应用程序共享配置文件
  • ReadWriteMany(RWX):读写权限,可以被多个节点挂载 应用场景:日志目录

四.回收策略

当PVC被删除时,对物理磁盘上的数据的处理策略。目前PV支持三种策略
  • Retain(保留):默认策略 表示删除PVC的时候,PV不会一起删除,而是变成Released状态等待管理员手动清理;
  • Recycle(回收):表示删除PVC的时候,清除PV中的数据,效果相当于rm -rf /ifs/kubernetes/* 与PVC解绑,Status重新变为Available
  • Delete(删除):与PV相连的后端存储同时删除

目前,仅 NFS 和 HostPath 支持回收(Recycle)。 AWS EBS、GCE PD、Azure Disk 和 Cinder 卷都支持删除(Delete)。

Delete的优缺点:
  • 优点:实现数据卷的全生命周期管理,应用删除PVC会自动删除后端云盘。能有效避免出现大量闲置云盘没有删除的情况
  • 缺点:删除PVC时候一起把后端云盘一起删除,如果不小心误删pvc,会出现后端数据丢失;

Retain的优缺点:

  • 优点:后端云盘需要手动清理,所以出现误删的可能性小
  • 缺点:没有实现数据卷生命周期管理,常常会造成pvc、pv删除后,后端云盘闲置未清理,长此以往导致大量磁盘浪费

[root@k8s-master ~]# kubectl get pv
NAME    CAPACITY   ACCESSMODES   RECLAIM POLICY    STATUS    CLAIM    STORAGECLASS    REASON    AGE
game-pv  5Gi      RWX         Recycle         Available                         58s

 

不过需要注意的是,目前只有 NFS 和 HostPath 两种类型支持回收策略。当然一般来说还是设置为 Retain 这种策略保险一点。

四.状态

一个 PV 的生命周期中,可能会处于4中不同的阶段:
  • Available(可用):表示可用状态,还未被任何 PVC 绑定
  • Bound(已绑定):表示 PV 已经被 PVC 绑定
  • Released(已释放):PVC 被删除,但是资源还未被集群重新声明
  • Failed(失败): 表示该 PV 的自动回收失败

 

 如果有海量项目,pv维护成本增高,所以引入storage class对象动态供给 

五.动态供给(StorageClass)

动态卷供给允许按需创建存储卷。如果没有动态供给,集群管理员必须手动联系他们的存储提供商来创建新的存储卷,然后在kubernetes集群创建PersistentVolume对象来表示这些卷。

动态供给功能消除了集群管理员预先配置存储的需要。相反,他在用户请求时自动供给存储

动态供给的实现基于storage.k8s.ioAPI组中的StorageClass对象。
集群管理员可以根据需求定义多个
storageClass对象,每个对象指定一个卷插件(又名provisioner),卷插件向卷供应商提供在创建卷时需要的数据卷信息级相关参数

每个StorageClass都有一个卷插件(Provisioner),用来决定使用哪个卷插件创建PV,该字段必须指定
支持动态供给的卷插件: https://kubernetes.io/zh/docs/concepts/storage/storage-classes/

git
hub上提供了外部制备器的插件:https://github.com/kubernetes-retired/external-storage

六.基于NFS卷插件实现动态供给

部署NFS实现自动创建PV插件:
git clone https://github.com/kubernetes-incubator/external-storage    
cd nfs-client/deploy
kubectl apply -f rbac.yaml # 授权访问apiserver
kubectl apply -f deployment.yaml # 部署插件,需修改里面NFS服务器地址与共享目录
kubectl apply -f class.yaml # 创建存储类

创建PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: storageclass-pvc
  namespace: volume
spec:
  storageClassName: "managed-nfs-storage"   # 声明存储类 
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 20Gi
查看存储类
[root@k8s-master volume]# kubectl get storageclass 
NAME                  PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   fuseim.pri/ifs   Delete          Immediate           false                  33m

# pvc中storageClassName就是这个NAME

# 查看pv和pvc
[root@k8s-master volume]# kubectl get pv 
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                     STORAGECLASS          REASON   AGE                                                           22h
pvc-176eb69c-546b-4de6-9e4a-fc3ac6ab0a02   20Gi       RWX            Delete           Bound       volume/storageclass-pvc   managed-nfs-storage            3m49s
# 回收策略是Delete,此策略由class.yaml的archiveOnDelete: "true"定义的 ,true表示删除PVC时,归档pvc后面的物理存储(集群中已删除,实际存储卷上绑我们改名归档了)

[root@k8s
-master volume]# kubectl get pvc -n volume NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE storageclass-pvc Bound pvc-176eb69c-546b-4de6-9e4a-fc3ac6ab0a02 20Gi RWX managed-nfs-storage 4m11s

应用程序使用pvc

apiVersion: v1
kind: Pod
metadata:
  name: nginx-storageclass
  namespace: volume
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: rootdir
 
  volumes:
  - name: rootdir
    persistentVolumeClaim:
      claimName: storageclass-pvc
posted @ 2020-12-16 17:38  碎梦重拾  阅读(694)  评论(0编辑  收藏  举报