【Kubernetes】持久卷的动态供给 Dynamic Provisioning

持久化存储》系列,共包含以下文章:

😊 如果您觉得这篇文章有用 ✔️ 的话,请给博主一个一键三连 🚀🚀🚀 吧 (点赞 🧡、关注 💛、收藏 💚)!!!您的支持 💖💖💖 将激励 🔥 博主输出更多优质内容!!!

Kubernetes 提供了一套可以自动创建 PV 的机制,即 Dynamic Provisioning。而这个机制的核心在于 StorageClass 这个 API 对象。

StorageClass 对象会定义下面两部分内容:

  • PV 的属性。比如,存储类型、Volume 的大小等。
  • 创建这种 PV 需要用到的存储插件。

有了这两个信息之后,Kubernetes 就能够根据用户提交的 PVC,找到一个对应的 StorageClass,之后 Kubernetes 就会调用该 StorageClass 声明的存储插件,进而创建出需要的 PV。

🚀 但是其实使用起来是一件很简单的事情,你只需要根据自己的需求,编写 YAML 文件即可,然后使用 kubectl create 命令执行即可。

在一个大规模的 Kubernetes 集群里,可能有成千上万个 持久卷声明PVC),这就意味着运维人员必须实现创建出这个多个 持久卷PV)。此外,随着项目的需要,会有新的 PVC 不断被提交,那么运维人员就需要不断的添加新的、满足要求的 PV,否则新的 Pod 就会因为 PVC 绑定不到 PV 而导致创建失败。而且通过 PVC 请求到一定的存储空间也很有可能不足以满足应用对于存储设备的各种需求。

而且不同的应用程序对于存储性能的要求可能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes 又为我们引入了一个新的资源对象:StorageClass

通过 StorageClass 的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据 StorageClass 的描述就可以非常直观的知道各种存储资源的具体特性了,这样就可以根据应用的特性去申请合适的存储资源了。

PV 对象和 PVC 对象可以通过 存储类 storageClass 实现自动的匹配和绑定。因此,存储类 storageClass 可以实现 PV 资源的动态供给,它是 PV 资源分配的一种策略。

基于存储类 storageClasss 实现持久卷的动态供给的过程如下图所示。
在这里插入图片描述

下面来演示如何实现持久卷的动态供给。

1.搭建 NFS 服务

apt install -y nfs-kernel-server
mkdir /nfs
echo "/nfs *(rw,sync,no_root_squash)" > /etc/exports
systemctl restart nfs-kernel-server
systemctl status nfs-server

在这里插入图片描述

🌞 更多详情可参考我的这篇博客《Ubuntu 安装 NFS 步骤详解》。

2.创建 RBAC 权限

vim nfs-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f nfs-rbac.yaml

在这里插入图片描述

3.部署 NFS Provisioner

要使用 StorageClass,我们就得安装对应的 自动配置程序,比如我们这里存储后端使用的是 NFS,那么我们就需要使用到一个 nfs-client-provisioner 的自动配置程序,我们也叫它 Provisioner,这个程序使用我们已经配置好的 NFS 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。

在这里插入图片描述
nfs-client-provisioner 是一个 Kubernetes 的简易 NFS 的外部 Provisioner,本身不提供 NFS,需要现有的 NFS 服务器提供存储。

在这里插入图片描述

🚀 注意:地址和目录要改成实际的 NFS 服务对应配置。

vim nfs-provisioner-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 172.30.1.2  
            - name: NFS_PATH
              value: /nfs
      volumes:
        - name: nfs-client-root
          nfs:
            server: 172.30.1.2
            path: /nfs
  • 存储类 StorageClass 需要使用 provisioner(制备器)字段来决定使用哪个卷插件来创建 PV。制备器字段必须指定。nfs-provisioner-deploy.yaml 文件通过创建制备器来提供基于 NFS 的 PV 存储方式。
  • 这里使用 k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 镜像作为 NFS Server 的客户端程序来访问 NFS。
kubectl apply -f nfs-provisioner-deploy.yaml 
kubectl get pods

在这里插入图片描述

4.创建 StorageClass

vim storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-provisioner-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
  archiveOnDelete: "false"
  pathPattern: "${.PVC.namespace}/${.PVC.name}"
  • metadata.name:PVC 申请时需明确指定的 storageclass 名称。
  • provisioner:制备器名称,必须和上面创建的 PROVISIONER_NAME 保持一致。
  • parameters.archiveOnDelete:如果值为 false,删除 PVC 后也会删除目录内容;值为 true 则会对数据进行保留。
  • parameters.pathPattern:创建目录路径的模板,默认为随机命名。
kubectl apply -f storageclass.yaml

查看创建的存储类 storageClass。

kubectl get storageclass

🚀 该命令可以简写成以下形式:kubectl get sc

输出的信息如下:

在这里插入图片描述

5.创建 PVC,自动关联 PV

