本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
CSI 临时内联卷
通常,Kubernetes 中外部存储驱动程序提供的卷是**持久的**,其生命周期完全独立于 Pod,或者(作为特例)与使用卷的第一个 Pod 松散耦合(延迟绑定模式)。在 Kubernetes 中请求和定义此类卷的机制是持久卷声明 (PVC) 和持久卷 (PV) 对象。最初,由容器存储接口 (CSI) 驱动程序支持的卷只能通过这种 PVC/PV 机制使用。
但也有一些用例需要数据卷,其内容和生命周期与 Pod 绑定。例如,驱动程序可能使用特定于在 Pod 中运行的应用程序的动态创建的 Secrets 来填充卷。此类卷需要与 Pod 一起创建,并且可以作为 Pod 终止的一部分被删除(**临时**)。它们被定义为 Pod 规范的一部分(**内联**)。
自 Kubernetes 1.15 起,CSI 驱动程序也可以用于此类**临时内联**卷。在 1.15 版中,必须设置 CSIInlineVolume 功能门才能启用它,因为支持仍处于 alpha 阶段。在 1.16 版中,该功能达到了 Beta 阶段,这通常意味着它在集群中默认启用。
CSI 驱动程序必须进行调整才能支持此功能,因为尽管使用了两个现有的 CSI gRPC 调用(`NodePublishVolume` 和 `NodeUnpublishVolume`),但它们的使用方式不同且未包含在 CSI 规范中:对于临时卷,`kubelet` 在请求 CSI 驱动程序获取卷时仅调用 `NodePublishVolume`。所有其他调用(如 `CreateVolume`、`NodeStageVolume` 等)都将被跳过。卷参数在 Pod 规范中提供,并从中复制到 `NodePublishVolumeRequest.volume_context` 字段。目前没有标准化参数;即使是大小等常见参数也必须以 CSI 驱动程序定义的格式提供。同样,只有在 Pod 终止并且需要移除卷后,才会调用 `NodeUnpublishVolume`。
最初的假设是 CSI 驱动程序将专门编写用于提供持久卷或临时卷。但也有一些驱动程序提供在两种模式下都很有用的存储:例如,PMEM-CSI 管理持久内存 (PMEM),这是一种由 Intel® Optane™ DC 持久内存提供的新型本地存储。这种内存既可以用作持久数据存储(比普通 SSD 快),也可以用作临时暂存空间(容量高于 DRAM)。
因此,Kubernetes 1.16 中的支持得到了扩展。
- Kubernetes 和用户可以通过 `CSIDriver` 对象中的 `volumeLifecycleModes` 字段来确定驱动程序支持哪种卷。
- 驱动程序可以通过启用“挂载时的 Pod 信息”功能来获取卷模式信息,该功能将在 `NodePublishRequest.volume_context` 中添加新的 `csi.storage.k8s.io/ephemeral` 条目。
有关在 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
镜像填充器
镜像填充器会自动解压容器镜像并将其内容作为临时卷提供。它仍在开发中,但已提供 canary 镜像,可以通过以下方式安装:
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 阶段,同时正在讨论此类问题。我们需要您的反馈来决定如何处理此功能。对于 KEP,上面链接的两个 PR 是一个很好的评论之处。SIG Storage 也定期开会,可以通过 Slack 和邮件列表联系。