K8S存储实战案例:NFS+StorageClass+PV/PVC+Deployment

科技   2024-11-29 07:31   广东  


本篇文章分享一下在 Kubernetes (K8s) 中搭建 NFS 存储,并实现 PersistentVolume (PV)PersistentVolumeClaim (PVC)、动态存储卷StorageClass,以及通过 Deployment 使用这些存储卷的完整流程,可以按照以下步骤进行。

实验步骤:

  1. 配置 NFS 服务器
  2. 创建 StorageClass
  3. 创建 PV
  4. 创建 PVC
  5. 创建 Deployment,并挂载 PVC 到应用
  6. 挂载验证
    实验架构图

步骤 1: 配置 NFS 服务器

首先,在 Kubernetes 集群外部的服务器上,我们需要搭建一个后端存储:NFS 服务器。

NFS服务器IP地址:10.0.0.103

1.1 安装 NFS 服务

 yum install -y nfs-utils

1.2 创建共享目录

mkdir -p /data/nfs

1.3 配置 NFS 共享目录

编辑 /etc/exports 文件以设置 NFS 共享目录。

vim /etc/exports

在文件中添加以下行:

/data/nfs *(rw,sync,no_subtree_check)

将 /data/nfs 目录以读写(rw)方式对所有客户端(*)共享。

1.4 启动 NFS 服务

启动并将NFS服务设置开机自启

systemctl enable --now nfs-server

1.5 导出共享目录

使共享目录立即生效:

 exportfs -a
 showmount -e

1.6 配置防火墙

如果启用了防火墙,需要允许 NFS 服务的相关端口:

firewall-cmd --per --add-service=nfs
firewall-cmd --per --add-service=mountd
firewall-cmd --per --add-service=rpc-bind
firewall-cmd --reload

步骤 2: 配置StorageClass

在 Kubernetes 中,我们将使用 StorageClass 来动态配置存储卷。通过 PVC 绑定现有的 NFS 存储。

2.1 创建 StorageClass 配置

创建一个名为 nfs-storage-class.yaml 的文件,内容如下:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage-class
provisioner: kubernetes.io/no-provisioner  # NFS 不需要动态 provisioner
reclaimPolicy: retain  # 默认值是 Delete
volumeBindingMode: WaitForFirstConsumer   # 等待 Pod 使用 PVC 时才绑定 PV,默认使用 Immediate 模式:立即绑定

2.2 应用 StorageClass 配置

kubectl apply -f nfs-storage-class.yaml

检查StorageClass状态

[root@k8s-master data]# kubectl get storageclass
NAME                PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
nfs-storage-class   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                  14s

步骤 3: 创建 PV

创建一个 PersistentVolume (PV),将它指向 NFS 共享的目录。

3.1 创建 PV 配置文件

创建一个 nfs-pv.yaml 文件,内容如下:


apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 10Gi  # 定义 PV 的存储容量
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany  # 允许多个 Pod 同时访问此 PV
  persistentVolumeReclaimPolicy: Retain  # 释放 PVC 后保留 PV 数据
  storageClassName: nfs-storage-class  # 与 StorageClass 名称一致
  nfs:
    path: /data/nfs  # NFS 共享目录的路径
    server: 10.0.0.103  # 替换为实际的 NFS 服务器 IP

3.2 应用 PV 配置

kubectl apply -f nfs-pv.yaml

检查 PV 的状态:

[root@k8s-master data]kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM            STORAGECLASS        REASON   AGE
nfs-pv   5Gi        RWX            Retain           Available                      nfs-storage-class            5s

如果 PV 配置正确,它应该处于 Available 状态。

步骤 4: 创建PVC

创建一个 PersistentVolumeClaim (PVC),它请求使用 NFS 存储。

4.1 创建 PVC 配置文件

创建一个 nfs-pvc.yaml 文件,内容如下:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany  # 允许多个 Pod 同时访问
  volumeMode: Filesystem
  resources:
    requests:
      storage: 3Gi  # 请求的存储容量,不能大于PV容量
  storageClassName: nfs-storage-class  # 与 StorageClass 名称一致

4.2 应用 PVC 配置

