Kubernetes高级对象PersistentVolume、PersistentVolumeClaim、StorageClass

PersistentVolume

Pod 里的容器是由镜像产生的,而镜像文件本身是只读的,进程要读写磁盘只能用一个临时的存储空间,一旦 Pod 销毁,临时存储也就会立即回收释放,数据也就丢失了。

为了保证即使 Pod 销毁后重建数据依然存在,就需要找出一个解决方案,让 Pod 用上真正的“虚拟盘”

Kubernetes 就顺着 Volume 的概念,延伸出了 PersistentVolume 对象,它专门用来表示持久存储设备,但隐藏了存储的底层实现,我们只需要知道它能安全可靠地保管数据就可以了(由于 PersistentVolume 这个词很长,一般都把它简称为 PV)。

作为存储的抽象,PV 实际上就是一些存储设备、文件系统,比如 Ceph、GlusterFS、NFS,甚至是本地磁盘,管理它们已经超出了 Kubernetes 的能力范围,所以,一般会由系统管理员单独维护,然后再在 Kubernetes 里创建对应的 PV。要注意的是,PV 属于集群的系统资源,是和 Node 平级的一种对象,Pod 对它没有管理权,只有使用权。

PersistentVolumeClaim/StorageClass

PersistentVolumeClaim,简称 PVC,就是用来向 Kubernetes 申请存储资源的。PVC 是给 Pod 使用的对象,它相当于是 Pod 的代理,代表 Pod 向系统申请 PV。一旦资源申请成功,Kubernetes 就会把 PV 和 PVC 关联在一起,这个动作叫做“绑定”(bind)。

但是,系统里的存储资源非常多,如果要 PVC 去直接遍历查找合适的 PV 也很麻烦,所以就要用到 StorageClass。

StorageClass 的作用有点像 IngressClass,它抽象了特定类型的存储系统(比如 Ceph、NFS),在 PVC 和 PV 之间充当“协调人”的角色,帮助 PVC 找到合适的 PV。也就是说它可以简化 Pod 挂载“虚拟盘”的过程,让 Pod 看不到 PV 的实现细节。

在这里插入图片描述

YAML 描述 PersistentVolume

Kubernetes 里有很多种类型的 PV,我们先看看最容易的本机存储“HostPath”,它和 Docker 里挂载本地目录的 -v 参数非常类似

因为 Pod 会在集群的任意节点上运行,首先在每个节点上创建一个目录,它将会作为本地存储卷挂载到 Pod 里。

在 /tmp 里建立名字是 host-10m-pv 的目录,表示一个只有 10MB 容量的存储设备。

kubectl create 不能直接创建 PV 对象,只能用 kubectl api-resources、kubectl explain 查看 PV 的字段说明,手动编写 PV 的 YAML 描述文件。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: host-10m-pv

spec:
  storageClassName: host-test
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Mi
  hostPath:
    path: /tmp/host-10m-pv/
  • storageClassName”就是刚才说过的,对存储类型的抽象 StorageClass。这个 PV 是手动管理的,名字可以任意起,这里的是 host-test,也可以把它改成 manual、hand-work 之类的词汇。

  • accessModes”定义了存储设备的访问模式,简单来说就是虚拟盘的读写权限,和 Linux 的文件访问模式差不多,目前 Kubernetes 里有 3 种:

  •   ReadWriteOnce:存储卷可读可写,但只能被一个节点上的 Pod 挂载。
    
  •   ReadOnlyMany:存储卷只读不可写,可以被任意节点上的 Pod 多次挂载。
    
  •   ReadWriteMany:存储卷可读可写,也可以被任意节点上的 Pod 多次挂载。
    

    注意,这 3 种访问模式限制的对象是节点而不是 Pod,因为存储是系统级别的概念,不属于 Pod 里的进程。
    显然,本地目录只能是在本机使用,所以这个 PV 使用了 ReadWriteOnce

  • capacity”就很好理解了,表示存储设备的容量,这里我设置为 10MB。
    Kubernetes 里定义存储容量使用的是国际标准,我们日常习惯使用的 KB/MB/GB 的基数是 1024,要写成 Ki/Mi/Gi,一定要小心不要写错了,否则单位不一致实际容量就会对不上。

  • hostPath”,它指定了存储卷的本地路径,也就是我们在节点上创建的目录。

