30 分钟玩转 Kubernetes 持久化存储之 NFS 实战入门

2023-11-30 16:56:07 浏览数 (1)

基于 KubeSphere 玩转 Kubernetes 第二季|30 分钟玩转 Kubernetes 持久化存储之 NFS 实战入门

大家好,欢迎来到运维有术

欢迎来到云原生运维实战系列之基于 KubeSphere 玩转 Kubernetes 第二季

前言

导图

ksp-v340-v126-nfs-mindmapksp-v340-v126-nfs-mindmap

知识量

  • 阅读时长:12 分
  • 行:737
  • 单词:4700
  • 字符:23500
  • 图片:6 张

知识点

  • 定级:入门级
  • NFS 服务器安装部署
  • Helm 安装配置 Kubernetes NFS Subdir External Provisioner
  • Kubernetes 使用 NFS 作为持久化存储
  • KubeSphere 管理控制台管理 NFS 存储

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

主机名

IP

CPU

内存

系统盘

数据盘

用途

k8s-master-1

192.168.9.91

4

16

40

100

KubeSphere/k8s-master

k8s-master-2

192.168.9.92

4

16

40

100

KubeSphere/k8s-master

k8s-master-3

192.168.9.93

4

16

40

100

KubeSphere/k8s-master

k8s-worker-1

192.168.9.95

4

16

40

100

k8s-worker/CI

k8s-worker-2

192.168.9.96

4

16

40

100

k8s-worker

k8s-worker-3

192.168.9.97

4

16

40

100

k8s-worker

k8s-storage-1

192.168.9.81

4

16

40

100/100/100/100/100

ElasticSearch/GlusterFS/Ceph-Rook/Longhorn/NFS/

k8s-storage-2

192.168.9.82

4

16

40

100/100/100/100

ElasticSearch/GlusterFS/Ceph-Rook/Longhorn/

k8s-storage-3

192.168.9.83

4

16

40

100/100/100/100

ElasticSearch/GlusterFS/Ceph-Rook/Longhorn/

registry

192.168.9.80

4

8

40

100

Sonatype Nexus 3

合计

10

40

152

400

2000

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

  • 操作系统:CentOS 7.9 x86_64
  • KubeSphere:v3.4.0
  • Kubernetes:v1.24.12
  • Containerd:1.6.4
  • KubeKey: v3.0.13
  • nfs-subdir-external-provisioner:v4.0.2

1. 简介

玩转 Kubernetes 必然少不了持久化存储,不考虑各种公有云上的 Kubernetes 集群和商业化集中存储,自建的 Kubernetes 集群中,后端持久化存储常见的解决方案有 Ceph、GlusterFS、NFS,以及这两年新兴起的 Longhorn(也可能还有我不了解的其他的更好的)。

所以我们的实战课程基于这四种常见持久化存储解决方案设计了「Kubernetes 持久化存储四部曲」。上一期我们完成了第一部 GlusterFS 存储的实战。本期实战课程,我们将完成第二部实战 NFS,我们使用 Helm 的方式安装 Kubernetes NFS Subdir External Provisioner 插件,并实战演示如何将 NFS 作为 Kubernetes 集群的后端持久化存储。

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

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

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

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

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

2. NFS 服务器部署

本文选择 IP 为 192.168.9.81 的 k8s-storage-1 节点,作为 NFS 存储服务器。本示例的 NFS 服务器配置仅适用于测试环境,生产环境请谨慎评估、配置。

2.1 安装 NFS 服务端软件包

代码语言:shell复制
yum install nfs-utils

2.2 创建共享数据目录

执行以下命令创建共享数据存储目录,本文以 /data/k8s 为例,请根据实际情况修改。

代码语言:shell复制
mkdir -p /data/k8s
chown nfsnobody:nfsnobody /data/k8s

2.3 编辑服务配置文件

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

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

代码语言:shell复制
/data/k8s 192.168.9.0/24(rw,sync,all_squash,anonuid=65534,anongid=65534,no_subtree_check)

说明:

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

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

代码语言:shell复制
systemctl enable nfs-server --now

2.5 查看共享目录

  • 查看导出目录
