Pod 动态分配存储空间实现持久化存储

devtools/2024/11/28 22:52:22/

配置 Pod 以使用 PersistentVolume 作为存储

​ 关于持久卷的介绍,可以看官方文档 https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/

​ 持久卷根据存储位置,可以使用本地存储和云存储,如果有云服务平台,可以动态使用配置云资源(如Google Cloud Platform (GCP) 、 AWS、Azure);使用的云提供商,需要使用相应的 provisioner 和参数,

provisioner: 指定存储插件(Provisioner),根据你实际环境调整。例如:

  • NFS 使用 nfs.csi.k8s.io
  • Ceph 使用 cephfs.csi.ceph.com
  • AWS 使用 kubernetes.io/aws-ebs

​ 云存储服务需要集群运行在云服务商提供的平台;如在 GCP 上运行 Kubernetes kubernetes.io/gce-pd;kubernetes.io/aws-ebs(适用于 AWS)或者 kubernetes.io/azure-disk(适用于 Azure),云存储服务有自带的 provisioner

​ 如果使用的是本地环境,可以使用以下几种方式来配置存储:

  1. 本地存储(Local Storage)
  2. NFS 存储
  3. 网络存储(如 iSCSI)

hostPath 类型

hostPath: 定义主机节点文件系统上的路径,作为存储位置。这里指定路径为 /mnt/repository;hostPath 类型的 PersistentVolume 使用节点上的文件或目

录来模拟网络附加存储

hostPath 卷 通常用于本地测试或单节点集群,在生产环境中并不推荐使用,因为它依赖于特定节点上的路径。在生产集群中,你不会使用 hostPath。 集群管理员会提供网络存储资源,比如 Google Compute Engine 持久盘卷、NFS 共享卷或 Amazon Elastic Block Store 卷。 集群管理员还可以使用 StorageClass 来设置动态制备存储

​ 确保在主机节点上存在 /mnt/repository 目录,并且 Kubernetes 进程对该目录有访问权限。

创建 PersistentVolume

hostPath PersistentVolume 的配置文件:

apiVersion: v1
kind: PersistentVolume
metadata:name: pv-volumelabels:type: local
spec:storageClassName: manualcapacity:storage: 20GiaccessModes:- ReadWriteOncehostPath:path: "/mnt/repository"

​ 这里是不使用动态分配的,因此是没有存储分配器来动态分配存储资源,即 kubernetes.io/no-provisioner, 配置文件指定卷位于集群节点上的 /mnt/repository 路径;其配置还指定了卷的容量大小为 20 GB,访问模式为 ReadWriteOnce, 这意味着该卷可以被单个节点以读写方式安装。 此配置文件还在 PersistentVolume 中定义了 StorageClass 的名称为 manual。 它将用于将 PersistentVolumeClaim 的请求绑定到此 PersistentVolume

​ 创建 PersistentVolume,查看 PersistentVolume 信息

image-20241123111956630

​ 输出结果显示该 PersistentVolume 的状态(STATUS)Available。 这意味着它还没有被绑定给 PersistentVolumeClaim

创建 PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pv-claim
spec:storageClassName: manualaccessModes:- ReadWriteOnceresources:requests:storage: 20Gi

​ 创建 PersistentVolumeClaim 之后,Kubernetes 控制平面将查找满足申领要求的 PersistentVolume。 如果控制平面找到具有相同 StorageClass 的适当的 PersistentVolume, 则将 PersistentVolumeClaim 绑定到该 PersistentVolume 上。

再次查看 PersistentVolume 信息:

image-20241123112203428

创建 Pod

创建一个使用 PersistentVolumeClaim 作为存储卷的 Pod

apiVersion: apps/v1
kind: Deployment
metadata:name: httpd-deployment
spec:replicas: 1selector:matchLabels:app: httpdtemplate:metadata:labels:app: httpdspec:containers:- name: httpdimage: m.daocloud.io/docker.io/httpd:latestports:- containerPort: 80volumeMounts:- name: httpd-pvcmountPath: "/usr/local/apache2/htdocs"  # 挂载路径volumes:- name: httpd-pvcpersistentVolumeClaim:claimName: pv-claim  # PVC 名称

​ 创建好之后可以看到,容器内部的文件夹与宿主机的文件夹的文件是同步的

image-20241124192726210

image-20241124192713637

NFS 存储

​ 在官方文档中并不建议使用 hostPath 卷,或者通常用于本地测试或单节点集群,在生产环境中并不推荐使用;因为我们显然可以发现一些问题,Pod 想要挂载本地磁盘,只能指定当前节点的文件路径作为存储,非常不灵活,且路径必须由管理员手动指定,无法动态分配存储资源

