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

CSI Ephemeral Inline Volumes

通常,Kubernetes 中由外部存储驱动提供的卷是持久的,其生命周期完全独立于 Pod,或(作为特例)松散地绑定到使用该卷的第一个 Pod (后期绑定模式)。在 Kubernetes 中请求和定义此类卷的机制是 Persistent Volume Claim (PVC) 和 Persistent Volume (PV) 对象。最初,由容器存储接口(CSI)驱动支持的卷只能通过这种 PVC/PV 机制使用。

但也有一些用例需要数据卷,其内容和生命周期与 Pod 绑定。例如,驱动可能会使用动态创建的秘密(secrets)填充卷,这些秘密特定于在 Pod 中运行的应用程序。此类卷需要与 Pod 一起创建,并且可以在 Pod 终止时删除(临时卷)。它们在 Pod 规范中定义(内联)。

自 Kubernetes 1.15 起,CSI 驱动程序也可以用于此类临时内联卷。在 1.15 中必须设置 CSIInlineVolume 特性门控才能启用此功能,因为支持仍处于 Alpha 状态。在 1.16 中,该特性达到 Beta 状态,这通常意味着它在集群中默认启用。

CSI 驱动程序必须进行适配才能支持此功能,因为虽然使用了两个现有的 CSI gRPC 调用(NodePublishVolumeNodeUnpublishVolume),但它们的使用方式不同且未包含在 CSI 规范中:对于临时卷,kubelet 在请求 CSI 驱动程序提供卷时仅调用 NodePublishVolume。所有其他调用(如 CreateVolumeNodeStageVolume 等)都会被跳过。卷参数在 Pod 规范中提供,并从那里复制到 NodePublishVolumeRequest.volume_context 字段。目前没有标准化的参数;即使是常见的参数(如大小)也必须以 CSI 驱动程序定义的格式提供。类似地,在 Pod 终止且需要移除卷后,仅调用 NodeUnpublishVolume

最初的设想是,CSI 驱动程序将专门用于提供持久卷或临时卷。但也存在提供两种模式下都实用的存储的驱动程序:例如,PMEM-CSI 管理持久内存(PMEM),这是一种由 Intel® Optane™ DC Persistent Memory 提供的新型本地存储。此类内存既可作为持久数据存储(比普通 SSD 快),也可作为临时暂存空间(容量高于 DRAM)。

因此,Kubernetes 1.16 中的支持得到了扩展

  • Kubernetes 和用户可以通过 CSIDriver 对象中的 volumeLifecycleModes 字段确定驱动程序支持的卷类型。
  • 驱动程序可以通过启用 "pod info on mount" 特性来获取卷模式信息,该特性随后会将新的 csi.storage.k8s.io/ephemeral 条目添加到 NodePublishRequest.volume_context 中。

有关如何在 CSI 驱动程序中实现临时内联卷支持的更多信息,请参阅 Kubernetes-CSI 文档原始设计文档

本文的其余部分是基于实际驱动程序的用法示例和末尾的总结。

示例

PMEM-CSI

临时内联卷的支持已添加到 v0.6.0 版本中。该驱动程序可以在具有真实 Intel® Optane™ DC 持久内存的主机上使用,在 GCE 中的特殊机器上或通过 QEMU 模拟硬件使用。后者已完全集成到 makefile 中,仅需要 Go、Docker 和 KVM,因此本示例使用了这种方法

git clone --branch release-0.6 https://github.com/intel/pmem-csi
cd pmem-csi
TEST_DISTRO=clear TEST_DISTRO_VERSION=32080 TEST_PMEM_REGISTRY=intel make start

启动四节点集群可能需要一段时间,但最终应该以以下内容结束:

The test cluster is ready. Log in with /work/pmem-csi/_work/pmem-govm/ssh-pmem-govm, run kubectl once logged in.
Alternatively, KUBECONFIG=/work/pmem-csi/_work/pmem-govm/kube.config can also be used directly.

To try out the pmem-csi driver persistent volumes:
...

To try out the pmem-csi driver ephemeral volumes:
   cat deploy/kubernetes-1.17/pmem-app-ephemeral.yaml | /work/pmem-csi/_work/pmem-govm/ssh-pmem-govm kubectl create -f -

deploy/kubernetes-1.17/pmem-app-ephemeral.yaml 指定了一个卷

kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app-inline-volume
spec:
  containers:
    - name: my-frontend
      image: busybox
      command: [ "sleep", "100000" ]
      volumeMounts:
      - mountPath: "/data"
        name: my-csi-volume
  volumes:
  - name: my-csi-volume
    csi:
      driver: pmem-csi.intel.com
      fsType: "xfs"
      volumeAttributes:
        size: "2Gi"
        nsmode: "fsdax"

创建该 Pod 后,我们可以检查结果

kubectl describe pods/my-csi-app-inline-volume
Name:         my-csi-app-inline-volume
...
Volumes:
  my-csi-volume:
    Type:              CSI (a Container Storage Interface (CSI) volume source)
    Driver:            pmem-csi.intel.com
    FSType:            xfs
    ReadOnly:          false
    VolumeAttributes:      nsmode=fsdax
                           size=2Gi
kubectl exec my-csi-app-inline-volume -- df -h /data
Filesystem                Size      Used Available Use% Mounted on
/dev/ndbus0region0fsdax/d7eb073f2ab1937b88531fce28e19aa385e93696
                          1.9G     34.2M      1.8G   2% /data

镜像填充器(Image Populator)

镜像填充器自动解压容器镜像,并将其内容作为临时卷提供。它仍在开发中,但金丝雀镜像已可用,可以通过以下方式安装:

kubectl create -f https://github.com/kubernetes-csi/csi-driver-image-populator/raw/master/deploy/kubernetes-1.16/csi-image-csidriverinfo.yaml
kubectl create -f https://github.com/kubernetes-csi/csi-driver-image-populator/raw/master/deploy/kubernetes-1.16/csi-image-daemonset.yaml

这个示例 Pod 将运行 nginx,并使其服务来自 kfox1111/misc:test 镜像的数据

kubectl create -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.16-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: data
      mountPath: /usr/share/nginx/html
  volumes:
  - name: data
    csi:
      driver: image.csi.k8s.io
      volumeAttributes:
          image: kfox1111/misc:test
EOF
kubectl exec nginx -- cat /usr/share/nginx/html/test

那个 test 文件只包含一个单词

testing

此类数据容器可以使用如下 Dockerfile 构建:

FROM scratch
COPY index.html /index.html

cert-manager-csi

cert-manager-csi 与 cert-manager 协同工作。此驱动程序的目标是促进证书密钥对的请求和无缝挂载到 Pod。这对于促进 mTLS 或以其他方式确保 Pod 连接的安全,同时拥有 cert-manager 提供的所有功能,都非常有用,并保证证书的存在。该项目处于实验阶段。

下一步

临时内联卷的一个问题是,Kubernetes 在调度 Pod 到节点时,对该节点上当前可用的存储一无所知。Pod 调度完成后,CSI 驱动程序必须在该节点上提供卷。如果当前无法提供,则 Pod 无法启动。这将重试直到卷最终准备就绪。存储容量跟踪 KEP 是解决此问题的一种尝试。

一个相关的 KEP 引入了标准化的尺寸参数

目前,CSI 临时内联卷仍处于 Beta 阶段,同时正在讨论这些问题。需要您的反馈来决定此功能如何继续推进。对于 KEPs,上面链接的两个 PR 是提供意见的好地方。SIG Storage 也定期举行会议,并且可以通过 Slack 和邮件列表联系。