Kubernetes PV与PVC

一、PV和PVC

PV的全称是: PersistentVolume (持久化卷),是对底层的共享存储的一种抽象,PV由管理员进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如Ceph、GlusterFS、NFS等,都是通过插件机制完成与共享存储的对接

PVC的全称是: PersistenVolumeClaim (持久化卷声明),PVC是用户存储的一种声明,PVC和Pod比较类型,Pod是消耗节点,PVC消耗的是PV资源,Pod可以请求CPU的内存,而PVC可以请求特定的存储空间和访问模式。对于真正存储的用户不需要关心底层的存储实现细节,只需要直接使用PVC即可

二、PV和PVC的生命周期

PV可以看作可用的存储资源,PVC则是对存储资源的需求,PV和PVC的互相关系遵循如下图

在这里插入图片描述

2.1 资源供应 (Provisioning)

Kubernetes支持两种资源的供应模式:静态模式(Staic)和动态模式(Dynamic)。资源供应的结果就是创建好的PV。

  • 静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置
  • 动态模式:集群管理员无须手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种 “类型(Class)”。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及PVC的绑定。PVC可以声明Class为””,说明该PVC禁止使用动态模式

2.2 资源绑定 (Binding)

在用户定义好PVC后,系统将根据PVC对存储资源的请求 (存储空间和访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将该PV与用户定义的PVC进行绑定,然后用户的应用就可以使用这个PVC了。如果系统中没有满足PVC要求的PV,PVC则会无限期处于Pending状态,直到等到系统管理员创建了一个符合要求的PV。PV一旦绑定在某个PVC上,就被这个PVC独占,不能再与其他PVC进行绑定了。在这种情况下,当PVC申请的存储空间比PV的少时,整个PV的空间都能够为PVC所用,可能会造成资源的浪费。如果资源供应使用的是动态模式,则系统在PVC找到合适的StorageClass后,将会自动创建PV并完成PVC的绑定

2.3 资源使用 (Using)

Pod 使用volume的定义,将PVC挂载到容器内的某个路径进行使用。volume的类型为persistentVoulumeClaim,在容器应用挂载了一个PVC后,就能被持续独占使用。不过,多个Pod可以挂载同一个PVC,应用程序需要考虑多个实例共同访问一块存储空间的问题

2.4 资源释放 (Releasing)

当用户对存储资源使用哪个完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为已释放,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还留在存储设备上,只有在清除之后该PV才能继续使用

2.5 资源回收 (Reclaiming)

对于PV,管理员可以设定回收策略(Reclaim Policy)用于设置与之绑定的PVC释放资源之后,对于遗留数据如何处理。只有PV的存储空间完成回收,才能供新的PVC绑定和使用。

静态资源下,通过PV和PVC完成绑定,并供Pod使用的存储管理机制
在这里插入图片描述

动态资源下,通过StorageClass和PVC完成资源动态绑定 (系统自动生成PV,并供Pod使用的存储管理机制)

三、使用NFS进行演示

3.1 首先我们需要安装NFS服务

# 安装nfs、rpcbind
yum install nfs-utils -y rpcbind
# 设置nfs存储目录
mkdir -p /data/k8s-volume
chmod 755 /data/k8s-volume/
# 编辑nfs配置文件
vim /etc/exports
# 存储目录,*允许所有人连接,rw读写权限,sync文件同时写入硬盘及内存,no_root_squash 使用者root用户自动修改为普通用户
/data/k8s-volume *(rw,no_root_squash,sync)
# 启动rpcbind
systemctl start rpcbind && systemctl enable rpcbind
# 启动NFS
systemctl restart nfs && systemctl enable nfs
# 查看nfs目录挂载权限
cat /var/lib/nfs/etab
/data/k8s-volume	*(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,no_root_squash,no_all_squash)

3.2 nfs server端安装完毕,然后所有需要nfs挂载的集群节点安装nfs

yum install -y nfs-utils rpcbind \
  && systemctl start rpcbind \
  && systemctl enable rpcbind \
  && systemctl start nfs \
  && systemctl enable nfs

3.3 客户端挂载测试

# 首先检查nfs挂载目录是否正常
[root@所有节点 ~]# showmount -e 192.168.1.40 # 服务端的IP
Export list for 192.168.1.40:
/data/k8s-volume *

# 现在进行节点挂载
# 先在客户端创建数据目录(挂载点位置)
[root@所有节点 ~]# mkdir -p /data/k8s/
#现在进行挂载 分别是ip:nfs目录 节点存储目录
[root@所有节点 ~]# mount -t nfs 192.168.1.40:/data/k8s-volume /data/k8s
#挂在完成后我们使用df -h 就可以看到挂载点
[root@所有节点 ~]# df -Th|grep /data/k8s-volume
文件系统                       类型  容量  已用 可用 已用% 挂载点
192.168.1.40:/data/k8s-volume nfs4  50G  5.0G 46G  10%  /data/k8s
#所有需要nfs节点这样挂载就可以

四、创建PV

有了我们NFS共享存储,下面就可以来使用PV和PVC。PV作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略等关键信息。这里使用nfs类型的后端存储,1g存储空间,访问模式为ReadWriteOnce,回收策略为Recyle,对应文件如下

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1         #pv名称
spec:
  capacity:         #存储能力,一个pv对象都要指定一个存储能力,目前仅支持存储空间的设置
    storage: 1Gi    #存储空间
  accessModes:
  - ReadWriteOnce   #访问模式
  persistentVolumeReclaimPolicy: Recycle     #回收策略
  nfs:              #服务模式 (nfs、ceph、hostpath等)
    path: /data/k8s-volume     #共享数据目录挂载点
    server: 192.168.1.40         #nfs服务器地址

创建pv

[root@harbor ~]# kubectl apply -f pv.yaml 
persistentvolume/pv1 created

查看pv

[root@harbor ~]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    1Gi        RWO            Recycle          Available                                   5s

参数解释

pv1 名称
1Gi 代表存储空间大小
RWO 访问模式(ReadWriteOnce缩写)
Recycle 回收策略
Available PV状态

PV相关配置说明

  1. Capacity 存储能力
  • 通过PV的capacity属性来设置存储空间,目前仅支持storage=数据大小,未来可能会加入IOPS、吞吐量等指标配置
  1. AccessModes 访问模式,AccessModes 是用来对PV进行访问模式的设置,用于描述用户应用对存储资源的访问权限
  • ReadWriteOnce (RWO) 读写权限,但是只能被单个节点挂载
  • ReadOnlyMany (ROX) 只读权限,可能被多个节点挂载
  • ReadWriteMany (RWX) 读写权限,可以被多个节点挂载
  1. persistentVolumeReclaimPolicy 回收策略
  • Retain (保留) 保留数据,需要管理员手动清理
  • Recycle (回收) 清除PV中的数据,效果相当于执行删除命令
  • Delete (删除) 与PV相连的后端存储完成volume的删除操作,常见于云服务商的存储服务

不过需要注意的是,目前只有NFS和HostPath两类支持回收策略,一般设置Retain比较保险

  1. 状态
  • Available (可用): 表示可用状态,还未被任何PVC绑定
  • Bound (已绑定):已经绑定到某个PVC
  • Released (已释放):对应的PVC已经删除,但资源还没有被集群收回
  • Failed:PV自动回收失败

五、创建PVC

#前面我们已经在集群上都安装nfs客户端,并且进行挂载了。下面进行创建pvc
[root@harbor ~]# kubectl get node
NAME    STATUS   ROLES                      AGE   VERSION
node1   Ready    controlplane,etcd,worker   42d   v1.17.5
node2   Ready    controlplane,etcd,worker   42d   v1.17.5
node3   Ready    controlplane,etcd,worker   42d   v1.17.5
node4   Ready    worker                     37d   v1.17.5
node5   Ready    worker                     37d   v1.17.5
node6   Ready    worker                     30d   v1.17.5

新建pvc同样需要建立一个数据卷声明

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-nfs
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

在Kubernetes中会自动帮我们查看pv状态为Available并且根据声明pvc容量storage的大小进行筛选匹配,同时还会根据AccessMode进行匹配。如果pvc匹配不到pv会一直处于pending状态。

[root@harbor ~]# kubectl apply -f pv.yaml 
persistentvolume/pv1 created

[root@harbor ~]# kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-nfs   Bound    pv1      1Gi        RWO                           71s

[root@harbor ~]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
pv1    1Gi        RWO            Recycle          Bound    default/pvc-nfs                           4m35s

# 这里我们可以看到,当我们创建pvc之后,pv的状态变成了Bound绑定状态,并且和pvc的状态相同。并且可以看到pvc已经绑定到名称为pv1的volume上,同时在pv上可以看到绑定到名称为pvc-nfs的pvc中

六、使用Labels匹配PV与PVC

pv与pvc中间还可以通过label标签进行匹配,配置如下

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv2
  labels:           #这里将pv设置一个labels
    app: nfs
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/k8s-volume
    server: 192.168.1.40
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2-nfs
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  selector:         ##pvc匹配标签为app=nfs的pv
    matchLabels:
      app: nfs

应用

[root@harbor ~]# kubectl apply -f pvc-pv.yaml 
persistentvolume/pv2 created
persistentvolumeclaim/pvc2-nfs created

注意:当我们申请pvc的容量大于pv的容量是无法进行绑定的。

七、Deployment引用pvc

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pv-nfs-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: pv-nfs-nginx
  template:
    metadata:
      labels:
        app: pv-nfs-nginx
    spec:
      containers:
      - name: pv-nfs-nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:           #挂载,首先添加需要挂载的目录
        - name: pv-nginx        #挂载点的名称
          mountPath: /usr/share/nginx/html   #挂载点的路径
      volumes:    #绑定
      - name: pv-nginx
        persistentVolumeClaim:    #将镜像中的nginx目录挂载到下面名称的pvc中
          claimName: pvc2-nfs   #pvc名称
---
apiVersion: v1
kind: Service
metadata:
  name: nfs-pvc
  labels:
    app: pv-nfs-nginx
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 32334
  selector:
    app: pv-nfs-nginx

接下来我们到nfs挂载点创建一个index.html

echo "I am tester" > /data/k8s/index.html

nginx可以显示该内容

注意:如果我们直接删除或者有pod在使用pv或者pvc是无法直接删除的,当我们使用Recycle模式时,删除所有pv和pvc后,数据也会进行删除。所以删除pv和pvc请谨慎操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章