0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

智汇华云 | kata container virtiofs测试和技术分析

话说科技 2021-07-15 14:07 次阅读

poYBAGDv0KKAXd88AAEX3qjI5BA09.jpeg

云原生技术已经成为加快企业数字化转型的一个不折不扣的风向标。而以容器为代表的云原生技术正在成为释放云价值的最短路径。本期智汇华云,带大家一起了解和体验安全容器kata container的⼀些特性。

前⾔

当前云原⽣技术发展的如⽕如荼,容器化技术以及kubernetes容器化应⽤管理平台,带来了全新的⽣ 态系统. 随着容器技术的发展,容器运⾏时规范OCI也逐渐脱离Docker被单独提了出来,kubernetes⻓期使⽤的容器运⾏时是runC,轻量,性能⾼,但因为共⽤linux内核以及namespace机制隔离的不彻 底,存在⼀定的安全问题,业界涌现了好⼏个安全容器的解决⽅案,⽐如Google的gVisor, Amazon的 Firecracker,vmware的CRX等, 开源世界⾥⾯⽐较有名的解决⽅案是kata container,本⽂主要就关 注在安全容器kata container的⼀些特性了解和体验。 kata Container

kata container 由⼀系列技术组成,来源于两个项⽬的合并,Intel Clear Containers和Hyper runV,然 后⼜加上redhat贡献的virtio-fs,⼀种在guest和宿主机之间共享⽂件系统的⽅案。涉及的技术有 QEMU/KVM,Linux kernel,⽂件系统,容器运⾏时,容器⽹络等,是⼀项⽐较复杂的组合产品,⽽ 且还保持着很⾼的新特性开发进度,本次主要体验和梳理virtiofs相关的内容,这些内容有部分是来源 于kata的社区邮件列表以及slack,还有微信群,⾮常感慨,kata的社区真是⾮常的Nice,专业程度和 热⼼都令⼈感动。

virtiofs ⽂件系统结构

默认容器是使⽤cgroup和namespace做进程,⽹络,⽂件系统挂载点等隔离,是⾮常轻量级的。⽽ kata container为了实现安全容器,使⽤了VM虚拟机作为强隔离⼿段,有独⽴的内核和虚拟机镜像, 为了降低资源消耗,hypervisor使⽤了⾮常⼩的guest kernel和guest image,⾼度优化了内核的启动 时间,最⼩化了内存占⽤,只提供容器负载所需要的最基本的服务。virtio-fs⽂件系统,在资源消耗上 也使⽤了多种优化特性。 下⾯就来看⼀看具体是怎么使⽤的,以及特性理解 kata container作为除了runC之外另⼀种runtime,需要先在kubernetes环境中做集成部署,以便做各 种观察。当然直接使⽤他的CTR⼯具也是可以,只是缺少CNI的⽀持,⽹络⽅⾯不能⾃动配置。kata container configuration.toml 配置参数有两种共享⽂件系统类型可以选择,之前默认是virtio-9p ,现 在基本上都会选择 virtio-fs,有若⼲优点。 virtio- 9p 和 virtio-fs ⽂件系统对⽐

1. virtio-9p基于现存的⽹络协议,并没有虚拟化场景提供优化

2. virtio-fs利⽤了hypervisor和虚拟机处于相同节点的优势

DAX特性,⽂件内容能够映射到宿主机的内存窗⼝,允许客户机直接访问宿主机的page cache

减少内存占⽤,因为客户机cache已经被绕过了

不需要⽹络节点通信,提⾼了IO性能

测试

kata container 与整合使⽤virtiofsd,把宿主机⽬录共享给微虚拟机使⽤。测试环境版本: Centos 8

qemu-kvm 5.1

kubernetes 1.18

containerd 1.4.4

kata container 2.0.4

使⽤kubernetes 新版本的RuntimeClass 对象,指定handler:kata

创建pod

1 apiVersion: v1

2 kind: Pod

3 metadata:

4 name: kata-alpine

5 spec:

6 runtimeClassName: kataclass

7 containers:

8 - name: alpine

9 image: alpine:latest

10 imagePullPolicy: IfNotPresent

11 command:

12 - /bin/sh

13 - "-c"