代码语言:shell复制
exportfs -v
  • 实际的效果
代码语言:shell复制
[root@ksp-v341-storage-1 ~]# exportfs -v
/data/k8s       192.168.9.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,all_squash)

2.6 客户端挂载测试

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

  • 创建测试挂载点
代码语言:shell复制
mkdir /mnt/nfs
  • 安装 NFS 软件包(一定要安装,否则无法识别 nfs 类型的存储)
代码语言:shell复制
yum install nfs-utils
  • 挂载 NFS 共享目录
代码语言:shell复制
mount -t nfs 192.168.9.81:/data/k8s /mnt/nfs/
  • 增删改查测试
代码语言:shell复制
# 创建测试目录、创建测试文件、测试文件写入内容、查看写入目录和文件权限、删除目录和文件
[root@k8s-master-1 ~]# cd /mnt/nfs/
[root@k8s-master-1 nfs]# mkdir nfs-test
[root@k8s-master-1 nfs]# touch nfs-test.txt
[root@k8s-master-1 nfs]# echo "nfs-test" > nfs-test.txt
[root@k8s-master-1 nfs]# ll
total 4
drwxr-xr-x 2 nfsnobody nfsnobody 6 Nov 29 16:56 nfs-test
-rw-r--r-- 1 nfsnobody nfsnobody 9 Nov 29 16:56 nfs-test.txt
[root@k8s-master-1 nfs]# rmdir nfs-test
[root@k8s-master-1 nfs]# rm nfs-test.txt
rm: remove regular file ‘nfs-test.txt’? y
[root@k8s-master-1 nfs]# ll
total 0

3. 安装 Kubernetes NFS Subdir External Provisioner

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

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

  • With Helm
  • With Kustomize
  • Manually

使用 Helm 的方式比较简单,也是现在官方推荐的、使用率最高的方式,本文仅实战演示 Helm 部署方式,其他方式请参考官方文档。

3.1 集群节点安装 NFS Client

所有 Kubernetes 集群节点需要提前安装 nfs-utils,否则在部署过程中会报错,报错信息见「常见问题 1」

代码语言:shell复制
yum install nfs-utils

3.2 添加 Helm 源

代码语言:shell复制
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner

3.3 创建 NameSpace

可选配置,主要是方便资源管理

代码语言:shell复制
kubectl create ns nfs-system

3.4 命令行快速安装 Kubernetes NFS Subdir External Provisioner

(首选方案,使用命令行设置变量参数)

  • 命令行安装 NFS Subdir External Provisioner
代码语言:shell复制
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --set storageClass.name=nfs-sc --set nfs.server=192.168.9.81 --set nfs.path=/data/k8s -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:指定命名空间

3.5 自定义 values 安装 NFS Subdir External Provisioner

(备选方案,使用配置文件设置变量参数),有更多定制化需求时可以选择自定义 values.yaml 的方式进行安装,实际使用中与命令行安装 NFS Subdir External Provisioner 的方式二选一即可。

  • 下载 Charts
代码语言:shell复制
helm pull nfs-subdir-external-provisioner/nfs-subdir-external-provisioner
  • 解压下载的 Charts
代码语言:shell复制
# 查看
[root@k8s-master-1 charts]# ll
total 8
-rw-r--r-- 1 root root 5991 Nov 30 10:26 nfs-subdir-external-provisioner-4.0.18.tgz

# 解压
[root@k8s-master-1 charts]# tar xvf nfs-subdir-external-provisioner-4.0.18.tgz
nfs-subdir-external-provisioner/Chart.yaml
nfs-subdir-external-provisioner/values.yaml
nfs-subdir-external-provisioner/templates/_helpers.tpl
nfs-subdir-external-provisioner/templates/clusterrole.yaml
nfs-subdir-external-provisioner/templates/clusterrolebinding.yaml
nfs-subdir-external-provisioner/templates/deployment.yaml
nfs-subdir-external-provisioner/templates/persistentvolume.yaml
nfs-subdir-external-provisioner/templates/persistentvolumeclaim.yaml
nfs-subdir-external-provisioner/templates/poddisruptionbudget.yaml
nfs-subdir-external-provisioner/templates/podsecuritypolicy.yaml
nfs-subdir-external-provisioner/templates/role.yaml
nfs-subdir-external-provisioner/templates/rolebinding.yaml
nfs-subdir-external-provisioner/templates/serviceaccount.yaml
nfs-subdir-external-provisioner/templates/storageclass.yaml
nfs-subdir-external-provisioner/README.md
nfs-subdir-external-provisioner/ci/test-values.yaml
  • 查看 values
