基于kata direct volume特性, 实现安全容器KataContainer的 CSI block volume直通方案
在 Kubernetes
中集成 Kata Containers
可以为容器运行时提供更好的安全性
和隔离性
,但在存储方面
仍然还存在一些限制与不足。
目前方案:virtiofs协议
Kata Containers
在 2.4 版本之前,挂载 PV
的整个过程与 CSI
之间是没有任何交互的,而且也不能直接使用 CSI
挂载的 PV
,只能通过 virtiofs 协议
将宿主机上的存储卷以文件共享的方式提供给 Kata Containers
虚拟机中的 container
使用。
这种方式虽然能够解决 PV
存储挂载的问题,但与直接在宿主机上使用存储卷相比,由于 virtiofs
实现方式的 I/O
路径过长,会带来不少的性能损耗。
经过环境实测,总结出以下几方面问题:
-
稳定性方面
:在实际环境中,对virtiofs
共享的盘进行fio 测试
,我们经常能观察到 io 不连续的现象,并且在对盘进行加压测试时,会影响到容器中其他进程的响应,比如 ssh 进程响应会超时; -
性能方面
:与直接在宿主机上使用存储卷相比,virtiofs
共享盘在iops
和带宽
方面有不少差距; -
功能方面
:virtiofs
共享盘方式无法在线调整PV
大小,需要通过重启Pod
才能使VM
能感知到PV
大小变化;
优化方案
基于 virtiofs 现存问题,Kata Containers
在 2.4 版本提供了 direct assigned volume
功能,能够将文件系统挂载操作从宿主机移动到 Guest
中,相当于是一种 block volume
直通方案。和 virtiofs
相比,不仅能提供接近直接宿主机上使用存储卷的性能,而且还能支持 native FS
。由于不需要借助于 virtiofs
,在使用上会更加稳定,也能带来安全性方面的提升。同时,这个特性还支持在线修改 PV
存储大小。
具体kata direct assigned volume
特性设计:https://github.com/kata-containers/kata-containers/blob/main/docs/design/direct-blk-device-assignment.md
在 CSI 中实现 direct volume
前提条件
-
由于需要在
host
上创建文件,CSI node
服务在部署时需要把/run/kata-containers/shared/direct-volumes
目录以hostpath
方式挂载到pod
里。 -
CSI
在挂载时需要明确知道所挂载的volume
是否是以direct volume
这种方式挂载,所以需要有一种机制能通知到CSI
,可以借助以下三种方式:通过
StorageClass
指定direct volume
属性在
PVC
对象里通过annotation
打上direct volume
属性,同时 CSI 插件需要打开--extra-create-metadata
属性来帮助CSI
能从K8s apiserver
查询到PVC
的annotation
信息通过查询
Pod
的runtimeclass
信息来判断是否是Kata direct volume
挂载
实现步骤
以下步骤主要都在 CSI NodePublishVolume
接口里实现:
- 把远程存储的
block device
挂载到host
上。 - 根据实际需求场景对
block device
做文件系统格式化。 - 生成
mountinfo.json
信息并把mountinfo.json
信息传递给 Kata。
mountInfo
的内容是 json 格式,主要数据结构如下:
其中 CSI 侧主要需要传递以下三个字段信息即可,例如:
CSI
负责把 mountinfo.json
传递给 Kata
,Kata
会在容器所在 host
的 /run/kata-containers/shared/direct-volumes/volume-path(base64加密)/
目录下生成 mountinfo.json
文件,目前 CSI
有两种方式可以传递 mountinfo.json
信息
- 通过调用
kata-container
代码里direct volume
模块的add
方法传递mountinfo.json
信息,部分代码实例如下:
- 通过
kata-runtime CLI
命令传递mountinfo.json
信息:
最后会在容器所在 host 的 /run/kata-containers/shared/direct-volumes/volume-path(base64加密)/
目录下生成 mountinfo.json
文件,然后 Kata Containers
会在启动容器时检查该目录是否有 mountinfo.json
文件并解析该文件,同时更新容器 spec
中 mount
信息,将直通卷的信息加入进去,然后将修改后的 spec
传给 kata-agent
;
方案限制:
- 使用
direct volume
方式的PV
只能给一个Pod
使用,所以在创建PVC
时需要指定accessMode
为ReadWriteOnce
- 使用
direct volume
方式不支持更高级的volume
功能,比如:fsGroup
、fsGroupChangePolicy
和subPath
未来:kata 联动 kubelet/kube-apiserver,实现CSI 卷的运行时辅助挂载
社区未通过的最终方案:KEP-2857:持久卷的运行时辅助安装