k8s存储卷(Volume)

官方文档: 卷 | Kubernetes

一.简介

存储券是定义在Pod资源之上、可被其内部的所有容器挂载的共享目录,它关联至外部的存储设备之上的存储空间,从而独立于容器自身的文件系统,而数据是否具有持久化能力则取决于存储券自身是否支持持久化机制。

Kubernetes支持众多存储券类型,其中,emptyDir与hostPath属于节点级别的卷类型,emptyDir的生命周期与Pod资源相同。

而使用了 hostPath卷的Pod一旦被重新调度至其他节点,那么它将无法在使用此前的数据。因此,这两种类型都不具有持久性。

要想使用持久类型的存储卷,就得使用网络存储系统,如NFS、Ceph、GlusterFS等,或云终端存储

二.存储卷的使用方式

在Pod中定义使用存储卷的配置由两部分组成:

.spec.volumes字段

设置存储卷名称以及存储卷类型

不同类型配置参数不同

.spec.containers.volumeMounts字段

在容器上定义的存储卷挂载列表,它只能挂载当前Pod资源中定义的具体存储卷,当然也可以不挂载任何存储卷

name指定为.spec.volumes中name名称,必须保持一致,表示将volumes中定义的存储卷挂在到容器内

示例:

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

三.常用卷类型

emptyDir

emptyDir存储卷的生命周期与其所属的Pod对象相同,它无法脱离Pod对象的生命周期提供数据存储功能,因此emptyDir通常用于数据缓存或临时存储

当Pod被分配给节点时,首先创建 emptyDir卷,正如卷的名字所述,它最初是空的。

尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,这些容器都可以读写 emptyDir 卷中相同的文件。

当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会被永久删除。

Note: 容器崩溃并会导致 Pod 被从节点上移除,因此容器崩溃期间 emptyDir 卷中的数据是安全的。

emptyDir 的用途:

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

emptyDir 配置示例:

apiVersion: v1
kind: Pod
metadata:
  name: test-emptydir
spec:
  containers:
  - name: test-emptydir-container
    image: nginx
    volumeMounts:
    - name: test-emptydir-volume
      mountPath: /cache

  volumes:
  - name: test-emptydir-volume
    emptyDir: {
    
    }

hostPath

hostPath卷是指将工作节点上某文件系统的目录或文件挂载于Pod中的一种存储卷,它可独立于Pod资源的生命周期,因而具有持久性。

HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。

当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。

如果通过 AdmissionPolicy 限制 HostPath 对特定目录的访问,则必须要求 volumeMounts 使用 readOnly 挂载以使策略生效。

hostPath的用途:

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

配置 hostPath存储卷的嵌套字段共两个:

  • 一个是用于指定工作节点上的目录路径的必须字段 path
  • 另一个是指定存储卷类型的type

支持的 type 值如下:

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

当使用这种类型的卷时要小心,因为:

  • HostPath 卷可能会暴露特权系统凭据(例如 Kubelet)或特权 API(例如容器运行时套接字),可用于容器逃逸或攻击集群的其他部分。
  • 具有相同配置(例如基于同一 PodTemplate 创建)的多个 Pod 会由于节点上文件的不同而在不同节点上有不同的行为。
  • 下层主机上创建的文件或目录只能由 root 用户写入。你需要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 hostPath 卷。

hostPath 配置示例:

apiVersion: v1
kind: Pod
metadata:
  name: test-hostpath
spec:
  containers:
  - name: test-hostpath-container
    image: nginx
    volumeMounts:
    - name: test-hostpath-volume
      mountPath: /test-volume

  volumes:
  - name: test-hostpath-volume
    hostPath:
      # 宿主上目录位置
      path: /data
      # 此字段为可选
      type: Directory

Caution: FileOrCreate 模式不会负责创建文件的父目录。 如果欲挂载的文件的父目录不存在,Pod 启动会失败。

为了确保这种模式能够工作,可以尝试把文件和它对应的目录分开挂载,如 FileOrCreate 配置 所示。

