Kubernetes 持久化存储之 NFS 终极实战指南

作者:运维有术星主 在 Kubernetes 生态系统中,持久化存储扮演着至关重要的角色,它是支撑应用稳定运行的基石。对于那些选择自建 Kubernetes 集群的运维架构师而言,选择合适的后端持久化存储解决方案是一项至关重要的选型决策。后端持久化存储常见的解决方案有 Ceph、GlusterFS、NFS、hostPath,以及这两年新兴起的 Longhorn。当然,技术领域日新月异,还有其他优秀的解决方案我尚未了解。

今天,我将为大家分享,如何在 Kubernetes 集群中手动安装 Kubernetes NFS Subdir External Provisioner 插件。这是一个强大的工具,能够实现为 Kubernetes 集群提供自动化的基于 NFS 存储的持久化动态卷管理能力。通过实战演示,您将学会如何将 NFS 作为后端的持久化存储解决方案集成至 Kubernetes 集群。

本文核心内容概览:

  • NFS 持久化存储选型说明: 理解为什么选择 NFS 及其优缺点。
  • NFS 存储服务如何部署: 如何在 openEuler 上部署配置 NFS 存储
  • 手动安装 NFS Subdir External Provisioner:一步步指导如何安装、配置、卸载这一关键插件。
  • 实战演示:创建测试资源,体验 NFS 作为持久化存储的效果。

实战服务器配置(架构 1:1 复刻小规模生产环境,配置略有不同)

主机名 IP CPU 内存 系统盘 数据盘 用途
ksp-registry 192.168.9.90 4 8 40 200 Harbor 镜像仓库
ksp-control-1 192.168.9.91 4 8 40 100 KubeSphere/k8s-control-plane
ksp-control-2 192.168.9.92 4 8 40 100 KubeSphere/k8s-control-plane
ksp-control-3 192.168.9.93 4 8 40 100 KubeSphere/k8s-control-plane
ksp-worker-1 192.168.9.94 4 16 40 100 k8s-worker/CI
ksp-worker-2 192.168.9.95 4 16 40 100 k8s-worker
ksp-worker-3 192.168.9.96 4 16 40 100 k8s-worker
ksp-storage-1 192.168.9.97 4 8 40 300+ Ceph/Longhorn/NFS/ElasticSearch
ksp-storage-2 192.168.9.98 4 8 40 300+ Ceph/Longhorn/ElasticSearch
ksp-storage-3 192.168.9.99 4 8 40 300+ Ceph/Longhorn/ElasticSearch
ksp-gpu-worker-1 192.168.9.101 4 16 40 100 k8s-worker(GPU NVIDIA Tesla M40 24G)
ksp-gpu-worker-2 192.168.9.102 4 16 40 100 k8s-worker(GPU NVIDIA Tesla P100 16G)
ksp-gateway-1 192.168.9.103 2 4 40 自建应用服务代理网关/VIP:192.168.9.100
ksp-gateway-2 192.168.9.104 2 4 40 自建应用服务代理网关/VIP:192.168.9.100
ksp-mid 192.168.9.105 4 8 40 100 部署在 k8s 集群之外的服务节点(Gitlab 等)
合计 15 56 152 600 2000+

实战环境涉及软件版本信息

  • 操作系统:openEuler 22.03 LTS SP3 x86_64
  • KubeSphere:v3.4.1
  • Kubernetes:v1.28.8
  • KubeKey: v3.1.1
  • Containerd:1.7.13
  • NVIDIA GPU Operator:v24.3.0
  • NVIDIA 显卡驱动:550.54.15
  • Kubernetes NFS Subdir External Provisioner:4.0.18

1. 前置条件

1.1 NFS 选型说明

本文介绍的内容可直接用于研发、测试环境,对于生产环境不建议使用 NFS 存储,主要原因如下:

  • 单点故障,生产上使用第一要解决的就是 NFS 单点的问题,有解决方案但是很麻烦,本文不涉及
  • 网络故障,要考虑 NFS 对网络的依赖度,网络波动造成的连接异常等问题
  • 容量限制,无法限制实际的使用容量
  • 存储的冗余,要考虑 NFS 底层磁盘是否有冗余备份
  • 有些组件和应用不兼容 NFS 存储(比如 Promethues,未实际验证,只是在网上多次看到相关的说明)
  • 性能优化(Pod 少的时候还可以,连接挂载点多了怎么优化是个问题)

虽然,我个人不建议在生产环境使用 NFS 作为 Kubernetes 的后端持久化存储。但是,在我做过的小调研中发现,生产环境使用 NFS 的比率还挺高。

