zoukankan      html  css  js  c++  java
  • k8s—centos7安装部署NFS服务器和客户端及基于nfs的动态存储storageclass使用总结

    技术公众号:后端技术解忧铺
    关注微信公众号:CodingTechWork,一起学习进步。

    NFS介绍

    概述

      网络文件系统(Network File System, NFS),是基于内核的文件系统,nfs主要是通过网络实现服务器和客户端之间的数据传输,采用远程过程调用RPC(Romete Procedure Call)机制,让不同的机器节点共享文件目录。只需将nfs服务器共享的文件目录挂载到nfs客户端,这样客户端就可以对远程服务器上的文件进行读写操作。
      一个NFS服务器可以对应多个nfs客户端,基于RPC机制,用户可以像访问本地文件一样访问远端的共享目录文件,使用起来很nice!

    原理

    挂载原理

    nfs挂载原理
      如图所示,在NFS服务器创建并设置好一个共享目录/nfs,其他网络互通的NFS客户端可以将该目录挂载到本地文件系统中的某个挂载点(可自定义),如NFS客户端A挂载到/nfs-a/data中,NFS客户端B挂载到/nfs-b/data中,这样NFS客户端可以在本地的挂载目录即可看到NFS服务器共享目录/nfs内的所有数据。具体的权限(如只读、读写等权限)根据服务器的配置而定。

    通信原理

    NFS通信原理
    如图所示,通过RPC和NFS服务传输数据。

    1. NFS服务端启动RPC服务,开启111端口,可以通过nfsnetstat。
    2. NFS服务端启动NFS服务,并向RPC注册端口信息。
    3. NFS客户端启动RPC服务,向服务端RPC服务请求NFS服务端口。
    4. NFS服务端RPC服务反馈NFS端口信息给NFS客户端。
    5. NFS客户端通过获取的NFS端口简历和服务端的NFS连接,并通过RPC及底层TCP/IP协议进行数据传输。

    NFS服务器搭建

    部署步骤

      可以在linux系统的k8s集群中任意一个node节点做nfs服务端。

    1. 检查防火墙服务
      $ systemctl status firewalld检查防火墙服务
      若防火墙未关闭,使用如下命令进行关闭
      $ systemctl stop firewalld
      $ systemctl disable firewalld

    2. 检查SELinux
      $ cat /etc/selinux/config
      检查SELinux
      若未关闭禁用,使用如下命令:
      $ setenforce 0
      $ sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

    3. 安装nfs相关服务软件包
      $ yum install -y nfs-utils rpcbind

    4. 创建共享存储文件夹
      $ mkdir /nfs

    5. 配置nfs
      $ vi /etc/exports
      输入以下内容,格式为:nfs共享目录 nfs客户端地址1(param1, param2,...) nfs客户端地址2(param1, param2,...)
      /nfs 10.1.1.0/24(rw,async,no_root_squash)

    6. 启动服务
      先启动rpc服务,再启动nfs服务
      $ systemctl start rpcbind
      $ systemctl enable rpcbind
      $ systemctl enable nfs && systemctl restart nfs

    7. 查看服务状态
      $ systemctl status rpcbind
      $ systemctl status nfs
      查看nfs和prcbind服务状态

    8. 查看可用的nfs地址
      showmount -e 127.0.0.1showmount -e localhost

    [root@k8s ~]# showmount -e localhost
    Export list for localhost:
    /nfs 10.1.1.0/24
    

    共享目录修改

      创建好共享目录通过/etc/exports进行编辑配置,若修改后,可以通过systemctl reload nfs或者exportfs -avr进行nfs服务的重新加载发布,从而使修改过的/etc/exports配置文件生效。

    NFS客户端配置

    配置步骤

    使用nfs共享目录的都需要配置一遍以下步骤。

    1. 安装nfs-utils和rpcbind
      $ yum install -y nfs-utils rpcbind
    2. 创建挂载的文件夹
      $ mkdir -p /nfs/data
    3. 挂载nfs
      $ mount -t nfs 10.1.1.1:/nfs /nfs/data
      其中:
      mount:表示挂载命令
      -t:表示挂载选项
      nfs:挂载的协议
      10.1.1.1:nfs服务器的ip地址
      /nfs:nfs服务器的共享目录
      /nfs/data:本机客户端要挂载的目录
    4. 查看挂载信息
      $ df -Th
    5. 测试挂载
      可以进入本机的/nfs/data目录,上传一个文件,然后去nfs服务器查看/nfs目录中是否有该文件,若有则共享成功。反之在nfs服务器操作/nfs目录,查看本机客户端的目录是否共享。
    6. 取消挂载
      $ umount /nfs/data

    挂载的方式

    除了上述通过mount -t nfs命令指定的方式进行目录挂载以外,还可以通过vim /etc/fstab文件进行挂载。

    10.1.1.1:/nfs /nfs/data nfs defaults 1 1
    

    其中:

    1. 第一列10.1.1.1:/nfs:(Device)磁盘设备文件或该设备的Label或者UUID,此处即为nfs服务器的地址和共享目录
    2. 第二列/nfs/data:(Mount point)是设备的挂载点,即本机挂载目录
    3. 第三列nfs:(Filesystem)是磁盘文件系统的格式,如ext2、nfs、vfat等。
    4. 第四列defaults:(parameters)是文件系统的参数,defaults即具有rw,suid,dev,exec,auto,nouser,async等默认参数。
    5. 第五列1:(Dump)能够被dump备份命令作用,一般是0或者1,0表示不用做dump备份,1表示每天进行dump操作,当然还有2,表示不定期进行dump操作。
    6. 第六列1:是否检验扇区,0表示不要检验,1表示最早检验(根目录一般会设置),2表示1级别检验完成之后进行检验。

    k8s基于nfs创建storageclass

    下载开源插件

    1. 下载
      git clone https://github.com/kubernetes-incubator/external-storage.git或者git clone https://github.com/kubernetes-retired/external-storage.git
    2. 进入部署目录
      cd external-storage/nfs-client/deploy

    部署授权

    [root@k8s deploy]# cat rbac.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nfs-client-provisioner
      # replace with namespace where provisioner is deployed
      namespace: default
    ---
    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
        # replace with namespace where provisioner is deployed
        namespace: default
    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
      # replace with namespace where provisioner is deployed
      namespace: default
    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
      # replace with namespace where provisioner is deployed
      namespace: default
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
        # replace with namespace where provisioner is deployed
        namespace: default
    roleRef:
      kind: Role
      name: leader-locking-nfs-client-provisioner
      apiGroup: rbac.authorization.k8s.io
    
    [root@k8s deploy] kubectl create -f rbac.yaml
    [root@k8s deploy] kubectl get sa
    NAME                     SECRETS   AGE
    default                  1         82d
    nfs-client-provisioner   1         25s
    

    部署插件

    [root@k8s deploy]# cat deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nfs-client-provisioner
      labels:
        app: nfs-client-provisioner
      # replace with namespace where provisioner is deployed
      namespace: default
    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: quay.io/external_storage/nfs-client-provisioner:latest
              volumeMounts:
                - name: nfs-client-root
                  mountPath: /persistentvolumes
              env:
                - name: PROVISIONER_NAME
                  # 必须与class.yaml中的provisioner的名称一致
                  value: fuseim.pri/ifs
                - name: NFS_SERVER
                  # NFS服务器的ip地址
                  value: 10.1.1.0
                - name: NFS_PATH
                  # 修改为实际创建的共享挂载目录
                  value: /nfs
          volumes:
            - name: nfs-client-root
              nfs:
                # NFS服务器的ip地址
                server: 10.154.2.154
                # 修改为实际创建的共享挂载目录
                path: /nfs
               
    [root@k8s deploy]# kubectl create -f deployment.yaml
    [root@k8s deploy]# kubectl get deploy
    NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
    nfs-client-provisioner                 1/1     1            1           10s
    

    部署storageclass

    [root@k8s deploy]# cat class.yaml
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: managed-nfs-storage
    # 必须与deployment.yaml中的PROVISIONER_NAME一致
    provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
    parameters:
      archiveOnDelete: "false"
    [root@k8s deploy]# kubectl create -f class.yaml
    [root@k8s deploy]# kubectl get sc
    NAME                  PROVISIONER         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
    managed-nfs-storage   fuseim.pri/ifs      Delete          Immediate           false                  15s
    

    测试

    测试pvc

    [root@k8s deploy]# cat test-claim.yaml
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: test-claim
      annotations:
        volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 1Mi
    [root@k8s deploy]# kubectl create -f test-claim.yaml
    [root@k8s deploy]# kubectl get pvc
    NAME                                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
    test-claim                                         Bound    pvc-938bb7ec-8a1f-44dd-afb8-2659e824564a   1Mi        RWX            managed-nfs-storage   10s
    

    测试pod

    [root@k8s deploy]# cat test-pod.yaml
    kind: Pod
    apiVersion: v1
    metadata:
      name: test-pod
    spec:
      containers:
      - name: test-pod
        image: gcr.io/google_containers/busybox:1.24
        command:
          - "/bin/sh"
        args:
          - "-c"
          - "touch /mnt/SUCCESS && exit 0 || exit 1"
        volumeMounts:
          - name: nfs-pvc
            mountPath: "/mnt"
      restartPolicy: "Never"
      volumes:
        - name: nfs-pvc
          persistentVolumeClaim:
            claimName: test-claim
    [root@k8s deploy]# kubectl create -f test-pod.yaml
    [root@k8s deploy]# kubectl get pods 
    NAME                                                    READY   STATUS        RESTARTS   AGE
    test-pod                                                1/1     Running       0          12s
    

    至此,完美!

    NFS配置文件参数

    参数 说明
    ro 只读(默认)
    rw 读写
    sync 同步,同时将数据写入内存和硬盘中,保证不丢数据
    async 异步,优先将数据保存到内存,再写入硬盘,有可能丢数据
    root_squash 当nfs客户端以root管理员访问时,映射为nfs服务器的匿名用户
    no_root_squash 当nfs客户端以root管理员访问时,映射为nfs服务器的root管理员用户
    all_squash 无论nfs客户端以什么账户访问,都映射为nfs服务器的匿名用户

    by
    https://github.com/kubernetes-retired/external-storage

    烧不死的鸟就是凤凰
  • 相关阅读:
    【原】 OPenCV学习笔记1:imread()
    windows8下:OpenCV2.2.0 +VS2005/2008/2010
    数组指针和指针数组的区别
    虚函数和纯虚函数 覆盖和隐藏
    C/C++文件之eof()
    【转】 CvArr、Mat、CvMat、IplImage、BYTE转换(总结而来)
    HTML 5是如何流行起来的
    Java程序员要注意的10个问题————————好东西就是要拿来分享
    祈福雅安
    对软件工程的思考
  • 原文地址:https://www.cnblogs.com/Andya/p/14760281.html
Copyright © 2011-2022 走看看