15-k8s-高级存储之pv与pvc

文章目录

    • 一、相关概念
    • 二、创建pv
    • 二、创建pvc
    • 三、创建pod调用pvc
    • 四、StorageClass动态制备pv

一、相关概念

  1. 关系
    15-k8s-高级存储之pv与pvc_第1张图片

  2. 生命周期相关概念

    2.1 静态构建:集群管理员创建若干PV卷。这些卷对象带有真实存储的细节信息,并且对集群用户可用(可见)。PV卷对象存在于Kubernetes API中,可供用户消费使用。

    2.2动态构建:如果集群中已经有的PV无法满足PVC的需求,那么集群会根据PVC自动构建一个PV,该操作是通过Storageclass 实现的。想要实现这个操作,前提是PVC必须设置StorageClass,否则会无法动态构建该PV,可以通过启用DefaultstorageClass来实现PV的构建。

    2.3 绑定:当用户创建一个 PVC对象后,主节点会监测新的 PVC对象,并且寻找与之匹配的PV卷,找到PV卷后将二者绑定在一起。如果找不到对应的PV,则需要看PVC是否设置StqrageClass来决定是否动态创建PV,若没有配置,PVC就会—致处于未绑定状态,直到有与之匹配的PV后才会申领绑定关系。

    2.4 使用:Pod 将PVC当作存储卷来使用,集群会通过PVC找到绑定的PV,并为Pod挂载该卷。Pod 一旦使用PVC绑定PV后,为了保护数据,避免数据丢失问题,PV对象会受到保护,在系统中无法被删除。

    2.5 回收策略:当用户不再使用其存储卷时,他们可以从API中将PVC对象删除,从而允许该资源被回收再利用。Persistentvolume对象的回收策略告诉集群,当其被从申领中释放时如何处理该数据卷。目前,数据卷可以被 Retained(保留)、Recyced(回收)或Deleted(删除)。

    2.6 保留:回收策略Retain 使得用户可以手动回收资源。当Persistentvolumeclaim对象被删除时,Persistentvolume卷仍然存在,对应的数据卷被视为"已释放(released) "。由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领。管理员可以通过下面的步骤来手动回收该卷:

    ​ 1)删除 Persistentvolume对象。与之相关的、位于外部基础设施中的存储资产(如AWS EBS、GCE PD、Azure Disk或 Cinder卷)在PV删除之后仍然存在。

    ​ 2)根据情况,手动清除所关联的存储资产上的数据。

    ​ 3)手动删除所关联的存储资产。如果你希望重用该存储资产,可以基于存储资产的定义创建新的Persistentvolume卷对象。

    ​ 4)删除:对于支持Delete回收策略的插件,删除动作会将Persistentvolume对象从Kubernetes中移除,同时也会从外部基础设施(如AwS EBS、GCE PD、Azure Disk 或 Cinder卷)中移除所关联的存储资产。动态制备的卷会继承基StorageClass中设置的回收策略,该策略默认为Delete。管理员需要根据用户的期望来配置StorageClass;否则PV卷被创建之后必须要被编辑或者修补。

    ​ 5)回收:动态制备。如果下层卷插件支持,回收策略Recycle会在卷上执行一些基本的擦除(rm -rf /thevolume/*)操作,之后允许该卷用于新的PVC申领。

  3. 生命周期相关概念

    Available:空闲,未被绑定
    Bound:已经被PVC绑定
    Released : PVC被册删除,资源已回收,俚是PV未被重新使用
    Failed:自动回收失败
    

二、创建pv

  1. 创建pv文件:vi /opt/pv.yaml

    apiVersion: v1
    kind: PersistentVolume #描述资源对象为PV类型
    metadata:
      name : pv0001 #PV的名字
    spec:
      capacity: #容量配置
        storage: 5Gi # pv的容量
      volumeMode: Filesystem #存储类型为文件系统
      accessModes: #访问模式:ReadWriteOnceReadWriteManyReadOnlyMany
         - ReadWriteMany #可被单节点独写
      persistentVolumeReclaimPolicy: Retain #回收策略
      storageClassName: sc0001 # 创建PV的存储类名,需要与 pvc 的相同
      mountOptions: #加载配置l
        - hard #使用硬挂载方式
        - nfsvers=4.1 #使用NFSv4.1版本
      nfs: #连接到nfs
        path: /root/data/nfs #存储路径
        server: 192.168.248.11 # nfs服务地址
    
  2. 创建资源:kubectl apply -f /opt/pv.yaml

  3. 查看: kubectl get pv
    在这里插入图片描述

  4. 查看详情:kubectl describe pv pv0001
    15-k8s-高级存储之pv与pvc_第2张图片

二、创建pvc

  1. 创建pvc文件:vi /opt/pvc.yaml

    apiVersion: v1
    kind: PersistentVolumeClaim #资源类型为 PVC
    metadata:
      name: pvc0001
    spec:
      accessModes:
        - ReadWriteMany #权限需要与对应的pv相同
      volumeMode: Filesystem
      resources:
        requests:
          storage: 5Gi  #资源可以小于 pv 的,但是不能大于,如果大于就会匹配不到 pv
      storageClassName: sc0001 #名字需要与对应的pv相同
    
  2. 创建资源:kubectl apply -f /opt/pvc.yaml

  3. 查看:kubectl get pvc
    在这里插入图片描述

  4. 查看详情:kubectl describe pvc pvc0001
    15-k8s-高级存储之pv与pvc_第3张图片

三、创建pod调用pvc

  1. 创建pod:vi /opt/testpvc.yaml

    apiVersion: v1
    kind : Pod
    metadata:
      name: test-pvc-pd
    spec:
      containers:
      - image: nginx
        name: nginx-volume
        volumeMounts:
        - mountPath: /usr/share/nginx/html #挂载到容器的哪个目录
          name: test-volume #挂载哪个volume
      volumes:
      - name: test-volume
        persistentVolumeClaim: 
          claimName: pvc0001 #要关联到哪个pvc
    
  2. 创建资源:kubectl apply -f /opt/testpvc.yaml

  3. 进入:vi /root/data/nfs/index.html

    111
    
  4. 进入pod并且查看

    kubectl exec -it test-pvc-pd  sh
    cd /usr/share/nginx/html
    cat  index.html
    

在这里插入图片描述

四、StorageClass动态制备pv

  1. 什么是StorageClass

    StorageClass又称为PV动态供给,是k8s1.4之后引入的一个新资源,StorageClass主要实现了存储卷PV按需创建,动态创建,当Pod需要使用PVC时,StorageClass会自动创建一个PV,并与PVC进行绑定,相比于传统的PV、PVC,管理员不再需要创建PV,PV由StorageClass自动创建。

    1.PV的属性。比如,存储类型,Volume的大小等。
    2.创建这种PV需要用到的存储插件,即存储制备器。有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass,之后Kubernetes就会调用该StorageClass声明的存储插件,进而创建出需要的PV
  2. 为什么需要StorageClass

    传统的PV和PVC属于静态的,静态的PV和PVC都需要运维手动来创建,如果有很多个Pod需要同时使用PVC,而一个PV只能挂载到一个Pod中,这时运维的工作量将会很大。

    而且不同的应用程序对于存储性能的要求可能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes 又为我们引入了一个新的资源对象:StorageClass,通过 StorageClass 的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据 StorageClass 的描述就可以非常直观的知道各种存储资源的具体特性了,这样就可以根据应用的特性去申请合适的存储资源了。

  3. 运行原理

    要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner(制备器),这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。

    1. 自动创建的 PV 以${namespace}-${pvcName}-${pvName}这样的命名格式创建在 NFS 服务器上的共享数据目录中
    2. 而当这个 PV 被回收后会以archieved-${namespace}-${pvcName}-${pvName}这样的命名格式存在 NFS 服务器上。
    
  4. 逻辑图
    15-k8s-高级存储之pv与pvc_第4张图片

  5. 实操StorageClass步骤

    1.创建nfs-client-provisioner程序的rbac授权角色账号,以及角色,然后将账户与rbac账号进行绑定,使nfs-client-provisioner对pv、pvc有增删改查权限
    2.创建制备器nfs-client-provisioner,同时指定操作用户为前面创建的rbac授权角色账号
    3.创建StorageClass存储类并且指定外部制备器,自动创建PV时,就将PV存储到了nfs-client对应的nfs存储上
    4.创建一个pod,并且指向StorageClass存储类,验证是否能自动创建PV
    
  6. 编写账号权限创建脚本:vi /opt/nfs-provisioner-rbac.yaml

    ps:定义了一个 ServiceAccount,然后定义了两个 ClusterRole,在分别在ClusterRoleBinding中进行绑定

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nfs-client-provisioner
      namespace: kube-system
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: nfs-client-provisioner-runner
      namespace: kube-system
    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: kube-system
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
        namespace: kube-system
    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
      namespace: kube-system
    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: kube-system
    subjects:
      - kind: ServiceAccount
        name: nfs-client-provisioner
    roleRef:
      kind: Role
      name: leader-locking-nfs-client-provisioner
      apiGroup: rbac.authorization.k8s.io
    
  7. 创建资源:kubectl apply -f /opt/nfs-provisioner-rbac.yaml

  8. 编写制备器创建脚本:vi /opt/sc-nfs-storage.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-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0
              volumeMounts:
                - name: nfs-client-root
                  mountPath: /persistentvolumes
              env:
                - name: PROVISIONER_NAME
                  value: fuseim.pri/ifs
                - name: NFS_SERVER
                  value: 192.168.248.10
                - name: NFS_PATH
                  value: /root/data/nfs
          volumes:
            - name: nfs-client-root
              nfs:
                server: 192.168.248.10
                path: /root/data/nfs
    
  9. 创建资源:kubectl apply -f /opt/sc-nfs-storage.yaml

  10. 编写StorageClass创建脚本:vi /opt/storageClass.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: fuseim.pri/ifs #外部制备器提供者,编写为提供者的名称
parameters:
archiveOnDelete: "false" #是否存档,false 表示不存档,会删除 oldPath下面的数据,true 表示存档,会重命名路径
reclaimPolicy: Retain #回收策略,默认为Delete可以配置为 Retain I
volumeBindingMode: Immediate #默认为Imediate,表示创建PVC立即进行绑定,只有 azuredisk和AuSelasticblockstore支持其他值
  1. 创建资源:kubectl apply -f /opt/storageClass.yaml

  2. 编写nginx应用创建脚本:vi /opt/sc-nginx.yaml

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-sc
      labels:
        app: nginx-sc
    spec:
      type: NodePort
      ports:
      - name: web
        port: 80
        protocol: TCP
      selector:
        app: nginx-sc
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: nginx-sc
    spec:
      replicas: 1
      serviceName: "nginx-sc"
      selector:
        matchLabels:
          app: nginx-sc
      template:
        metadata:
          labels:
            app: nginx-sc
        spec:
          containers:
          - image: nginx
            name: nginx-sc
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: nginx-sc-test-pvc
      volumeClaimTemplates:
      - metadata:
          name: nginx-sc-test-pvc
        spec:
          storageClassName: managed-nfs-storage
          accessModes:
          - ReadWriteMany
          resources:
            requests:
              storage: 1Gi
    
  3. 创建资源:kubectl apply -f /opt/sc-nginx.yaml

  4. 查看:kubectl get pvc
    在这里插入图片描述

  5. kubectl get pv

    ps:如果失败可以查看日志kubectl logs nfs-client-provisioner-6db49949bf-txqvl -n kube-system
    在这里插入图片描述

  6. 也可以手动创建pvc,同时将storageClassName指向当前StorageClass,即第三大点的yaml的storageClassName属性

你可能感兴趣的:(k8s学习笔记,kubernetes,容器,云原生)