代码语言:shell复制
[root@k8s-master-1 charts]# cat nfs-subdir-external-provisioner/values.yaml | egrep -v '#|^$'

筛选过滤后的可用配置项,详细配置及说明

代码语言:yaml复制
replicaCount: 1
strategyType: Recreate
image:
  repository: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner
  tag: v4.0.2
  pullPolicy: IfNotPresent
imagePullSecrets: []
nfs:
  server:
  path: /nfs-storage
  mountOptions:
  volumeName: nfs-subdir-external-provisioner-root
  reclaimPolicy: Retain
storageClass:
  create: true
  defaultClass: false
  name: nfs-client
  allowVolumeExpansion: true
  reclaimPolicy: Delete
  archiveOnDelete: true
  onDelete:
  pathPattern:
  accessModes: ReadWriteOnce
  volumeBindingMode: Immediate
  annotations: {}
leaderElection:
  enabled: true
rbac:
  create: true
podSecurityPolicy:
  enabled: false
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
serviceAccount:
  create: true
  annotations: {}
  name:
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
labels: {}
podDisruptionBudget:
  enabled: false
  maxUnavailable: 1
  • 根据实际情况修改 nfs-subdir-external-provisioner/values.yaml
代码语言:yaml复制
# 主要修改内容如下
image:
  repository: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner  #镜像拉取地址,默认可能拉取不下来,建议替换成本地或是其他可正常访问的仓库,也可以使用我DockerHub上的的 unopsman/nfs-subdir-external-provisioner
  tag: v4.0.2             #镜像 tag 默认为 v4.0.2,可根据实际情况替换
nfs:
  server: 192.168.9.81    #指定 NFS 服务器的地址
  path: /data/k8s         #指定 NFS 导出的共享数据目录
storageClass:
  defaultClass: false     #是否设置为默认的 StorageClass,本示例没设置,有需要的可以设置为 true
  name: nfs-sc            #指定 storageClass 的名字
  • 安装 NFS Subdir External Provisioner
代码语言:shell复制
[root@k8s-master-1 charts]# helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner -f nfs-subdir-external-provisioner/values.yaml -n nfs-system
NAME: nfs-subdir-external-provisioner
LAST DEPLOYED: Thu Nov 30 14:00:21 2023
NAMESPACE: nfs-system
STATUS: deployed
REVISION: 1
TEST SUITE: None

4. 验证测试

4.1 查看创建的资源

  • 查看 sc
代码语言:shell复制
[root@k8s-master-1 ~]# kubectl get sc nfs-sc -o wide
NAME     PROVISIONER                                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-sc   cluster.local/nfs-subdir-external-provisioner   Delete          Immediate           true                   66s
  • 查看 Image(在个人 Mac 电脑上查看的结果)
代码语言:shell复制
$ docker images
REPOSITORY                                                    TAG                            IMAGE ID       CREATED         SIZE
registry.k8s.io/sig-storage/nfs-subdir-external-provisioner   v4.0.2                         932b0bface75   2 years ago     43.8MB


$ docker scout quickview registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
    ✓ SBOM of image already cached, 46 packages indexed

  Target   │  registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2  │    3C    57H    34M     4L
    digest │  932b0bface75                                                        │

特殊说明:

镜像构建时间有点久远,在 2023 年 11 月 29 日查看时显示为 2 年前。 镜像安全扫描结果(安全隐患):98 vulnerabilities found in 9 packages,LOW 4,MEDIUM 34,HIGH 57,CRITICAL 3

  • 查看 Deployment