这是为什么呢?我左思右想可能的原因有:

  • NFS 简单易维护
  • 使用 NFS 的生产环境对于业务的中断和数据的丢失有一定的容忍度(或许对中断和数据丢失都有对应的应对方案
  • 成本低廉,降本增效(笑)。一台或两台存储就能搞定,比 Ceph、GlusterFS 动辄三台起步需要的资源少的太多了(但是也要考虑,因为存储导致集群故障从而导致业务故障的后果)

生产环境一定要使用 NFS?建议仔细考虑以下几点:

  • 建议选择硬件厂商的商业集中式存储产品不要自建
  • 存储网络一定要使用万兆网络,且有网卡冗余 bond 加持
  • 自建的 NFS 存储数据盘一定要做 Raid,最好 Raid10
  • 业务应用对存储 IO 能力要求高时,不要使用 NFS
  • 是否需要 NFS 服务的高可用?如何实现?

1.2 安装 NFS 客户端

在安装 Kubernetes NFS Subdir External Provisioner 之前,Kubernetes 集群所有节点需要提前安装 NFS 客户端,否则部署过程会报错。不同操作系统 NFS 客户端的包名不同,CentOS 和 openEuler 中包名为 nfs-utils

  • 安装 NFS 客户端
bash 复制代码
yum install nfs-utils

2. openEuler 部署 NFS 服务

本文的主要目的是测试 Kubernetes 使用 NFS 作为持久化存储的能力。因此,实战环境选择一台操作系统为 openEuler 的虚拟机部署 NFS 服务。该 NFS 服务器安装配置方法仅适用于测试环境,生产环境请谨慎评估、配置使用。

本文使用 IP 为 192.168.9.97ksp-storage-1 节点 , 部署单节点 NFS 存储服务器。部署过程中分配一块独立的 100G 数据盘 /dev/sde, 使用 LVM 类型将其格式化,挂载到 /datanfs/ 目录下作为共享存储的根目录。

2.1 初始化数据盘

LVM 配置比较简单,操作细节不做解释,直接上命令。

bash 复制代码
pvcreate /dev/sde
vgcreate datanfs /dev/sde
lvcreate -l 100%VG datanfs -n lvnfs
mkfs.xfs /dev/mapper/datanfs-lvnfs
mkdir /datanfs/
mount /dev/mapper/datanfs-lvnfs /datanfs/
tail -1 /etc/mtab >> /etc/fstab

2.2 安装 NFS 服务端软件包

bash 复制代码
yum install nfs-utils

2.3 创建共享数据根目录

执行以下命令,创建共享数据存储目录,本文以 /datanfs/k8s 为例,请根据实际情况调整路径和权限。

bash 复制代码
mkdir -p /datanfs/k8s
chown nobody:nobody /datanfs/k8s

2.4 编辑服务配置文件

配置 NFS 服务器数据导出目录及访问 NFS 服务器的客户端机器权限。

编辑配置文件 vi /etc/exports,添加如下内容:

bash 复制代码
/datanfs/k8s 192.168.9.0/24(rw,sync,all_squash,anonuid=65534,anongid=65534,no_subtree_check)

配置说明:

  • /datanfs/k8s:NFS 导出的共享数据目录
  • 192.168.9.0/24:可以访问 NFS 存储的客户端 IP 地址
  • rw:读写操作,客户端机器拥有对卷的读写权限。
  • sync:内存数据实时写入磁盘,性能会有所限制
  • all_squash:NFS 客户端上的所有用户在使用共享目录时都会被转换为一个普通用户的权限
  • anonuid:转换后的用户权限 ID,对应的操作系统的 nobody 用户
  • anongid:转换后的组权限 ID,对应的操作系统的 nobody 组
  • no_subtree_check:不检查客户端请求的子目录是否在共享目录的子树范围内,也就是说即使输出目录是一个子目录,NFS 服务器也不检查其父目录的权限,这样可以提高效率。

2.5 启动服务并设置开机自启

bash 复制代码
systemctl enable nfs-server --now

2.6 查看共享目录

  • 查看导出目录
bash 复制代码
exportfs -v

正确执行后,输出结果如下 :

bash 复制代码
$ exportfs -v
/datanfs/k8s    192.168.9.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,all_squash)

2.7 客户端挂载测试

找一台额外的机器作为客户端验证测试,本示例使用 ksp-worker-1 节点。

  • 创建测试挂载点
