美文网首页【Kubernetes】
【k8s学习】Kubernetes Volume介绍

【k8s学习】Kubernetes Volume介绍

作者: 伊丽莎白2015 | 来源:发表于2022-06-22 16:38 被阅读0次

    【本文目标】

    • Kubernetes集群怎样通过Volume做数据持久化的?
    • 持久卷组件 - Persistemt Volume
    • 使用持久卷,组件 - Persistent Volume Claim
    • 在使用持久卷中想要自动创建持久卷,组件 - Storage Class

    【前置文章】


    1. Volume使用场景

    1.1 Use Case-1:mysql Pod需要Storage:

    假设我们有个项目叫my-app,接连了另一个Pod叫mysql,如果mysql重启了,那么里面存放的数据也会丢失,原因是Kubernetes并没有提供在Pod之外的持久化,一旦Pod重启了,数据就丢失了。

    • Storage that doesn't depend on the pod lifecycle:我们需要在Pod外有存储数据,以便不受Pod重启的影响。
    • Storage must be available on all nodes:假设一个mysql Pod挂掉了,那么admin controller manager发现后,就会让scheduler再找合适的Node重新创建一个Pod,所以新的Pod有可能创建在活着的Worker Node中的任一一个,即这个存储要对所有的节点都可见。
    • Storage needs to survive even if cluster crashes:当所有的节点都挂了,Storage里的数据也不能丢失。
    1.2 Use Case-2:my-app本身可能也需要读写文件

    比如一些session或是额外的配置等信息,my-app Pod本身,也可能会读写数据,这时候我们就可以配置Persistent Volume,简称pv。

    2. Persistent Volume

    官网:https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/

    2.1 介绍
    • a cluster resource:集群中的一种资源,比如ram内存或是cpu。
    • created via YAML file:和别的组件一样,可以通过YAML文件创建。
      • 创建的时候kind为PersistentVolume
      • spec中定义了一些自有的属性,比如占有空间为多少?(spec.capacity.storage
    • Needs actual physical storage:持久化的地方必须是能支持存储的地方,如集群里的某个存储空间或是集群外的某台Server或是云服务器。所以这里有个问题就是如何让Kubernetes集群读取到这些存储。
    • what type of storage do you need? need to create & manage them by yourself:Persistent Volume更像是一个接口,它只提供了一些规范,至于存储的类型以及创建和管理、备份,都在Kubernetes之外,并不归K8s集群管理。
    2.2 yaml配置示例

    下述示例中的Storage的地方是NFS文件系统:

    apiVersion:
    kind: persistentVolume
    metadata:
      name: pv-name
    spec:
      capacity:
        storage: 5Gi
      volumeMode: Filesystem
      accessMode:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Recycle
      storageClassName: slow
      mountOptions:
        - hard
        - nfsvers=4.0
      nfs:
        path: /dir/path/on/nfs/server
        server: nfs-server-ip-address
    

    上述spec中定义了三部分:

    • 存储能力
    • 额外的信息比如进入的模式
    • nfs参数

    不同的存储类型,配置可能会长不一样。
    从官网上可以看到,卷的类型超过了20种:https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes

    Persistent Volume并不从属于某个命令空间,它是全局的组件。即所有的命名空间下的组件,都可引用到该pv组件。

    2.3 Local Volume vs. Remote Volume

    根据存放地点分类:

    • Local Volume(在Kubernetes集群内),这种Storage就违反了1.1章的特点2和特点3,即它是跟集群中的某个Node绑定了,所以有可能会挂掉,以及如果集群down了,这个Storage也可能down掉。正因为此,像DB数据库的持久化存储,最好放在集群外,即Remove Volume中。
    • Remote Volume,即集群外部存储,符合1.1章节的三个特点。

    什么时候创建Persistent Volume?
    如果某个Pod依赖于pv,那么这个pv需要在Pod被创建之前创建。

    谁来创建?
    一般来说,开发人员需要告诉admin(可能是DevOps Team)某个项目需要用到Persistent Volume,然后DevOps人员根据开发人员的需求,在Kubernetes集群中帮忙定义并创建好了该pv。

    在定义好之后,开发人员则需要在具体的Pod的yaml中定义引用该pv,在yaml中声明需要用到某个pv,这时候需要另一个组件,叫Persistent Volume Claim,简称pvc

    3. Persistent Volume Claim

    官网:

    3.1 Persistent Volume Claim yaml示例

    pvc如何找到pv?通过属性例如大小等找到合适的pv:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-name
    spec:
      storageClassName: manual
      volumeMode: Filesystem
      accessMode:
        - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
    

    定义了pvc后,怎么在Pod中引用呢?即通过spec.volumes.persistenceVolumeClaim.claimName进行关联:

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
        - name: myfrontend
          image: nginx
          volumeMounts:
          - mountPath: "/var/www/html"
            name: mypd
      volumes:
        - name: mypd
          persistentVolumeClaim:
            claimName: pvc-name
    

    【整个过程】
    Pod通过pv claim请求volume --> pv claim尝试在集群中找到合适的volume --> 找到的volume才是真正拥有存储空间的地方。 --> 这时候volume会被mounted(挂载)到这个Pod --> 然后才被挂载到Pod中的Container(这也是为什么上述Container中定义了volumeMounts属性) --> 至此,具体的app应用才能读写该volume

    pvc并不是全局的组件,它可以被创建到某个namespace下,pvc所属的namespace必须要和Pod相同(因为Pod定义中需要引用到pvc组件)。

    3.2 思考:为什么需要这么多层抽像?
    • DevOps人员声明并创建全局组件pv
    • 开发人员声明并创建pvc,并在Pod中使用。

    这样设计的主要好处是开发人员友好,因为开发人员并不需要具体知道Storage存放地点(解藕),而只需要使用即可。

    3.3 通过spec.volumes引用ConfigMap和Secret

    ConfigMap组件和Secret组件:

    • local volumes:这两个组件都是本地存储卷。
    • not created via pv and pvc:不是通过pv和pvc声明创建的。
    • managed by Kubernetes

    我们也可以通过volume属性定义这两个组件,然后在container中mounts,以下是示例:

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
        - name: busybox-container
          image: busybox
          volumeMounts:
            - name: config-dir
              mountPath: /etc/config
      volumes:
        - name: config-dir
          configMap:
            name: bb-configmap
    

    注:一个Pod可以有多个volume claim。

    4. Storage Class

    官网:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/

    为了让pv创建以及pvc创建更加高效,则需要第三个组件,叫Storage Class,简称sc。

    sc可以根据PersistentVolumeClaim的定义,动态的生成pv。

    示例:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: storage-class-name
    provisioner: kubernetes.io/aws-ebs
    parameters:
      type: io1
      iopsPerGB: "10"
      fsType: ext4
    
    • via "provisioner" attribute:provisioner意思为供应方,声明了pv的具体提供商,每个Storage类型都有自己的provisioner,在需要的时候查阅官网:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#provisioner
    • configure "parameters" for storage we want to request for Persistent Volume:parameters属性定义了pv所需要的信息,例如类型,空间大小等。

    sc主要是为了减少DevOps的工具,即可以动态的生成pv,那么谁来引入sc组件呢?答案很明显,是pvc。即开发人员不需要每次让DevOps的人手动创建pv,而是通过Storage Class来自动创建pv。

    在pvc中使用:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mypvc
    spec:
      accessMode:
      - ReadWriteOnce
      resources:
        requests:
          storage: 100Gi
        storageClassName: storage-class-name
    

    【整个过程】

    1. Pod通过pvc请求存储。
    2. pvc通过sc请求存储。
    3. sc自动创建可以满足要求的pv

    参考:
    https://www.youtube.com/watch?v=X48VuDVv0do

    相关文章

      网友评论

        本文标题:【k8s学习】Kubernetes Volume介绍

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