K8S持久化存储-NFS动态存储供给

环境准备

Kubeadm安装的集群版本: V1.21.0

IP地址用途
192.168.2.200Master
192.168.2.203NFS服务端
192.168.2.241Node01
192.168.2.244Node02

操作系统: CentOS Linux release 7.9.2009
内核版本: 4.18.9-1.el7.elrepo.x86_64

1.安装和配置nfs服务

  1. 禁用防火墙和Selinux
# 停止并禁用防火墙
$ sudo systemctl stop firewalld
$ sudo systemctl disable firewalld
# 关闭并禁用SELinux
$ sudo setenforce 0
$ sudo sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
  1. 安装nfs-utils和rpcbind
$ sudo yum install -y nfs-utils rpcbind
  1. 创建nfs共享存储文件夹
# 创建文件夹
$ mkdir /data/nfs_storage

# 更改归属组与用户
$ chown -R nfsnobody:nfsnobody  /data/nfs_storage
  1. 配置NFS
# 编辑exports
$ sudo vi /etc/exports

# 输入以下内容(格式:FS共享的目录 NFS客户端地址1(参数1,参数2,...) 客户端地址2(参数1,参数2,...))
/data/nfs_storage 192.168.2.0/24(rw,no_root_squash,no_all_squash,sync)

常用选项:

  • ro:客户端挂载后, 其权限为只读,默认选项;
  • rw:读写权限;
  • sync:同时将数据写入到内存与硬盘中;
  • async:异步,优先将数据保存到内存,然后再写入硬盘;
  • Secure:要求请求源的端口小于1024

用户映射:

  • root_squash:当NFS客户端使用root用户访问时,映射到NFS服务器的匿名用户;
  • no_root_squash:当NFS客户端使用root用户访问时,映射到NFS服务器的root用户;
  • all_squash:全部用户都映射为服务器端的匿名用户;
  • anonuid=UID:将客户端登录用户映射为此处指定的用户uid;
  • anongid=GID:将客户端登录用户映射为此处指定的用户gid;
  1. 设置服务开机自启动
$ sudo systemctl enable rpcbind.service
$ sudo systemctl enable nfs-server.service
$ sudo systemctl start nfs
$ sudo systemctl start rpcbind
  1. 查看是否有可用的NFS地址
$ sudo showmount -e 192.168.2.203

2. K8S持久化存储理论

分为静态供给和动态供给两种方式.
静态供给: 提前创建好PV。

动态供给:

  • 集群管理员不预分配 PV;
  • 用户提交PVC文件,并在 PVC 中指定使用的存储模版(StorageClass);
  • K8S会结合PVC和StorageClass信息动态生成PV;
  • 将PVC和PV进行绑定,业务pod就可以使用PV了。
  • 通过存储模版(StorageClass)和PVC文件实现按需分配PV。

3. PersistentVolume 动态供给部署

3.1 部署nfs-provisioner

NFS Provisioner 是一个自动配置卷程序,它使用现有的和已配置的 NFS 服务器来支持通过持久卷声明动态配置 Kubernetes 持久卷。

  1. 创建ServiceAccount、ClusterRole、ClusterRoleBinding等,为nfs-client-provisioner授权
$ cat nfs-rbac.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
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: ["create","update","patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: kube-system
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get","list","watch","create","update","patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: kube-system
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io
  1. 部署nfs-client-provisioner
    nfs-client-provisioner 是一个 Kubernetes 的简易NFS的外部 provisioner,本身不提供NFS,需要现有的NFS服务器提供存储。
$ cat nfs-provisioner.yaml 
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: nfs-client-provisioner
  namespace: kube-system   #与RBAC文件中的namespace保持一致
  labels:
    k8s-app: nfs-client-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: nfs-client-provisioner 
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        k8s-app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: gxf-nfs-storage  #provisioner名称,请确保该名称与 nfs-StorageClass.yaml文件中的provisioner名称保持一致
            - name: NFS_SERVER
              value: 192.168.2.203  #NFS服务端的IP地址
            - name: NFS_PATH
              value: /data/nfs_storage  # NFS提供的存储卷
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.2.203
            path: /data/nfs_storage  # NFS提供的存储卷

执行以下命令进行部署

$ kubectl apply -f  nfs-rbac.yaml 
$ kubectl apply -f  nfs-provisioner.yaml

$ kubectl get pods -l k8s-app=nfs-client-provisioner -n kube-system
$ kubectl get pods -l k8s-app=nfs-client-provisioner -n kube-system -o wide

查看nfs-client状态
nfs-client详细信息

3.2 部署StorageClass

StorageClass是对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端存储的细节,减轻管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现动态资源供给。
StorageClass的定义主要包括名称、后端存储的提供者(provisioner)和后端存储对应的参数。对于后端NFS存储来说,配置相对简单,只需要指定provisioner即可。

$ cat nfs-StorageClass.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage
provisioner: gxf-nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
reclaimPolicy: Retain # 默认为delete
parameters:
  archiveOnDelete: "true" # false表示pv被删除时,在nfs下面对应的文件夹也会被删除,true正相反
  1. nfs-StorageClass.yamlreclaimPolicy不写(或者为delete, 默认),archiveOnDelete: “false”,当pvc删除时,对应的pv也会被自动删除,而且nfs文件目录中的文件也同时被删除;
  2. nfs-StorageClass.yamlreclaimPolicy: retainarchiveOnDelete: “true”,pvc删除后需要手工删除pv,nfs上文件不会被删除。
    执行以下命令进行部署
$ kubectl apply -f nfs-StorageClass.yaml
$ kubectl get sc

查看StorageClass信息

3.3 验证

通过后续部署的Prometheus+Grafana监控平台进行验证。

3.4 问题排查命令

使用kubectl describe pod "名称",查看详细信息并排查错误。

4. 参考链接地址

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