bash 复制代码
mkdir /mnt/nfs
  • 安装 NFS 软件包(一定要安装,否则无法识别 nfs 类型的存储)
bash 复制代码
yum install nfs-utils
  • 查看 NFS 共享目录列表
bash 复制代码
$showmount -e 192.168.9.97
Export list for 192.168.9.97:
/datanfs/k8s 192.168.9.0/24
  • 挂载 NFS 共享目录
bash 复制代码
mount -t nfs 192.168.9.97:/datanfs/k8s /mnt/nfs/
  • 增删改查测试
bash 复制代码
# 创建测试目录、创建测试文件、测试文件写入内容、查看写入目录和文件权限、删除目录和文件
# 创建
mkdir /mnt/nfs/nfs-test
touch /mnt/nfs/nfs-test.txt
echo "nfs-test" > nfs-test.txt

# 查看
$ ls -l /mnt/nfs/
total 4
drwxr-xr-x 2 nobody nobody 6 Jul 11 21:37 nfs-test
-rw-r--r-- 1 nobody nobody 9 Jul 11 21:37 nfs-test.txt

$ cat /mnt/nfs/nfs-test.txt
nfs-test

# 删除
rmdir /mnt/nfs/nfs-test
rm -rf /mnt/nfs/nfs-test.txt
  • 卸载 NFS 存储
bash 复制代码
umount /mnt/nfs/

3. 安装配置 Kubernetes NFS Subdir External Provisioner

Kubernetes 支持 NFS 存储,需要安装 nfs-subdir-external-provisioner ,它是一个存储资源自动调配器,它可将现有的 NFS 服务器通过持久卷声明来支持 Kubernetes 持久卷的动态分配。该组件是对 Kubernetes NFS-Client Provisioner 的扩展, nfs-client-provisioner 已经不提供更新,而且 nfs-client-provisioner Github 仓库 也已经处于归档状态,已经迁移到 nfs-subdir-external-provisioner 的仓库。

官方提供的安装方式有三种:

  • With Helm
  • With Kustomize
  • Manually

使用 Helm 的方式比较简单,也是现在官方推荐的、使用率最高的方式。

往期我已经分享过如何使用 Helm 的方式部署 NFS Subdir External Provisioner。所以,今天实战演示如何手动部署。

其实,我个人更喜欢手动部署,手动方式更灵活,适用于没有 Helm 或是跟我一样不愿意用 Helm 的离线或在线环境。

3.1 获取 NFS Subdir External Provisioner 部署文件

在 K8S 控制节点 ksp-control-1 ,下载最新版 nfs-subdir-external-provisioner-4.0.18 Releases 文件,并解压。

bash 复制代码
wget https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/archive/refs/tags/nfs-subdir-external-provisioner-4.0.18.zip
unzip nfs-subdir-external-provisioner-4.0.18.zip
cd nfs-subdir-external-provisioner-nfs-subdir-external-provisioner-4.0.18/

3.2 创建 NameSpace

可选配置,默认为 default,新建方便资源管理

bash 复制代码
kubectl create ns nfs-system

3.3 配置 RBAC authorization

  • 替换命名空间名称
bash 复制代码
 sed -i'' "s/namespace:.*/namespace: nfs-system/g" ./deploy/rbac.yaml ./deploy/deployment.yaml
  • 创建 RBAC 资源
bash 复制代码
kubectl create -f deploy/rbac.yaml

3.4 配置 NFS subdir external provisioner

编辑 provisioner's deployment 文件 deploy/deployment.yaml,重点修改以下内容:

  • image: 默认使用 registry.k8s.io 镜像仓库的镜像 nfs-subdir-external-provisioner:v4.0.2,网络受限时需要想办法下载并上传到方便访问的镜像仓库
  • NFS 服务器的主机名或是 IP 地址
  • NFS 服务器导出的共享数据目录的路径(exportfs)

文件 deployment.yaml 默认内容如下:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: nfs-system
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: registry.k8s.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: 10.3.243.101
            - name: NFS_PATH
              value: /ifs/kubernetes
      volumes:
        - name: nfs-client-root
          nfs:
            server: 10.3.243.101
            path: /ifs/kubernetes

说明: 主要修改内容,用实际 NFS 配置信息替换默认值(受限于篇幅,未展示最终修改后的内容)

3.5 部署 NFS Subdir External Provisioner

  • 执行部署命令
bash 复制代码
 kubectl apply -f deploy/deployment.yaml
  • 查看 deployment、pod 部署结果
