跳过正文
  1. 博客文章/

在 Kubernetes 中部署 NFS 动态存储类完整指南

·453 字·3 分钟·
Kubernetes 存储 Kubernetes 存储 Nfs Storageclass
Zayn
作者
Zayn
专注 Kubernetes、CI/CD、可观测性等云原生技术栈,记录生产环境中的实战经验与踩坑复盘。
目录

在 Kubernetes 集群中,持久化存储是有状态应用的重要基础设施。NFS(Network File System)作为一种成熟的网络文件系统,可以为 Kubernetes 提供简单可靠的共享存储解决方案。本文将详细介绍如何部署 NFS StorageClass 实现动态存储供应。

什么是 StorageClass
#

StorageClass 是 Kubernetes 中的一种资源对象,用于描述存储的"类别"。它的主要作用包括:

  • 动态供应: 自动创建 PersistentVolume(PV)
  • 存储抽象: 为不同类型的存储提供统一接口
  • 参数化配置: 支持不同的存储参数和策略
  • 自动化管理: 减少手动创建 PV 的工作量

方案架构
#

本方案采用以下架构:

flowchart LR
    Pod[Pod 应用
PVC] -->|动态创建| NFSProvisioner[NFS Provisioner] NFSProvisioner -->|创建 PV| PV[PV] PV -->|挂载| NFSServer[NFS Server
NFS Share]

环境准备
#

在开始部署之前,请确保您的环境满足以下要求:

组件版本/配置说明
Kubernetesv1.19.6+支持 StorageClass 的版本
Helmv3.4.2+用于部署 NFS Provisioner
NFS Server任意 Linux 发行版提供 NFS 服务
网络集群内互通确保 Pod 可以访问 NFS Server

示例环境配置:

  • NFS Server IP: 192.168.8.66
  • 网络段: 192.168.8.0/24
  • 共享目录: /data/nfs.sharedir

NFS 服务器配置
#

第一步:安装 NFS 服务
#

在 NFS 服务器上安装必要的软件包:

# 安装 NFS 服务器和相关工具
yum install rpcbind nfs-utils -y

# 启动并设置开机自启
systemctl enable rpcbind nfs-server
systemctl start rpcbind nfs-server

第二步:创建专用用户和目录
#

为了安全和管理方便,创建专门的用户来管理 NFS 共享:

# 创建 NFS 用户组
groupadd -g 2233 nfs-user

# 创建 NFS 用户(不创建家目录,不允许登录)
useradd nfs-user -M -s /sbin/nologin -u 2233 -g nfs-user

# 验证用户创建
id nfs-user

# 创建 NFS 共享目录
mkdir -p /data/nfs.sharedir

# 设置目录权限
chown -R nfs-user:nfs-user /data/nfs.sharedir
chmod 755 /data/nfs.sharedir

权限说明:

  • 使用固定的 UID/GID (2233) 确保在不同节点上的一致性
  • 禁用用户登录提高安全性
  • 设置适当的目录权限

服务端 配置文件修改
#

cat /etc/exports # 配置文件 如下:

/data/nfs.sharedir 192.168.8.0/24(rw,no_root_squash,no_all_squash,sync,anonuid=2233,anongid=2233)

​ 参数说明:

  • read-write,可读写;
  • ro:read-only,只读;
  • sync:文件同时写入硬盘和内存;
  • async:文件暂存于内存,而不是直接写入内存;
  • no_root_squash:NFS客户端连接服务端时如果使用的是 root 的话,那么对服务端分享的目录来说,也拥有 root 权限。显然开启这项是不安全的。
  • root_squash:NFS客户端连接服务端时如果使用的是 root 的话,那么对服务端分享的目录来说,拥有匿名用户权限,通常他将使用 nobody 或 nfsnobody 身份;
  • all_squash:不论NFS客户端连接服务端时使用什么用户,对服务端分享的目录来说都是拥有匿名用户权限;
  • anonuid:匿名用户的 UID 值,可以在此处自行设定。
  • anongid:匿名用户的 GID 值

执行配置 生效
#

exportfs -r

启动服务 & 设置服务开机自启
#

service rpcbind start  

service nfs start

systemctl enable nfs \
&& systemctl enable rpcbind  

nfs 客户端配置
#

⚠️ 注意如果在 k8s 中使用 nfs时,需要在每一个节点中多配置安装 rpcbind,因为 nfs 依赖于使用 rpc 协议进行通讯。

yum install rpcbind  rpcbind nfs-utils -y

service rpcbind start 
systemctl enable rpcbind  

客户端测试挂载
#

showmount -e [nfs-server]  # 查看服务端 可挂载目录

示例 showmount -e 192.168.8.66

image-20210119170611572

mount -t nfs 192.168.8.66:/data/nfs.sharedir /mnt

如网络不太稳定时,可以尝试切换为 tcp 协议

mount -t nfs 192.168.8.66:/data/nfs.sharedir /mnt -o proto=tcp -o nolock

部署 nfs storageClass
#

helm 添加仓库
#

helm repo add stable https://charts.helm.sh/stable

helm repo update

创建 helm 部署文件
#

cat > prod-values.yaml << EOF
storageClass:
  name: nfs-retain  
  reclaimPolicy: Retain 
nfs:
  server: 192.168.8.66
  path: '/data/nfs.sharedir'
EOF

reclaimPolicyPersistentVolumes(pv) 的回收策略,包括 “Retain”、“Recycle” 和 “Delete”。 对于动态配置的 PersistentVolumes 来说,默认回收策略为 “Delete”。 这表示当用户删除对应的 PersistentVolumeClaim 时,动态配置的 volume 将被自动删除。 如果 volume 包含重要数据时,这种自动行为可能是不合适的。 那种情况下,更适合使用 “Retain” 策略。 使用 “Retain” 时,如果用户删除 PersistentVolumeClaim,对应的 PersistentVolume 不会被删除。 相反,它将变为 Released 状态,表示所有的数据可以被手动恢复。

部署
#

部署至 kube-system 命名空间, storageClass 为 集群 概念,集群内任意命名空间多可以使用。

helm upgrade --install nfs-storage-class -f ./prod-values.yaml -n kube-system stable/nfs-client-provisioner

image-20210119205725301

image-20210119205744586

部署后的测试
#

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sc-nginx-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: nfs-retain
  resources:
    requests:
      storage: 1Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sc-nginx
  namespace: default
  labels:
    name: sc-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      name: sc-nginx
  template:
    metadata:
      labels:
       name: sc-nginx
    spec:
      containers:
      - name: sc-nginx
        image: nginx:1.16.0
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: nginx-data
        ports:
        - containerPort: 80
      volumes:
      - name: nginx-data
        persistentVolumeClaim:
          claimName: sc-nginx-pvc
EOF

image-20210119201907839

nfs server 端口 echo 数据 至目录下的 index.html 文件内

echo 'hello' >>  /data/nfs.sharedir/default-sc-nginx-pvc-pvc-bd14929c-ed1f-4ede-baa7-a39de13ee169/index.html

image-20210119202614660

相关文章

Kubernetes 部署企业级 Kafka 集群完整指南
·3156 字·15 分钟
Kubernetes Kafka Zookeeper Helm Kubernetes Streaming
Traefik Ingress Controller 完整部署指南
·1330 字·7 分钟
Kubernetes 网络 Traefik Ingress Kubernetes 网关
修复 Rancher 单机部署升级后 Docker 无法启动问题
·257 字·2 分钟
Kubernetes Fix Docker Rancher