14 - "sleep 60m"

15 restartPolicy: Always

16 nodeSelector:

17 kubernetes.io/hostname:

k8s05 k8s05节点宿主机进程查看

1 [root@k8s05 ~]# ps aux|grep kata

2 root 500086 0.0 0.1 1412184 47796 ? Sl Jun18 14:00 /usr/bin/conta

3 root 500117 0.0 0.0 129064 4960 ? Sl Jun18 0:00 /usr/libexec/k

4 root 500155 0.2 3.2 4367516 1059672 ? Sl Jun18 41:47 /usr/bin/qemu-

5 root 500158 0.0 0.8 5667064 271696 ? Sl Jun18 0:03 /usr/libexec/k

可以看到kata container v2 启动了新的与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就是⼀个⾃定义⽂件系统需要接收的参数,定义路径⽤的。

Note that Linux 4.19-based virtio-fs kernels required a different mount syntax. mount -t virtio_fs none /mnt -o tag=myfs,rootmode=040000,user_id=0,group_id=0instead. mount_tag: A tag which acts as a hint to the guest OS and is used to mount this exported path.

1 -device vhost-user-fs-pci,chardev=char-538bb1c14588b18e,tag=kataShared

进⼊kata容器观察

1[root@k8s01 kata-container]# kubectl exec-it kata-alpine--sh

2/# df-h

3Filesystem Size Used Available Use%Mounted on

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

1 configuration.toml

2

3 [agent.kata]

4 debug_console_enabled = true

宿主机再⼿动启动kata-monitor 进程,获取sandbox的vsock地址,⾃⼰监听localhost:8090端⼝,就可以通 过kata-runtime exec $sandboxId 接⼊虚拟机bash了

1 [root@k8s05 kata]# /usr/bin/kata-monitor

2 INFO[0010] add sandbox to cache container=7e4cef94733381a9d9c509aa2a0be87e0c0bd

3 INFO[0020] delete sandbox from cache container=5246e787b17eeab4ca83e9e73583a1b5

进⼊虚拟机查看

kata根据sandbox的ID,指定唯⼀的宿主机内存共享⽬录source, 传递给virtiofsd. 虚拟机挂载 virtiofsd导出的共享的⽬录到/run/kata-containers/shared/containers,然后再以bind mount的⽅ 式挂载进容器。

1 [root@k8s05 ~]# kata-runtime exec 0965321e164975f01c85f997fbb0183773a9e97cb5767d9

2 bash-4.2# df -h

3 Filesystem Size Used Avail Use% Mounted on

4 rootfs 1.4G 350M 1.1G 25% /

5 dev 1.4G 0 1.4G 0% /dev

6 tmpfs 1.5G 0 1.5G 0% /dev/shm

7 tmpfs 1.5G 16K 1.5G 1% /run

8 tmpfs 1.5G 0 1.5G 0% /sys/fs/cgroup

9 kataShared 16G 1.6G 15G 11% /run/kata-containers/shared/containers

10 shm 1.5G 0 1.5G 0% /run/kata-containers/sandbox/shm

kata根据sandbox的ID,指定唯⼀的宿主机内存共享⽬录source, 传递给virtiofsd. 虚拟机挂载 virtiofsd导出的共享的⽬录到/run/kata-containers/shared/containers,然后再以bind mount的⽅ 式挂载进容器。

持久卷挂载

⽹络持久卷⽐如iscsi也是能直接挂载进kata容器的,例如创建⼀个pod,直接指定pvc,pv使⽤某⼀个 iscsi lun,然后在容器中创建⼀个⽂件

1 [root@k8s01 kata-container]# kubectl exec -it iscsipd -- sh

2 / # cd /mnt/iscsipd

3 /mnt/iscsipd # ls

4 lost+found

5 /mnt/iscsipd # touch aaaa.txt

在虚拟机⾥⾯已经通过virtiofs挂载在了⼀个容器id⽬录之下

1 [root@k8s05 ~]# kata-runtime exec e96d0ce2249e9027f0e1102e66a0c0013473ac48a088240

2 bash-4.2# mount

3 rootfs on / type rootfs (rw,size=1444588k,nr_inodes=361147)