代码语言:shell复制
[root@k8s-master-1 ~]# kubectl get deployment -n nfs-system -o wide
NAME                              READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS                        IMAGES                                                               SELECTOR
nfs-subdir-external-provisioner   1/1     1            1           73m   nfs-subdir-external-provisioner   registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2   app=nfs-subdir-external-provisioner,release=nfs-subdir-external-provisioner
  • 查看 Pod
代码语言:shell复制
[root@k8s-master-1 ~]# kubectl get pod -n nfs-system -o wide
NAME                                               READY   STATUS    RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
nfs-subdir-external-provisioner-65f66bc6cd-hdpts   1/1     Running   0          4m20s   10.233.85.5   k8s-master-2   <none>           <none>

4.2 创建测试 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
代码语言:shell复制
kubectl apply -f test-nfs-pvc.yaml -n nfs-system
  • 查看 PVC
代码语言:shell复制
[root@k8s-master-1 ~]# kubectl get pvc -n nfs-system -o wide
NAME           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
test-nfs-pvc   Bound    pvc-2d245af1-f613-485d-9782-0c315cead56c   1Gi        RWX            nfs-sc         20s   Filesystem

4.3 创建测试 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
代码语言:shell复制
kubectl apply -f test-nfs-pod.yaml -n nfs-system
  • 查看 Pod
代码语言:shell复制
[root@k8s-master-1 ~]# kubectl get pods -n nfs-system -o wide
NAME                                               READY   STATUS    RESTARTS   AGE   IP             NODE           NOMINATED NODE   READINESS GATES
nfs-subdir-external-provisioner-5d5bcf7fcb-d98gd   1/1     Running   0          97s   10.233.85.28   k8s-master-2   <none>           <none>
test-nfs-pod                                       1/1     Running   0          11s   10.233.85.29   k8s-master-2   <none>           <none>
  • 查看 Pod 挂载的存储
代码语言:shell复制
[root@k8s-master-1 ~]# kubectl exec test-nfs-pod -n nfs-system -- df -h
Filesystem                Size      Used Available Use% Mounted on
overlay                 100.0G      2.3G     97.7G   2% /
tmpfs                    64.0M         0     64.0M   0% /dev
tmpfs                     7.8G         0      7.8G   0% /sys/fs/cgroup
192.168.9.81:/data/k8s/nfs-system-test-nfs-pvc-pvc-2d245af1-f613-485d-9782-0c315cead56c
                         99.9G     33.0M     99.9G   0% /mnt
/dev/mapper/centos-root
                         37.0G      3.1G     33.8G   8% /etc/hosts
/dev/mapper/centos-root
                         37.0G      3.1G     33.8G   8% /dev/termination-log
/dev/sdb1               100.0G      2.3G     97.7G   2% /etc/hostname
/dev/sdb1               100.0G      2.3G     97.7G   2% /etc/resolv.conf
shm                      64.0M         0     64.0M   0% /dev/shm
tmpfs                    14.4G     12.0K     14.4G   0% /var/run/secrets/kubernetes.io/serviceaccount
tmpfs                     7.8G         0      7.8G   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.8G         0      7.8G   0% /proc/scsi
tmpfs                     7.8G         0      7.8G   0% /sys/firmware

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

  • 测试存储空间是否能超限
代码语言:shell复制
# 写入 2G 的数据
[root@k8s-master-1 ~]# kubectl exec test-nfs-pod -n nfs-system -- dd if=/dev/zero of=/mnt/test.img bs=1M count=2000
2000 0 records in
2000 0 records out
2097152000 bytes (2.0GB) copied, 3.115083 seconds, 642.0MB/s

# 查看结果
[root@k8s-master-1 ~]# kubectl exec test-nfs-pod -n nfs-system -- ls -lh /mnt/
total 3G
-rw-r--r--    1 nobody   nobody         0 Nov 30 06:01 SUCCESS
-rw-r--r--    1 nobody   nobody      2.0G Nov 30 06:04 test.img

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

4.4 存储节点查看验证

SSH 登陆 NFS 存储节点,执行以下命令。

