(译)CSI 的内联暂存卷
但有些情况下,数据卷的内容和生命周期是和 Pod 紧密相关的。例如有的驱动会使用动态的创建 Secret 生成卷,这个 Secret 是为了运行在 Pod 中的应用特意创建的。这种卷需要和 Pod 一起生成,并且作为 Pod 的一部分,和 Pod 一起终结。可以在 Pod Spec 中(用内联/inline 的方式)定义这种卷。
从 Kubernetes 1.15 开始,CSI 驱动也能用于这种内联暂存卷了。这个功能还处于 Alpha 阶段,因此在 1.15 中需要打开 CSIInlineVolume 特性开关 才能尝试使用这一新功能。而 1.16 中,该功能升级为 Beta 阶段,因此是缺省打开的。
虽说这个功能用到了两个现存的 gRPC 调用( NodePublishVolume
和 NodeUnpublishVolume
),但是其中的用法和 CSI 规范并不一致:在暂存卷中,Kubelet 在向 CSI 驱动请求卷时,只调用了 NodePublishVolume
。跳过了其他的(例如 CreateVolume
、 NodeStageVolume
)调用,所以要对 CSI 驱动进行一些改变。Pod Spec 中写明了卷参数,这个参数会被拷贝给 NodePublishVolumeRequest.volume_context
。目前没有标准化的参数,即使是容量这种参数也是定义在 CSI 驱动之中的。类似地,在 Pod 结束需要释放存储卷时,只调用了 NodeUnpublishVolume
。
起初有考虑分别为持久化和暂存卷编写不同的 CSI 驱动。但是有些驱动提供的存储在两种模式下都可以使用,例如 PMEM-CSI 管理的是由 Intel Optane 技术提供的持久化内存方式的本地存储。这种类型的存储既可以用作一种比普通 SSD 更快的持久化存储,也可以用作比 DRAM 更大容量的暂时性存储。
因此在 Kubernetes 1.16 中产生了变化:用户可以使用 CSIDriver
的 volumeLifecycleModes
字段来确定该驱动支持的卷类型。启用加载时 Pod 信息功能之后,驱动程序能够获取卷模式的信息,并在 NodePublishRequest.volume_context
加入 csi.storage.k8s.io/ephemeral
。
关于 CSI 驱动支持内联暂存卷的更多信息,可以浏览 Kubernetes CSI 文档 及其原始设计文档。
后续内容中包含了真实的示例以及内容总结。
示例
PMEM-CSI
在 v0.6.0 中加入了内联暂存的支持。在使用 Intel Optane 技术的主机上可以使用这种驱动,GCE 的特定类型服务器或者 QEMU 的硬件模拟上都是可用的。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.13-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 testing
cert-manager-csi
这个驱动和 cert-manager 协同工作,其目的是无缝地为 Pod 完成证书的请求和加载。这对于 mTLS 或者其它需要使用可信、有效证书的 Pod 间安全连接的工作是很有意义的。这个项目还在实验之中。
下一步
提出这个功能的原因之一就是,Kubernetes 把一个 Pod 调度到节点上时,对节点的存储情况是无知的。Pod 被调度之后,CSI 必须在该节点上创建卷。如果失败,Pod 无法启动,这个过程会一直持续到存储卷可用。存储能力跟踪的 KEP 是一个解决问题的尝试。
另外还有一个相关的 用于标准化容量参数的 KEP。
相关链接
-
CSI Ephemeral Inline Volumes:
https://kubernetes.io/blog/2020/01/21/csi-ephemeral-inline-volumes/
-
Patrick Ohly:
https://github.com/pohly
-
后绑定模式:
https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode
-
CSIInlineVolume 特性开关:
https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/
-
PMEM-CSI:
https://github.com/intel/pmem-csi
-
CSIDriver
:
https://kubernetes-csi.github.io/docs/csi-driver-object.html#what-fields-does-the-csidriver-object-have
-
加载时 Pod 信息:
https://kubernetes-csi.github.io/docs/pod-info.html
-
Kubernetes CSI 文档:
https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html
-
原始设计文档:
https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/20190122-csi-inline-volumes.md
-
v0.6.0:
https://github.com/intel/pmem-csi/releases/tag/v0.6.0
-
GCE 的特定类型服务器:
https://github.com/intel/pmem-csi/blob/v0.6.0/examples/gce.md
-
QEMU 方式已经集成到了 Makefile:
https://github.com/intel/pmem-csi/tree/v0.6.0#qemu-and-kubernetes
-
cert-manager:
https://github.com/jetstack/cert-manager
-
存储能力跟踪的 KEP:
https://github.com/kubernetes/enhancements/pull/1353
-
用于标准化容量参数的 KEP:
https://github.com/kubernetes/enhancements/pull/1409