美文网首页Docker&Kubernetes
k8s动态存储nfs部署

k8s动态存储nfs部署

作者: Firetheworld | 来源:发表于2020-08-24 19:07 被阅读0次

    k8s中存储分为静态存储以及动态存储。k8s提供了一套可以自动创建PV的机制,即:Dynamic Provisioning.而这个机制的核心在于:StorageClass这个API对象.

    用户在部署应用。通过指定对应的动态存储卷,自动创建pvc。格式如下:

    1.自动创建的 PV 以${namespace}-${pvcName}-${pvName}这样的命名格式创建在 NFS 服务器上的共享数据目录中
    2.而当这个 PV 被回收后会以archieved-${namespace}-${pvcName}-${pvName}这样的命名格式存在 NFS 服务器上
    

    StorageClass对象会定义下面两部分内容:
    1,PV的属性.比如,存储类型,Volume的大小等.
    2,创建这种PV需要用到的存储插件
    有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass,之后Kubernetes就会调用该StorageClass声明的存储插件,进而创建出需要的PV.

    过程如下:
    1)k8s运维人员先创建好storageclass;
    2)用户创建使用存储类的持久化存储声明(PVC:PersistentVolumeClaim);
    3)存储持久化声明通知系统,它需要一个持久化存储(PV: PersistentVolume);
    4)系统读取存储类的信息;
    5)系统基于存储类的信息,在后台自动创建PVC需要的PV;
    6)用户创建一个使用PVC的Pod;
    7)Pod中的应用通过PVC进行数据的持久化;
    8)而PVC使用PV进行数据的最终持久化处理。


    一、 我们进行动态存储卷的部署
    首先需要准备一台nfs服务器、k8s集群v1.153。

    动态存储卷由三部分组成:①权限控制创建②创建NFS provisioner③创建NFS资源的StorageClass。动态存储的yaml文件如'pub-nfs-sc.yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nfs-client-provisioner
      # replace with namespace where provisioner is deployed
      namespace: storageclass        #根据实际环境设定namespace,下面类同
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: nfs-client-provisioner-runner
      namespace: storageclass        #根据实际环境设定namespace,下面类同
    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
      namespace: storageclass        #根据实际环境设定namespace,下面类同
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
        # replace with namespace where provisioner is deployed
        namespace: storageclass
    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: storageclass
    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
      namespace: storageclass        #根据实际环境设定namespace,下面类同
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
        # replace with namespace where provisioner is deployed
        namespace: storageclass
    roleRef:
      kind: Role
      name: leader-locking-nfs-client-provisioner
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nfs-client-provisioner
      labels:
        app: nfs-client-provisioner
      # replace with namespace where provisioner is deployed
      namespace: storageclass  #与RBAC文件中的namespace保持一致
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nfs-client-provisioner
      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: docker.in.zwxict.com/official/kubesphere/nfs-client-provisioner:v3.1.0-k8s1.11
              volumeMounts:
                - name: nfs-client-root
                  mountPath: /persistentvolumes
              env:
                - name: PROVISIONER_NAME
                  value: pub-nfs-storage  #provisioner名称,请确保该名称与 nfs-StorageClass.yaml文件中的provisioner名称保持一致
                - name: NFS_SERVER
                  value: 10.192.52.140   #NFS Server IP地址
                - name: NFS_PATH  
                  value: /mnt/nfs/pub-nfs-sc    #NFS挂载卷
          volumes:
            - name: nfs-client-root
              nfs:
                server: 10.192.52.140  #NFS Server IP地址
                path: /mnt/nfs/pub-nfs-sc     #NFS 挂载卷
    ---
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: pub-nfs-sc
    provisioner: pub-nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
    reclaimPolicy: Retain    #  回收策略,pv以及pvc删除后,nfs服务器文件保留
    
    部署:
    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl apply -f pub-nfs-sc.yaml 
    serviceaccount/nfs-client-provisioner created
    clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
    clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
    role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
    rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
    deployment.apps/nfs-client-provisioner created
    storageclass.storage.k8s.io/pub-nfs-sc created
    
    查看创建的storageclass
    
    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl get sc
    NAME         PROVISIONER        AGE
    pub-nfs-sc   pub-nfs-storage    6m1s
    
    

    二、验证
    创建pvctest-claim.yaml,并挂载到pod。

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: test-claim
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: pub-nfs-sc  # 指定创建的sc名称
      resources:
        requests:
          storage: 1Mi
    

    查看pvc的状态是否为Bound:

    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl apply -f test-claim.yaml 
    persistentvolumeclaim/test-claim created
    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl get pvc
    NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    test-claim   Bound    pvc-b06ba929-bb98-42cf-93f8-465cb9c64520   1Mi        RWX            pub-nfs-sc     7s
    

    test-po.yaml使用指定创建的pvc:

    kind: Pod
    apiVersion: v1
    metadata:
      name: test-pod
    spec:
      containers:
      - name: test-pod
        image: docker.in.zwxict.com/tools/busybox:latest
        command:
          - "/bin/sh"
        args:
          - "-c"
          - "touch /mnt/SUCCESS && exit 0 || exit 1"   #创建一个SUCCESS文件后退出
        volumeMounts:
          - name: nfs-pvc
            mountPath: "/mnt"
      restartPolicy: "Never"
      volumes:
        - name: nfs-pvc
          persistentVolumeClaim:
            claimName: test-claim  #与PVC名称保持一致
    

    到nfs路径中查看是否正常创建SUCCESS文件:

    [root@nfs-140 pub-nfs-sc]# ls default-test-claim-pvc-b06ba929-bb98-42cf-93f8-465cb9c64520/  #文件规则是按照${namespace}-${pvcName}-${pvName}创建的
    SUCCESS
    

    ps: 创建pvc的时候发现pvc的状态为Pending,查看nfs创建的日志确认原因,大部分是由于角色绑定对应的权限没有生效导致的,确保角色与权限以及对应的deployment在同一命名下空间。

    创建一个nginx应用test-pod.yaml,把web页面挂载出来,指定动态存储卷:

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-headless
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None   #注意此处的值,None表示无头服务
      selector:
        app: nginx
    ---
    apiVersion: apps/v1beta1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      serviceName: "nginx"
      replicas: 2  #两个副本
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: docker.in.zwxict.com/official/nginx:1.19.2
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: www
          annotations:
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: pub-nfs-sc
          resources:
            requests:
              storage: 1Mi
    

    结果如下:

    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl apply -f nginx.yaml
    service/nginx-headless created
    statefulset.apps/web created
    [root@k8s-10-192-52-123 pub-nfs-sc]# cat nginx.yaml 
    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl get pvc  # 查看pvc
    NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    www-web-0    Bound    pvc-4a12ddef-8c37-4c9d-ba35-e200595e1d16   1Mi        RWO            pub-nfs-sc     92s
    www-web-1    Bound    pvc-f7a17f18-21b7-44da-bf23-48671bf8a0f2   1Mi        RWO            pub-nfs-sc     88s
    
    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl get pv|grep pub-nfs-sc  # 查看pv
    pvc-4a12ddef-8c37-4c9d-ba35-e200595e1d16   1Mi        RWO            Retain           Bound         default/www-web-0                                                     pub-nfs-sc                     2m58s
    pvc-b06ba929-bb98-42cf-93f8-465cb9c64520   1Mi        RWX            Retain           Bound         default/test-claim                                                    pub-nfs-sc                     12m
    pvc-f7a17f18-21b7-44da-bf23-48671bf8a0f2   1Mi        RWO            Retain           Bound         default/www-web-1                                                     pub-nfs-sc                     2m54s
    
    
    

    nfs服务器查看自动创建的结果如下:

    default-test-claim-pvc-b06ba929-bb98-42cf-93f8-465cb9c64520
    [root@nfs-140 pub-nfs-sc]# ll
    total 0
    drwxrwxrwx 2 root root  6 Aug 25 14:31 default-www-web-0-pvc-4a12ddef-8c37-4c9d-ba35-e200595e1d16
    drwxrwxrwx 2 root root  6 Aug 25 14:31 default-www-web-1-pvc-f7a17f18-21b7-44da-bf23-48671bf8a0f2
    

    到nfs服务器上给两个nginx添加不同内容,并进入pod中进行访问:

    [root@nfs-140 pub-nfs-sc]#  echo "web-00" > default-www-web-0-pvc-4a12ddef-8c37-4c9d-ba35-e200595e1d16/index.html
    [root@nfs-140 pub-nfs-sc]#  echo "web-11" > default-www-web-1-pvc-f7a17f18-21b7-44da-bf23-48671bf8a0f2/index.html
    
    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl exec -it web-0 -- /bin/sh
    / # nslookup nginx-headless
    Server:     192.168.0.10
    Address:    192.168.0.10:53
    Name:   nginx-headless.default.svc.cluster.local
    Address: 192.168.58.207
    Name:   nginx-headless.default.svc.cluster.local
    Address: 192.168.90.42
    
    / # curl 192.168.58.207
    web-00
    / # curl 192.168.90.42
    web-11
    

    设置默认的storageclass

    [root@k8s-master-155-221 classStorage]# kubectl patch storageclass pub-nfs-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'  #设置pub-nfs-sc为默认后端存储
    storageclass.storage.k8s.io/managed-nfs-storage patched
    
    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl get sc
    NAME                   PROVISIONER        AGE
    pub-nfs-sc (default)   pub-nfs-storage    30s
    
    [root@k8s-master-155-221 deploy]# kubectl patch storageclass pub-nfs-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}' #取消默认存储后端
    storageclass.storage.k8s.io/managed-nfs-storage patched
    
    [root@k8s-10-192-52-123 pub-nfs-sc]# kubectl get sc
    NAME         PROVISIONER        AGE
    pub-nfs-sc   pub-nfs-storage    2m44s
    

    相关文章

      网友评论

        本文标题:k8s动态存储nfs部署

        本文链接:https://www.haomeiwen.com/subject/ksagjktx.html