代码语言:shell复制
[root@k8s-storage-1 ~]# cd /data/k8s/
[root@k8s-storage-1 k8s]# ll
total 0
drwxrwxrwx 2 nfsnobody nfsnobody 37 Nov 30 14:04 nfs-system-test-nfs-pvc-pvc-2d245af1-f613-485d-9782-0c315cead56c
[root@k8s-storage-1 k8s]# ll nfs-system-test-nfs-pvc-pvc-2d245af1-f613-485d-9782-0c315cead56c/
total 2975684
-rw-r--r-- 1 nfsnobody nfsnobody          0 Nov 30 14:01 SUCCESS
-rw-r--r-- 1 nfsnobody nfsnobody 2097152000 Nov 30 14:04 test.img

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

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

4.5 清理测试资源

  • 清理测试 Pod、Pvc
代码语言:shell复制
kubectl delete -f test-nfs-pod.yaml -n nfs-system
kubectl delete -f test-nfs-pvc.yaml -n nfs-system
  • 在存储侧查看数据目录
代码语言:shell复制
[root@k8s-storage-1 k8s]# ll
total 0
drwxrwxrwx 2 nfsnobody nfsnobody 37 Nov 30 14:04 archived-nfs-system-test-nfs-pvc-pvc-2d245af1-f613-485d-9782-0c315cead56c

[root@k8s-storage-1 k8s]# ll archived-nfs-system-test-nfs-pvc-pvc-2d245af1-f613-485d-9782-0c315cead56c/
total 2048004
-rw-r--r-- 1 nfsnobody nfsnobody          0 Nov 30 14:01 SUCCESS
-rw-r--r-- 1 nfsnobody nfsnobody 2097152000 Nov 30 14:04 test.img

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

5. 其它实用操作

5.1 在 KubeSphere 管理控制台创建 PVC

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

ksp-v340-clusters-volumesksp-v340-clusters-volumes
  • 按提示填写基本信息
ksp-v340-clusters-volumes-baseksp-v340-clusters-volumes-base
  • 按提示填写存储设置,存储类选择 nfs-sc,容量选择 2G
ksp-v340-clusters-volumes-storageksp-v340-clusters-volumes-storage
  • 高级设置保持默认
ksp-v340-clusters-volumes-advancedksp-v340-clusters-volumes-advanced

创建完成后,查看已经创建的 PVC 及详情。

  • 已有 PVC
ksp-v340-clusters-volumes-volumesksp-v340-clusters-volumes-volumes
  • 已经挂载使用的 PVC 详情(test-nfs-pod,测试时使用的,用了 2G,显示结果略有差异属于正常现象)
ksp-v340-clusters-volumes-resource-statusksp-v340-clusters-volumes-resource-status
  • 未挂载使用的 PVC 详情(nfs-test-pvc1,未使用所有显示容量为 0)
ksp-v340-clusters-volumes-resource-status-nuksp-v340-clusters-volumes-resource-status-nu

5.2 卸载 NFS Subdir External Provisioner

