k8s 持久化存储 PV 和 PVC 的简单使用

概述

Kubernetes 对于有状态的容器应用或者对数据需要持久化的应用,可以通过 hostPath 或者 emptyDir 的方式来持久化我们的数据,但是我们需要更加可靠的存储来保存应用的持久化数据。不过存储资源和 CPU 资源以及内存资源有很大不同,为了屏蔽底层的技术实现细节,让用户更加方便的使用,Kubernetes 便引入了 PVPVC 两个重要的资源对象来实现对存储的管理。

概念

PV (PersistentVolume) 是对底层网络共享存储的抽象,将共享存储定义为一种 “资源”。PV 一般由K8S的管理员所创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如 CephGlusterFSNFS 等,都是通过插件机制完成与共享存储的对接。

PVC (PersistentVolumeClaim) 是用户对存储资源的一个 “申请”。就像 Pod消费 Node 资源一样,PVC 能够消费 PV 的资源。Pod 可以请求节点的CPU和内存,而 PVC 可以请求特定的存储空间和访问模式。对于用户来说,不需要关心底层的存储实现细节,只需要直接使用 PVC 即可。

实战:基于NFS共享存储创建PV和PVC

示例:基于NFS存储来创建PV和PVC

本次共享存储资源选择本地自建的NFS,关于搭建NFS的教程参考之前写的博文:centos7搭建NFS服务

试验环境如下,注意所有k8s节点都要安装nfs,yum install -y nfs-tools

主机名hostname IP地址 说明
master 192.168.18.10 k8s主节点
node1 192.168.18.11 k8s的node1节点
node2 192.168.18.12 k8snode2节点
db 192.168.18.7 NFS服务器,共享目录/data/nfs/test-pv

PV

PV 作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略、后端存储类型等关键信息的设置。PV 是没有名称空间的隔离性的。下面来创建一个PV 资源对象:

apiVersion: v1
kind: PersistentVolume
metadata:
  name:  pv001
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs-slow
  nfs:
    path: /data/nfs/test-pv
    server: 192.168.18.7

上面yaml文件表明:创建了一个名字是pv001的PV,使用NFS类型的后端存储,声明5G的存储空间,访问模式是 ReadWriteMany ,回收策略为 Recyle。有了yaml文件后,直接创建即可。

# 创建pv
[root@master k8s-yaml]# kubectl create -f pv.yaml
# 查看pv
[root@master k8s-yaml]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   5Gi        RWX            Recycle          Available           nfs-slow                5s

PV的常用配置参数

1. 存储能力(Capacity)

一个 PV 对象一般都要指定一个存储能力,通过 PV 的 capacity 属性来设置的,比如这里的 storage: 5Gi,目前只支持对存储空间的设置,未来可能加入IOIPS、吞吐量等指标的设置。

2. 访问模式(Access Modes)

对 PV 进行访问模式的设置,用于描述用户的应用对存储资源的访问权限。分为三种:

  • ReadWriteOnce:读写权限,并且只能被单个 Node 挂载;
  • ReadOnlyMany:只读权限,允许被多个 Node 挂载;
  • ReadWriteMany:读写权限,允许被多个 Node 挂载

一些 PV 可能支持多种访问模式,但是在挂载的时候只能使用一种访问模式,多种访问模式是不会生效的。

3. 存储类别(Class)

PV 可以设定其存储的类别,通过 storageClassName 参数指定一个 StorageClass 资源对象的名称。具有特定类别的 PV 只能与请求了该类别的 PVC 进行绑定。未设定类别的 PV 则只能与不请求任何类别的 PVC 进行绑定。

4. 回收策略

回收策略是通过 persistentVolumeReclaimPolicy 参数进行设置,可选性如下:

  • Retain:保留,需要手动清理数据
  • Recycle:回收,清楚PV中的数据,相当于 rm -rf /thevolume/* 命令
  • Delete:删除,与 PV 相连的后端存储完成volume的删除操作,删除 PVC 后,PV也会被删掉。这一类的PV,需要支持删除功能,是动态存储的默认方式。

PV 的生命周期

一个 PV 在生命周期可能处于下面四个阶段之一:

  • Available:可用状态,还没有于某个PVC进行绑定
  • Bound:已跟某个PVC绑定
  • Released:绑定的PVC已经删除,资源已经释放,但是没有被集群回收
  • Failed:自动资源回收失败

上面创建了PV之后,由于还没有任何PVC跟PV绑定,所以PV的状态还是 Available

PVC

PVC 作为用户对存储资源的需求申请,主要包括存储空间请求、访问模式、PV选择条件和存储类别的信息的设置。如下,新建一个PVC,跟上面创建的PV进行绑定。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 3Gi
  storageClassName: nfs-slow

该PVC申请了与存储类别名称为 nfs-slow 的 PV 进行绑定,请求3G的存储容量,访问模式是 ReadWriteMany,创建该PVC:

[root@master k8s-yaml]# kubectl create -f pvc.yaml

# 查看default名称空间下的PVC
[root@master k8s-yaml]# kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim   Bound    pv001    5Gi        RWX            nfs-slow       6s

# 注意,PVC有名称空间的隔离性
[root@master k8s-yaml]# kubectl get pvc -n kube-system
No resources found in kube-system namespace.

# 查看PV状态
[root@master k8s-yaml]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
pv001   5Gi        RWX            Recycle          Bound    default/myclaim   nfs-slow                3h29m

可以看到,在PVC与PV进行绑定之后,PV的状态变成了 Bound。但是从上面也看出,我的 PVC 里面声明的容量是3G,而PV里面声明的容量是5G,结果创建出来的PVC容量却是5G,说明,PV的容量是多少,PVC的容量就是多少。

如果PVC里面设置的容量超过PV里面定义的容量,那么PVC是创建不成功的,会一直处于Pending状态。

使用PVC

上面创建了PV和PVC,接下来就可以使用它们了,使用下面nginx-pvc.yaml 进行测试:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-pvc
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.18.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: my-pvc-volume

      volumes:
      - name: my-pvc-volume
        persistentVolumeClaim:
          claimName: myclaim

然后在nfs的共享目录里面创建个html文件:

[root@db ]# cd /data/nfs/test-pv/
[root@db test-pv]# echo "hello k8s pvc" > index.html

创建Deployment

[root@master k8s-yaml]# kubectl create -f nginx-pvc.yaml 

查看Pod:

[root@master k8s-yaml]# kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
nginx-pvc-78c9859d7-94lxn   1/1     Running   0          38s   10.244.166.165   node1   <none>           <none>

访问Pod:

[root@master k8s-yaml]# curl 10.244.166.165
hello k8s pvc

可以看到,Pod内部的容器已经成功挂载nfs的后端存储。

参考资料

posted @ 2021-06-17 15:24  syushin  阅读(1663)  评论(0编辑  收藏  举报