Kata Containers 高效的 Direct Block Volume 方案及 CSI | 技术解读

eb4295b43762b139248c1a511056b6ae.gif

背景介绍

文件系统卷通常通过virtio-fs共享到虚拟机中。在典型的工作流程中,CSI Controller会确保后端存储(通常是块设备)已连接到节点。然后,CSI Node Driver会创建文件系统并将其挂载。如图所示:

12738a6d9b2279c575e40179e59dcd84.png

Virtio-fs Sharing

但在虚拟化场景中,比较理想的操作是虚拟机应该直接使用块设备本身,而不是共享文件系统卷。并且直接使用块设备还能大大简化宿主机上的卷管理,并能获得更高效的存储IO性能。

7e02b3c47a9f86954bc2756fe94782b9.png

Direct Block Device Assignment

这就是我们今天要讲的Kata的Direct Block Device Assignment(直接使用块设备) 假如kata VM要支持直接使用块设备而不是共享文件,那么我们需要解决以下两个问题:

•如何将后端设备文件插入到Kata VM中?这是kata要解决的重要问题。•在K8S环境中,用户如何像使用其他CSI一样为Kata Pod提供后端存储?这是CSI与kata协同处理直接使用块设备的问题。

接下来将针对这两个问题,作出解释。

(本文仅限于Direct Block Device Assignment与CSI协同工作设计/实现思路,至于具体实现细节,请参考代码仓库kata-containers[1])。

Kata 支持Direct Block Device

Kata-Containers/Direct Volume存储路径/run/kata-containers/shared/direct-volumes 我们在此约定,在本文描述时,将使用DIRECTVOLUMEPATH代替/run/kata-containers/shared/direct-volumes.

假设用户通过containerd客户端ctr创建并运行一个Kata Pod,并且运行时指定pod使用Host上的一个rawdisk,那么实现步骤以及执行流程是什么样的呢?

1. 首先需要创建backing file作为direct block device based volume的后端存储,并对该文件格式化

$ sudo dd if=/dev/zero of=/tmp/stor/rawdisk01.20g bs=1M count=20480
$ sudo mkfs.ext4 /tmp/stor/rawdisk01.20g

2. 通过kata-runtime/kata-ctl 添加direct volume并生成指定路径下的mountInfo.json

sudo kata-ctl direct-volume add /kubelet/kata-direct-vol-002/directvol002 "{\"device\": \"/tmp/stor/rawdisk01.20g\", \"volume-type\": \"directvol\", \"fstype\": \"ext4\", \"metadata\":"{}", \"options\": []}"

在该命令行中,我们需要知道以下几个问题:

•通过kata-runtime/kata-ctl direct volume相关工具生成可持久化配置文件,其存储路径如下: "$DIRECTVOLUMEPATH/$base64.URLEncodedSRC/mountInfo.json" 需要明确的是用户指定volume path在此路径中是以加密的字符串(即$base64.URLEncodedSRC)形式存在的。•指定配置路径Volume Path,比如/kubelet/kata-direct-vol-002/directvol002。在K8S中,该路径为带有DirectVolume PVC的Pod被调度到某个节点上时,Kubelet为该Pod创建的Volume路径: /var/lib/kubelet/pods/<POD>/volumes/kubernetes.io~csi/<NAME>/mount•指定配置信息Mount Info,以字符串形式给出: "{\"device\": \"/to/path/rawdisk.x\", \"volume-type\": \"directvol\", \"fstype\": \"ext4\", \"metadata\":"{}", \"options\": []}",该字符串将最终写入到一个可持久化的backing block device 配置文件MountInfo.json,比如命令行中,Mount Info转换成mountInf.json,如下:

# cat mountInfo.json | jq
{
  "device": "/tmp/stor/rawdisk01.20g", 
  "volume-type": "directvol", 
  "fstype": "ext4", 
  "metadata":"{}", 
  "options": []
}

其中