​ 解决动态分配可以使用存储资源自动调配器,想要灵活选择存储位置可以使用 NFS 不局限于本地存储路径

NFS Subdir External Provisioner

nfs-subdir-external-provisioner ,是一个存储资源自动调配器,它可将现有的 NFS 服务器通过持久卷声明来支持 Kubernetes 持久卷的动态分配。该组件是对 Kubernetes NFS-Client Provisioner 的扩展

安装 NFS Client

​ 所有的集群节点都需要安装客户端

sudo apt-get update && sudo apt-get install -y nfs-common

Helm 安装

# 添加 Helm 源
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner
  • 命令行安装 NFS Subdir External Provisioner
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --set storageClass.name=nfs-sc --set nfs.server=172.100.0.109 --set nfs.path=/mnt/nfs-repository -n nfs-system

说明:

–set storageClass.name=nfs-sc:指定 storageClass 的名字(没有的话会自己创建)

–set nfs.server=192.168.9.81:指定 NFS 服务器的地址

–set nfs.path=/data/k8s:指定 NFS 导出的共享数据目录

–set storageClass.defaultClass=true:指定为默认的 sc,本示例没使用

-n nfs-system:指定命名空间

​ 这里是会默认下载一个镜像 registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2

  • 自定义 values 安装 NFS Subdir External Provisioner

​ 有更多定制化需求时可以选择自定义 values.yaml 的方式进行安装,实际使用中与命令行安装 NFS Subdir External Provisioner 并无区别,(如果网络限制无法下载镜像建议使用)

helm pull nfs-subdir-external-provisioner/nfs-subdir-external-provisionertar xvf nfs-subdir-external-provisioner-4.0.18.tgz
  • 查看 values.yaml 文件
cat nfs-subdir-external-provisioner/values.yaml | egrep -v '#|^$'
replicaCount: 1
strategyType: Recreate
image:repository: registry.k8s.io/sig-storage/nfs-subdir-external-provisionertag: v4.0.2pullPolicy: IfNotPresent
imagePullSecrets: []
nfs:server:path: /nfs-storagemountOptions:volumeName: nfs-subdir-external-provisioner-rootreclaimPolicy: Retain
storageClass:create: truedefaultClass: falsename: nfs-clientallowVolumeExpansion: truereclaimPolicy: DeletearchiveOnDelete: trueonDelete:pathPattern:accessModes: ReadWriteOncevolumeBindingMode: Immediateannotations: {}
leaderElection:enabled: true
rbac:create: true
podSecurityPolicy:enabled: false
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
serviceAccount:create: trueannotations: {}name:
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
labels: {}
podDisruptionBudget:enabled: falsemaxUnavailable: 1
  • 根据自己集群实际配置更改
# 主要修改内容如下
image:repository: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner  #镜像拉取地址,默认可能拉取不下来,建议替换成本地或是其他可正常访问的仓库,也可以使用我DockerHub上的的 unopsman/nfs-subdir-external-provisionertag: v4.0.2             #镜像 tag 默认为 v4.0.2,可根据实际情况替换
nfs:server: 172.100.0.109    #指定 NFS 服务器的地址path: /mnt/nfs-repository         #指定 NFS 导出的共享数据目录
storageClass:defaultClass: false     #是否设置为默认的 StorageClass,本示例没设置,有需要的可以设置为 truename: nfs-sc            #指定 storageClass 的名字

​ 这里的挂载路径需要提前共享导出

/mnt/nfs-repository  *(rw,sync,no_subtree_check,no_root_squash)
  • 应用更改后的 values.yaml 安装下载
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner -f nfs-subdir-external-provisioner/values.yaml -n nfs-system

image-20241124205800010

​ 正常情况下,查看 pod 的状态应该是 Running

image-20241123195020680

​ 如果出现一直为容器创建中的情况,查看日志报错为如下情况,需要在集群每一个节点不只是 master 上安装 nfs 客户端

image-20241124101119932

image-20241124101145706

# 安装 客户端
sudo apt-get update && sudo apt-get install -y nfs-common

验证测试

​ 因为我们现在有了 NFS Subdir External Provisioner 分配器,我们就需要向上面一样先申请 pv 再定义 pvc 绑定,然后 Pod 再挂载 PVC 了;我们可以直接创建 pvc ,分配器可以动态分配相应的 pv ,来绑定我们的 pvc;分配规则是由 storageClass 配置决定的

