背景介绍
文件系统卷通常通过virtio-fs共享到虚拟机中。在典型的工作流程中,CSI Controller会确保后端存储(通常是块设备)已连接到节点。然后,CSI Node Driver会创建文件系统并将其挂载。如图所示:
但在虚拟化场景中,比较理想的操作是虚拟机应该直接使用块设备本身,而不是共享文件系统卷。并且直接使用块设备还能大大简化宿主机上的卷管理,并能获得更高效的存储IO性能。
这就是我们今天要讲的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 type
,src
和dst
等,如下所示:
--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
对应的Storage
和Mount
对象;•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的架构图:
假如用户已经创建了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中获取type
,src
,dst
以及options
。在kata runtime中如何处理呢?首先runtime会判断该volume是否为direct volume
。在处理volume之前,首要任务是判断volume type,这一步也是至关重要的,原因是什么呢?
1.借助containerd ctr/nerdctl等工具运行一个带有direct volume的kata是没有很多“故事”可讲的,直接按照上述方式,启动时通过--mount
添加对应的type
,src
和dst
等,就可以正确传递配置信息给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
。该 “查找-匹配” 的逻辑将在下图红框中进行。
尽管“查找-匹配”是一种有效的解决手段,但这并不是一种优秀的或者最终的解决手段,局限于现有的K8S/CSI 规范,无法传递具体的Mount Type到Kata。在kata containers看来,更希望处理明确的指令,通过指令直达volume handler来做进一步处理,而不是模糊的信息,需要根据该信息,经过在kata 中进行一些学习之后才能判断出到底该如何处理!所以,或许我们还有继续优化directvolume的想象空间。
根据解析出来的volume type
,将处理分派到具体的volume handler作进一步处理,比如获取device
路径,然后通过Device Manager
纳入管理,并插入到Guest中。
接着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提供后端存储服务呢?我们可以通过下面这张图简单了解下其协同流程。
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