|
智汇华云|katacontainervirtiofs测试和技术分析
云原生技术已经成为加快企业数字化转型的一个不折不扣的风向标。而以容器为代表的云原生技术正在成为释放云价值的最短路径。本期智汇华云,带大家一起了解和体验安全容器katacontainer的?些特性。
前?
当前云原?技术发展的如?如荼,容器化技术以及kubernetes容器化应?管理平台,带来了全新的?态系统.随着容器技术的发展,容器运?时规范OCI也逐渐脱离Docker被单独提了出来,kubernetes?期使?的容器运?时是runC,轻量,性能?,但因为共?linux内核以及namespace机制隔离的不彻底,存在?定的安全问题,业界涌现了好?个安全容器的解决?案,?如Google的gVisor,Amazon的Firecracker,vmware的CRX等,开源世界???较有名的解决?案是katacontainer,本?主要就关注在安全容器katacontainer的?些特性了解和体验。kataContainer
katacontainer由?系列技术组成,来源于两个项?的合并,IntelClearContainers和HyperrunV,然后?加上redhat贡献的virtio-fs,?种在guest和宿主机之间共享?件系统的?案。涉及的技术有QEMU/KVM,Linuxkernel,?件系统,容器运?时,容器?络等,是?项?较复杂的组合产品,?且还保持着很?的新特性开发进度,本次主要体验和梳理virtiofs相关的内容,这些内容有部分是来源于kata的社区邮件列表以及slack,还有微信群,?常感慨,kata的社区真是?常的Nice,专业程度和热?都令?感动。
virtiofs?件系统结构
默认容器是使?cgroup和namespace做进程,?络,?件系统挂载点等隔离,是?常轻量级的。?katacontainer为了实现安全容器,使?了VM虚拟机作为强隔离?段,有独?的内核和虚拟机镜像,为了降低资源消耗,hypervisor使?了?常?的guestkernel和guestimage,?度优化了内核的启动时间,最?化了内存占?,只提供容器负载所需要的最基本的服务。virtio-fs?件系统,在资源消耗上也使?了多种优化特性。下?就来看?看具体是怎么使?的,以及特性理解katacontainer作为除了runC之外另?种runtime,需要先在kubernetes环境中做集成部署,以便做各种观察。当然直接使?他的CTR?具也是可以,只是缺少CNI的?持,?络??不能?动配置。katacontainerconfiguration.toml配置参数有两种共享?件系统类型可以选择,之前默认是virtio-9p,现在基本上都会选择virtio-fs,有若?优点。virtio-9p和virtio-fs?件系统对?
1.virtio-9p基于现存的?络协议,并没有虚拟化场景提供优化
2.virtio-fs利?了hypervisor和虚拟机处于相同节点的优势
DAX特性,?件内容能够映射到宿主机的内存窗?,允许客户机直接访问宿主机的pagecache
减少内存占?,因为客户机cache已经被绕过了
不需要?络节点通信,提?了IO性能
测试
katacontainer与整合使?virtiofsd,把宿主机?录共享给微虚拟机使?。测试环境版本:Centos8
qemu-kvm5.1
kubernetes1.18
containerd1.4.4
katacontainer2.0.4
使?kubernetes新版本的RuntimeClass对象,指定handler:kata
创建pod
1apiVersion:v1
2kindod
3metadata:
4name:kata-alpine
5spec:
6runtimeClassName:kataclass
7containers:
8-name:alpine
9image:alpine:latest
10imagePullPolicy:IfNotPresent
11command:
12-/bin/sh
13-"-c"
14-"sleep60m"
15restartPolicy:Always
16nodeSelector:
17kubernetes.io/hostname:
k8s05k8s05节点宿主机进程查看
1[root@k8s05~]#psaux|grepkata
2root5000860.00.1141218447796?SlJun1814:00/usr/bin/conta
3root5001170.00.01290644960?SlJun180:00/usr/libexec/k
4root5001550.23.243675161059672?SlJun1841:47/usr/bin/qemu-
5root5001580.00.85667064271696?SlJun180:03/usr/libexec/k
可以看到katacontainerv2启动了新的与kubernetes对接的CRI进程containerd-shim-kata-v2,KVM虚拟机,还有2个virtiofsd进程。为什么会启动2个virtiofs呢?为了提?安全性,virtiofsd进程fork??,以便进?新的mount/pid/net命名空间,只有?进程内存映射,CPU使???处于活跃状态。
可以看到qemu虚拟化了设备vhost-user-fs-pci,有?个tag为kataShared,这个就是虚拟机要mount的源。tag就是?个?定义?件系统需要接收的参数,定义路径?的。
NotethatLinux4.19-basedvirtio-fskernelsrequiredadifferentmountsyntax.mount-tvirtio_fsnone/mnt-otag=myfs,rootmode=040000,user_id=0,group_id=0instead.mount_tag:AtagwhichactsasahinttotheguestOSandisusedtomountthisexportedpath.
1-devicevhost-user-fs-pci,chardev=char-538bb1c14588b18e,tag=kataShared
进?kata容器观察
1[root@k8s01kata-container]#kubectlexec-itkata-alpine--sh
2/#df-h
3FilesystemSizeUsedAvailableUse%Mountedon
4kataShared74.0G49.5G24.4G67%/
5tmpfs64.0M064.0M0%/dev
6tmpfs1.4G01.4G0%/sys/fs/cgroup
7kataShared74.0G49.5G24.4G67%/etc/hosts
8kataShared74.0G49.5G24.4G67%/dev/termination-log
9kataShared74.0G49.5G24.4G67%/etc/hostname
10kataShared74.0G49.5G24.4G67%/etc/resolv.conf
11shm1.4G01.4G0%/dev/shm
12kataShared15.7G12.0K15.7G0%/run/secrets/kubernetes.i
13tmpfs64.0M064.0M0%/proc/keys
14tmpfs64.0M064.0M0%/proc/timer_list
可以看到容器已经挂载了tag定义的?件系统。tag名字可以是任意取的,只要能guest挂载时候指定相同的就可以。对于kata来说,已经整合好了,不需要??指定
有时候如果处于调试?的或者是想看?下虚拟机的信息,可以配置kata开启debug模式,qemu暴露vsock接?,虚拟机通过agent开启shell
1configuration.toml
2
3[agent.kata]
4debug_console_enabled=true
宿主机再?动启动kata-monitor进程,获取sandbox的vsock地址,??监听localhost:8090端?,就可以通过kata-runtimeexec$sandboxId接?虚拟机bash了
1[root@k8s05kata]#/usr/bin/kata-monitor
2INFO[0010]addsandboxtocachecontainer=7e4cef94733381a9d9c509aa2a0be87e0c0bd
3INFO[0020]deletesandboxfromcachecontainer=5246e787b17eeab4ca83e9e73583a1b5
进?虚拟机查看
kata根据sandbox的ID,指定唯?的宿主机内存共享?录source,传递给virtiofsd.虚拟机挂载virtiofsd导出的共享的?录到/run/kata-containers/shared/containers,然后再以bindmount的?式挂载进容器。
1[root@k8s05~]#kata-runtimeexec0965321e164975f01c85f997fbb0183773a9e97cb5767d9
2bash-4.2#df-h
3FilesystemSizeUsedAvailUse%Mountedon
4rootfs1.4G350M1.1G25%/
5dev1.4G01.4G0%/dev
6tmpfs1.5G01.5G0%/dev/shm
7tmpfs1.5G16K1.5G1%/run
8tmpfs1.5G01.5G0%/sys/fs/cgroup
9kataShared16G1.6G15G11%/run/kata-containers/shared/containers
10shm1.5G01.5G0%/run/kata-containers/sandbox/shm
kata根据sandbox的ID,指定唯?的宿主机内存共享?录source,传递给virtiofsd.虚拟机挂载virtiofsd导出的共享的?录到/run/kata-containers/shared/containers,然后再以bindmount的?式挂载进容器。
持久卷挂载
?络持久卷?如iscsi也是能直接挂载进kata容器的,例如创建?个pod,直接指定pvc,pv使?某?个iscsilun,然后在容器中创建?个?件
1[root@k8s01kata-container]#kubectlexec-itiscsipd--sh
2/#cd/mnt/iscsipd
3/mnt/iscsipd#ls
4lost+found
5/mnt/iscsipd#touchaaaa.txt
在虚拟机??已经通过virtiofs挂载在了?个容器id?录之下
1[root@k8s05~]#kata-runtimeexece96d0ce2249e9027f0e1102e66a0c0013473ac48a088240
2bash-4.2#mount
3rootfson/typerootfs(rw,size=1444588k,nr_inodes=361147)
4kataSharedon/run/kata-containers/shared/containerstypevirtiofs(rw,relatime)
5kataSharedon/run/kata-containers/e96d0ce2249e9027f0e1102e66a0c0013473ac48a08824
6kataSharedon/run/kata-containers/839162f25b7907bf91ecb027305e64dd5ccf36f55b15b6
7bash-4.2#find/-nameaaaa.txt
8/run/kata-containers/shared/containers/839162f25b7907bf91ecb027305e64dd5ccf36f55b
在宿主机上是识别为硬盘块设备/dev/sdd,被kubelet挂载在特定?录下?,?个是sandbox_id,?个是应?container_id
1[root@k8s05~]#lsblk
2NAMEMAJ:MINRMSIZEROTYPEMOUNTPOINT
3sda8:0050G0disk
4├─sda18:101G0part/boot
5sdc8:3202G0disk
6sdd8:4802G0disk/run/kata-containers/shared/sandboxes/e96d0ce2
就如前?说的,所有数据都要经过virtiofs,不管是镜像数据还是?络存储卷。虚拟机要和宿主机数据交互,就必须要穿过qemu,virtiofs就是穿过qemu的桥梁,提供共享?件机制。数据相关的操作最终还是在宿主机上,?如镜像层的合并,仍然是containerd的存储层插件snapshotter完成,底层仍然是调?了overlayfs?件系统
1/etc/containerd/config.toml
2[plugins."io.containerd.grpc.v1.cri".containerd]
3snapshotter="overlayfs"
4default_runtime_name="runc"
5no_pivot=false
6disable_snapshot_annotations=true
7discard_unpacked_layers=false
8...
9[plugins."io.containerd.service.v1.diff-service"]10default=["walking"]
另外katacontainer整合使?virtiofs的?式,与独???操作virtiofs的?式,有些地?稍有不同,?如按virtiofs官?说明,可以指定host?件?录$TESTDIR作为源
1./virtiofsd--socket-path=/tmp/vhostqemu-osource=$TESTDIR-ocache=alwa
?在kataruntime??是不允许的,?如在configuration.toml?配置
1virtio_fs_extra_args=["-o","--thread-pool-size=1","-o","/opt/kata-instance"]
kubelet会报错:
WarningFailedCreatePodSandBox1s(x14over15s)kubelet,k8s05Failedtocreatepodsandbox:rpcerror:code=Unknowndesc=failedtocreatecontainerdtask:failedtolaunchqemu:exitstatus1,errormessagesfromqemulog:qemu-system-x86_64:cannotcreatePIDfifile:Cannotopenpidfifile:Nosuchfifileordirectory
kata还会打开vhost-usersocket?件描述符,传递给virtiofsd。可能有?会有疑问,为什么每?个virtiofsd进程的fd参数都等于3,会不会有冲突。其实不会,因为?件描述符是进程独?的,STDIO占据了0,1和2,那么virtiofsd第?个可?的fdnum就是3了
virtiofsdcacheguest
guest?成是会指定内存??,virtiofsd会共享使?guest的内存。默认使?memory-backend-fifile内存对象
virtiofsd共享使?VM内存,configuration.toml配置参数default_memory
qemu命令?接受的参数
1-objectmemory-backend-file,id=dimm1,size=3072M,mem-path=/dev/shm,share=on-numa
guest和host数据传输都是通过virtio-fs,包括容器镜像和容器卷,读写权限取决于virtiofsd进程的权限
DAX(直接访问)
dax
DAXwindows是?块虚拟内存区域,通过PCIBar把?件映射到guest??,并不真正的占?主机那么多内存,即使有100个虚拟机,设置的DAXcache是1G,也不会真的使?100G内存。只是?种page映射机制,所以也不需要任何的cache策略。
要任何的cache策
katacontainer官?下载的版本默认没有不?持,需要编译安装gitlab托管的virtio-fsqemu项?qemu5.0-virtiofs-dax分?
configuration.toml设置virtio_fs_cache_sizedaxwindow??,qemu初始化vhost-user-fs-pci设备
1-machineq35,accel=kvm,kernel_irqchip,nvdimm
2-devicenvdimm,id=nv0,memdev=mem0-objectmemory-backend-file,id=mem0,mem-path=/o
3-devicevhost-user-fs-pci,chardev=char-ea09ec33d071ac42,tag=kataShared,cache-size
如果是rootfsimage可以看到模拟的nvdimm信息,??编译镜像的话,image_builder.sh构建脚本会在image?件头部写?daxmetadata信息。initrdimage看不到。image相当于是直接?rootfs引导,initramfs(initrd)是把cpio+gz打包压缩的rootfs解压到内存?,再?内存?的initramfs来引导。前者可以利?dax,让guestos认为这就是个dimm内存,不需要再加载到另?块内存?,后者就是需要解压到?块内存。
DAX背后的想法是避免在guest中使?_second_缓冲区缓存。?般对于常规?件,guest会维护???件系统缓冲区。
现在呢,对于与virtiofs共享的?件,由于它们驻留在主机上,您将在主机上拥有?份缓存副本,然后virtiofs会将其发送给guest,然后guest就也有了?份副本,成本就?较?。DAX就是为了解决这个问题的,它所做的就是将主机buffffermap到客户机中,guest使?与主机相同的物理内存,即使它使?不同的虚拟地址。如果没有DAX,内存使?量可能会?常?,因为每个guest都有??的?件缓冲区。例如,如果您启动?个Fedora容器并“dnfinstallsomething”,您将看到内存使?量增加了约300M,因为在该操作期间读取/写?了许多?件。如果没有DAX,那么guest也需要分配350M。使?DAX,它就会直接使?宿主机中已为这些?件缓冲分配的350M内存
性能测试
测测DAXwindow??对性能的影响(virtio_fs_cache_size=512)
??件测试
1fio--name=small-file-multi-read--directory=/usr/share/nginx/html\
2--rw=randread--file_service_type=sequential\
3--bs=4k--filesize=10M--nrfiles=100\
4--runtime=60--time_based--numjobs=1
5...
6small-file-multi-read: (groupid=0,jobs=1):err=0:pid=190:MonJul507:05:18
7read:IOPS=12.0k,BW=46.0MiB/s(49.2MB/s)(212MiB/4505msec)
件测试
1fio--name=5G-bigfile-rand-read--directory=/usr/share/nginx/html--rw=ra
2...
35G-bigfile-rand-read: (groupid=0,jobs=1):err=0:pid=184:MonJul506:57:0824read:IOPS=1255,BW=5024KiB/s(5144kB/s)(294MiB/60002msec)
从压测观察到当读写的?件超过daxwindow后,性能下降很多,原因和dax映射机制有关,dax窗?的回收是?较慢的,当活跃数据超过daxwindow,产?很多的回收?作会导致性能很差。另外daxwindow的映射单元是按每2MB内存??映射的,具体来说就是由512个structpage(onestructpageforeach4Krange)和?个structfuse_dax_mapping。每个单元映射范围?约需要消耗32K额外内存。?如1GBofdaxwindow:512*32K=16MBofmemoryusage.
同时还观察到virtiofsd占?内存很?,?如本实例qemu-system-x86_64rss内存3.1G,virtiofsdrss1.6G,?产中对资源的控制需要细节控制。
总结
katacontainer还是?项?较复杂的技术组合,实践?档较少,有问题要不就是求教于社区,要不就得翻源码,源码牵涉到linuxkernel,qemu/kvm,fifilesystem,内存映射,容器等多种技术,?且还是?较新的技术。但云原?安全?是未来越来越受到重视的领域,极?影响业务容器化的决策。希望?业能更多的参与到安全容器上来,增加实践场景,畅快投?云原?的怀抱。
|
|