虚拟机容器Kata架构,让你了解

2020-01-26 作者:亚洲城动态   |   浏览(146)

容器是一种轻量级虚拟化技术,“轻量”主要是因为容器与传统虚拟机比较,是内核共享的,所以启动快、资源占用小。随着虚拟化技术发展,Docker与Kubernets逐步成为应用打包与部署的标准,以及公有云租赁模式推广,出现了“虚拟机容器”这种形态。

Linux 容器模型飞速发展,因为容器轻巧,快速且易于集成到许多不同的应用程序工作流程中。

虚拟机容器首先是一台虚拟机,由于Docker镜像打包与分发方面的优势,虚拟机容器也兼容Docker镜像;并提供了OCI规范的 runtime ,且适配了Kubernetes调度管理API,能够被Kubernetes调度,因此被称为虚拟机容器。

任何有关 Linux 容器的讨论总是会涉及容器技术和虚拟化之间的差异。现在,由OpenStack Foundation 管理的开源 Kata Containers 项目正在利用这些差异来使Linux 容器的实现更加安全。

虚拟机容器主要使用场景是在公有云模式下,云服务厂商提供无服务器计算服务,这种模式下租户只租一个容器或进程,不同租户的容器/进程可能运行到同一台机器上,传统的内核共享模式在这种场景下安全风险太高,虚拟机容器能够做到内核独占,适合这种场景。

Kata Containers  开源项目和社区的目标是构建轻量级虚拟机 ( VM ) 的标准实现,这些虚拟机可以像容器一样被感受和执行,但是可以提供虚拟机的工作负载隔离和安全优势。这意味着,Kata 可能会缓解一些关于容器的担忧,特别是在大规模应用时。以下是关于 Kata Containers 你需要了解的 10 件事。

Kata 项目介绍

1.为什么有Kata?

Kata 源自 Intel 的开源项目 Hyper.sh ,当前在 Openstack 软件基金会下治理。

Linux 容器轻巧,快速且易于集成到许多不同的应用程序工作流程中。

Kata南向虚拟化实现技术可插拔,当前支持QEMU/NEMU,在最新的1.5版本里支持Firecrack;北向支持与Docker的Containerd对接,并可以被Kubernetes编排,接入Docker与Kubernetes生态。

但是,在运行容器时存在一些潜在的安全问题,特别是在单个操作系统中的多租户容器:最终,容器共享一个内核、 I / O 的一条路径、网络和内存等。

Kata 架构概览 (基于1.5版本)Kata container runtime and shimv2

因此,一个容器的妥协就是潜在的许多容器的妥协。

Kata容器项目主要由容器运行时与一个兼容CRI接口的 shim 部件组成。

Kata旨在通过虚拟机管理程序来缓解这种安全问题——创建一个外观和感觉像容器的虚拟机。

Kata container runtime 符合 OCI 运行时规范 因此能够被Docker引擎管理,作为Docker引擎的一个runtime插件。 Kata container runtime 还基于Containerd的CRI插件与CRI-O实现了Kubernetes的CRI规范,因此,使用者可以在Docker默认的runtime runc 与 kata container runtime (runv) 之间平滑切换,上层组件不感知差异。

2.Kata是如何管理的

Kata容器的另外一个组成部分是 containerd-shim-kata-v2 ,简称为 shimv2 , shimv2 提供了了 Containerd Runtime V2 (Shim API) 的 Kata 实现,从而使得 Kubernetes 场景下能够实现每个 Pod 一个 shim 进程 – shimv2 ;而在此之前,一个Pod需要一个2个shim,如果 Pod Sandbox没有暴露 VSOCK 则还需要一个 kata-proxy 。

Kata Containers项目由 OpenStack Foundation 管理。OpenStack 宣布打算在开源运动中发挥更广泛的作用,而 Kata 是其第一次进军。Kata Containers不是“ OpenStack 项目”的一部分,而是一个拥有自己的技术管理和贡献者基础的独立项目。除了OpenStack 驱动的云之外,Kata Containers 路线图还支持多种流行的基础设施提供商和容器编排框架,而 Kata Architecture 委员会也有来自谷歌和微软等公司的代表。

