文章目录
- [Kubernetes 存储](#Kubernetes 存储)
-
- [Volume 与存储卷详解](#Volume 与存储卷详解)
- [PV 与 PVC](#PV 与 PVC)
-
- 核心概念
- [PV 与 PVC 生命周期](#PV 与 PVC 生命周期)
- [PV 的 4 种状态](#PV 的 4 种状态)
- [PV 的创建方式](#PV 的创建方式)
- 关键配置字段
-
- [PV 配置(`spec` 字段)](#PV 配置(
spec
字段)) - [PVC 配置(`spec` 字段)](#PVC 配置(
spec
字段))
- [PV 配置(`spec` 字段)](#PV 配置(
- 示例
-
- [静态 PV 与 PVC 示例](#静态 PV 与 PVC 示例)
- [动态 PV 示例(StorageClass)](#动态 PV 示例(StorageClass))
- 总结
- 存储卷类型对比
- [静态创建 PV 与动态创建 PV 对比](#静态创建 PV 与动态创建 PV 对比)
- [实例:用 NFS 作为存储后端的 PV 与 PVC 配置指南](#实例:用 NFS 作为存储后端的 PV 与 PVC 配置指南)
-
- [1. 配置 NFS 服务器](#1. 配置 NFS 服务器)
- [2. 静态创建 PV 资源](#2. 静态创建 PV 资源)
- [3. 创建 PVC 并绑定 PV](#3. 创建 PVC 并绑定 PV)
- [4. 测试数据持久化](#4. 测试数据持久化)
- 注意
- [搭建 StorageClass + NFS-Client-Provisioner 实现 NFS 动态 PV 创建](#搭建 StorageClass + NFS-Client-Provisioner 实现 NFS 动态 PV 创建)
Kubernetes 存储
Volume 与存储卷详解
背景
容器磁盘上的文件生命周期是短暂的,这会导致以下问题:
- 容器崩溃时数据丢失:当容器崩溃后,kubelet 会重启容器,但容器中的文件会丢失,恢复到镜像的初始状态。
- 多容器间文件共享需求 :在同一个 Pod 中运行的多个容器通常需要共享文件。
Kubernetes 通过 Volume 抽象 解决了这些问题。Pod 中的容器通过 Pause 容器 共享 Volume,从而实现数据的持久化和共享。
emptyDir 存储卷
- 特点 :
- 当 Pod 被分配到节点时,emptyDir 卷会被创建。
- 只要 Pod 在该节点上运行,emptyDir 卷就会存在。
- 卷最初是空的,Pod 中的容器可以读取和写入 emptyDir 卷中的相同文件。
- 当 Pod 从节点中删除时,emptyDir 中的数据会被永久删除。
- 适用场景 :
- 临时数据存储。
- 多容器间文件共享。
emptyDir 存储卷示例
-
创建 YAML 文件
在/opt/volumes
目录下创建pod-emptydir.yaml
文件:yamlapiVersion: v1 kind: Pod metadata: name: pod-emptydir namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /data/ command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done'] volumes: - name: html emptyDir: {}
-
应用 YAML 文件
使用以下命令创建 Pod:bashkubectl apply -f pod-emptydir.yaml
-
查看 Pod 状态
确认 Pod 已成功运行:bashkubectl get pods -o wide
输出示例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-emptydir 2/2 Running 0 36s 10.244.2.19 node02 <none> <none>
-
验证数据共享
-
busybox
容器会每隔 2 秒将当前日期写入/data/index.html
文件。 -
myapp
容器通过挂载的 emptyDir 卷读取/usr/share/nginx/html/index.html
文件。 -
使用
curl
命令访问 Nginx 服务,验证是否能够获取日期信息:bashcurl 10.244.2.19
输出示例:
Thu May 27 18:17:11 UTC 2021 Thu May 27 18:17:13 UTC 2021 Thu May 27 18:17:15 UTC 2021 Thu May 27 18:17:17 UTC 2021 Thu May 27 18:17:19 UTC 2021 Thu May 27 18:17:21 UTC 2021 Thu May 27 18:17:23 UTC 2021
-
hostPath 存储卷
- 功能:将 Node 节点上的文件或目录挂载到 Pod 中。
- 特点 :
- 实现持久化存储,但数据与 Node 节点绑定。
- 如果 Node 节点故障,数据会丢失。
- 适用于单节点数据持久化或调试场景。
hostPath 存储卷示例
-
在 Node 节点上创建挂载目录
-
在
node01
上:bashmkdir -p /data/pod/volume1 echo 'node01.xy101.com' > /data/pod/volume1/index.html
-
在
node02
上:bashmkdir -p /data/pod/volume1 echo 'node02.xy101.com' > /data/pod/volume1/index.html
-
-
创建 Pod 资源 YAML 文件
yamlapiVersion: v1 kind: Pod metadata: name: pod-hostpath namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html readOnly: false volumes: - name: html hostPath: path: /data/pod/volume1 type: DirectoryOrCreate
-
应用 YAML 文件
bashkubectl apply -f pod-hostpath.yaml
-
验证 Pod 状态
bashkubectl get pods -o wide
输出示例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-hostpath 1/1 Running 0 37s 10.244.2.35 node02 <none> <none>
-
访问测试
bashcurl 10.244.2.35
输出示例:
node02.xy101.com
-
验证数据持久化
-
删除 Pod 并重新创建:
bashkubectl delete -f pod-hostpath.yaml kubectl apply -f pod-hostpath.yaml
-
再次访问 Pod:
bashcurl 10.244.2.37
输出示例:
node02.xy101.com
-
NFS 共享存储卷
- 功能:将 NFS 服务器的共享目录挂载到 Pod 中。
- 特点 :
- 实现跨节点的数据持久化和共享。
- 数据存储在 NFS 服务器上,即使 Pod 或 Node 故障,数据也不会丢失。
NFS 存储卷示例
-
在 NFS 服务器上配置 NFS 服务
-
创建共享目录并设置权限:
bashmkdir /data/volumes -p chmod 777 /data/volumes
-
编辑
/etc/exports
文件:bash/data/volumes 192.168.80.0/24(rw,no_root_squash)
-
启动 NFS 服务:
bashsystemctl start rpcbind systemctl start nfs
-
验证 NFS 共享:
bashshowmount -e
输出示例:
Export list for stor01: /data/volumes 192.168.80.0/24
-
-
创建 Pod 资源 YAML 文件
yamlapiVersion: v1 kind: Pod metadata: name: pod-vol-nfs namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html nfs: path: /data/volumes server: stor01
-
应用 YAML 文件
bashkubectl apply -f pod-nfs-vol.yaml
-
验证 Pod 状态
bashkubectl get pods -o wide
输出示例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-vol-nfs 1/1 Running 0 21s 10.244.2.38 node02 <none> <none>
-
在 NFS 服务器上创建测试文件
bashcd /data/volumes echo '<h1> nfs stor01</h1>' > index.html
-
访问测试
bashcurl 10.244.2.38
输出示例:
<h1> nfs stor01</h1>
-
验证数据持久化
-
删除 Pod 并重新创建:
bashkubectl delete -f pod-nfs-vol.yaml kubectl apply -f pod-nfs-vol.yaml
-
再次访问 Pod:
bashcurl 10.244.2.38
输出示例:
<h1> nfs stor01</h1>
-
总结
特性 | emptyDir | hostPath | nfs |
---|---|---|---|
功能 | 实现 Pod 内容器之间的目录数据共享。 | 将 Node 节点上的目录或文件挂载到 Pod 容器中使用。 | 将 NFS 服务的共享目录挂载到 Pod 容器中使用。 |
持久化能力 | 无持久化能力,数据随 Pod 删除而丢失。 | 具备持久化能力,但数据仅绑定到单个 Node 节点。 | 具备持久化能力,数据存储在 NFS 服务器上。 |
数据共享范围 | 仅限于 Pod 内容器之间共享。 | 仅限于 Pod 所在 Node 节点上的容器使用。 | 支持跨 Node 节点的容器共享数据。 |
适用场景 | 临时数据存储或容器间数据共享。 | 单节点数据持久化或调试场景。 | 多节点数据共享或持久化存储。 |
数据可靠性 | 低,数据随 Pod 删除而丢失。 | 中,数据与 Node 节点绑定,节点故障时数据丢失。 | 高,数据存储在 NFS 服务器上,可靠性高。 |
配置复杂度 | 简单,无需额外配置。 | 中等,需在 Node 节点上创建目录。 | 较高,需配置 NFS 服务器和共享目录。 |
跨节点支持 | 不支持跨节点共享。 | 不支持跨节点共享。 | 支持跨节点共享。 |
PV 与 PVC
核心概念
-
PV(PersistentVolume):
- 定义:集群中的持久化存储资源,由运维人员创建和管理。
- 特点:独立于 Pod 生命周期,支持多种存储类型(如 NFS、Ceph、iSCSI 等)。
-
PVC(PersistentVolumeClaim):
- 定义:用户对存储资源的请求,描述所需的存储特性(如容量、访问模式)。
- 特点:通过绑定 PV 实现存储资源的动态分配。
-
StorageClass(SC):
- 作用:动态创建 PV 的模板,自动化管理存储资源。
- 核心字段 :
provisioner
:存储插件(如nfs-client
、ceph-rbd
)。reclaimPolicy
:PV 回收策略(默认Delete
)。
PV 与 PVC 生命周期
阶段 | 描述 |
---|---|
Provisioning | 创建 PV(静态手动创建 或 动态通过 StorageClass 自动创建)。 |
Binding | PVC 与 PV 绑定,PV 进入 Bound 状态。 |
Using | Pod 通过 PVC 使用 PV 存储资源。 |
Releasing | Pod 释放存储资源,删除 PVC,PV 进入 Released 状态。 |
Recycling | 根据回收策略处理 PV(保留、删除或复用)。 |
PV 的 4 种状态
状态 | 描述 |
---|---|
Available | PV 已创建但未被 PVC 绑定。 |
Bound | PV 已与 PVC 绑定,可被 Pod 使用。 |
Released | PVC 已删除,但 PV 尚未回收(数据可能保留)。 |
Failed | PV 或 PVC 配置错误或存储后端故障,无法正常使用。 |
PV 的创建方式
方式 | 特点 |
---|---|
静态创建 | 手动创建 PV,适合固定存储需求。 |
动态创建 | 通过 StorageClass 自动创建 PV,适合大规模动态存储需求。 |
关键配置字段
PV 配置(spec
字段)
-
存储类型:
yamlnfs: path: /data/volumes server: stor01
-
访问模式(
accessModes
):ReadWriteOnce
(RWO):单节点读写。ReadOnlyMany
(ROX):多节点只读。ReadWriteMany
(RWX):多节点读写。ReadWriteOncePod
(RWOP):单 Pod 读写。
-
容量(
capacity
):yamlcapacity: storage: 10Gi
-
回收策略(
persistentVolumeReclaimPolicy
):Retain
:保留数据,需手动清理。Delete
:自动删除 PV 及后端存储(仅支持云存储)。Recycle
:清除数据并复用 PV(已废弃,建议使用动态配置)。
PVC 配置(spec
字段)
-
资源请求(
resources
) :yamlresources: requests: storage: 5Gi
-
存储类(
storageClassName
) :yamlstorageClassName: "nfs-storage"
示例
静态 PV 与 PVC 示例
-
创建 PV:
yamlapiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs spec: capacity: storage: 10Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: path: /data/volumes server: stor01
-
创建 PVC:
yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nfs spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi storageClassName: ""
-
Pod 挂载 PVC:
yamlapiVersion: v1 kind: Pod metadata: name: pod-pvc spec: containers: - name: nginx image: nginx volumeMounts: - name: data mountPath: /usr/share/nginx/html volumes: - name: data persistentVolumeClaim: claimName: pvc-nfs
动态 PV 示例(StorageClass)
-
创建 StorageClass:
yamlapiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-storage provisioner: example.com/nfs reclaimPolicy: Delete
-
创建 PVC:
yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-dynamic spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: nfs-storage
总结
存储卷类型对比
特性 | emptyDir | hostPath | nfs | PV/PVC |
---|---|---|---|---|
持久化能力 | 无 | 单节点持久化 | 跨节点持久化 | 持久化(依赖后端存储) |
数据共享范围 | Pod 内容器 | Pod 所在节点 | 跨节点 | 集群范围 |
适用场景 | 临时数据共享 | 单节点调试/数据持久化 | 多节点共享数据 | 生产环境持久化存储 |
配置复杂度 | 简单 | 中等 | 高 | 高(需管理 PV 和 PVC) |
- PV/PVC :
- 实现存储资源与 Pod 解耦,提供灵活的存储管理。
- 静态配置适合固定需求,动态配置适合大规模场景。
- StorageClass :
- 自动化 PV 创建,降低运维成本。
- 访问模式与回收策略 :
- 根据业务需求选择,例如
ReadWriteMany
适合多节点读写,Retain
策略保障数据安全。
- 根据业务需求选择,例如
静态创建 PV 与动态创建 PV 对比
步骤 | 静态创建 PV | 动态创建 PV |
---|---|---|
1. 准备存储设备 | 确保存储设备可用并配置好(如 NFS、Ceph、iSCSI 等)。 | 确保存储设备可用并配置好(如 NFS、Ceph、iSCSI 等)。 |
2. 创建 PV 资源 | 手动创建 PV,定义访问模式、存储空间、回收策略、存储设备类型等。 | 无需手动创建 PV,由 StorageClass 自动创建。 |
3. 创建 PVC 资源 | 手动创建 PVC,绑定已创建的 PV,定义访问模式和请求的存储空间。 | 创建 PVC,指定 StorageClass,动态生成并绑定 PV。 |
4. 创建 Pod 资源 | 挂载 PVC 存储卷,定义挂载点目录。 | 挂载 PVC 存储卷,定义挂载点目录。 |
5. 存储卷插件 | 无需额外配置存储卷插件。 | 需配置存储卷插件(Provisioner),如 NFS、Ceph 等。 |
6. RBAC 授权 | 无需 RBAC 授权。 | 如果是外置卷插件,需创建 ServiceAccount 和 RBAC 授权。 |
7. StorageClass | 无需 StorageClass。 | 需创建 StorageClass,定义 Provisioner、参数和回收策略。 |
适用场景 | 适合固定存储需求,PV 数量较少。 | 适合动态存储需求,PV 数量较多,自动化程度高。 |
运维复杂度 | 较高,需手动管理 PV 和 PVC。 | 较低,自动化管理 PV 和 PVC。 |
灵活性 | 灵活性较低,需提前规划存储资源。 | 灵活性高,按需动态创建存储资源。 |
-
静态创建 PV:
- 适合固定存储需求,PV 数量较少。
- 需手动管理 PV 和 PVC,运维复杂度较高。
- 灵活性较低,需提前规划存储资源。
-
动态创建 PV:
- 适合动态存储需求,PV 数量较多。
- 自动化管理 PV 和 PVC,运维复杂度较低。
- 灵活性高,按需动态创建存储资源。
实例:用 NFS 作为存储后端的 PV 与 PVC 配置指南
1. 配置 NFS 服务器
目标:创建共享目录并配置 NFS 服务,使 Kubernetes 集群可以访问这些存储资源。
-
创建共享目录
在 NFS 服务器上创建多个共享目录:
bashmkdir -p /data/volumes/v{1,2,3,4,5}
-
配置 NFS 共享
编辑
/etc/exports
文件,定义共享目录及访问权限:bashvim /etc/exports
添加以下内容:
/data/volumes/v1 192.168.80.0/24(rw,no_root_squash) /data/volumes/v2 192.168.80.0/24(rw,no_root_squash) /data/volumes/v3 192.168.80.0/24(rw,no_root_squash) /data/volumes/v4 192.168.80.0/24(rw,no_root_squash) /data/volumes/v5 192.168.80.0/24(rw,no_root_squash)
-
生效配置并验证
bashexportfs -arv # 重新加载 NFS 共享配置 showmount -e # 验证共享目录是否生效
2. 静态创建 PV 资源
目标:定义多个 PV,关联 NFS 共享目录,并设置容量、访问模式和回收策略。
-
定义 PV 资源文件
创建
pv-demo.yaml
,配置 5 个 PV:yamlapiVersion: v1 kind: PersistentVolume metadata: name: pv001 labels: name: pv001 spec: nfs: path: /data/volumes/v1 server: stor01 accessModes: ["ReadWriteMany", "ReadWriteOnce"] capacity: storage: 1Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv002 labels: name: pv002 spec: nfs: path: /data/volumes/v2 server: stor01 accessModes: ["ReadWriteOnce"] capacity: storage: 2Gi --- # 其他 PV 配置(pv003、pv004、pv005)类似,需修改路径和容量
-
应用 PV 配置
bashkubectl apply -f pv-demo.yaml
-
验证 PV 状态
bashkubectl get pv
输出示例:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS AGE pv001 1Gi RWO,RWX Retain Available 10s pv002 2Gi RWO Retain Available 10s pv003 2Gi RWO,RWX Retain Available 10s pv004 4Gi RWO,RWX Retain Available 10s pv005 5Gi RWO,RWX Retain Available 10s
3. 创建 PVC 并绑定 PV
目标:定义 PVC 请求存储资源,并自动绑定符合条件的 PV。
-
定义 PVC 和 Pod 资源文件
创建
pod-vol-pvc.yaml
:yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc namespace: default spec: accessModes: ["ReadWriteMany"] resources: requests: storage: 2Gi --- apiVersion: v1 kind: Pod metadata: name: pod-vol-pvc namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: mypvc
-
应用 PVC 和 Pod 配置
bashkubectl apply -f pod-vol-pvc.yaml
-
验证 PVC 和 PV 绑定状态
bashkubectl get pv kubectl get pvc
输出示例:
# PV 状态 NAME STATUS CLAIM CAPACITY ACCESS MODES pv003 Bound default/mypvc 2Gi RWO,RWX # PVC 状态 NAME STATUS VOLUME CAPACITY ACCESS MODES mypvc Bound pv003 2Gi RWO,RWX
4. 测试数据持久化
目标:验证 Pod 通过 PVC 挂载的存储是否正常工作。
-
在 NFS 服务器上创建测试文件
bashecho "welcome to use pv3" > /data/volumes/v3/index.html
-
访问 Pod 服务
获取 Pod 的 IP 地址并访问:
bashkubectl get pods -o wide curl <Pod_IP>
输出示例:
welcome to use pv3
注意
-
PV 配置字段
accessModes
:定义 PV 的访问模式(如ReadWriteMany
)。capacity
:设置存储容量(如2Gi
)。persistentVolumeReclaimPolicy
:回收策略(默认Retain
)。
-
PVC 配置字段
accessModes
:必须与 PV 支持的访问模式匹配。resources.requests.storage
:请求的存储空间大小。
常见问题与其他注意事项
-
访问模式匹配
- PVC 的
accessModes
必须是 PV 支持的模式子集。 - 例如,若 PVC 请求
ReadWriteMany
,则 PV 必须支持该模式。
- PVC 的
-
存储容量匹配
- PVC 请求的存储空间需小于等于 PV 的容量。
- Kubernetes 会自动选择容量最小的符合条件的 PV。
-
回收策略影响
Retain
策略下,删除 PVC 后 PV 不会自动清理,需手动处理。Delete
策略仅适用于部分存储后端(如云存储)。
-
多 Pod 共享存储
- 若多个 Pod 使用同一 PVC,需确保存储后端支持并发读写(如 NFS 的
ReadWriteMany
)。
- 若多个 Pod 使用同一 PVC,需确保存储后端支持并发读写(如 NFS 的
搭建 StorageClass + NFS-Client-Provisioner 实现 NFS 动态 PV 创建
背景
Kubernetes 默认不支持 NFS 的动态 PV 创建,因此需要使用外部存储卷插件(Provisioner)来实现。NFS-Client-Provisioner 是一个常用的 Provisioner,它能够自动在 NFS 服务器上创建目录,并将其与 PV 关联。
步骤概览
- 配置 NFS 服务器:准备 NFS 共享目录。
- 创建 RBAC 权限:为 NFS-Client-Provisioner 配置 ServiceAccount 和权限。
- 部署 NFS-Client-Provisioner:使用 Deployment 部署 Provisioner。
- 创建 StorageClass:定义动态 PV 的创建规则。
- 测试 PVC 和 Pod:验证动态 PV 创建和挂载功能。
详细步骤
1. 配置 NFS 服务器
在 NFS 服务器上创建共享目录并配置 NFS 服务。
-
创建共享目录
bashmkdir -p /opt/k8s chmod 777 /opt/k8s
-
配置 NFS 共享
编辑/etc/exports
文件:bashvim /etc/exports
添加以下内容:
/opt/k8s 192.168.80.0/24(rw,no_root_squash,sync)
-
重启 NFS 服务
bashsystemctl restart nfs
2. 创建 RBAC 权限
为 NFS-Client-Provisioner 配置 ServiceAccount 和权限。
-
创建 RBAC 配置文件
创建nfs-client-rbac.yaml
:yamlapiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: nfs-client-provisioner-clusterrole rules: - 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: ["list", "watch", "create", "update", "patch"] - apiGroups: [""] resources: ["endpoints"] verbs: ["create", "delete", "get", "list", "watch", "patch", "update"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: nfs-client-provisioner-clusterrolebinding subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: default roleRef: kind: ClusterRole name: nfs-client-provisioner-clusterrole apiGroup: rbac.authorization.k8s.io
-
应用 RBAC 配置
bashkubectl apply -f nfs-client-rbac.yaml
3. 部署 NFS-Client-Provisioner
使用 Deployment 部署 NFS-Client-Provisioner。
-
解决 Kubernetes 1.20+ 的 SelfLink 问题
编辑
kube-apiserver.yaml
:bashvim /etc/kubernetes/manifests/kube-apiserver.yaml
添加以下内容:
yamlspec: containers: - command: - kube-apiserver - --feature-gates=RemoveSelfLink=false
重启 kube-apiserver:
bashkubectl delete pods kube-apiserver -n kube-system
-
创建 Provisioner 配置文件
创建
nfs-client-provisioner.yaml
:yamlapiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner spec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner strategy: type: Recreate template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: quay.io/external_storage/nfs-client-provisioner:latest imagePullPolicy: IfNotPresent volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: nfs-storage - name: NFS_SERVER value: stor01 - name: NFS_PATH value: /opt/k8s volumes: - name: nfs-client-root nfs: server: stor01 path: /opt/k8s
-
应用 Provisioner 配置
bashkubectl apply -f nfs-client-provisioner.yaml
-
验证 Provisioner 状态
bashkubectl get pods
输出示例:
NAME READY STATUS RESTARTS AGE nfs-client-provisioner-7f5d8c5c5c-6q9q2 1/1 Running 0 10s
4. 创建 StorageClass
定义动态 PV 的创建规则。
-
创建 StorageClass 配置文件
创建
nfs-client-storageclass.yaml
:yamlapiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client-storageclass provisioner: nfs-storage parameters: archiveOnDelete: "false"
-
应用 StorageClass 配置
bashkubectl apply -f nfs-client-storageclass.yaml
-
验证 StorageClass 状态
bashkubectl get storageclass
输出示例:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE AGE nfs-client-storageclass nfs-storage Delete Immediate 10s
5. 测试 PVC 和 Pod
验证动态 PV 创建和挂载功能。
-
创建 PVC 和 Pod 配置文件
创建test-pvc-pod.yaml
:yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-nfs-pvc spec: accessModes: - ReadWriteMany storageClassName: nfs-client-storageclass resources: requests: storage: 1Gi --- apiVersion: v1 kind: Pod metadata: name: test-storageclass-pod spec: containers: - name: busybox image: busybox:latest command: ["/bin/sh", "-c", "sleep 3600"] volumeMounts: - name: nfs-pvc mountPath: /mnt volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test-nfs-pvc
-
应用 PVC 和 Pod 配置
bashkubectl apply -f test-pvc-pod.yaml
-
验证 PVC 和 PV 状态
bashkubectl get pvc kubectl get pv
输出示例:
NAME STATUS VOLUME CAPACITY ACCESS MODES AGE test-nfs-pvc Bound pvc-11670f39-782d-41b8-a842-eabe1859a456 1Gi RWX 10s
-
验证数据持久化
-
进入 Pod 并创建测试文件:
bashkubectl exec -it test-storageclass-pod -- /bin/sh echo "this is test file" > /mnt/test.txt
-
在 NFS 服务器上验证文件:
bashcat /opt/k8s/default-test-nfs-pvc-pvc-11670f39-782d-41b8-a842-eabe1859a456/test.txt
输出示例:
this is test file
-