4 kataShared on /run/kata-containers/shared/containers type virtiofs (rw,relatime)

5 kataShared on /run/kata-containers/e96d0ce2249e9027f0e1102e66a0c0013473ac48a08824

6 kataShared on /run/kata-containers/839162f25b7907bf91ecb027305e64dd5ccf36f55b15b6

7 bash-4.2# find / -name aaaa.txt

8 /run/kata-containers/shared/containers/839162f25b7907bf91ecb027305e64dd5ccf36f55b

在宿主机上是识别为硬盘块设备/dev/sdd,被kubelet挂载在特定⽬录下⾯,⼀个是sandbox_id,⼀ 个是应⽤container_id

1 [root@k8s05 ~]# lsblk

2 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT

3 sda 8:0 0 50G 0 disk

4 ├─sda1 8:1 0 1G 0 part /boot

5 sdc 8:32 0 2G 0 disk

6 sdd 8:48 0 2G 0 disk /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]

3 snapshotter = "overlayfs"

4 default_runtime_name = "runc"

5 no_pivot = false

6 disable_snapshot_annotations = true

7 discard_unpacked_layers = false

8 ...

9 [plugins."io.containerd.service.v1.diff-service"] 10 default = ["walking"]

另外kata container 整合使⽤virtiofs的⽅式,与独⽴⼿⼯操作virtiofs的⽅式,有些地⽅稍有不同,⽐ 如按virtiofs官⽅说明,可以指定host⽂件⽬录$TESTDIR作为源

1 ./virtiofsd --socket-path=/tmp/vhostqemu -o source=$TESTDIR -o cache=alwa

⽽在kata runtime⾥⾯是不允许的,⽐如在configuration.toml ⾥配置

1 virtio_fs_extra_args = ["-o","--thread-pool-size=1","-o","/opt/kata-instance"]

kubelet 会报错:

Warning FailedCreatePodSandBox 1s (x14 over 15s) kubelet, k8s05 Failed to create pod sandbox: rpc error: code = Unknown desc = failed to create containerd task: failed to launch qemu: exit status 1, error messages from qemu log: qemu-system- x86_64: cannot create PID fifile: Cannot open pid fifile: No such fifile or directory

kata还会打开vhost-user socket ⽂件描述符,传递给virtiofsd。可能有⼈会有疑问,为什么每⼀个 virtiofsd进程的fd参数都等于3,会不会有冲突。其实不会,因为⽂件描述符是进程独⽴的,STDIO占 据了0,1和2,那么virtiofsd第⼀个可⽤的fd num就是3了

virtiofsd cache guest

guest ⽣成是会指定内存⼤⼩,virtiofsd会共享使⽤guest的内存。默认使⽤memory-backend-fifile内存对象

virtiofsd共享使⽤VM内存,configuration.toml 配置参数default_memory

qemu 命令⾏接受的参数

1 -object memory-backend-file,id=dimm1,size=3072M,mem-path=/dev/shm,share=on -numa

guest和host数据传输都是通过virtio-fs,包括容器镜像和容器卷,读写权限取决于virtiofsd进程的权限

DAX(直接访问)

dax

DAX windows 是⼀块虚拟内存区域,通过PCI Bar 把⽂件映射到guest⾥⾯,并不真正的占⽤主机那么多内存,即使有100个虚拟机,设置的DAX cache是1G,也不会真的使⽤100G内存。只是⼀种page映射机制,所以也不需要任何的cache 策略。

要任何的cache 策

kata container官⽅下载的版本默认没有不⽀持,需要编译安装gitlab托管的virtio-fs qemu项⽬qemu5.0-virtiofs-dax 分⽀

configuration.toml 设置virtio_fs_cache_size dax window ⼤⼩,qemu初始化vhost-user-fs-pci设备

1-machine q35,accel=kvm,kernel_irqchip,nvdimm

2-device nvdimm,id=nv0,memdev=mem0 -object memory-backend-file,id=mem0,mem-path=/o

3-device vhost-user-fs-pci,chardev=char-ea09ec33d071ac42,tag=kataShared,cache-size

如果是rootfs image 可以看到模拟的nvdimm信息,⾃⼰编译镜像的话,image_builder.sh构建脚本会在image⽂件头部写⼊dax metadata信息。initrd image看不到。image 相当于是直接⽤rootfs引导,initramfs(initrd)是把cpio+gz打包压缩的rootfs解压到内存⾥,再⽤内存⾥的initramfs来引导。前者可以利⽤dax,让guest os认为这就是个dimm内存,不需要再加载到另⼀块内存⾥,后者就是需要解压到⼀块内存。

DAX 背后的想法是避免在guest中使⽤ _second_ 缓冲区缓存。⼀般对于常规⽂件,guest会维护⾃⼰⽂件系统缓冲区。

现在呢,对于与 virtiofs 共享的⽂件,由于它们驻留在主机上,您将在主机上拥有⼀份缓存副本,然后virtiofs 会将其发送给guest ,然后guest就也有了⼀份副本,成本就⽐较⾼。DAX 就是为了解决这个问题的,它所做的就是将主机buffffer map到客户机中,guest使⽤与主机相同的物理内存,即使它使⽤不同的虚拟地址。如果没有 DAX,内存使⽤量可能会⾮常⼤,因为每个guest都有⾃⼰的⽂件缓冲区。例如,如果您启动⼀个 Fedora 容器并“dnf install something”,您将看到内存使⽤量增加了约 300M,因为在该操作期间读取/写⼊了许多⽂件。如果没有 DAX,那么guest也需要分配 350M。使⽤ DAX,它就会直接使⽤宿主机中已为这些⽂件缓冲分配的350M内存

性能测试