当需要卸载 NFS Subdir External Provisioner 时,建议按以下操作流程执行。

  • 清理所有的 PVC(可以选择在 KubeSphere 的管理控制台页面中清理,可视化看着更全面清晰)
  • 手工清理 NFS 存储中残留的以 archived- 命名的所有数据目录(可选,谨慎操作
  • 使用 Helm 卸载 NFS Subdir External Provisioner
代码语言:shell复制
# 查看 helm 资源
[root@k8s-master-1 ~]# helm list -n nfs-system
NAME                            NAMESPACE       REVISION        UPDATED                                 STATUS      CHART                                    APP VERSION
nfs-subdir-external-provisioner nfs-system      1               2023-11-29 14:40:31.868722982  0800 CST deployed    nfs-subdir-external-provisioner-4.0.18   4.0.2

# 卸载
[root@k8s-master-1 ~]# helm uninstall nfs-subdir-external-provisioner -n nfs-system
release "nfs-subdir-external-provisioner" uninstalled

# 查看
[root@k8s-master-1 ~]# helm list -n nfs-system
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION
  • 验证资源是否卸载
代码语言:shell复制
[root@k8s-master-1 ~]# 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(如果有,可选
代码语言:shell复制
kubectl delete ns nfs-system

6. 常见问题

6.1 问题 1

  • 报错信息
代码语言:shell复制
# Pod nfs-subdir-external-provisioner 创建失败,查看详细报错
$ kubectl describe pod nfs-subdir-external-provisioner-7845498695-hmf7f -n nfs-system
报错如下:

Events:
  Type     Reason       Age                   From               Message
  ----     ------       ----                  ----               -------
  Normal   Scheduled    4m58s                 default-scheduler  Successfully assigned nfs-system/nfs-subdir-external-provisioner-7845498695-hmf7f to k8s-master-2
  Warning  FailedMount  48s (x10 over 4m58s)  kubelet            MountVolume.SetUp failed for volume "nfs-subdir-external-provisioner-root" : mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t nfs 192.168.9.81:/data/k8s /var/lib/kubelet/pods/371d85d0-5e31-4d9e-a56f-87a66a35b97e/volumes/kubernetes.io~nfs/nfs-subdir-external-provisioner-root
Output: mount: wrong fs type, bad option, bad superblock on 192.168.9.81:/data/k8s,
       missing codepage or helper program, or other error
       (for several filesystems (e.g. nfs, cifs) you might
       need a /sbin/mount.<type> helper program)

       In some cases useful info is found in syslog - try
       dmesg | tail or so.
  Warning  FailedMount  38s (x2 over 2m55s)  kubelet  Unable to attach or mount volumes: unmounted volumes=[nfs-subdir-external-provisioner-root], unattached volumes=[nfs-subdir-external-provisioner-root kube-api-access-jnxrs]: timed out waiting for the condition
  • 解决方案

所有节点需要安装 nfs 客户端软件包,CentOS 使用 yum install nfs-utils

7. 总结

本文实战演示了在操作系统 CentOS 7.9 x64 上安装配置 NFS 的详细过程,同时,也详细讲解了在基于 KubeSphere 部署的 Kubernetes 集群中,使用 helm 方式安装 Kubernetes NFS Subdir External Provisioner 的两种方法及相关技术细节。

概括总结全文主要涉及以下内容:

  • 基于 CentOS 7.9 的 NFS 服务器安装部署
  • Kubernetes NFS Subdir External Provisioner 常用方式安装介绍
  • Helm 命令行方式安装 Kubernetes NFS Subdir External Provisioner
  • Helm 配置文件方式安装 Kubernetes NFS Subdir External Provisioner
  • Helm 安装的 Kubernetes NFS Subdir External Provisioner 如何卸载
  • Kubernetes 集群使用 NFS 作为后端存储示例、常见问题及小技巧
  • KubeSphere 管理控制台管理持久化存储

本文的实战环境虽然是基于 CentOS 7.9 x64,但是整个操作流程同样适用于其他操作系统。

结束语

如果你喜欢本文,请持续关注我,并将本文分享给你的小伙伴!

基于 KubeSphere 玩转 Kubernetes 第二季系列文档,是 知识星球 运维有术 推出的云原生运维实战训练营之基于 KubeSphere 玩转 Kubernetes 第二季的实战文档。

该系列文档从纯实战角度出发,无废话、纯实战快速带你玩转 KubeSphere、玩转 Kubernetes 运维。

本系列文档内容涵盖 (但不限于) 以下技术领域:

  • OpenStackProxmox Virtual Environment(PVE)
  • KubeSphereKubernetes
  • Ansible自动化运维DevOps
  • 大数据AIGC
  • 云原生CNCF 技术栈

获取更多的 KubeSphere、Kubernetes、云原生运维实战技能,请持续关注我,也可以直接加入我们。

Get 技术支持

  • 知识星球: 运维有术(知识付费

Get 文档 / 代码

  • 微信公众号: 运维有术(创作不易,感谢关注与支持)

Get 视频

  • B 站 运维有术

版权声明

  • 所有内容均属于原创,整理不易,感谢收藏、阅读,未经授权不得转载

About Me

  • 昵称:OpsMan
  • 职业:自由职业者
  • 服务的领域:云计算 、 云原生技术运维,自动化运维,大数据运维
  • 技能标签:OpenStack、Kubernetes、KubeSphere、Ansible、Python、Go、DevOps、CNCF、大数据、云原生、AIGC

0 人点赞