•volume-type表示该设备对应的volume的类型,最基础的类型为"directvol",还支持其他几种类型,比如vfiovol,spdkvol等。•device表示backing device在host上的真实存在的路径,可以是一个普通文件,也可以是一个/dev/下的block设备。•fstype表示device设备在插入Kata VM之前必须先按照fstype指定类型进行格式化,否则插入VM时会失败。•metadata并非必填项,用户可以根据需求进行设置。•options是需要进行相应配置的,因为该配置影响了volume 挂载时的读写方式。

3. 用户在完成配置后,kata runtime运行Kata pod时,指定mount命令选项

$ # type=disrectvol,src=/kubelet/kata-direct-vol-002/directvol002,dst=/disk002,options=rbind:rw
$ sudo ctr run -t --rm \
  --runtime io.containerd.kata.v2 \
  --mount type=directvol,src=/kubelet/kata-direct-vol-002/directvol002,dst=/disk002,options=rbind:rw \
  "$image" test-directvol-01 /bin/bash

mount选项对应的Mount typesrcdst等,如下所示:

--mount type=directvol,src=/tmp/raw-disk01,dst=/data,options=rbind:rw

type:通过该type直接查找对应volume handler,比如directvol handler,vfiovol handler等;•src:从"$DIRECTVOLUMEPATH/$EncodedSRC}/mountInfo.json"中获取device路径,然后调用Device Manager将block device插入到Kata VM中,并构建Kata Agent对应的StorageMount对象;•dst:该dst指定了设备插入VM后设备挂载在容器中的路径,该部分通过kata-agent将根据RPC传递过来的Storage/Mount信息找到对应的storage handler,对Guest中block设备作相应的处理和挂载操作。

至此,一个block device assigned volume已经成功出现Kata Pod中(可以通过lsblk查看)。简单总结一下,Kata Containers若想成功运行一个使用Direct Volume的pod,需要遵循以下步骤:

•创建一个backing file或者/dev/blockX设备,并对其格式化(挂载文件系统);•利用kata-ctl/kata-runtime 添加direct volume并生成mountInfo.json;•指定的参数选项并运行一个Kata:ctr run --mount type=<TYPE>,src=<SRC>,dst=<DST>,options=rbind:rw ...

Tips:在以上ctr run的过程中,我们指定了--mount type=directvol, ...是必须的么? 当然不是!用户也可以指定bind,kata runtime(runtime-rs)是可以对其进行处理的。

那么kata runtime是如何对direct volume进行处理的呢?如下图中红框为kata-runtime处理direct block volume的架构图:

4bc66e251519b5cd536f90fd2a57fbd0.png

kata direct block volume

假如用户已经创建了backing file并对其进行格式化,然后通过kata-runtime/kata-ctl direct-volume添加volume,此时已经成功生成了mountInfo.json配置文件。接着,通过ctr run --mount type=bind[directvol],src=source,dst=dest,options=bind:rw指定mountInfo.json配置文件的位置来运行一个pod,kata-runtime在处理volume时,从oci spec的mount中获取typesrcdst以及options。在kata runtime中如何处理呢?首先runtime会判断该volume是否为direct volume。在处理volume之前,首要任务是判断volume type,这一步也是至关重要的,原因是什么呢?