hostPath FileOrCreate 配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-webserver
spec:
  containers:
  - name: test-webserver
    image: k8s.gcr.io/test-webserver:latest
    volumeMounts:
    - mountPath: /var/local/aaa
      name: mydir
    - mountPath: /var/local/aaa/1.txt
      name: myfile
  volumes:
  - name: mydir
    hostPath:
      # 确保文件所在目录成功创建。
      path: /var/local/aaa
      type: DirectoryOrCreate
  - name: myfile
    hostPath:
      path: /var/local/aaa/1.txt
      type: FileOrCreate

local

Local PV是从kuberntes 1.10开始引入,本质目的是为了解决hostPath的缺陷。

通过PV控制器与Scheduler的结合,会对local PV做针对性的逻辑处理,从而,让Pod在多次调度时,能够调度到同一个Node上。

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 字段。

Kubernetes 调度器使用 PersistentVolume 的 nodeAffinity 信息来将使用 local 卷的 Pod 调度到正确的节点。

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

使用 local 卷时,建议创建一个 StorageClass 并将其 volumeBindingMode 设置为 WaitForFirstConsumer

要了解更多详细信息,请参考 local StorageClass 示例

延迟卷绑定的操作可以确保 Kubernetes 在为 PersistentVolumeClaim 作出绑定决策时,会评估 Pod 可能具有的其他节点约束,例如:如节点资源需求、节点选择器、Pod亲和性和 Pod 反亲和性。

你可以在 Kubernetes 之外单独运行静态驱动以改进对 local 卷的生命周期管理。

请注意,此驱动尚不支持动态配置。 有关如何运行外部 local 卷驱动,请参考 local 卷驱动用户指南

Note: 如果不使用外部静态驱动来管理卷的生命周期,用户需要手动清理和删除 local 类型的持久卷。

configMap

configMap 卷提供了向 Pod 注入配置数据的方法。

ConfigMap 对象中存储的数据可以被 configMap 类型的卷引用,然后被 Pod 中运行的容器化应用使用。

引用 configMap 对象时,可以在 volume 中通过它的名称来引用。

也可以自定义 ConfigMap 中特定条目所要使用的路径。

configMap配置示例:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox:1.28
      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 路径下。 请注意,这个路径来源于卷的 mountPathlog_level 键对应的 path

Note:

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

secret

secret 卷用来给 Pod 传递敏感信息,例如密码。

你可以将 Secret 存储在 Kubernetes API 服务器上,然后以文件的形式挂在到 Pod 中,无需直接与 Kubernetes 耦合。

secret 卷由 tmpfs(基于 RAM 的文件系统)提供存储,因此它们永远不会被写入非易失性(持久化的)存储器

Note: 使用前你必须在 Kubernetes API 中创建 secret。

Note: 容器以 subPath 卷挂载方式挂载 Secret 时,将感知不到 Secret 的更新。

更多详情请参考配置 Secrets

iscsi

iscsi 卷能将 iSCSI (基于 IP 的 SCSI) 卷挂载到你的 Pod 中。

不像 emptyDir 那样会在删除 Pod 的同时也会被删除,iscsi 卷的内容在删除 Pod 时会被保留,卷只是被卸载。

这意味着 iscsi 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享

注意: 在使用 iSCSI 卷之前,你必须拥有自己的 iSCSI 服务器,并在上面创建卷。

iSCSI 的一个特点是它可以同时被多个用户以只读方式挂载。 这意味着你可以用数据集预先填充卷,然后根据需要在尽可能多的 Pod 上使用它。 不幸的是,iSCSI 卷只能由单个使用者以读写模式挂载。不允许同时写入。

更多详情请参考 iSCSI 示例

nfs

nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。

不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。

这意味着 nfs 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。

注意: 在使用 NFS 卷之前,你必须运行自己的 NFS 服务器并将目标 share 导出备用。

要了解更多详情请参考 NFS 示例

persistentVolumeClaim

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

持久卷申领(PersistentVolumeClaim)是用户在不知道特定云环境细节的情况下“申领”持久存储(例如 GCE PersistentDisk 或者 iSCSI 卷)的一种方法。

更多详情请参考持久卷示例

猜你喜欢

转载自blog.csdn.net/wq1205750492/article/details/125004811