Kubernetes那点事儿——持久卷PVC/PV

持久卷PVC/PV

  • 前言
  • 一、PV/PVC
  • 二、PV动态供给(StorageClass)
  • 三、PV 生命周期


前言

前面我们了解了K8s中各种存储卷及其特点,PV/PVC也是存储卷的一种,PV/PVC主要解决提高安全问题和组织结构分工问题。

一、PV/PVC

为了解决提高安全问题和组织结构分工问题,k8s引入pvc和pv

  • PersistentVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
  • PersistentVolumeClaim(PVC):让用户不需要关心具体的Volume实现细节

示例:

# cat nfs-pvc示例.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-pvc
spec:
  selector:
    matchLabels:
      app: nginx-nfs-pvc
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx-nfs-pvc
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
        - name: wwwroot
          persistentVolumeClaim:
            claimName: my-pvc

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
   - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

该yaml文件分为两部分,第一部分为deployment(具体运行业务的pod),第二部分为PersistentVolumeClaim(开发人员申请的PVC)

# kubectl describe web-pvc-7f646ddbdb-hbrlh
Events:
  Type     Reason            Age   From  Message
  ----     ------            ----  ----  -------
  Warning  FailedScheduling  59s         0/3 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims.
  Warning  FailedScheduling  59s         0/3 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims.
  
# kubectl get pvc
NAME     STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc   Pending

生成出来pod为Pending状态,报错是没有绑定pvc,查看pvc为Pending状态可知,还没有pv去给pvc提供可用存储空间。

# cat pv示例.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteMany
  nfs:
    path: /ifs/nfsdir
    server: 10.7.7.222
# kubectl  get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
my-pv   5Gi        RWX            Retain           Bound    default/my-pvc                           8s
# kubectl  get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc   Bound    my-pv    5Gi        RWX                           126m

创建完成pv之后发现pv为Bound状态,pvc从Pending变成Bound状态,此时pod也从Pending状态变为running状态。

此时pv与pvc是一一对应的。每个pvc对应一个pv,pvc有开发人员提供,pv由运维人员维护。

pv与pvc的匹配条件:

  1. 存储空间。pvc会根据定义的存储容量去匹配pv(大于pvc且最接近pvc的pv)
  2. 访问模式

存储容量限制:

  1. 存储空间字段只是一个匹配标记,没有限制。具体限制取决于存储本身(nfs、ceph)
  2. 是否可以自动设置存储容量,这取决于存储技术本身是否支持(k8s逐步对部分存储自动限制的支持)

二、PV动态供给(StorageClass)

PV静态供给明显的缺点是维护成本太高了!
因此,K8s开始支持PV动态供给,使用StorageClass对象实现(StorageClass帮助我们自动创建pv)

# ls -l
total 12
-rw-r--r-- 1 root root  225 Oct 30  2020 class.yaml     # 创建存储类(StorageClass)
-rw-r--r-- 1 root root  994 Oct 30  2020 deployment.yaml   # 部署nfs插件,需修改里面NFS服务器地址与共享目录
-rw-r--r-- 1 root root 1526 Oct 30  2020 rbac.yaml       # 授权访问apiserver

修改nfs插件deployment,需要修改部分(25、33、35、39、40)

 22       serviceAccountName: nfs-client-provisioner
 23       containers:
 24         - name: nfs-client-provisioner
 25           image: nfs-client-provisioner:latest
 26           volumeMounts:
 27             - name: nfs-client-root
 28               mountPath: /persistentvolumes
 29           env:
 30             - name: PROVISIONER_NAME
 31               value: fuseim.pri/ifs
 32             - name: NFS_SERVER
 33               value: 10.7.7.222
 34             - name: NFS_PATH
 35               value: /ifs/nfsdir
 36       volumes:
 37         - name: nfs-client-root
 38           nfs:
 39             server: 10.7.7.222
 40             path: /ifs/nfsdir

class.yaml文件

# cat class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage # 创建pvc时需要指定这个name
provisioner: fuseim.pri/ifs # 接口fuseim.pri/ifs,与插件deployment中"env.name (PROVISIONER_NAME)"保持一致,无需改动
parameters:
  archiveOnDelete: "true" # 是否归档,true为删除pv并备份nfs-server储存的文件

自动pv供给示例

# cat autopv示例.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-autopvc
spec:
  selector:
    matchLabels:
      app: nginx-nfs-autopvc
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx-nfs-autopvc
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
        - name: wwwroot
          persistentVolumeClaim:
            claimName: my-autopvc

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-autopvc
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
   - ReadWriteMany
  resources:
    requests:
      storage: 30Gi

# kubectl get pods |grep auto
web-autopvc-dd9f7bc78-bwq46               1/1     Running             0          42s
web-autopvc-dd9f7bc78-vdjqm               1/1     Running             0          42s
# kubectl get pvc
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
my-autopvc   Bound    pvc-b5b27e9a-8741-497f-a1a0-cda57de73421   30Gi       RWX            managed-nfs-storage   46s
my-pvc       Bound    my-pv                                      5Gi        RWX                                  178m
# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS          REASON   AGE
my-pv                                      5Gi        RWX            Retain           Bound    default/my-pvc                                      52m
pvc-b5b27e9a-8741-497f-a1a0-cda57de73421   30Gi       RWX            Delete           Bound    default/my-autopvc   managed-nfs-storage            50s

在nfs-server机器查看nfs目录,可知自动创建一个目录对应pv
ls -l /ifs/nfsdir/
total 4
drwxrwxrwx 2 root root  6 Feb 14 21:16 default-my-autopvc-pvc-b5b27e9a-8741-497f-a1a0-cda57de73421
-rw-r--r-- 1 root root 20 Feb 14 17:53 index.html

总结:
唯一与手动创建pv不同的时,这里pvc申请pv需要指定存储类名称storageClassName: “managed-nfs-storage”
存储类用调用nfs-client-pod(nfs存储插件)去创建pv,自动创建出来的pv为Delete回收策略。
部分存储插件已经内置k8s:https://kubernetes.io/zh/docs/concepts/storage/storage-classes
如果没有内置k8s中,可使用外部插件:https://github.com/kubernetes-retired/external-storage
当删除pvc时,pv会直接删除(回收策略),nfs-server使用的存储目录会备份一份(class.yaml中定义的归档)

三、PV 生命周期

AccessModes(访问模式)

AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:

  • ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
  • ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
  • ReadWriteMany(RWX):读写权限,可以被多个节点挂载

RECLAIM POLICY(回收策略)

目前 PV 支持的策略有三种:

  • Retain(保留): 保留数据,需要管理员手工清理数据
  • Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/nfsdir/*
  • Delete(删除):与 PV 相连的后端存储同时删除

STATUS(状态)

一个 PV 的生命周期中,可能会处于4中不同的阶段:

  • Available(可用):表示可用状态,还未被任何 PVC 绑定
  • Bound(已绑定):表示 PV 已经被 PVC 绑定
  • Released(已释放):PVC 被删除,但是资源还未被集群重新声明
  • Failed(失败): 表示该 PV 的自动回收失败

你可能感兴趣的:(Kubernetes,kubernetes,容器,云原生)