创建测试 PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: test-nfs-pvc
spec:storageClassName: nfs-scaccessModes:- ReadWriteManyresources:requests:storage: 1Gi

​ 正常情况下,查看 pvc 应该是绑定的状态,如果不是,有几种常见的错误

image-20241124103346052

image-20241123200000074

​ 如果是这两种情况,检查配置的路径是否共享导出了;编辑 /etc/exports 文件,并且重新导出

image-20241124101418191

image-20241124103450219

image-20241124205332885

/mnt/nfs-repository  *(rw,sync,no_subtree_check,no_root_squash)

​ 如果是这种情况,只要把存储目录的权限放开就好

image-20241123195946618

image-20241124103807259

​ 这是情况下的状态

image-20241124104627134

image-20241123195923410

创建测试 Pod
apiVersion: v1
kind: Pod
metadata:name: test-nfs-pod
spec:volumes:- name: test-nfs-pvcpersistentVolumeClaim:claimName: test-nfs-pvccontainers:- name: test-nfs-containerimage: nginx:latestports:- containerPort: 80name: "http-server"volumeMounts:- mountPath: "/usr/share/nginx/html"name: test-nfs-pvc

​ 如果 pod 运行正常,在指定的目录下会自动创建目录文件并挂载到容器的指定目录下面

image-20241124105040279

image-20241124105122822

测试

image-20241124105502999

image-20241123210721772

image-20241123210741816

参考官网:

​ 配置 Pod 以使用 PersistentVolume 作为存储

​ 持久存储设计文档


http://www.ppmy.cn/devtools/137771.html

相关文章

树莓派3:64位系统串口(UART)使用问题的解决方法

前言 当我们要使用串口进行zigbee的短距离通信时,发现无法使用串口. 原因 树莓派3bCPU内部有两个串口,一个硬件串口(就是我们平时使用的UART),还有一个迷你串口(mini-uart),在老版本的树莓派中把硬件串口分配在GPIO上,可以单独使用.但是在新的树莓派中官方把硬件串口给了蓝牙…

Android Audio实战——音频多声道基础适配(七)

通过《Android Audio基础——音频输出声道设置》这篇文章,我们了解了 Android 11 中通道掩码校验的时候最好只校验到 7.1 声道(8声道),而在通道常量参数中有定义了 7.1.2 声道(10 声道)和 7.1.4声道(12 声道)。如果这里我们 Android 11 的项目想要使用 7.1.4 声道就需要…

Android Audio实战——音频多声道混音适配(八)

上一篇文章我们修改了在 Android 11 中适配 7.1.4 声道的相关常量定义及部分代码,这里我们来看一下另外两个部分重要逻辑的修改及优化。 在音频处理过程中,经常需要将不同采样率的音频统一到相同的采样率,以便进行进一步处理。而在 AudioMixer 中,很可能会使用 AudioResamp…

Java图书管理系统(简易保姆级)

前面学习了这么多知识,为了巩固之前的知识,我们就要写一个图书管理系统来帮助大家复习,让大家的知识融会贯通~~~ 话不多说,直接开始今天的内容~ 首先呢,我们要有一个大体的思路: 实现效果思路有两种情况&a…

Vue 3 Teleport 教程

Vue 3 Teleport 教程 1. Teleport 是什么? Teleport 是 Vue 3 中引入的一个强大组件,它允许你将组件的一部分渲染到文档中的其他位置,而不受原始组件嵌套层级的限制。这个特性特别适合处理模态框、弹窗、通知等需要脱离普通文档流的场景。 …

视频推拉流EasyDSS互联网直播点播平台技术特点及应用场景剖析

在数字科技日新月异的今天,视频直播和点播已经成为互联网内容传播的重要方式之一。而互联网直播点播平台EasyDSS作为功能强大的流媒体直播点播视频能力平台,提供了一站式的视频推拉流、转码、直播、点播、时移回放、存储等视频服务,广泛应用于…

设计模式之破环单例模式和阻止破坏

目录 1. 序列化和反序列化2. 反射 这里单例模式就不多说了 23种设计模式之单例模式 1. 序列化和反序列化 这里用饿汉式来做例子 LazySingleton import java.io.Serializable;public class LazySingleton implements Serializable {private static LazySingleton lazySinglet…

使用 pycharm 新建不使用 python 虚拟环境( venv、conda )的工程

有时候我们发现一个好玩的 demo,想赶快在电脑上 pip install 一下跑起来,发现因为 python 的 venv、conda 环境还挺费劲的,因为随着时间的发展,之前记得很清楚的 venv、conda 的用法,不经常使用,半天跑不起…