YAML 描述 PersistentVolumeClaim

有了 PV,就表示集群里有了这么一个持久化存储可以供 Pod 使用,我们需要再定义 PVC 对象,向 Kubernetes 申请存储。
PVC,要求使用一个 5MB 的存储设备,访问模式是 ReadWriteOnce:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: host-5m-pvc

spec:
  storageClassName: host-test
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Mi

PVC 的内容与 PV 很像,但它不表示实际的存储,而是一个“申请”或者“声明”,spec 里的字段描述的是对存储的“期望状态”。

PVC 里的 storageClassName、accessModes 和 PV 是一样的,但不会有字段 capacity,而是要用 resources.request 表示希望要有多大的容量。Kubernetes 就会根据 PVC 里的描述,去找能够匹配 StorageClass 和容量的 PV,然后把 PV 和 PVC“绑定”在一起,实现存储的分配。

PersistentVolume的使用

执行命令:

#创建目录
sudo mkdir -p /tmp/host-10m-pv/
sudo chmod 777 /tmp/host-10m-pv/
# 编辑pv文件
vim host-pv.yml
#应用pv
kubectl apply -f host-pv.yml 
# 查看pv
kubectl get pv


在这里插入图片描述
PV 的容量是 10MB,访问模式是 RWO(ReadWriteOnce),StorageClass 是我们自己定义的 host-test,状态显示的是 Available,也就是处于可用状态,可以随时分配给 Pod 使用。

PersistentVolumeClaim的使用

执行命令

vim host-pvc.yml
cat host-pvc.yml
kubectl apply -f host-pvc.yml
kubectl get pvc
kubectl get pv

在这里插入图片描述
在这里插入图片描述
一旦 PVC 对象创建成功,Kubernetes 就会立即通过 StorageClass、resources 等条件在集群里查找符合要求的 PV,如果找到合适的存储对象就会把它俩“绑定”在一起。

PVC 对象申请的是 5MB,但现在系统里只有一个 10MB 的 PV,没有更合适的对象,所以 Kubernetes 也只能把这个 PV 分配出去,多出的容量就算是“福利”了。

这两个对象的状态都是 Bound,也就是说存储申请成功,PVC 的实际容量就是 PV 的容量 10MB,而不是最初申请的容量 5MB。

Pod 挂载 PersistentVolume

PV 和 PVC 绑定好了,有了持久化存储,就可以为 Pod 挂载存储卷。先要在 spec.volumes 定义存储卷,然后在 containers.volumeMounts 挂载进容器。

PVC要在 volumes 里用字段 persistentVolumeClaim 指定 PVC 的名字。

Pod 的 YAML 描述文件,把存储卷挂载到了 Nginx 容器的 /tmp 目录:

apiVersion: v1
kind: Pod
metadata:
  name: host-pvc-pod

spec:
  volumes:
  - name: host-pvc-vol
    persistentVolumeClaim:
      claimName: host-5m-pvc

  containers:
    - name: ngx-pvc-pod
      image: nginx:alpine
      ports:
      - containerPort: 80
      volumeMounts:
      - name: host-pvc-vol
        mountPath: /tmp

Pod 和 PVC/PV 关系图
在这里插入图片描述
执行命令:

vim host-pvc-nginx.yml
kubectl apply -f host-pvc-nginx.yml
kubectl get pod -o wide

在这里插入图片描述
它被 Kubernetes 调到了 worker 节点上用 kubectl exec 进入容器,执行一些命令看看PV 是否确实挂载成功:

kubectl exec -it host-pvc-pod -- sh
cd /tmp
echo aaa->a.txt

在这里插入图片描述
登录work节点,查看/tmp/host-10m-pv/目录下是否有对应文件

cat /tmp/host-10m-pv/a.txt 

在这里插入图片描述
Pod 产生的数据已经通过 PV 存在了磁盘上,所以如果 Pod 删除后再重新创建,挂载存储卷时会依然使用这个目录,数据保持不变,也就实现了持久化存储。

注意:
PV 是 HostPath 类型,只在本节点存储,如果 Pod 重建时被调度到了其他节点上,那么即使加载了本地目录,也不会是之前的存储位置,持久化功能也就失效了。

所以,HostPath 类型的 PV 一般用来做测试,或者是用于 DaemonSet 这样与节点关系比较密切的应用

  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值