应用 PVC 配置文件:

kubectl apply -f nfs-pvc.yaml

检查 PVC 的状态:

[root@k8s-master data]kubectl get pvc
NAME      STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS        AGE
nfs-pvc   Pending                                      nfs-storage-class   4m30s

【温馨提示】由于在声明StorageClass时,将volumeBindingMode设置为WaitForFirstConsumer,等待 Pod 使用 PVC 时才绑定 PV,所以现在的PVC是Pending状态,没有绑定对应的Pod。

如果volumeBindingMode设置为Immediate,则会立即绑定,显示为Bound。

步骤 5: 挂载 PVC

创建一个 Deployment,并将 PVC 挂载到 Pod 中。

5.1 创建 Deployment 配置文件

创建一个名为 nginx-deployment.yaml 的文件,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1  # 部署 1 个副本(Pod)
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: docker.m.daocloud.io/nginx:1.25
          volumeMounts:
            - mountPath: /usr/share/nginx/html  # 将 PVC 挂载到此目录
              name: nfs-volume
      volumes:
        - name: nfs-volume
          persistentVolumeClaim:
            claimName: nfs-pvc  # 挂载 PVC

5.2 应用 Deployment 配置

kubectl apply -f nginx-deployment.yaml

5.3 再次检查PVC状态

[root@k8s-master data]kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS        AGE
nfs-pvc   Bound    nfs-pv   5Gi        RWX            nfs-storage-class   10m

此时可以看到已经是Bound状态,说明已经和Pod产生了关联。

5.4 检查 Pod 状态

使用以下命令检查 Pod 状态:

[root@k8s-master data]kubectl get pod 
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-645c47fd8b-sjv5m   1/1     Running   0          8m35s

确保 Pod 正在运行并没有错误。

【温馨提示】如果使用NFS作为后端存储,需要在每个节点上安装NFS客户端,不然Pod无法连接NFS,导致创建Pod失败。

步骤 6: 验证挂载

验证 Nginx Pod 是否正确挂载了 NFS 存储。

6.1 进入 Pod 检查挂载

首先,通过 kubectl exec 命令进入 Pod,检查 /usr/share/nginx/html 目录,看看是否已挂载 NFS 存储

[root@k8s-master data]kubectl exec -it nginx-deployment-645c47fd8b-sjv5m -- /bin/bash 
root@nginx-deployment-645c47fd8b-sjv5m:/ls /usr/share/nginx/html
kube-system-es-pv-claim-pvc-ef2cc9a4-d836-49fe-8d30-b9c98238f5b5
root@nginx-deployment-645c47fd8b-sjv5m:/

如果一切正常,你应该能够看到 NFS 存储中的内容。如果是空的,那就意味着 Nginx Pod 已经成功挂载了 NFS 存储卷。

6.2 测试验证

测试:给index.html文件增加内容

root@nginx-deployment-645c47fd8b-sjv5m:/usr/share/nginx/htmlecho  "hello nginx" > index.html

验证:进入后端NFS挂载目录查看:

[root@harbor ~]cd /data/nfs
[root@harbor nfs]# ls
index.html  kube-system-es-pv-claim-pvc-ef2cc9a4-d836-49fe-8d30-b9c98238f5b5
[root@harbor nfs]cat index.html 
hello nginx

可以看到在Pod里面创建的数据已经存储到NFS存储中。

至此,整个持久化存储的环境已经搭建完成。里面涉及的一些理论概念,我将在下一篇文章进行详细讲解



有缘相遇,不妨点个关注!

END


往期推荐


1

万字长文:K8S命令详解汇总【自用珍藏版】

2

Linux上有趣的8个命令,你玩过几个?

3

Linux的150个常用命令汇总,运维大神不一定全部掌握!

4

【Docker系列知识】常用命令大全汇总

5

局域网内构建统一可访问的YUM源(基础运维必备技能)

6

Nginx配置文件详解及常用功能配置(实用率90%)

运维李哥不背锅
专注于各种运维技术、,分享Linux基础知识,服务器,数据库,云原生和网络安全等相关技术,各种进阶知识等着你,助你成为技术达人!
 最新文章