agent 与 kata-proxy

3.Kata的起源是什么?

Kata容器运行在虚拟机沙箱内,每个虚拟机内运行一个Agent,Agent负责运行container。Agent同时提供gRPC接口,通过QEMU的VIRTIO serial或VSOCK接口向HOST主机暴露接口,主机上的 kata-runtime 使用gRPC协议与Agent通信,向虚拟机内的容器发送指令,I/O流也通过此通道管理。 如果是使用 VIRTIO serial 的方式暴露接口到Host主机,那么还需要在主机上部署一个 kata-proxy 负责转发指令到Agent。

Kata基于 Intel Clear Containers 和  Hyper runV  技术。

容器进程管理

英特尔和 Hyper 都在运行自己的容器项目,拥有不同的优势:英特尔专注于性能,而 Hyper 则与平台无关。英特尔和 Hyper 的独立项目并行解决了容器安全问题,但两者并非完全隔离,其结果有些类似。两者都解决了容器化环境中的关键问题:环境的分层,例如 OpenStack 上的 Kubernetes 或Kubernetes 上的 OpenStack ,甚至 Kubernetes  上的 OpenStack 上的 Kubernetes 。

在Host主机上,每个容器进程的清理是由更上层的进程管理器完成的,在Docker containerd的实现里,进程管理器是 containerd-shim ;在CRI-O的实现里是common。

容器编排是堆栈中的一个层,Kata 在维护安全性的同时简化了这些层的集成。

在Kata容器场景下,容器进程运行在虚拟机内,Host主机上的进程管理器不能直接管理到容器进程,Kata容器项目通过 kata-shim 来解决此问题。kata-shim 运行在Host主机上,介于容器进程管理器与kata-proxy之间,kata-shim 将来自Host主机的信号量、stdin 转发到虚拟机内的容器进程上,并将虚拟机容器内的stdout与stderr转发到Host主机上的容器进程管理器。

4.Kata是如何获得许可的

kata-runtime 为每个容器进程创建一个 kata-shim 守护进程,为每个通过OCI命令连接到容器进程内部执行用户命令的操作创建一个 kata-shim 守护进程。

Kata Containers 根据 Apache 2 许可在 Github 上托管。欲了解更多信息并参与其中,请访问www.katacontainers.io。

在 Kata1.5 版本,shimv2 收编 kata-runtime, kata-shim, kata-proxy 到 shimv2 进程中。

  1. Kata架构如何设计

虚拟化

Kata Containers 项目最初将包含六个组件:Agent、Runtime、Proxy、Shim、Kernel和QEMU 2.9 打包。

Kata 架构上能够支持多种虚拟化实现,在 Kata1.0 版本,支持 QEMU/KVM 虚拟化。在 Kata1.5 版本,支持 AWS Firecracker 极轻量的虚拟机。

它被设计成与架构无关,运行在多个虚拟机管理程序上,并与 Docker 容器的 OCI 规范和 Kubernetes 的  CRI  兼容。

QEMU/KVM

6.Kata运行在什么操作系统上?

根据Host主机架构,Kata容器支持多种主机类型,比如 x86 上的 pcq35 ,ARM 上的 virt , IBM Power System 上的 pseries 。默认的Kata容器主机类型是 pc ,默认主机类型可以通过配置修改。

目前,Kata Containers 仅限于Linux。

Kata容器使用下面的 QEMU 特性来管理资源配额、缩短启动时间、减少内存占用:

在主机端,有几种流行的发行版的安装说明。

机器加速器热插拔设备机器加速器

此外,通过 OSBuilder 还支持 Clear Linux、Fedora 和 CentOS 7 rootfs  镜像(还可用于展示自己的guest 镜像)。

机器加速器是与特定服务器架构相关的,机器加速器能够提升性能并开启某些特性。下面这些机器加速器在Kata容器中使用。

7.Kata如何与现有的容器平台整合