bash 复制代码
$ kubectl get deployment,pods -n nfs-system
NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nfs-client-provisioner   1/1     1            1           41s

NAME                                          READY   STATUS    RESTARTS   AGE
pod/nfs-client-provisioner-75df4c7d5b-nc2ts   1/1     Running   0          41s

3.6 部署 Storage Class

Step 1: 编辑 NFS subdir external provisioner 定义 Kubernetes Storage Class 的配置文件 deploy/class.yaml,重点修改以下内容:

  • 存储类名称
  • 存储卷删除后的默认策略

文件默认内容如下:

yaml 复制代码
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"

修改后的文件内容如下:

yaml 复制代码
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-sc
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
  archiveOnDelete: "true"

说明: 主要修改内容

  • metadata.name,设置存储类的名称为 nfs-sc
  • parameters.archiveOnDelete,设置为 true

重点说说 Parameters archiveOnDelete 的配置。

  • 该值为 false 时,存储卷删除时,在 NFS 上直接删除对应的数据目录
  • 该值为 true 时,存储卷删除时,在 NFS 上以 archived-<volume.Name> 的命名规则,归档保留原有的数据目录
  • 具体如何设置请一定结合自己的实际环境酌情处理,数据量小的场景下,个人喜欢设置为 true,手动或自动定时清理归档数据。

Parameters 所有可选设置项如下所示,各位可自行研究、使用:

Name Description Default
onDelete If it exists and has a delete value, delete the directory, if it exists and has a retain value, save the directory. will be archived with name on the share: archived-<volume.Name>
archiveOnDelete If it exists and has a false value, delete the directory. if onDelete exists, archiveOnDelete will be ignored. will be archived with name on the share: archived-<volume.Name>
pathPattern Specifies a template for creating a directory path via PVC metadata's such as labels, annotations, name or namespace. To specify metadata use ${.PVC.<metadata>}. Example: If folder should be named like <pvc-namespace>-<pvc-name>, use ${.PVC.namespace}-${.PVC.name} as pathPattern. n/a

Step 2: 执行部署命令,部署 Storage Class。

bash 复制代码
kubectl apply -f deploy/class.yaml

查看 Storage Class 部署结果。

bash 复制代码
$ kubectl get sc
NAME                 PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local (default)      openebs.io/local                              Delete          WaitForFirstConsumer   false                  50d
nfs-sc               k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate              false                  19s

4. 验证测试

4.1 创建测试 PVC

  • 编写测试 PVC 资源清单,vi test-nfs-pvc.yaml
yaml 复制代码
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-nfs-pvc
spec:
  storageClassName: nfs-sc
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  • 创建 PVC
bash 复制代码
kubectl apply -f test-nfs-pvc.yaml
  • 查看 PVC
bash 复制代码
$ kubectl get pvc -o wide
NAME           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
test-nfs-pvc   Bound    pvc-6b7abed8-805e-45ff-82c8-1ad3beca8b9e   1Gi        RWX            nfs-sc         10s   Filesystem

4.2 创建测试 Pod

  • 编写测试 Pod 资源清单,vi test-nfs-pod.yaml
yaml 复制代码
kind: Pod
apiVersion: v1
metadata:
  name: test-nfs-pod
spec:
  containers:
  - name: test-nfs-pod
    image: busybox:stable
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/SUCCESS && sleep 3600"
    volumeMounts:
      - name: nfs-pvc
        mountPath: "/mnt"
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: test-nfs-pvc
  • 创建 Pod
bash 复制代码
kubectl apply -f test-nfs-pod.yaml
  • 查看 Pod
bash 复制代码
$ kubectl get pods -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP              NODE           NOMINATED NODE   READINESS GATES
test-nfs-pod   1/1     Running   0          5s    10.233.68.152   ksp-worker-2   <none>           <none>
  • 查看 Pod 挂载的存储
bash 复制代码
$ kubectl exec test-nfs-pod -- df -h
Filesystem                Size      Used Available Use% Mounted on
overlay                  99.9G      6.6G     93.3G   7% /
tmpfs                    64.0M         0     64.0M   0% /dev
tmpfs                     7.6G         0      7.6G   0% /sys/fs/cgroup
192.168.9.97:/datanfs/k8s/default-test-nfs-pvc-pvc-6b7abed8-805e-45ff-82c8-1ad3beca8b9e
                         99.9G    746.0M     99.2G   1% /mnt
/dev/mapper/openeuler-root
                         34.2G      2.2G     30.2G   7% /etc/hosts
