暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kubernetes系列14 一【实战】StorageClass创建动态PV

栋总侃技术 2021-06-27
1475

上一节我们讨论了 Kubernetes 通过PVC指定StorageClass对象提供 Dynamic Provisioning 机制动态的创建 PV 对象。虽然也引入了yaml文件示例子讲解,但是我还是觉得需要通过一节实战课程来动手操作加深理解。

以下示意图是动态存储的完整过程:

我们这节的动手实践,利用NFS动态提供Kubernetes存储卷。

创建NFS服务

  • 服务端

    1. rpcbind nfs-utils

        yum -y install rpcbind
        yum -y install nfs-utils
      • 创建共享文件夹
          mkdir opt/share
        • 设置共享目录访问的权限
            vi etc/exports

            // /opt/share 共享目录
            // 172.16.212.0/24 可访问d的ip
            // rw可读写,sync同步,no_root_squash:root远程用户使用时不降权
            /opt/share 172.16.212.0/24(insecure,rw,async,no_root_squas)
          • 开启rcband和nfs服务并设置开机启动

              systemctl start rpcbind
              systemctl start nfs
              systemctl enable rpcbind
              systemctl enable nfs

          Kubernetes 集群创建授权管理

          在 Kubernetes 中 ServiceAccount 是给 Pod 内的进程用来访问资源授权用的,我们可以理解为 Pod 内的进程需要访问 NFS Client Provisioner 需要有授权认证。使用 ServiceAccount 的流程如下:

          • 创建 ServiceAccount 对象

            apiVersion: v1
            kind: ServiceAccount
            metadata:
              name: nfs-client-provisioner
              namespace: default
            • 创建 Role 对象

              kind: Role
              apiVersion: rbac.authorization.k8s.io/v1
              metadata:
                name: leader-locking-nfs-client-provisioner
              namespace: default
              rules:
              - apiGroups: [""]
              resources: ["endpoints"]
              verbs: ["get", "list", "watch", "create", "update", "patch"]
              • 创建RoleBinding对象绑定 ServiceAccount 和 Role

                kind: RoleBinding
                apiVersion: rbac.authorization.k8s.io/v1
                metadata:
                name: leader-locking-nfs-client-provisioner
                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

                绑定Role和 ServiceAccount 后我们可以看到生成了对应的secret 对象:

                  kubectl get secret
                  NAME                                 TYPE                                  DATA   AGE

                  nfs-client-provisioner-token-44jgf   kubernetes.io/service-account-token   3      40s
                  kubectl describe secret nfs-client-provisioner-token-44jgf
                  Name: nfs-client-provisioner-token-44jgf
                  Namespace: default
                  Labels: <none>
                  Annotations: kubernetes.io/service-account.name: nfs-client-provisioner
                  kubernetes.io/service-account.uid: 19f19d11-2839-4157-890f-d60975b32090

                  Type: kubernetes.io/service-account-token

                  Data
                  ====
                  ca.crt: 1066 bytes
                  namespace: 7 bytes
                  token:      xxxxxxxxxxxxxxxxxxxx

                  同样的,如果希望不仅仅只是当前 Namespace 空间下的资源可以使用该NFS Client Provisioner ,还可以创建 ClusterRole 同 ServiceAccount 绑定:

                    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: default
                    roleRef:
                    kind: ClusterRole
                    name: nfs-client-provisioner-runner
                    apiGroup: rbac.authorization.k8s.io

                    可以看到 Role 对象需要指定 Namespace,而 ClusterRole不需要。

                    创建StorageClass对象

                      apiVersion: storage.k8s.io/v1
                      kind: StorageClass
                      metadata:
                      name: demo-nfs-storage
                      provisioner: demo-nfs-storage
                      parameters:
                      archiveOnDelete: "false"

                      注意 provisioner的值,在创建 provisioner时需要指定该值。

                      创建 NFS Provisioner

                        apiVersion: apps/v1
                        kind: Deployment
                        metadata:
                        name: nfs-client-provisioner
                        labels:
                            app: nfs-client-provisioner
                            namespace: default
                        namespace: default
                        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: quay.io/external_storage/nfs-client-provisioner:latest
                        volumeMounts:
                        - name: nfs-client-root
                        mountPath: /persistentvolumes
                        env:
                        - name: PROVISIONER_NAME
                        value: demo-nfs-storage
                        - name: NFS_SERVER
                                      value: 172.16.212.25
                        - name: NFS_PATH
                        value: /opt/share
                        volumes:
                        - name: nfs-client-root
                        nfs:
                        server: 172.16.212.25
                        path: /opt/share

                        注意看 env的 PROVISIONER_NAME 与StorageClass的 provisioner字段一致。

                        到这里搭建 StorageClass + NFS远程存储的过程就完成了,我们可以创建一个PVC来验证 Dynamic Provisioning

                          kind: PersistentVolumeClaim
                          apiVersion: v1
                          metadata:
                          name: test-claim
                          annotations:
                              volume.beta.kubernetes.io/storage-class: "demo-nfs-storage"
                          spec:
                          accessModes:
                          - ReadWriteMany
                          resources:
                          requests:
                          storage: 1Mi

                          可以看到该 PVC对象指定了使用StorageClass对象完成 Dynamic Provisioning 过程,当使用 kubectl apply 命令创建完成PVC后,我们可以查看下 PVC的状态:

                            kubectl get pvc
                            NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
                            test-claim   Bound    pvc-dd5d8bb7-c457-4bbd-9dca-dd4e92172edd   1Mi        RWX            demo-nfs-storage    36s

                            可以看到该PVC已经是绑定状态了,我们再来看看与其绑定的PV详细信息:

                              kubectl get pv
                              NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
                              pvc-dd5d8bb7-c457-4bbd-9dca-dd4e92172edd   1Mi        RWX            Delete           Bound    default/test-claim   demo-nfs-storage              38s

                              kubectl describe pv pvc-dd5d8bb7-c457-4bbd-9dca-dd4e92172edd
                              Name: pvc-dd5d8bb7-c457-4bbd-9dca-dd4e92172edd
                              Labels: <none>
                              Annotations: pv.kubernetes.io/provisioned-by: nfs-storage
                              Finalizers: [kubernetes.io/pv-protection]
                              StorageClass: demo-nfs-storage
                              Status: Bound
                              Claim: default/test-claim
                              Reclaim Policy: Delete
                              Access Modes: RWX
                              VolumeMode: Filesystem
                              Capacity: 1Mi
                              Node Affinity: <none>
                              Message:
                              Source:
                              Type: NFS (an NFS mount that lasts the lifetime of a pod)
                              Server: 172.16.212.25
                              Path: opt/share/default-test-claim-pvc-dd5d8bb7-c457-4bbd-9dca-dd4e92172edd
                              ReadOnly: false
                              Events: <none>

                              可以看到该PV的存储目为 172.16.212.25 NFS服务的 /opt/share/default-test-claim-pvc-dd5d8bb7-c457-4bbd-9dca-dd4e92172edd 路径。

                              我们在NFS服务下可以看到该路径是存在的:

                                ls /opt/share/
                                default-test-claim-pvc-dd5d8bb7-c457-4bbd-9dca-dd4e92172edd

                                以上是验证 StorageClass 动态存储机制完整的过程。

                                本系列回顾:

                                Kubernetes系列1 一 容器是什么?

                                Kubernetes系列2 一 小鲸鱼与船长的历险记

                                Kubernetes系列3 一 docker隔离与限制的原理

                                Kubernetes系列4 一 docker镜像

                                Kubernetes系列5 一 实践课

                                Kubernetes系列6 一 Kubernetes登场

                                Kubernetes系列7 一 最小编排单位Pod

                                Kubernetes系列8 一 Pod的生命周期

                                Kubernetes系列9 一 终于聊到编排了

                                Kubernetes系列10 一 容器编排之StatefulSet

                                Kubernetes系列11 一 容器编排之DaemonSet

                                Kubernetes系列12 一 Job 与 CronJob

                                Kubernetes系列13 一 持久化存储 PV、PVC、StorageClass


                                文章转载自栋总侃技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                评论