NVDIMM: x86平台的机器加速器,仅支持 pcq35 机器类型。nvdimm 用来以持久化内存方式提供虚拟机的根文件系统。

通过将两个高度集成的虚拟化容器开源代码库结合起来,并将项目转为开放式治理,Kata Containers社区支持多种架构,并推动跨多个基础设施和容器编排社区的技术采用,包括 Kubernetes、Docker、OCI、CRI、CNI、 QEMU、KVM 和 OpenStack 。例如, OCI 合规性使得 Docker 镜像无需重新加工即可被拿来使用。此外,由于 Kubernetes 已经在公有云上运行并编排容器,Kata 已经与 Kubernetes 取得了进展,并与其他新技术相结合。

虽然Kata容器能够支持大多数QEMU发行版本,但是考虑到Kata容器的启动时间、内存占用、IO性能因素,Kata容器使用一个针对这些因素专门优化过的QEMU版本 qemu-lite ,并增加了一些自定义的机器加速器,这些自定义加速器在 QEMU Upstream 版本中不可用。

8.典型用例

nofw: x86平台的机器加速器,仅支持 pcq35 机器类型。 nofw 用来启动 ELF 格式的系统内核,但是可以跳过 BIOS 与固件自检 (BIOS/firmware) ,这个加速器可以显著提升虚拟机启动速度。static-prt: x86平台的机器加速器,仅支持 pcq35 机器类型。 static-prt 用来减少虚拟机ACPI(Advanced Configuration and Power Management Interface)的解释负担。热插拔设备

相比在单个内核中并行运行容器,Kata 在高安全性的容器堆栈环境中更高效。这包括持续集成/持续交付、网络功能虚拟化、边缘计算、开发和测试以及容器即服务。

Kata容器虚拟机初始以最小的资源启动,为了提升启动速度,在启动过程中,设备可以热插到虚拟机上。如,容器定义了cpu资源,可以通过热插的方式加到虚拟机上。Kata容器虚拟机支持如下热插设备:

此外,Kata体积小、安全性高,因此非常适合资源有限的边缘部署。Kata Containers 仍处于起步阶段,但该项目的技术基础,Clear Containers和runV,已经在全球范围内被企业规模化使用,例如京东。

Virtio blockVirtio SCSIVFIOCPUKernel 与 Image虚拟机内核

9.谁在支持Kata

虚拟机内核在虚拟机启动时候被加载,Kata容器提供的虚拟机内核针对启动时间与内存占用做了优化。

在发布时,Kata 得到了包括中国移动、CoreOS 、戴尔/ EMC、EasyStack、烽火、谷歌、华为、京东、Mirantis、NetApp、红帽、SUSE、腾讯和中兴等20多家公司的支持。

虚拟机镜像

10.“Kata”是什么意思?

Kata 容器支持 initrdroot filesystem 两种虚拟机镜像。

Kata 这个词来自希腊文, Καταπίστευμα (“ka-ta-PI-stev-ma”),意思是“信任某人”。Kata Containers 正在努力获得希望启动或扩展其 Linux 容器使用的组织的信任。

root filesystem

Kata 容器提供的默认打包好的 root filesystem 镜像,这种镜像也被称为 “mini O/S”,是基于 Clear Linux 优化的,提供最小的运行环境与高度优化的启动路径。 镜像中只有Kata Agent与systemd两个进程,用户的工作负载被打包到docker镜像,在虚拟机内通过libcontainer库,以runc方式运行起来。

举例,当用户执行 docker run -it ubuntu date 命令时,流程如下:

虚拟化层加载虚拟机内核,虚拟机内核加载虚拟机镜像。systemd 启动虚拟机运行环境,并启动 kata-agent 进程kata-agent 创建一个独立的context,运行用户指定的命令kata-agent 准备 ubuntu 的运行环境并运行 date 命令initrd

待补充。

Agent

kata-agent 是一个运行在虚拟机中的进程管理虚拟机中的容器进程。

kata-agent 的最小运行单元是沙箱,一个 kata-agent 沙箱是一个由一些列namespace(NS, UTS, IPC, PID)隔离出来的。 kata-runtime 能够在一个虚拟机内运行多个容器进程以支持POD内多个container模式。

kata-agent 使用gRPC协议与Kata其他组件通信,在gRPC同一个URL上还运行了一个 yamux 服务。

kata-agent 使用 libcontainer 管理容器生命周期,复用了 runc 的大部分代码。

Runtime

kata-runtime 是一个符合OCI规范的容器运行时,负责处理OCI运行时规范中的所有命令,并启动 kata-shim 进程。

关键的OCI命令实现create

kata-runtime 处理 OCI create 命令步骤:

创建虚拟机与shim进程的network namespace。执行 pre-start hook ,回调中负责创建 veth 网络设备,用于连接主机网络与新创建的network namespace。扫描新创建的network namespace,在其中的veth设备上创建一个macvtab设备。在新的network namespace中创建虚拟机,并将tab设备传递给虚拟机。等待虚拟机启动完成。启动kata-proxy,kata-proxy负责代理所有发送给虚拟机的请求,每个虚拟机一个kata-proxy进程。调用kata-agent接口配置虚拟机内的沙箱。调用kata-agent接口创建容器,使用kata-runtime提供的默认的OCI配置文件 config.json 。启动kata-shim进程,kata-shim连接到kata-agent的gRPC socket端口。kata-shim会创建几个Go routine阻塞式调用 ReadStdout(), ReadStderr(), WaitProcess()ReadStdout(), ReadStderr() 以死循环方式执行直到虚拟机内的容器进程中止。 WaitProcess() 返回虚拟机内容器进程的 exit code。 kata-shim运行在虚拟机的network namespace中,通过kata-shim进程可以找到创建了哪些namespace。启动 kata-shim 进程还会创建一个新的PID namespace,对应到同一个container的所有kata-shim进程都在同一个PID namespace,这样当容器进程终止时候很容器将所有kata-shim进程终止掉。

此时容器进程在虚拟机内部运行起来了,在Host主机上对应到kata-shim进程。

start

传统容器的 start 会在容器namespace中启动容器进程。Kata容器中, start 会在虚拟机内启动容器的工作负载,步骤如下;

调用kata-agent接口在虚拟机内启动容器负载命令。如,容器内负载命令为 top ,kata-shim 进程的 ReadStdout() 会读取到 top 的输出, WaitProcess() 会一直等待到 top 命令结束。执行 post-start 回调,当前 post-start 实现为空。exec

OCI 的 exec 命令允许在已有的容器中执行命令。在Kata容器中, exec 执行步骤如下:

调用kata-agent接口在已有容器中执行命令。一个新的kata-shim进程会创建出来,被放置到已有容器对应的kata-shim所在的PID namespace中。

此时通过 exec 命令启动的新的容器负载已经在虚拟机内运行,共享已有容器的namespace (uts, pid, mnt, ipc) 。

kill

OCI kill 命令通过发送 UNIX 信号,如 SIGTERM, SIGKILL ,来终止容器进程。在Kata容器中, kill 命令会终止虚拟机内的容器进程与虚拟机。

调用kata-agent接口请求kill容器进程。等待 kata-shim 进程退出。调用kata-agent接口请求强制kill容器进程,如果 kata-shim 进程在超时时间内未退出。等待 kata-shim 进程退出,如果等待超时则报错。调用kata-agent接口删除虚拟机内的容器配置。调用kata-agent接口删除虚拟机内的沙箱配置。停止虚拟机。删除network namespace中的网络配置,删除network namespace。执行 post-stop 回调。delete

delete 指令删除容器所有相关的资源,正在运行中的容器不能不删除,除非通过 --force 指令强制删除。

如果虚拟机内的沙箱未停止,但是沙箱内的容器进程已经推出,kata-runtime会先执行一次kill流程,之后如果沙箱已经停止,kata-runtime执行如下动作:

删除容器相关资源:目录 /var/{lib,run}/virtcontainers/sandboxes/sandboxID/containerID 下的所有文件。删除沙箱:目录 /var/{lib,run}/virtcontainers/sandboxes/sandboxID 下的所有文件。

此时,所有容器相关内容都已经在Host主机上被删除,没有任何相关进程在运行。

state

state 返回容器的运行状态。在Kata容器中,state 需要检测容器进程是否在运行,通过检查对应容器进程的 kata-shim 进程的状态。

通过存储在磁盘上的信息获得容器状态。检查kata-shim进程。如果kata-shim进程不存在,但是磁盘上的容器状态文件还是ready或running,那么意味着在得到容器返回状态之前,容器进程已经被正常停止了。Proxy

Host主机与虚拟机通信可以通过 virtio-serialvirtio-socketvirtio-socket 需要内核版本 4.8 以上。默认使用 virtio-serial

虚拟机内可能运行多个容器进程,在使用 virtio-serial 场景下,需要Host主机上运行 multiplexed 与 demultiplexed 进程;使用 virtio-socket 则不需要。

kata-proxy 进程提供代理访问虚拟机内的 kata-agent ,对应到多个 kata-shim 进程与 kata-runtime 客户端。 kata-proxy主要功能是负责代理IO流与信号量到 kata-agentkata-proxy 通过Unix domain socket方式连接 kata-agent

Shim

容器进程回收器,如Docker的 containerd-shim 或 CRI-O 的 common ,其设计假设是基于能够监控并回收实际的容器进程。在Kata容器中,由于容器进程运行在虚拟机中,Host主机上的容器进程回收器不能直接监控到虚拟机内的容器进程,至多能看到QEMU进程,这个是远远不够的。Kata容器中的kata-shim进程是主机上对应到虚拟机内容器进程的映射,因此kata-shim进程需要处理容器进程的I/O流并负责转发信号到容器进程。

kata-shim 通过Unix domain socket连接到kata-proxy,socket URL是由kata-runtime在启动kata-shim进程时候传递给kata-shim的,一并传递的参数还有containerID与execID,containerID与execID用来标识虚拟机内的容器进程。转发来自容器进程回收器的标准输入流,通过kata-proxy的gRPC的 WriteStdin API。从容器进程读取标准输出与错误输出。转发来自容器进程回收器的信号,通过kata-proxy的 SignalProcessRequest API。监控终端的变化并转发,通过kata-proxy的 TtyWinResize API。Networking

容器进程一般被放置在独立的network namespace中,在容器生命周期的某个点,容器引擎会创建network namespace并将容器进程加入到network namespace中。容器进程网络与主机Host网络隔离。 在实现技术上,通常使用veth技术,veth的两端分别放置到容器的network namespace与主机Host的network namespace中。这种方式是以namespace为中心的,而一些虚拟化技场景下不支持veth,特别是QEMU,这种情况下使用TAP技术替代。

为了消除虚拟化场景下网络隔离与容器场景下网络隔离的不兼容,kata-runtime使用veth tab(MACVLAN)方式实现网络隔离与互通。

主机Host网络与容器网络通过network namespace隔离,使用veth互通。容器网络network namespace内的veth网络设备上创建MACVLAN设备。在创建虚拟机时候,将TAP网络设备作为虚拟机网卡。虚拟机内的容器进程使用虚拟机网卡作为主网卡与外部通信,虚拟机内部的多个POD共享虚拟机网络,不再隔离。

Kata容器支持 CNM 与 CNI 两种容器网络标准。

CNMCNM lifecycleRequestPoolCreateNetworkRequestAddressCreateEndPointCreateContainerCreate config.jsonCreate PID and network namespaceProcessExternalKeyJoinEndPointLaunchContainerLaunchRun containerCNM 网络配置过程读取 config.json亚洲城官网,创建network namespace: netns回调 prestart 钩子扫描netns命名空间下的,由prestart回调创建的网络接口创建bridge/tap并通过veth与主机连接网络热插拔

Kata容器开发了一套命令与api支持添加/删除/查看 guest网络。下面流程图展示了Kata容器热插拔的流程。

存储