/dev/mapper/openeuler-root
                         34.2G      2.2G     30.2G   7% /dev/termination-log
/dev/mapper/data-lvdata
                         99.9G      6.6G     93.3G   7% /etc/hostname
/dev/mapper/data-lvdata
                         99.9G      6.6G     93.3G   7% /etc/resolv.conf
shm                      64.0M         0     64.0M   0% /dev/shm
tmpfs                    13.9G     12.0K     13.9G   0% /var/run/secrets/kubernetes.io/serviceaccount
tmpfs                     7.6G         0      7.6G   0% /proc/acpi
tmpfs                    64.0M         0     64.0M   0% /proc/kcore
tmpfs                    64.0M         0     64.0M   0% /proc/keys
tmpfs                    64.0M         0     64.0M   0% /proc/timer_list
tmpfs                    64.0M         0     64.0M   0% /proc/sched_debug
tmpfs                     7.6G         0      7.6G   0% /proc/scsi
tmpfs                     7.6G         0      7.6G   0% /sys/firmware

注意: 在输出结果中我们可以看到挂载的 NFS 存储的可用空间为 99.9G ,而不是我们 PVC 中分配的 1G

  • 测试存储空间是否能超限(分配 1G,使用 2G
bash 复制代码
# 写入 2G 的数据
$ kubectl exec test-nfs-pod -- dd if=/dev/zero of=/mnt/test-nfs.img bs=1M count=2000
2000+0 records in
2000+0 records out
2097152000 bytes (2.0GB) copied, 2.731103 seconds, 732.3MB/s

# 查看结果
$ kubectl exec test-nfs-pod -- ls -lh /mnt/
total 2G
-rw-r--r--    1 nobody   nobody         0 Jul 11 21:45 SUCCESS
-rw-r--r--    1 nobody   nobody      2.0G Jul 11 21:47 test-nfs.img

注意: 实际测试我们写入了 2G 的数据量,已经超过了我们创建的 PVC 1G 的限制。因此,要特别注意,使用 NFS 存储时无法限制存储使用量

4.3 存储节点查看验证

SSH 登陆 NFS 存储服务器( ksp-storage-1 节点),执行以下命令。

bash 复制代码
# 查看 NFS 导出数据根目录
$ ls -l /datanfs/k8s/
total 0
drwxrwxrwx. 2 nobody nobody 41 Jul 11 21:47 default-test-nfs-pvc-pvc-6b7abed8-805e-45ff-82c8-1ad3beca8b9e

# 查看分配的 PVC 数据目录
$ ls -l /datanfs/k8s/default-test-nfs-pvc-pvc-6b7abed8-805e-45ff-82c8-1ad3beca8b9e/
total 2048000
-rw-r--r--. 1 nobody nobody          0 Jul 11 21:45 SUCCESS
-rw-r--r--. 1 nobody nobody 2097152000 Jul 11 21:47 test-nfs.img

在输出结果中,可以看见 SUCCESStest.img 两个文件,并且可以看出命名目录的规则为 namespace 名称-pvc 名称-pv 名称

PV 名称格式是 pvc+随机字符串,所以,每次只要不删除 PVC,那么 Kubernetes 中 PV 与存储绑定将不会丢失,要是删除 PVC 也就意味着删除了绑定的文件夹,下次就算重新创建相同名称的 PVC,生成的文件夹名称也不会一致,因为 PV 名是随机生成的字符串,而文件夹命名又跟 PV 有关,所以删除 PVC 需谨慎。

4.4 清理测试资源

  • 清理测试 Pod、PVC
bash 复制代码
kubectl delete -f test-nfs-pod.yaml  -f test-nfs-pvc.yaml
  • 在 NFS 存储服务器查看数据目录
bash 复制代码
# 查看 NFS 导出数据根目录
$ ls -l /datanfs/k8s/
total 0
drwxrwxrwx. 2 nobody nobody 41 Jul 11 21:47 archived-default-test-nfs-pvc-pvc-6b7abed8-805e-45ff-82c8-1ad3beca8b9e

# 查看删除的 PVC 数据目录
$ ls -l /datanfs/k8s/archived-default-test-nfs-pvc-pvc-6b7abed8-805e-45ff-82c8-1ad3beca8b9e/
total 2048000
-rw-r--r--. 1 nobody nobody          0 Jul 11 21:45 SUCCESS
-rw-r--r--. 1 nobody nobody 2097152000 Jul 11 21:47 test-nfs.img

从结果中可以看到,Kubernetes 删除 PVC 后,在 NFS 存储层并没有立即删除 PVC 对应的数据目录及数据,而是将原来的数据目录改名为 archived-+原有数据目录名称的形式。

该结果与我们配置 Storage Class 时,将参数 archiveOnDelete 值设置为 true 的预期相符(你可以可自行测试其他参数和值的配置效果)。

5. KubeSphere 控制台管理存储资源

5.1 管理存储类

在控制台左侧功能菜单,依次选择「集群」->「存储」->「存储类」。

5.2 创建持久卷声明(PVC)

Step 1: 在控制台左侧功能菜单,依次选择「集群」->「存储」->「持久卷声明」,点击「创建」按钮。

  • 按提示填写基本信息
  • 按提示填写存储设置,存储类选择 nfs-sc,容量选择 2G
  • 高级设置保持默认,点击「创建」

Step 2: 创建完成后,查看已经创建的 PVC、PV 及详情。

  • 已创建的 PVC 列表
  • 已创建的 PV 列表
  • 查看 nfs-test-pvc1 详情(未挂载使用,所以显示容量为 0
  • 创建一个 Pod,挂载 nfs-test-pvc1,再次查看详情。

容量显示 NFS 存储空间的总容量、剩余容量、已使用百分比,并不是单个 PV 的容量信息。初始测试时占用 2G 未删除,因此 NFS 存储空间总体分配了 4G,显示结果略有差异也属于正常现象。

6. 卸载 NFS Subdir External Provisioner

6.1 卸载前提条件

当需要卸载 NFS Subdir External Provisioner 时,先确认满足以下前提条件。

  • 清理所有使用 PVC 资源的 Pod(谨慎操作
  • 清理所有的 PVC(可以选择在 KubeSphere 的管理控制台页面中清理,可视化更全面、更清晰)
  • 手工清理 NFS 存储中残留的以 archived- 命名的所有数据目录(可选,谨慎操作

6.2 卸载 NFS Subdir External Provisioner

按顺序执行资源删除命令, 卸载 NFS Subdir External Provisioner。

  • 删除 Storage Class
bash 复制代码
kubectl delete -f deploy/class.yaml
  • 删除 NFS Subdir External Provisioner
bash 复制代码
kubectl delete -f deploy/deployment.yaml
  • 删除 RBAC authorization 配置
bash 复制代码
kubectl delete -f deploy/rbac.yaml
  • 验证资源是否卸载
bash 复制代码
$ kubectl get deploy,pod,sc -n nfs-system
NAME                                          PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
storageclass.storage.k8s.io/local (default)   openebs.io/local   Delete          WaitForFirstConsumer   false                  22h

说明: 结果中显示的是默认的 openebs 存储,nfs 相关资源已经删除

  • 删除 NameSpace(如果有,可选
bash 复制代码
kubectl delete ns nfs-system

免责声明:

  • 笔者水平有限,尽管经过多次验证和检查,尽力确保内容的准确性,但仍可能存在疏漏之处。敬请业界专家大佬不吝指教。
  • 本文所述内容仅通过实战环境验证测试,读者可学习、借鉴,但严禁直接用于生产环境由此引发的任何问题,作者概不负责

本文由博客一文多发平台 OpenWrite 发布!

相关推荐
是芽芽哩!41 分钟前
【Kubernetes 指南】基础入门——Kubernetes 基本概念(二)
云原生·容器·kubernetes
怡雪~2 小时前
k8s使用ceph
ceph·容器·kubernetes
运维小文3 小时前
K8S中的服务质量QOS
云原生·容器·kubernetes
华为云开发者联盟4 小时前
Karmada v1.12 版本发布!单集群应用迁移可维护性增强
云原生·kubernetes·开源·容器编排·karmada
Hadoop_Liang4 小时前
Kubernetes Secret的创建与使用
云原生·容器·kubernetes
元气满满的热码式4 小时前
K8S集群部署实战(超详细)
云原生·容器·kubernetes
上海运维Q先生5 小时前
面试题整理13----deployment和statefulset区别
运维·面试·kubernetes
AKA小徐11 小时前
Debian12使用RKE2离线部署3master2node三主两从的k8s集群详细教程
kubernetes·rancher·rke2
花晓木1 天前
k8s etcd 数据损坏处理方式
容器·kubernetes·etcd
运维&陈同学1 天前
【模块一】kubernetes容器编排进阶实战之基于velero及minio实现etcd数据备份与恢复
数据库·后端·云原生·容器·kubernetes·etcd·minio·velero