21

(译)CSI 的内联暂存卷

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzIxMDY5ODM1OA%3D%3D&%3Bmid=2247484987&%3Bidx=1&%3Bsn=bfff7577709d6c2340c2a4a04289c693
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Kubernetes 利用外部存储驱动提供出来的存储卷一般来说都是持久化的,它的生命周期可以完全独立于 Pod,(特定情况下)也可以和第一个用到该卷的 Pod(后绑定模式)有着宽松的耦合关系。在 Kubernetes 中使用 PVC 和 PV 对象完成了存储卷的申请和供给机制。起初,容器存储接口(CSI)支持的存储卷只能用于 PVC/PV 的场合。

但有些情况下,数据卷的内容和生命周期是和 Pod 紧密相关的。例如有的驱动会使用动态的创建 Secret 生成卷,这个 Secret 是为了运行在 Pod 中的应用特意创建的。这种卷需要和 Pod 一起生成,并且作为 Pod 的一部分,和 Pod 一起终结。可以在 Pod Spec 中(用内联/inline 的方式)定义这种卷。

从 Kubernetes 1.15 开始,CSI 驱动也能用于这种内联暂存卷了。这个功能还处于 Alpha 阶段,因此在 1.15 中需要打开 CSIInlineVolume 特性开关 才能尝试使用这一新功能。而 1.16 中,该功能升级为 Beta 阶段,因此是缺省打开的。

虽说这个功能用到了两个现存的 gRPC 调用( NodePublishVolumeNodeUnpublishVolume ),但是其中的用法和 CSI 规范并不一致:在暂存卷中,Kubelet 在向 CSI 驱动请求卷时,只调用了 NodePublishVolume 。跳过了其他的(例如 CreateVolumeNodeStageVolume )调用,所以要对 CSI 驱动进行一些改变。Pod Spec 中写明了卷参数,这个参数会被拷贝给 NodePublishVolumeRequest.volume_context 。目前没有标准化的参数,即使是容量这种参数也是定义在 CSI 驱动之中的。类似地,在 Pod 结束需要释放存储卷时,只调用了 NodeUnpublishVolume

起初有考虑分别为持久化和暂存卷编写不同的 CSI 驱动。但是有些驱动提供的存储在两种模式下都可以使用,例如 PMEM-CSI 管理的是由 Intel Optane 技术提供的持久化内存方式的本地存储。这种类型的存储既可以用作一种比普通 SSD 更快的持久化存储,也可以用作比 DRAM 更大容量的暂时性存储。

因此在 Kubernetes 1.16 中产生了变化:用户可以使用 CSIDrivervolumeLifecycleModes 字段来确定该驱动支持的卷类型。启用加载时 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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK