概述

家里的电脑重装了系统,原来环境上的kata-containers 1.x版本也没有了,所以趁着这个机会就鼓捣一下在新的Ubuntu 20.04系统上安装一个最新的kata-containers 2.4.0版本。

kata社区推荐从Linux发行版的软件源中安装kata安全容器组件,但是社区只提供了CentOS 8 和 Fedora 34 以上版本配套的官方软件安装包:Official packages Ubuntu系统可以采用Snap包管理器进行安装:Snap Installation

上述官方推荐的方法都是简单的一键安装方式,如果想弄清楚kata软件安装包中有什么文件内容,建议直接下载社区发布已经预编译好的二进制安装包进行手动安装。所以,本文中主要介绍的是如何在一台Ubuntu系统中安装kata-containers 2.x版本二进制软件包。

注意:kata官方社区提供的只有x86架构预编译好的二进制压缩包,如果你的机器arm64架构版本,那么你只能参考社区的编译方法手动编译安装了。

安装准备

1. 准备一台Linux系统的物理机,Ubuntu、openEuler、CentOS等常见的Linux发行版系统都可以

2. 确保的你的机器环境上已经开启了BIOS中的硬件虚拟化加速支持

可以通过下面的命令来检查你物理机上的CPU是否是支持硬件虚拟化加速功能:

$ grep -E  '(vmx|svm)' /proc/cpuinfo

flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d
vmx flags	: vnmi preemption_timer invvpid ept_x_only ept_ad ept_1gb flexpriority tsc_offset vtpr mtf vapic ept vpid unrestricted_guest ple pml ept_mode_based_exec

如果输出的结果中包含vmx或svm,恭喜你的CPU支持硬件虚拟化能力。

检查完CPU是否支持硬件虚拟化能力之后,你还需要确认你物理机上的BIOS是否开启了硬件虚拟化能力。

开启的方法也非常简单,步骤如下:

  1. 根据机器所安装主板的厂商,搜索一下进入BIOS的按键上什么,一般都是F12ESC键等
  2. 重启电脑,然后一直按住进入BIOS的按键,等待进入BIOS环境
  3. 进入BIOS配置界面后,找到CPU处理器的设置界面,然后开启虚拟化技术支持。
  4. 保存后退出,然后正常进入系统启动流程,启动系统

3. 加载KVM虚拟化模块

在一般发行版系统中都保存有KVM内核模块文件,只需要手动加载一下即可:

$ sudo modprobe kvm kvm_intel

查看KVM模块是否加载到内核中了:

$ sudo lsmod | grep kvm
kvm_intel             303104  0
kvm                   864256  1 kvm_intel

手动安装

安装kata-containers二进制组件

1. 从kata-containers官方社区下载编译好的二进制压缩包

从下载链接页面中找到最新release的二进制压缩包即可 下载链接:https://github.com/kata-containers/kata-containers/releases

下载图中红色框起来的压缩包:

2. 解压二进制软件包,并拷贝到/opt/目录下

下载下来的二进制软件包采用xz命令进行解压,得到如下的目录和文件,其结构如下所示:

$ tar -xf kata-static-2.4.0-x86_64.tar.xz

$ ls
kata-static-2.4.0-x86_64.tar.xz  opt

$ tree -L 4 ./opt/
./opt/
└── kata
    ├── bin
    │   ├── cloud-hypervisor
    │   ├── containerd-shim-kata-v2
    │   ├── firecracker
    │   ├── jailer
    │   ├── kata-collect-data.sh
    │   ├── kata-monitor
    │   ├── kata-runtime
    │   └── qemu-system-x86_64
    ├── libexec
    │   └── kata-qemu
    │       └── virtiofsd
    └── share
        ├── bash-completion
        │   └── completions
        ├── defaults
        │   └── kata-containers
        ├── kata-containers
        │   ├── config-5.15.26
        │   ├── kata-alpine-3.15.initrd
        │   ├── kata-clearlinux-latest.image
        │   ├── kata-containers-initrd.img -> kata-alpine-3.15.initrd
        │   ├── kata-containers.img -> kata-clearlinux-latest.image
        │   ├── vmlinux-5.15.26-90
        │   ├── vmlinux.container -> vmlinux-5.15.26-90
        │   ├── vmlinuz-5.15.26-90
        │   └── vmlinuz.container -> vmlinuz-5.15.26-90
        └── kata-qemu
            └── qemu

12 directories, 18 files

简要介绍一下上述各个目录中存放文件的作用:

  • ./opt/kata/bin:该目录下主要存放了kata运行时相关的二进制文件(例如最主要的二进制文件containerd-shim-kata-v2)、虚拟化组件的二进制文件,例如qemu-system-x86_64
  • ./opt/kata/libexec/kata-qemu:该目录存放的是virtiofsd二进制文件,它的作用事在宿主机上作为virtiofs的后端,实现宿主机和安全容器虚拟机中之间目录文件的共享
  • ./opt/kata/share/bash-completion:该目录下存放的就是bash环境中的自动补全脚本
  • ./opt/kata/share/defaults/kata-containers/:该目录下存放的是kata-containers安全容器的配置文件configuration.toml
  • ./opt/kata/share/kata-containers/:该目录下存放的则是安全容器中Guest Kernel的裁剪的配置选项文件、Guest OS的initrd格式和image格式镜像,以及Guest Kernel的二进制文件
  • ./opt/kata/share/kata-qemu/qemu:该目录下主要存放了qemu虚拟化相关的bios二进制文件、firmware固件信息

然后,把解压到当前目录下./opt/kata文件夹给移动到根目录下的/opt/下面:

$ mv ./opt/kata /opt/

3. 将containerd-shim-kata-v2二进制软链接到/usr/local/bin/目录下,以便containerd容器引擎可以找到kata运行时对应的二进制文件

$ sudo ln -s /opt/kata/bin/containerd-shim-kata-v2 /usr/local/bin/containerd-shim-kata-v2

安装和配置containerd容器引擎

1. 安装containerd

由于kata-containers 2.x版本已经不支持OCI Runtime Spec的shimv1标准,因此需要通过containerd容器引擎或者我们在openEuler上开源的iSulad容器引擎来支持Containerd-Shimv2接口标准。

我本地的环境上Ubuntu系统,并且我之前环境中已经装过了Docker CE 20.10.14版本。由于在安装Docker软件包的同时,它也会安装好containerd组件。

所以,这里建议你直接参考Docker官方的教程来安装Docker,顺便完成containerd组件的安装。

Get Docker CE for Ubuntu

2. 修改containerd配置文件,支持kata运行时

containerd默认的配置文件路径:/etc/containerd/config.toml,将该文件中的内容修改为如下的内容,添加对于kata容器运行时的支持:

$ cat /etc/containerd/config.toml
#   Copyright 2018-2022 Docker Inc.

#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at

#       http://www.apache.org/licenses/LICENSE-2.0

#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

disabled_plugins = ["cri"]

root = "/var/lib/containerd"
state = "/run/containerd"
subreaper = true
oom_score = 0

[grpc]
  address = "/run/containerd/containerd.sock"
  uid = 0
  gid = 0

#[debug]
#  address = "/run/containerd/debug.sock"
#  uid = 0
#  gid = 0
#  level = "info"

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    [plugins."io.containerd.grpc.v1.cri".containerd]
      default_runtime_name = "kata"
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]
          runtime_type = "io.containerd.kata.v2"

注意:上面的containerd配置文件中,我已经把Docker安装包默认安装时配置的containerd.toml文件做了一些修改,把很多注释掉的配置选项都打开了。 其中,关于kata容器运行时的配置主要集中在[plugins]配置项中。

3. 重启containerd系统服务

完成上述的配置之后,重启一下containerd.service系统服务,使配置生效。

$ sudo systemctl restart containerd

$ sudo systemctl status containerd.service
● containerd.service - containerd container runtime
     Loaded: loaded (/lib/systemd/system/containerd.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2022-04-22 21:52:39 CST; 1h 47min ago
       Docs: https://containerd.io
    Process: 388705 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
   Main PID: 388706 (containerd)
      Tasks: 11
     Memory: 19.0M
     CGroup: /system.slice/containerd.service
             └─388706 /usr/bin/containerd

测试kata安全容器是否安装成功

好了,通过上面的步骤我们已经在本地的机器上安装好kata安全容器的二进制软件包和containerd容器引擎,接下来我们通过下面的命令来验证一下安装的kata安全容器是否已经安装成功。

$ image="docker.io/library/busybox:latest"

$ sudo ctr image pull "$image"

# 查看安全容器中Guest Kernel的版本号
$ sudo ctr run --runtime "io.containerd.kata.v2" --rm -t "$image" test-kata uname -r

5.15.26

# 查看物理机上安装的Linux内核版本号,两者不同则说明安全容器已经成功运行了
$ uname -r
5.13.0-30-generic

另外,我们还可以启动一个kata安全容器,在宿主机上观察是否存在qemu进程:

$ sudo ctr run --runtime "io.containerd.kata.v2" -d -t "$image" test-kata sleep 999999

$ ps -ef | grep qemu
root      395216  395206  0 23:47 ?        00:00:00 /opt/kata/libexec/kata-qemu/virtiofsd --syslog -o cache=auto -o no_posix_lock -o source=/run/kata-containers/shared/sandboxes/test-kata/shared --fd=3 -f --thread-pool-size=1 -o announce_submounts
root      395223       1  1 23:47 ?        00:00:00 /opt/kata/bin/qemu-system-x86_64 -name sandbox-test-kata -uuid 9ecd8760-80dc-41c1-8e4e-58adc4f68079 -machine q35,accel=kvm,kernel_irqchip=on,nvdimm=on -cpu host,pmu=off -qmp unix:/run/vc/vm/test-kata/qmp.sock,server=on,wait=off -m 2048M,slots=10,maxmem=16688M -device pci-bridge,bus=pcie.0,id=pci-bridge-0,chassis_nr=1,shpc=off,addr=2,io-reserve=4k,mem-reserve=1m,pref64-reserve=1m -device virtio-serial-pci,disable-modern=false,id=serial0 -device virtconsole,chardev=charconsole0,id=console0 -chardev socket,id=charconsole0,path=/run/vc/vm/test-kata/console.sock,server=on,wait=off -device nvdimm,id=nv0,memdev=mem0,unarmed=on -object memory-backend-file,id=mem0,mem-path=/opt/kata/share/kata-containers/kata-clearlinux-latest.image,size=134217728,readonly=on -device virtio-scsi-pci,id=scsi0,disable-modern=false -object rng-random,id=rng0,filename=/dev/urandom -device virtio-rng-pci,rng=rng0 -device vhost-vsock-pci,disable-modern=false,vhostfd=3,id=vsock-3535502973,guest-cid=3535502973 -chardev socket,id=char-59c971d21afa49b1,path=/run/vc/vm/test-kata/vhost-fs.sock -device vhost-user-fs-pci,chardev=char-59c971d21afa49b1,tag=kataShared -rtc base=utc,driftfix=slew,clock=host -global kvm-pit.lost_tick_policy=discard -vga none -no-user-config -nodefaults -nographic --no-reboot -daemonize -object memory-backend-file,id=dimm1,size=2048M,mem-path=/dev/shm,share=on -numa node,memdev=dimm1 -kernel /opt/kata/share/kata-containers/vmlinux-5.15.26-90 -append tsc=reliable no_timer_check rcupdate.rcu_expedited=1 i8042.direct=1 i8042.dumbkbd=1 i8042.nopnp=1 i8042.noaux=1 noreplace-smp reboot=k console=hvc0 console=hvc1 cryptomgr.notests net.ifnames=0 pci=lastbus=0 root=/dev/pmem0p1 rootflags=dax,data=ordered,errors=remount-ro ro rootfstype=ext4 quiet systemd.show_status=false panic=1 nr_cpus=4 systemd.unit=kata-containers.target systemd.mask=systemd-networkd.service systemd.mask=systemd-networkd.socket scsi_mod.scan=none -pidfile /run/vc/vm/test-kata/pid -smp 1,cores=1,threads=1,sockets=4,maxcpus=4
root      395226  395216  0 23:47 ?        00:00:00 /opt/kata/libexec/kata-qemu/virtiofsd --syslog -o cache=auto -o no_posix_lock -o source=/run/kata-containers/shared/sandboxes/test-kata/shared --fd=3 -f --thread-pool-size=1 -o announce_submounts
flyflyp+  395289  380349  0 23:47 pts/3    00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox qemu

看来真的是通过qemu hypervisor把安全容器虚拟机给拉起来了,如果大家有兴趣,可以分析一下这个qemu进程中各个命令行参数的含义。

参考