一、NFS的搭建部署

1.1 前言

NFS 是一款老牌的基于网络共享文件的存储解决方案,即网络文件系统。NFS 允许在一 个系统网络上与他人共享目录和文件。通过使用 NFS,用户和程序可以像访问本地文件 一样访问远端系统上的文件。

  • nfs: 是我们最终的存储;
  • nfs-client: 是用来动态创建 pv 和 pvc 的,我们称为 provisioner;
  • StorageClass: 关联到对应的 provisioner 就可以使用;
  • statefulset/deployment/daemonset:(或别的资源)需要配置storageClassName 进行使用;

优点:

  • 部署快速,维护简单方便;
  • 集中存放在一台机器上,网络内部所有计算机可以通过网络访问,不必单独存储。;
  • 从软件层面上来看,数据可靠性高,经久耐用,服务稳定;

缺点:

  • 存在单点故障,如果nfs server宕机了,所有的客户都不能访问共享目录;
  • 大数据高并发的场景,nfs效率低(网络/磁盘IO);

1.2 存储提供

1、所有节点安装rpcbind nfs-utils

$ yum -y install rpcbind nfs-utils

2、在服务端(10.0.0.61)上启动服务

$ systemctl enable rpcbind && systemctl start rpcbind
$ systemctl enable nfs-server && systemctl start nfs-server

3、在服务端(10.0.0.61)创建一个共享目录 /opt/sharedata ,作为客户端挂载的远端入口,然后设置权限。

[root@node01 ~]# mkdir -p /opt/sharedata/
[root@node01 ~]# chmod 666 /opt/sharedata/

4、在服务端(10.0.0.61)修改 NFS 配置文件 /etc/exports

[root@node01 ~]# vim /etc/exports
/opt/sharedata 10.0.0.0/24(rw,sync,insecure,no_subtree_check,no_root_squash)

# 配置生效
[root@k8s-node01 ~]# exportfs -r

# 重新加载NFS
[root@k8s-node01 ~]# systemctl reload nfs-server

说明:这里配置后边有很多参数,每个参数有不同的含义,具体可以参考下边。此处,我配置了将 /opt/sharedata 文件目录设置为允许 IP 为该10.0.0.0/24 区间的客户端挂载,当然,如果客户端 IP 不在该区间也想要挂载的话,可以设置 IP 区间更大或者设置为 * 即允许所有客户端挂载,例如:/home *(ro,sync,insecure,no_root_squash) 设置 /home 目录允许所有客户端只读挂载。

其中关于/etc/exports下面参数说明:

  • rw:允许客户端对共享目录进行读写操作
  • sync:在写操作时,数据写入磁盘之前必须先确认客户端的请求
  • insecure:允许使用不安全的端口进行 NFS 连接
  • no_subtree_check:禁用子目录检查
  • no_root_squash:允许 NFS 客户端的 root 用户具有对共享目录的 root 权限。

5、在每台主机上查看是否可以成功挂载

$ showmount -e 10.0.0.61
Export list for 10.0.0.61:
/opt/sharedata 10.0.0.0/24

至此操作基本完成。(后面工作只是拓展,不需要执行)

当然,你还可以在任意主机挂载远端目录到本地 /share 目录。

$ mount 10.0.0.61:/opt/sharedata /share
$ df -h | grep 10.0.0.61
10.0.0.61:/opt/sharedata   36G  4.9G   31G  14% /root/share

6、客户端要卸载 NFS 挂载的话,使用如下命令即可。

$ umount /share

#卸载完进行验证
$ df -h | grep 10.0.0.61

1.3 编写nfs-client的rbac角色授权yaml文件

# 定义yaml文件
[root@master01 2]# vim nfs-client-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - 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"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
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
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: kube-system
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: kube-system
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: kube-system
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

# 应用
[root@master01 2]# kaf  nfs-client-rbac.yaml

# 查看
[root@master01 2]# kg -f nfs-client-rbac.yaml
NAME                                    SECRETS   AGE
serviceaccount/nfs-client-provisioner   1         14m

NAME                                                                  CREATED AT
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner   2023-11-12T11:14:38Z

NAME                                                                      ROLE                                        AGE
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner   ClusterRole/nfs-client-provisioner-runner   7m17s

NAME                                                                   CREATED AT
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner   2023-11-12T11:22:14Z

NAME                                                                          ROLE                                         AGE
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner   Role/leader-locking-nfs-client-provisioner   7m17s

1.4 编写nfs-client-provisioner资源yaml文件

nfs-client-provisioner相当于一个nfs 客户端程序,用于声明nfs服务端的服务器地址、 路径。

创建storageclass资源时需要指定使用某个nfs-client-provisioner来提供数据存储

# 定义yaml文件
[root@master01 2]# vim nfs-client-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  namespace: kube-system
  labels:
    app: nfs-client-provisioner
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.cn-hangzhou.aliyuncs.com/abroad_images/nfs-subdir-external-provisioner:v4.0.2
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs  #定义nfs-client-provisioner名字
            - name: NFS_SERVER
              value: 10.0.0.61 #指定自己nfs服务器地址
            - name: NFS_PATH
              value: /opt/sharedata/ #nfs服务器共享的目录
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes #具体挂载路径
      volumes:  #定义一个nfs类型的volume,将nfs挂载到容器中
        - name: nfs-client-root
          nfs:
            server: 10.0.0.61 #指定自己nfs服务器地址
            path: /opt/sharedata/  #nfs服务器共享的目录

# 应用
[root@master01 2]# kaf nfs-client-deployment.yaml

# 查看
[root@master01 2]# kg deploy -nkube-system | grep nfs
nfs-client-provisioner-7cc5f8c6dc-r8x9w    1/1     Running   0               3m24s

1.5 编写storageclass资源yaml文件

创建一个storageclass资源,storageclass资源需要指定使用哪个nfs-client-provisioner

[root@master01 2]# vim nfs-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage    #重点后续需要引用的名字
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: fuseim.pri/ifs    #指定使用哪个nfs-client-provisioner
parameters:
  archiveOnDelete: "true" #删除pv的时候pv的内容是否要备份

# 应用
[root@master01 2]# kaf nfs-storageclass.yaml

# 查看storageclass资源的状态
[root@master01 2]# kg sc
NAME               PROVISIONER   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-storageclass   nfs-storage   Delete          Immediate           false                  70s

ReclaimPolicy 回收策略:

  • Delete(删除):当 PVC 被删除时,PV 同样会被删除。
  • Retain(保留):当 PVC 被删除时,PV 并不会被删除,需要手动进行删除。
  • Recycle(回收):当 PVC 被删除时,PV 上的数据也会随之删除,以便和新的 PVC 进行绑定(已被遗弃

1.6 NFS实现总结

Day02-持久化存储NFS和CEPH-图1