Kata容器的虚拟机与Host通过9pfs共享文件,对于虚拟机内的容器,不建议使用主流的overlay2存储驱动,overlay2存储驱动是基于文件系统的。

Kubernetes 集成

Kubernetes目前是容器编排的事实标准,Kubernetes为了解耦Kubelet与各种容器runtime,抽象了CRI(Container Runtime Interface)接口规范,Kubelet相当于是一个CRI客户端,不同的CRI实现提供gRPC接口与Kubelet对接,接入到Kubernetes生态。当前基于OCI标准容器提供的CRI接口实现有CRI-O与Containerd CRI Plugin。

Kata容器的runtime是CRI-O与Containerd CRI Plugin的官方runtime之一,因此Kata容器可以很容易的集成到Kubernetes生态中。

但是由于Kubernetes最小调度单元是Pod而非容器进程,一个Pod可以有多个容器进程,而Kata容器又是将容器进程跑在虚拟机内的,因此Kata容器需要Kubernetes在创建容器进程传递更多信息,用来告知Kata runtime是要创建一个新的虚拟机,还是在已有虚拟机内启动容器进程。

Containerd CRI Plugin 集成kata-runtime

在Kata1.5版本,对应containerd1.2.0,通过shimv2实现了Kata runtime与Kubernetes集成,具体指导参考链接。CRI-O的实现也正在开发中,跟踪此Issue。

CRI-O 集成Kata-runtimeOCI annotations

为了让kata-runtime区分是要创建一个虚拟机还是仅在虚拟机内创建容器进程,CRI-O在OCI配置文件中增加了一个annotation来告知这个区分给kata-runtime。

在执行runtime之前,CRI-O会增加一个io.kubernetes.cri-o.ContainerType的annotation,这个注解由Kubelet生成,取值范围是sandbox, container,kata-runtime将sandbox对应到创建虚拟机,container对应到在已有Pod中创建容器进程。

containerType, err := ociSpec.ContainerType()if err != nil { return err}handleFactory(ctx, runtimeConfig)disableOutput := noNeedForOutput(detach, ociSpec.Process.Terminal)var process vc.Processswitch containerType {case vc.PodSandbox: process, err = createSandbox(ctx, ociSpec, runtimeConfig, containerID, bundlePath, console, disableOutput, systemdCgroup) if err != nil { return err }case vc.PodContainer: process, err = createContainer(ctx, ociSpec, containerID, bundlePath, console, disableOutput) if err != nil { return err }}

虚拟机容器与namespace隔离容器混合管理

一个有趣的演进是在一个Kubernetes集群中混合管理虚拟机容器与namespace隔离的容器。 现在Kubernetes集群运维人员可以对工作负载打trusted, untrusted标签,trusted标签表示工作负载是安全的,untrusted表示工作负载存在潜在风险,在支持kata容器的Kubernetes集群中,会自动根据标签,将trusted工作负载以runc方式运行,untrusted工作负载以runv方式运行。

CRI-O默认行为是认为所有的工作负载在都是trusted,除非设置了注解io.kubernetes.cri-o.TrustedSandbox=false,CRI-O默认的trust配置在configuration.toml中。

综合来看,CRI-O是选择runc还是runv,由Pod的Privileged参数,CRI-O trust配置trusted/untrustedio.kubernetes.cri-o.TrustedSandbox注解三个值确定。 如果Pod是Privileged,那么只能是runc。如果Pod不是Privileged,那么runtime的选择方式如下:

io.kubernetes.cri-o.TrustedSandbox 未设置

io.kubernetes.cri-o.TrustedSandbox=true

io.kubernetes.cri-o.TrustedSandbox=false

默认的CRI-O turst设置: trustedruncruncrunv(kata-runtime)默认的CRI-O turst设置: untrustedrunv(kata-runtime)runv(kata-runtime)runv(kata-runtime)原文链接

虚拟机容器Kata架构

关注公众号获得更多云最佳实践

本文由yzc216亚洲城发布于亚洲城动态,转载请注明出处:虚拟机容器Kata架构,让你了解

关键词: 亚洲城官网 yzc216亚洲城