• Kubernetes-8.存储卷


    • docker version:20.10.2

    • kubernetes version:1.20.1

    本文概述Kubernetes存储的基本组成。

    概述

    Kubernetes支持诸多类型的卷。卷的核心是包含一些数据的一个目录。存储卷属于Pod,Pod的存储卷Pod内的容器能够共享使用。

    临时卷的生命周期与Pod相同,持久卷则有自己独立的生命周期。

    使用.spec.volumes字段为Pod设置卷,在.spec.containers[*].volumeMounts字段中声明卷在容器中的挂载位置。卷挂载在镜像内的指定路径上,卷不能挂载到其他卷之上,也不能与其他卷有硬链接。

    volumeMounts

    pod.spec.containers.volumeMounts,将卷挂载到容器。

    常用字段
    pod.spec.containers.volumeMounts.mountPath:挂载到容器内的路径
    pod.spec.containers.volumeMounts.mountPropagation:卷的挂载传播特性
    pod.spec.containers.volumeMounts.name:挂载的卷的名称
    pod.spec.containers.volumeMounts.readOnly:挂载的卷是否只读,默认false
    pod.spec.containers.volumeMounts.subPath:子路径挂载
    pod.spec.containers.volumeMounts.subPathExpr:带有变量的子路径挂载

    挂载卷的传播

    挂在卷的传播能力允许将容器安装的卷共享到同一Pod中的其他容器,甚至共享到同一节点上的其他Pod。

    卷的挂载传播特性由pod.spec.containers.volumeMounts.mountPropagation字段控制。值如下:

    • None:此卷挂载模式将不会感知到主机后续在此卷或其任何子目录上执行的挂载变化,同样,容器所创建的卷挂载在主机上也是不可见的。默认模式。该模式等同于Linux中private挂载传播选项。
    • HostToContainer:此卷挂载模式将会感知到主机后续针对此卷或其任何子目录的挂载操作。该模式等同于Linux中rslave挂载传播选项。
    • Bidirectional:与HostToContainer表现相同,另外,容器创建的卷挂载将被传播回至主机和使用同一卷的所有Pod的所有容器。该模式等同于Linux中rehared挂载传播选项。

    NotesBidirectional形式的挂载传播可能比较危险。 它可以破坏主机操作系统,因此它只被允许在特权容器中使用。

    Docker mount share

    挂载传播需要Docker配置正确的挂载共享。

    编辑Docker systemd服务文件,设置MountFlags

    MountFlags=shared
    

    如果存在MountFlags=slave就删除掉。然后重启Docker守护进程。

    PersistentVolume

    持久卷(PersistentVolume,PV)属于集群资源。持久卷是集群中的一块存储,可以事先定义或动态供应。PV持久卷和普通的卷一样,使用卷插件来实现,持久卷有自己独立的生命周期。

    PersistentVolume API资源对象中记录了存储的实现细节,无论其背后是NFS、iSCSI还是特定的云平台存储系统。

    PV是集群中的资源,PVC(PersistentVolumeClaim)是对这些资源的请求。

    定义一个NFS类型的PV示例:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv0003
    spec:
      capacity:
        storage: 5Gi
      volumeMode: Filesystem
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Recycle
      storageClassName: slow
      mountOptions:
        - hard
        - nfsvers=4.1
      nfs:
        path: /tmp
        server: 172.17.0.2
    

    存储卷类型

    emptyDir

    emptyDir:临时存储空间,使用集群节点的存储空间映射到Pod中。Pod结束则存储空间生命周期结束。

    emptyDir的一些用途:

    • 缓存空间
    • 为耗时较长的计算提供检查点,以便任务能够方便地从崩溃前状态恢复执行
    • 在Web服务器容器服务数据时,保存内容管理器容器获取的文件

    emptyDir.medium的类型可以指定为"Memory",在节点重启时会被清除,未指定大小时默认为主机系统内存的50%。容器崩溃时并不会导致Pod从节点上移除,因此容器崩溃期间emptyDir卷中的数据是安全的。

    常用字段
    pod.spec.volumes.emptyDir.medium:存储类型;空("")为使用磁盘,Memory为使用内存
    pod.spec.volumes.emptyDir.medium:存储上限

    示例:

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pd
    spec:
      containers:
      - image: k8s.gcr.io/test-webserver
        name: test-container
        volumeMounts:
        - mountPath: /cache
          name: cache-volume
      volumes:
      - name: cache-volume
        emptyDir: {}
    

    hostPath

    hostPath:将主机节点文件系统上的文件或目录挂载到Pod中。

    hostPath的一些用法:

    • 运行一个需要访问Docker内部机制的容器;可使用hostPath挂载/var/lib/docker路径
    • 在容器中运行cAdvisor时,以hostPath方式挂载/sys
    • 允许Pod指定给定的hostPath在运行Pod之前是否应该存在,是否应该创建以及应该以什么方式存在

    常用字段
    pod.spec.volumes.hostPath.path:节点的路径
    pod.spec.volumes.hostPath.type:hostPath的类型;默认为空;

    hostPath支持以下type

    取值 行为
    空字符串(默认)用于向后兼容,这意味着在安装hostPath卷之前不会执行任何检查。
    DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为0755,具有与kubelet相同的组和属主信息。
    Directory 在给定路径上必须存在的目录。
    FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为0644,具有与kubelet相同的组和所有权。
    File 在给定路径上必须存在的文件。
    Socket 在给定路径上必须存在的UNIX套接字。
    CharDevice 在给定路径上必须存在的字符设备。
    BlockDevice 在给定路径上必须存在的块设备。

    Notes:FileOrCreate 模式不会负责创建文件的父目录。 如果欲挂载的文件的父目录不存在,Pod启动会失败。 为了确保这种模式能够工作,可以尝试把文件和它对应的目录分开挂载。

    注意

    1. 在具有相同配置(例如基于同一PodTemplate创建)的多个Pod会由于节点上文件的不同而在不同节点上有不同的行为。
    2. 下层主机上创建的文件或目录只能由root用户写入。需要在特权容器中以root身份运行进程,或者修改主机上的文件权限以便容器能够写入hostPath卷。

    示例:

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pd
    spec:
      containers:
      - image: k8s.gcr.io/test-webserver
        name: test-container
        volumeMounts:
        - mountPath: /test-pd
          name: test-volume
      volumes:
      - name: test-volume
        hostPath:
          # 宿主上目录位置
          path: /data
          # 此字段为可选
          type: Directory
    

    local

    local:某个被挂载的本地存储设备,如磁盘、分区或者目录。

    local卷只能用作静态创建的持久卷,尚不支持动态配置。

    与hostPath卷相比,local卷能够以持久和可移植的方式使用,而无需手动将Pod调度到节点。系统通过查看PersistentVolume的节点亲和性配置,能够了解卷的节点约束。

    local卷仍然取决于底层节点的可用性,并不适合所有应用程序。如果节点出现问题,那么local卷也将变得不可被Pod访问,使用它的Pod将不能运行。

    常用字段
    pv.spec.local.fsType:文件系统类型,如ext4、xfs、ntfs,可不指定
    pv.spec.local.path:节点上的路径,必选

    示例:
    具有nodeAffinity的local持久卷

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: example-pv
    spec:
      capacity:
        storage: 100Gi
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      persistentVolumeReclaimPolicy: Delete
      storageClassName: local-storage
      local:
        path: /mnt/disks/ssd1
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - example-node
    

    使用local卷是,需要设置PersistentVolume对象的nodeAffinity字段,调度器通过该详细来将使用local卷的Pod调度到正确的节点上。

    PersistentVolume对象的volumeMount字段可被设置为Block(而不是默认值Filesystem),以将local卷作为原始块设备暴露出来。

    使用local卷时,建议设置一个StorageClass并将其volumeBiddingMode设置为WaitForFirstConsumer。延迟卷绑定的操作可以确保作出绑定决策时,会评估Pod可能具有的其他节点约束,例如:节点资源需求、节点选择器、Pod亲和性和Pod反亲和性。

    NFS

    nfs:将NFS挂载到Pod中。Pod删除时,nfs卷内容被保存,数据可以在Pod间共享。

    注意:使用NFS卷之前,必须要配置好NFS服务器并将其exports

    常用字段
    pod.spec.volumes.nfs.path:nfs的exports路径
    pod.spec.volumes.nfs.readOnly:是否只读;默认false
    pod.spec.volumes.nfs.server:nfs服务器地址

    示例:
    创建一个NFS pv

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: nfs
    spec:
      capacity:
        storage: 1Mi
      accessModes:
        - ReadWriteMany
      nfs:
        server: nfs-server.default.svc.cluster.local
        path: "/"
    

    configMap

    configMap:提供了向Pod注入配置数据的方法。ConfigMap对象中存储的数据可以被configMap类型的卷引用,然后被Pod中运行的容器化应用使用。

    引用configMap对象时,你可以在volume中通过它的名称来引用。你可以自定义ConfigMap中特定条目所要使用的路径。

    下面的配置显示了如何将名为log-config的ConfigMap挂载到名为configmap-pod的Pod中:

    apiVersion: v1
    kind: Pod
    metadata:
      name: configmap-pod
    spec:
      containers:
        - name: test
          image: busybox
          volumeMounts:
            - name: config-vol
              mountPath: /etc/config
      volumes:
        - name: config-vol
          configMap:
            name: log-config
            items:
              - key: log_level
                path: log_level
    

    log-config ConfigMap以卷的形式挂载,并且存储在log_level条目中的所有内容都被挂载到Pod的/etc/config/log_level路径下。请注意,这个路径来源于卷的mountPath和log_level键对应的path。

    说明

    • 在使用ConfigMap之前首先要创建它
    • 容器以subPath卷挂载方式使用configMap时,将无法接收configMap的更新
    • 文本数据挂载成文件时采用UTF-8字符编码。如果使用其他字符编码形式,可使用binaryData字段。

    gitRepo

    gitRepo:该卷挂载一个空目录,并将一个Git代码仓库克隆到这个目录中供Pod使用。

    注意已弃用,如果需要在容器中提供git仓库,请将一个EmptyDir卷挂载到InitContainer中,使用git命令完成仓库的克隆操作, 然后将EmptyDir卷挂载到Pod的容器中。

    downwardAPI

    downwardAPI:用于使downward API数据对应用程序可用。这种卷类型挂载一个目录并在纯文本文件中写入所请求的数据。

    容器以subPath卷挂载方式使用downward API时,将不能接收到它的更新。

    PVC

    persistentVolumeClaim:将持久卷(PersistentVolume)挂载到Pod中。

    其他

    一些分布式存储:glusterfs、rbd、cephfs
    一些云存储:EBS、AzureDisk、gcePersistentDisk

    subPath

    有时,在单个Pod中共享卷以供多方使用是很有用的。volumeMounts.subPath属性用于指定所引用的卷内的子路径,而不是其根路径。

    示例:
    PHP应用的代码和相关数据映射到卷的html文件夹,MySQL数据库存储在卷的mysql文件夹中

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-lamp-site
    spec:
        containers:
        - name: mysql
          image: mysql
          env:
          - name: MYSQL_ROOT_PASSWORD
            value: "rootpasswd"
          volumeMounts:
          - mountPath: /var/lib/mysql
            name: site-data
            subPath: mysql
        - name: php
          image: php:7.0-apache
          volumeMounts:
          - mountPath: /var/www/html
            name: site-data
            subPath: html
        volumes:
        - name: site-data
          persistentVolumeClaim:
            claimName: my-lamp-site-data
    

    带有扩展变量的subPath

    使用subPathExpr字段可以基于Downward API环境变量来构造subPath目录名。subPath和subPathExpr属性是互斥的。

    在这个示例中,Pod使用subPathExpr来hostPath卷/var/log/pods中创建目录pod1。hostPath卷采用来自downwardAPI的Pod名称生成目录名。宿主目录/var/log/pods/pod1被挂载到容器的/logs中。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod1
    spec:
      containers:
      - name: container1
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        image: busybox
        command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
        volumeMounts:
        - name: workdir1
          mountPath: /logs
          subPathExpr: $(POD_NAME)
      restartPolicy: Never
      volumes:
      - name: workdir1
        hostPath:
          path: /var/log/pods
    
  • 相关阅读:
    没人比程序猿更讨厌软件
    随心所欲~我也做个集合遍历器吧(自己的foreach,委托的威力)
    EF架构~DefaultValue让我的UnitOfWork更可读
    EF架构~数据分批批量提交
    陷阱~EF中的Update与Insert共用一个数据上下文
    我心中的核心组件(可插拔的AOP)~第四回 异常拦截器
    zigbee学习:示例程序SampleApp中通讯流程
    【网络可靠版】Extjs4 Treegrid 使用实例
    C#实现微信公众号群发消息(解决一天只能发一次的限制)
    oracle12c(oracle12.1.0.1.0)安装指南--实测OEL5.9(RH5)
  • 原文地址:https://www.cnblogs.com/ioops/p/14493167.html
Copyright © 2020-2023  润新知