本文超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

原始块卷支持进入 Beta 阶段

Kubernetes v1.13 将原始块卷支持升级到 Beta 版。此功能允许在容器内部将持久卷作为块设备而不是作为挂载的文件系统公开。

什么是块设备?

块设备支持以固定大小的块随机访问数据。硬盘驱动器、SSD 和 CD-ROM 驱动器都是块设备的示例。

通常,持久存储以分层方式实现,文件系统(如 ext4)位于块设备(如旋转磁盘或 SSD)之上。然后应用程序读取和写入文件,而不是对块进行操作。操作系统负责使用指定的文件系统将文件读取和写入到底层设备作为块。

值得注意的是,虽然整个磁盘是块设备,但磁盘分区也是块设备,存储区域网络 (SAN) 设备中的 LUN 也是块设备。

为什么要向 kubernetes 添加原始块卷?

有些专用应用程序需要直接访问块设备,因为例如文件系统层引入了不必要的开销。最常见的情况是数据库,它们更喜欢直接在底层存储上组织数据。任何本身实现某种存储服务(软件定义存储系统)的软件也常用原始块设备。

从程序员的角度来看,块设备是一个非常大的字节数组,通常具有一定的最小读取和写入粒度,通常为 512 字节,但通常为 4K 或更大。

随着在 Kubernetes 内部运行数据库软件和存储基础设施软件变得越来越普遍,Kubernetes 中对原始块设备支持的需求也变得越来越重要。

哪些卷插件支持原始块?

截至本博客发布时,以下内置卷类型支持原始块

  • AWS EBS
  • Azure 磁盘
  • Cinder
  • 光纤通道
  • GCE PD
  • iSCSI
  • 本地卷
  • RBD (Ceph)
  • Vsphere

树外CSI 卷驱动程序也可能支持原始块卷。Kubernetes CSI 对原始块卷的支持目前为 Alpha 版。请参阅此处的文档。

Kubernetes 原始块卷 API

原始块卷与普通卷有很多共同点。两者都是通过创建绑定到PersistentVolume对象的PersistentVolumeClaim对象来请求的,并通过将它们包含在PodSpec的 volumes 数组中来附加到 Kubernetes 中的 Pod。

然而,有两个重要的区别。首先,要请求原始块PersistentVolumeClaim,必须在PersistentVolumeClaimSpec中设置volumeMode = "Block"。将volumeMode留空与指定volumeMode = "Filesystem"相同,这将导致传统行为。PersistentVolumes在其PersistentVolumeSpec中也有一个volumeMode字段,并且"Block"类型的 PVC 只能绑定到"Block"类型的 PV,而"Filesystem"类型的 PVC 只能绑定到"Filesystem"类型的 PV。

其次,在 Pod 中使用原始块卷时,必须在PodSpec的容器部分中指定VolumeDevice而不是VolumeMountVolumeDevices具有devicePaths而不是mountPaths,并且在容器内部,应用程序将在该路径上看到一个设备而不是挂载的文件系统。

应用程序打开、读取和写入容器内的设备节点,就像它们在非容器化或虚拟化环境中与系统上的任何块设备交互一样。

创建新的原始块 PVC

首先,确保与您选择的存储类关联的供应器是支持原始块的供应器。然后创建 PVC。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Block
  storageClassName: my-sc
  resources:
    requests:
    storage: 1Gi

使用原始块 PVC

在 pod 定义中使用 PVC 时,您可以选择块设备的设备路径,而不是文件系统的挂载路径。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: busybox
      command:
        - sleep
        - “3600”
      volumeDevices:
        - devicePath: /dev/block
          name: my-volume
      imagePullPolicy: IfNotPresent
  volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: my-pvc

作为存储供应商,如何向我的 CSI 插件添加对原始块设备的支持?

CSI 插件的原始块支持仍处于 alpha 阶段,但今天可以添加支持。CSI 规范详细说明了如何处理对具有`BlockVolume`功能而不是`MountVolume`功能的卷的请求。CSI 插件可以支持两种卷,也可以支持其中一种。有关更多详细信息,请参阅此处的文档

问题/陷阱

由于块设备实际上是设备,因此可以从容器内部对它们执行低级操作,而这在文件系统卷中是不可能的。例如,实际上是 SCSI 磁盘的块设备支持使用 Linux ioctl 向设备发送 SCSI 命令。

但是,默认情况下,Linux 不允许容器从容器内部向磁盘发送 SCSI 命令。为此,您必须向容器安全上下文授予`SYS_RAWIO`功能才能允许这样做。请参阅此处的文档。

此外,虽然 Kubernetes 保证向容器提供块设备,但不能保证它实际上是 SCSI 磁盘或任何其他类型的磁盘。用户必须确保在其 pod 中使用所需的磁盘类型,或者仅部署可以处理各种块设备类型的应用程序。

我如何了解更多?

在此处查看有关快照功能的其他文档:原始块卷支持

我如何参与?

加入 Kubernetes 存储 SIG 和 CSI 社区,帮助我们添加更多出色功能并改进现有功能,例如原始块存储!

https://github.com/kubernetes/community/tree/master/sig-storage https://github.com/container-storage-interface/community/blob/master/README.md

特别感谢所有帮助向 Kubernetes 添加块卷支持的贡献者,包括