zoukankan      html  css  js  c++  java
  • (转)原理到实现 | K8S 存储之 NFS

    转:https://mp.weixin.qq.com/s/Mrr1Rnl_594Gyyn9fHekjw

    1NFS介绍

    NFS是Network File System的简写,即网络文件系统,NFS是FreeBSD支持的文件系统中的一种。NFS基于RPC(Remote Procedure Call)远程过程调用实现,其允许一个系统在网络上与它人共享目录和文件。通过使用NFS,用户和程序就可以像访问本地文件一样访问远端系统上的文件。NFS是一个非常稳定的,可移植的网络文件系统。具备可扩展和高性能等特性,达到了企业级应用质量标准。由于网络速度的增加和延迟的降低,NFS系统一直是通过网络提供文件系统服务的有竞争力的选择 。

     

    1.1 NFS原理

    NFS 使用RPC(Remote Procedure Call)的机制进行实现,RPC使得客户端可以调用服务端的函数。同时,由于有 VFS 的存在,客户端可以像使用其它普通文件系统一样使用 NFS 文件系统。经由操作系统的内核,将 NFS 文件系统的调用请求通过 TCP/IP 发送至服务端的 NFS 服务。NFS服务器执行相关的操作,并将操作结果返回给客户端。

    NFS服务主要进程包括:

    • rpc.nfsd:最主要的NFS进程,管理客户端是否可登录

    • rpc.mountd:挂载和卸载NFS文件系统,包括权限管理

    • rpc.lockd:非必要,管理文件锁,避免同时写出错

    • rpc.statd:非必要,检查文件一致性,可修复文件

    NFS的关键工具包括:

    • 主要配置文件:/etc/exports;

    • NFS文件系统维护命令:/usr/bin/exportfs;

    • 共享资源的日志文件: /var/lib/nfs/*tab;

    • 客户端查询共享资源命令: /usr/sbin/showmount;

    • 端口配置: /etc/sysconfig/nfs。

     

    1.2 共享配置

    在NFS服务器端的主要配置文件为/etc/exports时,通过此配置文件可以设置共享文件目录。每条配置记录由NFS共享目录、NFS客户端地址和参数这3部分组成,格式如下:

    [NFS共享目录] [NFS客户端地址1(参数1,参数2,参数3……)] [客户端地址2(参数1,参数2,参数3……)]

    • NFS共享目录:服务器上共享出去的文件目录;

    • NFS客户端地址:允许其访问的NFS服务器的客户端地址,可以是客户端IP地址,也可以是一个网段(192.168.64.0/24);

    • 访问参数:括号中逗号分隔项,主要是一些权限选项。

    1)访问权限参数

    2)用户映射参数 图表

    3)其它配置参数 图表

    2

    NFS服务端配置

    在nfs作为网络文件存储系统前,首先,需要安装nfs和rpcbind服务;接着,需要创建使用共享目录的用户;然后,需要对共享目录进行配置,这是其中相对重要和复杂的一个步骤;最后,需要启动rpcbind和nfs服务,以供应用使用。

     

    2.1 安装nfs服务

    1)通过yum目录安装nfs服务和rpcbind服务:

    1. $ yum -y install nfs-utils rpcbind

    2)检查nfs服务是否正常安装

    1. $ rpcinfo -p localhost

     

    2.2 创建用户

    为NFS服务其添加用户,并创建共享目录,以及设置用户设置共享目录的访问权限:

    1. $ useradd  nfs

    2. $ mkdir -p /nfs-share

    3. $ chmod a+w /nfs-share

     

    2.3 配置共享目录

    在nfs服务器中为客户端配置共享目录:

    1. $ echo "/nfs-share 172.16.0.0(rw,async,no_root_squash)" >> /etc/exports

    通过执行如下命令是配置生效:

    1. $exportfs -r

     

    2.4 启动服务

    1)由于必须先启动rpcbind服务,再启动nfs服务,这样才能让nfs服务在rpcbind服务上注册成功:

    1. $ systemctl start rpcbind

    2)启动nfs服务:

    1. $ systemctl start nfs-server

    3)设置rpcbind和nfs-server开机启动:

    1. $ systemctl enable rpcbind

    2. $ systemctl enable nfs-server

     

    2.5 检查nfs服务是否正常启动

    1. $ showmount -e localhost

    2. $ mount -t nfs 127.0.0.1:/data /mnt

     

    3

    NFS作为Volume

    nfs可以直接作为存储卷使用,下面是一个redis部署的YAML配置文件。在此示例中,redis在容器中的持久化数据保存在/data目录下;存储卷使用nfs,nfs的服务地址为:192.168.8.150,存储路径为:/k8s-nfs/redis/data。容器通过volumeMounts.name的值确定所使用的存储卷。

    1. apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2

    2. kind: Deployment

    3. metadata:

    4.  name: redis

    5. spec:

    6.  selector:

    7.    matchLabels:

    8.      app: redis

    9.  revisionHistoryLimit: 2

    10.  template:

    11.    metadata:

    12.      labels:

    13.        app: redis

    14.    spec:

    15.      containers:

    16.      # 应用的镜像

    17.      - image: redis

    18.        name: redis

    19.        imagePullPolicy: IfNotPresent

    20.        # 应用的内部端口

    21.        ports:

    22.        - containerPort: 6379

    23.          name: redis6379

    24.        env:

    25.        - name: ALLOW_EMPTY_PASSWORD

    26.          value: "yes"

    27.        - name: REDIS_PASSWORD

    28.          value: "redis"  

    29.        # 持久化挂接位置,在docker中

    30.        volumeMounts:

    31.        - name: redis-persistent-storage

    32.          mountPath: /data

    33.      volumes:

    34.      # 宿主机上的目录

    35.      - name: redis-persistent-storage

    36.        nfs:

    37.          path: /k8s-nfs/redis/data

    38.          server: 192.168.8.150

     

    4

    NFS作为PersistentVolum

    在Kubernetes当前版本的中,可以创建类型为nfs的持久化存储卷,用于为PersistentVolumClaim提供存储卷。在下面的PersistenVolume YAML配置文件中,定义了一个名为nfs-pv的持久化存储卷,此存储卷提供了5G的存储空间,只能由一个PersistentVolumClaim进行可读可写操作。此持久化存储卷使用的nfs服务器地址为192.168.5.150,存储的路径为/tmp。

    1. apiVersion: v1

    2. kind: PersistentVolume

    3. metadata:

    4.  name: nfs-pv

    5. spec:

    6.  capacity:

    7.    storage: 5Gi

    8.  volumeMode: Filesystem

    9.  accessModes:

    10.  - ReadWriteOnce

    11.  persistentVolumeReclaimPolicy: Recycle

    12.  storageClassName: slow

    13.  mountOptions:

    14.  - hard

    15.  - nfsvers=4.1

    16.  # 此持久化存储卷使用nfs插件

    17.  nfs:

    18.    # nfs共享目录为/tmp

    19.    path: /tmp

    20.    # nfs服务器的地址

    21.    server: 192.168.5.150

    通过执行如下的命令可以创建上述持久化存储卷:

    1. $ kubectl create -f {path}/nfs-pv.yaml

    存储卷创建成功后将处于可用状态,等待PersistentVolumClaim使用。PersistentVolumClaim会通过访问模式和存储空间自动选择合适存储卷,并与其进行绑定。

    5

    NFS作为动态存储提供

    5.1 部署nfs-provisioner

    为nfs-provisioner实例选择存储状态和数据的存储卷,并将存储卷挂接到容器的/export 命令。

    1. ...

    2. volumeMounts:

    3.    - name: export-volume

    4.      mountPath: /export

    5. volumes:

    6.  - name: export-volume

    7.    hostPath:

    8.      path: /tmp/nfs-provisioner

    9. ...

    为StorageClass选择一个供应者名称,并在deploy/kubernetes/deployment.yaml进行设置。

    1. args:

    2.  - "-provisioner=example.com/nfs"

    3. ...

    完整的deployment.yaml文件内容如下:

    1. kind: Service

    2. apiVersion: v1

    3. metadata:

    4.  name: nfs-provisioner

    5.  labels:

    6.    app: nfs-provisioner

    7. spec:

    8.  ports:

    9.    - name: nfs

    10.      port: 2049

    11.    - name: mountd

    12.      port: 20048

    13.    - name: rpcbind

    14.      port: 111

    15.    - name: rpcbind-udp

    16.      port: 111

    17.      protocol: UDP

    18.  selector:

    19.    app: nfs-provisioner

    20. ---

    21. apiVersion: extensions/v1beta1

    22. kind: Deployment

    23. metadata:

    24.  name: nfs-provisioner

    25. spec:

    26.  replicas: 1

    27.  strategy:

    28.    type: Recreate

    29.  template:

    30.    metadata:

    31.      labels:

    32.        app: nfs-provisioner

    33.    spec:

    34.      containers:

    35.        - name: nfs-provisioner

    36.          image: quay.io/kubernetes_incubator/nfs-provisioner:v1.0.8

    37.          ports:

    38.            - name: nfs

    39.              containerPort: 2049

    40.            - name: mountd

    41.              containerPort: 20048

    42.            - name: rpcbind

    43.              containerPort: 111

    44.            - name: rpcbind-udp

    45.              containerPort: 111

    46.              protocol: UDP

    47.          securityContext:

    48.            capabilities:

    49.              add:

    50.                - DAC_READ_SEARCH

    51.                - SYS_RESOURCE

    52.          args:

    53.            # 定义提供者的名称,存储类通过此名称指定提供者

    54.            - "-provisioner=nfs-provisioner"

    55.          env:

    56.            - name: POD_IP

    57.              valueFrom:

    58.                fieldRef:

    59.                  fieldPath: status.podIP

    60.            - name: SERVICE_NAME

    61.              value: nfs-provisioner

    62.            - name: POD_NAMESPACE

    63.              valueFrom:

    64.                fieldRef:

    65.                  fieldPath: metadata.namespace

    66.          imagePullPolicy: "IfNotPresent"

    67.          volumeMounts:

    68.            - name: export-volume

    69.              mountPath: /export

    70.      volumes:

    71.        - name: export-volume

    72.          hostPath:

    73.            path: /srv

    在设置好deploy/kubernetes/deployment.yaml文件后,通过kubectl create命令在Kubernetes集群中部署nfs-provisioner。

    1. $ kubectl create -f {path}/deployment.yaml

     

    5.2 创建StorageClass

    下面是example-nfs的StorageClass配置文件,此配置文件定义了一个名称为nfs-storageclass的存储类,此存储类的提供者为nfs-provisioner。

    1. apiVersion: storage.k8s.io/v1

    2. kind: StorageClass

    3. metadata:

    4.  name: nfs-storageclass

    5.  provisioner: nfs-provisioner

    通过kubectl create -f命令使用上面的配置文件创建:

    1. $ kubectl create -f deploy/kubernetes/class.yaml

    2. storageclass “example-nfs” created

    在存储类被正确创建后,就可以创建PersistenetVolumeClaim来请求StorageClass,而StorageClass将会为PersistenetVolumeClaim自动创建一个可用PersistentVolume。

    5.3 创建PersistenetVolumeClaim

    PersistenetVolumeClaim是对PersistenetVolume的声明,即PersistenetVolume为存储的提供者,而PersistenetVolumeClaim为存储的消费者。下面是PersistentVolumeClaim的YAML配置文件,此配置文件通过metadata.annotations[].volume.beta.kubernetes.io/storage-class字段指定所使用的存储储类。

    在此配置文件中,使用nfs-storageclass存储类为PersistenetVolumeClaim创建PersistenetVolume,所要求的PersistenetVolume存储空间大小为1Mi,可以被多个容器进行读取和写入操作。

    1. apiVersion: v1

    2. kind: PersistentVolumeClaim

    3. metadata:

    4.  name: nfs-pvc

    5.  annotations:

    6.    volume.beta.kubernetes.io/storage-class: "nfs-storageclass"

    7. spec:

    8.  accessModes:

    9.  - ReadWriteMany

    10.  resources:

    11.    requests:

    12.      storage: 1Mi

    通过kubectl create命令创建上述的持久化存储卷声明:

    1. $ kubectl create -f {path}/claim.yaml

     

    5.4 创建使用PersistenVolumeClaim的部署

    在这里定义名为busybox-deployment的部署YAML配置文件,使用的镜像为busybox。基于busybox镜像的容器需要对/mnt目录下的数据进行持久化,在YAML文件指定使用名称为nfs的PersistenVolumeClaim对容器的数据进行持久化。

    1. # This mounts the nfs volume claim into /mnt and continuously

    2. # overwrites /mnt/index.html with the time and hostname of the pod.

    3. apiVersion: v1

    4. kind: Deployment

    5. metadata:  

    6.  name: busybox-deployment

    7. spec:  

    8.  replicas: 2  

    9.  selector:    

    10.    name: busybox-deployment

    11.  template:    

    12.    metadata:      

    13.      labels:        

    14.        name: busybox-deployment    

    15.    spec:      

    16.      containers:      

    17.      - image: busybox        

    18.        command:          

    19.        - sh          

    20.        - -c          

    21.        - 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep $(($RANDOM % 5 + 5)); done'        

    22.        imagePullPolicy: IfNotPresent        

    23.        name: busybox        

    24.        volumeMounts:          

    25.        # name must match the volume name below          

    26.        - name: nfs            

    27.          mountPath: "/mnt"    

    28.     #

    29.     volumes:      

    30.     - name: nfs        

    31.       persistentVolumeClaim:          

    32.         claimName: nfs-pvc

    通过kubectl create创建busy-deployment部署:

    1. $ kubectl create -f {path}/nfs-busybox-deployment.yaml

  • 相关阅读:
    Ext JS学习第三天 我们所熟悉的javascript(二)
    Ext JS学习第二天 我们所熟悉的javascript(一)
    Ext JS学习第十七天 事件机制event(二)
    Ext JS学习第十六天 事件机制event(一)
    Ext JS学习第十五天 Ext基础之 Ext.DomQuery
    Ext JS学习第十四天 Ext基础之 Ext.DomHelper
    Ext JS学习第十三天 Ext基础之 Ext.Element
    Ext JS学习第十天 Ext基础之 扩展原生的javascript对象(二)
    针对错误 “服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF” 的原因分析
    C# 使用HttpWebRequest通过PHP接口 上传文件
  • 原文地址:https://www.cnblogs.com/wangle1001986/p/9726890.html
Copyright © 2011-2022 走看看