1.借助containerd ctr/nerdctl等工具运行一个带有direct volume的kata是没有很多“故事”可讲的,直接按照上述方式,启动时通过--mount添加对应的typesrcdst等,就可以正确传递配置信息给Kata来处理。2.在K8S中却不没有那么简单! 因为Container Mount经过CRI传递给containerd,经由containerd处理后,通用的Mount.Source信息都会给处理成OCI spec Mount的形式,而且类型全部是`"bind"``;3.由于OCI Mount的Type类型总是"bind",传递给kata runtime后对Mount的路径正确有效地区分路径对应哪个类型,最终导致无法直接通过Mount Type区分出来volume handler。

那么如何解决这个问题呢? 一种简单有效的方式就是 “查找-匹配” ,通过指定的src,查找该路径$DIRECTVOLUMEPATH/$EncodedSRC/下是否存在mountInfo.json并尝试解析,如果成功,证明该volume为Direct Volume,否则认为不是Direct Volume。该 “查找-匹配” 的逻辑将在下图红框中进行。

c8d408862279e17b9e5dab0972d19820.png

查找-匹配

尽管“查找-匹配”是一种有效的解决手段,但这并不是一种优秀的或者最终的解决手段,局限于现有的K8S/CSI 规范,无法传递具体的Mount Type到Kata。在kata containers看来,更希望处理明确的指令,通过指令直达volume handler来做进一步处理,而不是模糊的信息,需要根据该信息,经过在kata 中进行一些学习之后才能判断出到底该如何处理!所以,或许我们还有继续优化directvolume的想象空间。

根据解析出来的volume type,将处理分派到具体的volume handler作进一步处理,比如获取device路径,然后通过Device Manager纳入管理,并插入到Guest中。

a22dd0568a7f7b195c692e3092f32570.png

Device Manager处理

接着volume handler构建host/guest之间的共享路径,并根据插入Guest中的设备,还有VMM支持的block device driver等信息构建kata Agent ttrpc Storage对象,该对象在create container流程通过ttrpc传递给Gues中的Agent作add storage的处理。至此完成volume挂载。

CSI协同Kata支持Direct Block Volume

在容器生态中,K8S + Kata Containers组合在很多重要场景中发挥作用,并为容器提供资源性能IO等方面的隔离能力。在此场景下,业务应用总希望能有一种高效的后端存储能力与之协同,这就需要能提供一个CSI来灵活配置基于Direct Block Device Assignment的后端存储,这就是CSI。

在K8S环境中,若想让kata pod正确使用direct volume,必须先在K8S环境中部署Direct Volume CSI Driver。用户也可以参考社区相关文档(https://github.com/kata-containers/kata-containers/blob/main/docs/how-to/how-to-run-kata-containers-with-kinds-of-Block-Volumes.md)。

接下来将介绍如何部署CSI Driver到一个K8S环境中。当然,我们需要先假设用户已经有K8S(k8s 1.20+)环境以及相关golang的开发工具链。

kata direct volume CSI driver镜像制作

# 假设已经下载了kata-containers源码到本地,首先进入到csi-kata-directvolume目录中执行make
$ cd kata-containers/src/tools/csi-kata-directvolume && make
$ ls bin/
directvolplugin
# 接下来,根据direct volume的Dockerfile制作镜像kata-directvolume:${TAG}
# 镜像制作依赖当前环境所安装的运行时,我们以podman/buildah为例。
$ tree csi-kata-directvolume/ -L 1
csi-kata-directvolume/
├── bin
├── cmd
├── deploy
├── Dockfile
├── docs
├── examples
├── go.mod
├── go.sum
├── internal
├── Makefile
├── pkg
├── README.md
└── release-tools
# buildah构建kata direct volume image
$ mkdir /tmp/build-images && cp Dockerfile /tmp/build-images/
$ cd /tmp/build-images && buildah bud -t kata-directvolume:v1.0.19
STEP 1/7: FROM alpine
STEP 2/7: LABEL maintainers="Kata Containers Authors"
STEP 3/7: LABEL description="Kata DirectVolume Driver"
STEP 4/7: ARG binary=./bin/directvolplugin
...
Successfully tagged localhost/kata-directvolume:v1.0.19
244001cc51d77302c4ed5e1a0ec347d12d85dec4576ea1313f700f66e2a7d36d
# 接下来的步骤,主要目的是将制作好的镜像load起来并能通过crictl images查看到。
$ podman save localhost/kata-directvolume:v1.0.19 -o kata-directvolume-v1.0.19.tar
$ ctr -n k8s.io image import kata-directvolume-v1.0.19.tar
unpacking localhost/kata-directvolume:v1.0.19 (sha256:1bdc33ff7f9cee92e74cbf77a9d79d00dce6dbb9ba19b9811f683e1a087f8fbf)...done
$ crictl images |grep 1.0.19
localhost/kata-directvolume                                          v1.0.19             244001cc51d77       83.8MB
$ cd - && cat deploy/kata-directvolume/csi-directvol-plugin.yaml |grep -A10 "name: kata-directvolume"
        - name: kata-directvolume
          # build and push it into registry
          # 用户需要在此处替换前面已经制作好的direct volume image
          # image: localhost/kata-directvolume:v1.0.18
          image: localhost/kata-directvolume:v1.0.19
          args:
            - --drivername=directvolume.csi.katacontainers.io
            - --v=5
            - --endpoint=$(CSI_ENDPOINT)
            - --statedir=$(STATE_DIR)
            - --storagepath=$(STORAGE_POOL)
            - --nodeid=$(KUBE_NODE_NAME)
          env:

kata direct volume CSI driver部署

当kata direct volume镜像制作完成后,我们开始部署CSI Driver。为了方便用户部署,我们提供了一个deploy.sh一键部署脚本,操作如下

$ cd kata-containers/src/tools/csi-kata-directvolume/
$ sudo deploy/deploy.sh 
Creating Namespace kata-directvolume ...
kubectl apply -f /tmp/tmp.kN43BWUGQ5/kata-directvol-ns.yaml
namespace/kata-directvolume created
Namespace kata-directvolume created Done !
Applying RBAC rules ...
curl https://raw.githubusercontent.com/kubernetes-csi/external-provisioner/v3.6.0/deploy/kubernetes/rbac.yaml --output /tmp/tmp.kN43BWUGQ5/rbac.yaml --silent --location
kubectl apply -f ./kata-directvolume/kata-directvol-rbac.yaml
serviceaccount/csi-provisioner created
clusterrole.rbac.authorization.k8s.io/external-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/csi-provisioner-role created
role.rbac.authorization.k8s.io/external-provisioner-cfg created
rolebinding.rbac.authorization.k8s.io/csi-provisioner-role-cfg created
...
NAMESPACE           NAME                                       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kata-directvolume   daemonset.apps/csi-kata-directvol-plugin   1         1         1       1            1           <none>                   4s
kube-flannel        daemonset.apps/kube-flannel-ds             1         1         1       1            1           <none>                   67d
kube-system         daemonset.apps/kube-proxy                  1         1         1       1            1           kubernetes.io/os=linux   67d

我们可以通过执行kubectl get po -n kata-directvolume验证kata-directvolume namespace中是否出现csi-kata-directvol-plugin-* Pod处于Running状态。如下结果说明kata direct volume CSI 已经部署成功。

$ kubectl get po -n kata-directvolume
NAME                              READY   STATUS    RESTARTS   AGE
csi-kata-directvol-plugin-hfdfd   4/4     Running   0          90s

至此,Kata Direct Volume CSI部署完成。

•运行一个使用kata direct volume 的kata pod

在K8S环境中,创建并运行一个Kata Pod是通过yaml文件来约定Pod的资源限额和使用方式的,比如Pod通过CSI配置后端存储。为了验证CSI Driver是否正常工作,可以通过examples/pod-apply.sh创建storage class,csi pvc和使用direct volume的kata pod。

$ cd kata-containers/src/tools/csi-kata-directvolume/
# 执行pod-apply.sh自动创建storage class,csi pvc和使用direct volume的kata pod
$ examples/pod-apply.sh
# 验证运行结果
$ kubectl get po -A
NAMESPACE      NAME                              READY   STATUS    RESTARTS       AGE
kata-directvolume        csi-kata-directvol-plugin-dlphw   4/4     Running   0              68m
default        kata-driectvol-01                 1/1     Running   0              67m


$ kubectl get sc,pvc -A
NAME                                                   PROVISIONER                          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
storageclass.storage.k8s.io/csi-kata-directvolume-sc   directvolume.csi.katacontainers.io   Delete          Immediate           false                  71m


NAMESPACE   NAME                                         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS               AGE
default     persistentvolumeclaim/csi-directvolume-pvc   Bound    pvc-d7644547-f850-4bdf-8c93-aa745c7f31b5   1Gi        RWO            csi-kata-directvolume-sc   71m

现在我们已经通过以上步骤将一个使用direct volume的kata pod顺利运行起来。

那么CSI如何协同Direct Volume来为Kata Pod提供后端存储服务呢?我们可以通过下面这张图简单了解下其协同流程。

1f4c27d6f3983c5d8ba8ac22c2f29827.png

CSI协同Kata支持Direct Block Volume

1. 创建 StorageClass:集群管理员定义 StorageClass,并指定Provisioner以及与Direct Volume相关的参数,比如direct volume类型,direct volume对应后端存储的文件系统类型等。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-kata-directvolume-sc
parameters:
  katacontainers.direct.volume/volumetype: directvol
  katacontainers.direct.volume/fstype: ext4
provisioner: directvolume.csi.katacontainers.io
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: false

2. 用户请求存储:用户创建 PVC,并指定所需的存储大小和 StorageClass。K8S 会Watch到一个新的 PVC,并开始处理存储请求。如下yaml所示,用户创建PVC,并关联StorageClass。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-directvolume-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  storageClassName: csi-kata-directvolume-sc # defined in csi-storageclass.yaml

•运行一个Kata Pod

kind: Pod
apiVersion: v1
metadata:
  name: kata-driectvol-01
spec:
  runtimeClassName: kata
  containers:
    - name: first-container
      image: ubuntu:22.04 
      volumeMounts:
      - mountPath: "/data"
        name: kata-driectvol-volume-01
      command: [ "sleep", "1000000" ]
  volumes:
    - name: kata-driectvol-volume-01
      persistentVolumeClaim:
        claimName: csi-directvolume-pvc # defined in csi-pvc.yaml

1.动态供应卷:K8S 的控制平面检测到一个未绑定的Kata Direct Volume的 PVC,并调用指定的 Direct Volume CSI Driver来创建一个新的存储卷。CSI Driver与存储后端交互创建卷,并返回有关新卷的信息。2.创建 PV 对象:一旦存储卷被成功创建,K8S 会在集群中创建一个匹配的PV对象,并填充与CSI Driver返回的存储卷信息相对应的属性。3.PVC 与 PV 绑定:K8S 将新创建的PV与请求它的PVC进行绑定,绑定后的PVC可以被Pod使用。4.使用存储卷:用户在Pod的定义中引用PVC。当Pod被调度运行时,K8S负责将PV挂载到Pod的容器中,应用程序即可开始使用存储资源。5.清理与回收:当PVC不再需要时,可以删除它。根据StorageClass中的reclaimPolicy设置,相应的PV可以被保留(保留Policy),手动回收(回收Policy),或者自动删除(删除Policy),从而释放后端存储资源。

通过这个过程,K8S 能够提供一个灵活的、与存储供应商无关的方式来自动供应存储资源,这使得应用部署和管理更加简单和高效。通过该流程的简述,我们可以看到Kata Direct Volume CSI 与其他CSI的使用方式,并没有什么差别,若非要说有,可能Kata Direct Volume对应的CSI Driver的名称,有些不同甚至专属于Kata Direct Volume。有时候我们对某一事物需要有一定的掌控力,而掌控力的来源之一,可能就是对该事物有进一步的了解。我相信大家也一定对Direct Volume想有进一步的了解。希望接着能针对Direct Volume CSI实现过程中的重点做一些描述。那就是接下来的工作原理分析。

工作原理分析

Direct Volume CSI Driver 为Pod提供的资源方式,采用一种动态创建和分配存储资源的机制。该机制主要涉及以下主要组件:

StorageClass

定义存储卷的类别,其中包括CSI driver名称和与此类存储相关的参数。在K8S中使用direct volume时,管理员创建StorageClass 来告知K8S如何与特定的存储系统交互。并约定管理员创建StorageClass使用前缀“katacontainers.direct.volume”代表kata containers direct volume。同时还规定需要在storage class配置中比较重要的参数(parameters)。

katacontainers.direct.volume/volumetype: directvol:

该参数也是必需的。代表指定storage class提供的volume type,是需要传递给kata direct volume并根据该类型选择对应的volume handler。

katacontainers.direct.volume/fstype: ext4:该参数是必需的。管理员需要根据情况选择指定的direct volume所挂载的文件系统类型。

另一重要的约定是CSI Driver的名称directvolume.csi.katacontainers.io,该名称是Direct Volume CSI在K8S系统中注册的名称并作为storage class中provisioner的值,即provisioner: directvolume.csi.katacontainers.io。对于storage class配置文件的名称,用户可根据具体需求来选填符合yaml规范的名称。

PersistentVolumeClaim (PVC)

用户创建PVC来请求存储资源,PVC规定了所需存储的大小和访问模式,并且指定了要使用的StorageClass。对于用户使用PVC配置申请direct volume的用法与其他通用的PVC使用方式并没有区别。这也是Kata Containers Direct Volume CSI实现时要达到的一个重要目标,就是希望延续用户使用其他CSI的习惯,只需要通用的配置就可以使用direct volume CSI。在用户设置PVC时,需要填写对应storage class的name。

Direct Volume CSI Driver

在Kata Direct Volume CSI Driver中,需要实现必要的gRPC Server并按需实现对应的API集合。比如在此Driver中我们主要实现以下三个Server:

•Identity Server•Controller Server•Node Server

Identity Server

Identify Server是必须实现的一个Server,但对于direct volume而言,并没有多少需要大篇幅修改的地方,只需要按部就班地仿照模版进行修改即可,这里也就不再过多描述细节问题。

type IdentityServer interface {
    GetPluginInfo(context.Context, *GetPluginInfoRequest) (*GetPluginInfoResponse, error)
    GetPluginCapabilities(context.Context, *GetPluginCapabilitiesRequest) (*GetPluginCapabilitiesResponse, error)
    Probe(context.Context, *ProbeRequest) (*ProbeResponse, error)
}
Controller Server

接着是Controller Server及API的实现,Controller Server对应着Provisionin和Deleting阶段,实现卷的创建、删除、分配、绑定等操作。其实在基于Kata Direct Volume CSI中,我们并没有在此过多着墨,并不需要做太多工作,只需要负责实现卷的创建和删除。由于现阶段Direct Volume的使用场景是基于本地的文件作为存储后端,并没有Attach和Detach Volume等操作 (注:但在后续实现中会增加远程盘的支持)。因此只需要关注如何把必要的信息获取到并保存到VolumeContext中即可。在Kata Direct Volume必须实现的Controller Server,其对应的API如下:

// ControllerServer is the server API for Controller service.
type ControllerServer interface {
    CreateVolume(context.Context, *CreateVolumeRequest) (*CreateVolumeResponse, error)
    DeleteVolume(context.Context, *DeleteVolumeRequest) (*DeleteVolumeResponse, error)
    ControllerGetCapabilities(context.Context, *ControllerGetCapabilitiesRequest) (*ControllerGetCapabilitiesResponse, error)
    ...
}

当然这需Controller Server 提前声明了相关capability: ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,相应地,则只需要实现 CreateVolume 和 DeleteVolume 方法。

1.CreateVolume方法用于创建卷,在Direct Volume处理流程中,其关键:

•从CreateVolumeRequest中获取volume type和volume fs,然后将volume type和volume fs存储到VolumeContext中。•从request中获取PVC指定的存储大小capacity,并将该capacity存储到CreateVolumeResponse中。

1.DeleteVolume方法用于删除卷,其关键步骤如下:

•从VolumeContext中获取volume ID。•删除相关的信息。

经过Controller Server的处理,我们已经能够将必要的volume type,volume fstype,以及capacity存储到Response中。这些信息可以从Node Sever相关请求接口中获取到,并用于后续Node Server的处理流程。

NodeServer

Node Server,主要职责在于管理存储卷在具体节点上的生命周期操作。一旦Controller Server创建了一个存储卷,并且该卷已经被挂载到节点上 (尽管Direct Volume并不需要这么做),Node Server需要根据VolumeRequest提供的详细信息将该Volume挂载(Mount)到Pod上,或者在不再需要时将其卸载(Umount)。我们需要再次知晓并不是所有的Node Server APIs都要实现,根据具体情况选择接口具体实现。由于Kata Direct Volume使用时,需要预先创建backing file storage,需要通过kata-runtime/kata-ctl等生成相关配置文件(mountInfo.json),所以在CSI具体实现中,我们除了要实现NodePublish阶段的接口之外,还需要增加NodeStage阶段的接口实现,在两个不同的阶段进行不同的操作。把创建后端设备流程与生成配置阶段分离,希望如此做法,能在错误发生时更易定位哪个阶段出现的问题。在Kata Direct Volume的Node Server中,其必须实现的APIs,如下所示:

type NodeServer interface {
    NodeStageVolume(context.Context, *NodeStageVolumeRequest) (*NodeStageVolumeResponse, error)
    NodeUnstageVolume(context.Context, *NodeUnstageVolumeRequest) (*NodeUnstageVolumeResponse, error)
    NodePublishVolume(context.Context, *NodePublishVolumeRequest) (*NodePublishVolumeResponse, error)
    NodeUnpublishVolume(context.Context, *NodeUnpublishVolumeRequest) (*NodeUnpublishVolumeResponse, error)
    NodeGetCapabilities(context.Context, *NodeGetCapabilitiesRequest) (*NodeGetCapabilitiesResponse, error)
    ...
}
NodeStage阶段

该阶段主要负责direct volume backing file的创建工作,重要实现两个API:NodeStageVolume/NodeUnstageVolume

1.在NodeStageVolume流程中:

•根据NodeStageVolumeRequest信息,获取volumeId和Volume capacity;•然后调用backing file storage的创建方法CreateDirectBlockDevice完成backing file创建和挂载指定文件系统的工作,并存储在集群管理员预先设定好的存储位置StoragePath。

1.在NodeUnstageVolume流程进行相关逆向操作。

NodePublish阶段

该阶段主要负责完成DirectVolume Add/Remove以及将mount/umount Volume的工作。

•需要从NodePublishVolumeRequest中获取Kata Direct Volume 相关的信息,比如fstype, volume-type,backing file path(device path),以及其他属性信息,比如readonly,options,attribute等;•并根据获取的信息来构建Direct Volume的MountInfo结构体;•然后调用direct volume的方法AddDirectVolume(targetPath, mountInfo)生成$DIRECTVOLUMEPATH/$EncodedTargetPath/mountInfo.json

至此,kata direct volume的配置工作已经基本完成,接下来就是k8s通过containerd将volume Mount信息传递给kata runtime,然后在runtime中解析mountInfo.json文件,构建结构体对象,并做进一步的处理,该流程已在Kata 支持Direct Block Device部分介绍的很清楚,就不再赘述。

References

[1] kata-containers: https://github.com/kata-containers/kata-containers
[2] 请参考kata-containers社区: https://github.com/kata-containers/kata-containers/blob/main/docs/how-to/how-to-run-kata-containers-with-kinds-of-Block-Volumes.md
[3] direct assign volume: https://github.com/egernst/kata-containers/blob/da-proposal/docs/design/direct-assign-volume.md
[4] how to run kata containers with kinds of Block Volumes: https://github.com/kata-containers/kata-containers/blob/main/docs/how-to/how-to-run-kata-containers-with-kinds-of-Block-Volumes.md
[5] csi driver host path: https://github.com/kubernetes-csi/csi-driver-host-path

ad31e2636244f3be43928a14708e3ca8.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值