测测DAX window⼤⼩对性能的影响(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:Mon Jul5 07: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:Mon Jul5 06:57:08 24read:IOPS=1255,BW=5024KiB/s(5144kB/s)(294MiB/60002msec)

从压测观察到当读写的⽂件超过dax window后,性能下降很多,原因和dax映射机制有关,dax窗⼝的回收是⽐较慢的,当活跃数据超过dax window ,产⽣很多的回收⼯作会导致性能很差。另外daxwindow的映射单元是按每2MB内存⼤⼩映射的,具体来说就是由512个 struct page (one structpage for each 4K range) 和⼀个 struct fuse_dax_mapping 。每个单元映射范围⼤约需要消耗32K额外内存。⽐如1GB of dax window: 512 * 32K = 16MB of memory usage.

同时还观察到virtiofsd占⽤内存很⾼,⽐如本实例qemu-system-x86_64 rss 内存3.1G,virtiofsd rss1.6G,⽣产中对资源的控制需要细节控制。

总结

kata container 还是⼀项⽐较复杂的技术组合,实践⽂档较少,有问题要不就是求教于社区,要不就得翻源码,源码牵涉到linux kernel,qemu/kvm,fifilesystem,内存映射,容器等多种技术,⽽且还是⽐较新的技术。但云原⽣安全⼜是未来越来越受到重视的领域,极⼤影响业务容器化的决策。希望⾏业能更多的参与到安全容器上来,增加实践场景,畅快投⼊云原⽣的怀抱。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数字化
    +关注

    关注

    8

    文章

    7579

    浏览量

    60759
收藏 人收藏

    评论

    相关推荐

    秋2023年度大事记~~

    国内首款免费PCB可制造性和PCBA装配分析软件,秋DFM打破国外软件高价的局面,为设计与生产搭建了桥梁,帮助工程师发现PCB设计隐患,杜绝问题流入生产端,提升产品品质以及生产效率,缩短研发周期
    发表于 01-05 10:59

    HarmonyOS应用性能与功耗测试

    ,进入到控制台。 选择或者创建一个项目,如果新创建一个项目,注意选择 HarmonyOS。 进入项目空间,在左侧导航栏中选择 测试服务 > HarmonyOS 测试 ,进入
    发表于 12-26 16:39

    HarmonyOS应用兼容稳定性测试

    > HarmonyOS 测试 ,进入 HarmonyOS 测试页面 , 点击 HarmonyOS
    发表于 12-25 10:56

    秋荣获2023中国产业数字化百强榜企业

    盛大举行。 大会发布“ 2023中国产业数字化百强榜 ”,秋专注于电子产业数字化智造服务,凭借其卓越的技术实力和业务创新能力,以及在产业数字化方面的突出表现,荣获了2023中国产业数字化百强这一荣誉
    发表于 12-04 10:01

    喜讯!秋荣获2023中国产业数字化百强榜企业

    盛大举行。 大会发布“ 2023中国产业数字化百强榜 ”,秋专注于电子产业数字化智造服务,凭借其卓越的技术实力和业务创新能力,以及在产业数字化方面的突出表现,荣获了2023中国产业数字化百强这一荣誉
    发表于 12-04 09:58

    助力电子产业高质量发展,秋电子设计与制造技术研讨会成功举办

    可靠。同时,全面系统的焊接FA分析,可监测PCBA产品的质量缺陷问题,以确保最终产品的质量。 秋PCBA业务线厂长 肖峰 电子产品设计与制造虽说是老生常谈,但如何通过数字化及智能化等技术,变革产业
    发表于 11-24 16:50

    数字化供应链助力电子产业高质量发展,秋2023电子设计与制造技术研讨会成功举办!

    可靠。同时,全面系统的焊接FA分析,可监测PCBA产品的质量缺陷问题,以确保最终产品的质量。 秋PCBA业务线厂长 肖峰 电子产品设计与制造虽说是老生常谈,但如何通过数字化及智能化等技术,变革产业
    发表于 11-24 16:47

    详细聊聊container_of这个宏定义

    大家周末好,我是bug菌~ 今天主要是跟大家详细聊聊container_of这个宏定义,非常经典的宏,只是一直没有抽时间细细品味,今天就跟大家一起来看看有何神奇之处。
    的头像 发表于 11-13 09:45 303次阅读

    Linux内核中container_of应用

    Linux内核中经常可见 container_of 的身影,它在实际驱动的编写中也是广泛应用。 container_of原理 作用 :通过结构体的某个 成员变量地址 找到该 结构体的首地址 。 定义
    的头像 发表于 10-04 15:23 188次阅读
    Linux内核中<b class='flag-5'>container</b>_of应用

    大北斗简介

    引进的产业链薄弱环节企业,同时,孙家栋院士领衔的院士(专家)工作站以及广东省北斗卫星导航和定位技术工程技术研究中心也落户在此。2019年11月01日,大北斗宣布完成A轮融资,投资方为招银国际资本,中电
    发表于 08-30 14:36

    Linux内核中container_of原理详解

    Linux内核中经常可见container_of的身影,它在实际驱动的编写中也是广泛应用。
    发表于 07-14 15:19 133次阅读
    Linux内核中<b class='flag-5'>container</b>_of原理详解

    Linux内核中的宏/container_of分析

    今天在看平台设备实现的时候,看到to_xxx开头的“函数”。包括在内核中也有很多此类的“函数”,其实他们都是container_of的宏。因为内核是链表和结构体的世界,因此内核中有大量需求要 根据结构体成员获取结构体地址 ,或者根据结构体类型和结构体成员类型获取成员在结构体的偏移。
    发表于 06-23 14:26 208次阅读
    Linux内核中的宏/<b class='flag-5'>container</b>_of<b class='flag-5'>分析</b>

    秋亮相汽车电子研讨会,展出高可靠PCB板

    数据存储、车联网端边的车载网管系统等等都将会进入汽车。 业内人士预计电动化是汽车的上半场,智能化则是汽车发展的下半场。为此,电子发烧友网特举办“2023年汽车电子创新技术研讨会”,邀请汽车生态圈
    发表于 06-16 15:43

    秋亮相汽车电子研讨会,展出智能座舱方案、高可靠PCB板

    数据存储、车联网端边的车载网管系统等等都将会进入汽车。 业内人士预计电动化是汽车的上半场,智能化则是汽车发展的下半场。为此,电子发烧友网特举办“2023年汽车电子创新技术研讨会”,邀请汽车生态圈
    发表于 06-16 15:10

    Singularity—生信流程搭建的幸运儿

    怎么样高效的搭建分析流程且能保证分析流程稳定运行的使用效果呢?目前主流的是conda和容器技术container)。
    的头像 发表于 05-22 14:46 1874次阅读
    Singularity—生信流程搭建的幸运儿