编辑 nfs-pvc-test.yaml 文件创建测试的 PVC 对象,以检测存储类 storageClass 能否正常工作。

vim nfs-pvc-test.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc-test
spec:
  storageClassName: "nfs-provisioner-storage"
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 0.5Gi
kubectl apply -f nfs-pvc-test.yaml

查看 Deploy、Pod、SC 和 PVC 的信息。

kubectl get deploy,pod,sc,pvc

在这里插入图片描述

🚀 可以看到,PVC 已经绑定成功。

kubectl describe pv pvc-6f1a4f2d-5db9-4c08-bed7-9ce84e2472b6

在这里插入图片描述

6.创建 Pod,测试数据是否持久

编辑 nginx-pvc-test.yaml 文件创建 Pod 来使用 PVC 资源。

vim nginx-pvc-test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-sc
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: nginx-page
      mountPath: /usr/share/nginx/html
  volumes:
  - name: nginx-page
    persistentVolumeClaim:
      claimName: nfs-pvc-test
kubectl apply -f nginx-pvc-test.yaml 

查看 Deploy、Pod、SC 和 PVC 的信息。

kubectl get deploy,pod,sc,pvc

在这里插入图片描述

在 master 节点 NFS Server 的共享目录 /nfs/default/nfs-pvc-test 下,创建数据文件 data.txt

echo hello world > /nfs/default/nfs-pvc-test/data.txt

🚀 由于 Kubernetes 实现了持久卷的动态供给,并将 NFS 作为存储的方式,因此,即使没有指定存储路径,也会在 NFS Server上自动为 PVC 创建存储的目录。

进入 Pod 中观察是否能够访问新创建的文件。

kubectl exec -it pod/nginx-sc sh

输出的信息如下:

在这里插入图片描述

7.总结

在 Kubernetes 中,动态供给 是一种自动化机制,用于根据 Persistent Volume ClaimPVC)的需求自动创建 Persistent VolumePV)。这一机制极大地简化了存储资源的管理和分配流程,使得用户无需手动预置 PV,而是通过声明式的 PVC 请求来自动获得存储资源。

动态供给的核心组件是 StorageClass,它是 Kubernetes 中定义存储类别的对象,包含了存诸供应策略的信息,例如存储类型、参数以及是否支持读写一次或读写多次等。当用户创建 PVC 并指定一个 StorageClass 时,Kubernetes 会根据这个 StorageClass 自动创建并绑定 PV 到 PVC 上。

StorageClass 包含以下关键属性:

  • Provisioner:指定用于创建 PV 的插件或驱动程序,例如 kubernetes.io/aws-ebs 表示使用 AWS EBS 存储。
  • Parameters:提供给 provisioner 的参数,用于配置存储的具体特性,如存储类型、IOPS 等。
  • ReclaimPolicy:定义了当 PVC 被删除时,PV 应该如何被回收,常见的策略有 DeleteRetain
  • VolumeBindingMode:控制 PV 何时与 PVC 绑定,例如 Immediate 表示立即绑定, WaitForFirstConsumer 表示等待第一个消费者(即 PVC)出现时才绑定。
  • AllowVolumeExpansion:指示是否允许 PVC 扩容。

管理员可以创建多个 StorageClass 对象,每个对象代表不同类型的存储资源,如高性能 SSD、标准硬盘或网络存储等。用户在创建 PVC 时可以选择特定的 StorageClass,从而根据需求自动获得相应类型的存储资源。

动态供给的工作流程 如下:

  • 1️⃣ 创建 StorageClass:管理员预先定义一个或多个 StorageClass,每个 StorageClass 描述了不同的存储类型和配置选项。
  • 2️⃣ 创建 PVC:用户创建 PVC 并指定所需的存储量和访问模式,同时关联一个 StorageClass。
  • 3️⃣ 自动创建 PV:Kubernetes 根据 PVC 中指定的 StorageClass 动态创建 PV。这通常涉及到与外部存储系统的交互,如云存储服务、网络文件系统(NFS)或其他存储阵列。
  • 4️⃣ PV 绑定到 PVC:一旦 PV 创建完成,它会被自动绑定到 PVC 上,使 PVC 的状态变为 Bound
  • 5️⃣ Pod 使用 PVC:Pod 可以通过引用 PVC 来使用存储资源,而不需要关心底层 PV 的具体细节。

动态供给的好处包括:

  • 自动化:减少了手动预置 PV 的工作量,提高了存储资源的分配效率。
  • 灵活性:可以根据不同的应用需求快速调整存储资源,提高资源利用率
  • 标准化:通过 StorageClass 标准化了存储供应策略,便于管理和维护。

总之,动态供给 是 Kubernetes 中处理存储资源自动化分配的重要机制,它简化了存储管理,提高了存储资源的灵活性和响应速度。


参考:《Kubernetes 数据持久化 StorageClass 动态供给

  • 14
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

G皮T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值