基于kubernetes的VM解决方案探讨

MaloryBarbara 发布于13天前
0 条问题

分享 | 基于kubernetes的VM解决方案探讨

供稿 | eBay Infrastructure Engineering 刘应科

翻译&编辑 | 顾欣怡

本文3526字,预计阅读时间11分钟

更多干货请关注“eBay技术荟”公众号

导读

随着kubernetes的发展壮大 ,越来越多的公司开始基于kubernetes构建云平台,eBay也不例外。为了便于同时管理kubernetes和OpenStack集群, eBay选用了virtlet管理方案,并在其基础上做了相应的定制和改进,以增强其可靠性和性能, 从而更好地管理eBay云平台。

分享 | 基于kubernetes的VM解决方案探讨

一、背景

分享 | 基于kubernetes的VM解决方案探讨

eBay从 2015年 就开始适配 kubernetes平台 并逐渐部署各个团队的产品。然而eBay仍然部署着很大规模的 OpenStack集群 。同时管理kubernetes集群和OpenStack集群需要耗费更多的人力和物力。但由于eBay内部还有一部分业务无法迁移到容器, 我们能否用一套控制平面(control plane)同时管理容器和虚拟机呢?

二、已有的方案

在几年的时间里,kubernetes不断发展壮大,各个功能逐渐完善,越来越多的公司基于kubernetes构建云平台。在eBay内部,越来越多的产品基于kubernetes构建,因此用kubernetes来统一云平台是大势所趋, 我们需要一种方案来基于kubernetes管理虚拟机。

现在社区有两套相对成熟的基于kubernetes来管理虚拟机的方案,分别是kubevirt和virtlet。

1. Kubevirt

Kubevirt是redhat发起的项目,它使用CRD去描述一个VM(Virtual  Machine,虚拟机),通过它的控制器(controller)去把CRD转换成一个POD。由于它使用的是CRD而不是POD,导致需要额外的控制器来实现kubernetes里 原生的部署和服务(deployment,service) 这些功能。VM的实例运行在 容器(container) 里,一个VM有对应的libvirt来管理。Kubevirt的社区比较活跃,但版本还在较早的阶段。

2. Virtlet

Virtlet来自于Mirantis,跟kubevirt的不同之处在于它使用POD来描述一个VM。因为kubelet是通过CRI接口跟下面的运行时交互的,virtlet实现了一套VM的CRI。因为POD是kubernetes的一等公民, 任何现有的kubernetes功能都可以用于virtlet管理的VM,且不需要额外的控制器,比如服务、部署等等,这样几乎不需要额外的学习和维护成本。 但因为一些VM特定的信息无法完全用POD来描述,virtlet借助了POD的 注解(annotation) 来表达更多VM的信息。

三、我们的选择

根据我们的评估以及eBay现有的架构,选择了virtlet来作为kube VM方案。首先 kube VM入口 是基于 AZ(Availability Zone,可用区域) 的,已经有了一套CRD来描述现有的kubernetes节点,只需要加一个 provider(提供者) 就可以重用现有AZ的各种控制器。其次,需要各种定制来达到跟 OpenStack VM 同样的功能和性能。Virtlet因为有一套单独的CRI实现,可以更容易地加入各种定制。

1. Virtlet概览

图1是来自virtlet社区的架构图。 一个节点上virtlet  POD包含 三个 容器:

  • virtlet:接收CRI调用,管理VM

  • libvirt:接收virtlet的请求创建、停止或销毁VM

  • VMs:所有virtlet管理的VM都会在这个容器的命名空间里

分享 | 基于kubernetes的VM解决方案探讨

图1(点击可查看大图)

2. 运行时

分享 | 基于kubernetes的VM解决方案探讨

图2(点击可查看大图)

01

CRIProxy

如图2所示,因为virtlet有单独的CRI实现,如果在一个节点上既需要支持VM又要支持容器,就需要有一个proxy来分发CRI调用:

  • 镜像:CRIProxy通过区分一个可配置的前缀来区分是一个容器镜像还是一个VM镜像。

  • 运行时:CRIProxy通过特定的注解来区分容器或VM。

默认情况下所有的调用会分发给容器运行时。

02

改进

因为引入了CRIProxy,多了一层中间调用,使这个架构看起来不够统一,多了一层可能的出错点,增加了出问题的几率以及调试的难度。所以我们下阶段计划开发一个 VM shim ,如图3所示。它满足containerd的shim规范。这样单个节点的运行时看起来更统一和干净。

分享 | 基于kubernetes的VM解决方案探讨

图3(点击可查看大图)

四、模型

刚有提到,操作VM的入口是在 AZ层 ,而且已经有了CRD来描述一个节点。 同一个AZ管理着一个或者多个kubernetes集群。

分享 | 基于kubernetes的VM解决方案探讨

图4(点击可查看大图)

这里的 providervirtlet ,专门管理VM的生命周期。如图4所示,它主要的任务是根据 ComputeNode ,首先挑选一个 kubernetes集群 ,然后在这个集群里创建一个对应VM的 POD ,同步他们之间的状态。对于用户而言,下面的POD是不可见的, 用户通过创建或者删除ComputeNode来管理VM。

五、定制

Virtlet已经有了大部分所需要的功能,但还不能完全满足需求,我们对以下方面做了定制和改进:

  • VM网络

  • NUMA Pin

  • VM的重启、停止

  • OpenStack镜像兼容

  • Virtlet的可靠性

1. VM网络

01

Virtlet网络管理

对于现有的eBay VM,都是 桥接(bridge)网络 ,只需要在 libvirt domain 指定 目标桥接器 ,libvirt就会在启动VM的时候创建一个 TAP接口 ,并把这个接口连接到指定的桥接器。

然而对于kubernetes的VM,网络接口是调用CNI插件先配置好,然后才会创建和启动VM。Virtlet引入了 vmwrapper ,它是所有VM启动的入口,virtlet会把vmwapper设置成 libvirt domain的 入口(emulator)

分享 | 基于kubernetes的VM解决方案探讨

图5(点击可查看大图)

从图5可见,启动一个libvirt实例后,vmwrapper会被首先执行:

  • Virtlet侦听在一个 unix domain socket 上,并且virtlet已经打开了相应VM的TAP接口。

  • vmwrapper发起连接跟virtlet通信,拿到TAP接口的 文件描述符(FD)。

  • vmwrapper填写好网络相关的参数,最后启动真正的 qemu进程。

    qemu网络参数举例如下:

分享 | 基于kubernetes的VM解决方案探讨

(点击查看大图)

这里涉及到了进程间传递描述符(FD),virtlet使用的是Linux的SCM(Socket level control messages)方式。

02

网络改进

每一次CNI插件配置网络,都会建一个新的 网络命名空间(network namespace) ,一般需要有一对 veth pair 来连接主机的网络和新建的网络空间。Virtlet默认VM网络如图6:

分享 | 基于kubernetes的VM解决方案探讨

图6(点击可查看大图)

连通一个VM,需要建一个 bridge ,一对 veth pair ,这样网络的性能会有一定的影响。

VM本身有 强隔离性 ,我们又有自己的CNI插件实现, 为了减少网络的路径,创建VM的网络不需要新的网络命名空间。 最终一个节点的网络结构如图7所示:

分享 | 基于kubernetes的VM解决方案探讨

图7(点击可查看大图)

03

Vhost net

Virtlet不支持vhost net,而eBay OpenStack上使用virtio的VM都有vhost net。增加这个功能,对每一个TAP接口,都需要有一个vhost net的描述符,这个描述符是通过打开/dev/vhost-net而来的。描述符的传递跟前面提到过的TAP描述符传递类似。

04

支持TSO(TCP Segment Offload)

在对virtlet的VM进行网络性能测试的时候,网络吞吐量只有OpenStack VM的 一半 , 在VM里面, soft IRQ负载 很高,最终发现virtlet VM的网络 没有打开TSO和TX/RX校验

无论是Open Stack的VM还是virtlet的VM,都没有显示配置这个选项,但为什么OpenStack的VM默认是打开的呢?

前面提到, 常规VM 的网络接口是 libvirt 创建和删除的,而 virtlet的VM网络接口 是由 CNI 创建、 virtlet 管理的。通过阅读libvirt和qemu的源代码,libvirt在打开TAP接口的时候会加一个IFF_VNET_HDR的选项,qemu检查到这个选项后, VM实例的网络接口就会默认打开TSO。 通过这个小小的改动,virtlet VM的网络吞吐量跟OpenStack的VM旗鼓相当。

2. NUMA Pin

eBay数据中心的服务器都有 2个或以上 的NUMA节点,在这些节点上运行的VM,需要把他们尽量固定在NUMA节点上,否则跨NUMA节点的访问会带来性能问题。 Kubernetes有CPU manager这个功能,CPU的分配也顾及到了机器上的NUMA节点,但不能完全满足要求,原因如下:

  • CPU是独占的。也就是一个CPU被分配给一个POD后,其它任何POD就不能再分配到这个CPU了,这样不能做到超售。

  • CPU的分配可能会跨NUMA节点,但并不平衡。比如 一个 POD需要 8个 CPU,那就有可能 2个 CPU分配在 一个 NUMA节点,另外的 6个 CPU分配在 另一个 NUMA节点,导致了不平衡。

基于以上原因,我们没有使用CPU manager这个功能,而是在virtlet里增加了一个模块来管理NUMA节点的分配和释放(这也是virtlet有自己的CRI实现的好处之一):

  • 固定VM所运行的NUMA节点,但不固定VM运行在NUMA节点对应的CPU。比如一台机器有 2个 NUMA节点, CPU 0-15 NUMA 0 CPU 16-31 NUMA 1 ,如果申请一个 4核 的 VM ,那这个VM只会运行在其中的一个NUMA节点上,但VM能用到的CPU可以是这个NUMA节点上所有的CPU(当然这只是标准的VM,对于有高性能要求的VM,既要有NUMA固定也需要有CPU固定)。

  • 对于NUMA的分配,采取的是CPU、内存最平衡的方式,也就是在一个NUMA节点上,在分配量不超过某个阈值的前提下, 计算已经分配的CPU和内存,加上将要被分配的VM需要的CPU和内存, CPU分配量和内存分配量差值的绝对值哪个最小,哪个优先级就最高。

3. VM的重启和停止

Virtlet没有提供 VM重启(reset)和停止(stop) ,但eBay有些团队需要这样的功能。前面提到,virtlet的VM就是一个普通的POD,在kubernetes里如果一个POD不是在 运行(running)状态 ,kubernetes就会不断重试,去把POD带回到运行状态。 因此需要一个单独的模块来管理VM的状态。

  • 综合当前VM的实际状态和用户所期望的状态,做到最后状态一致。

  • 增加一个POD的注解,里面包含所 需要(request) 的状态和 实际(status) 状态。

  • 在给kubelet汇报VM状态的时候,如果用户显示的是该VM已停止,仍然要向kubelet汇报是运行状态,这样kubelet就不会反复地调用启动的接口。

4. OpenStack镜像兼容

eBay运行着很大规模的OpenStack集群,有许多已有的VM镜像,virtlet必须能无缝地使用这些已有的镜像。

在eBay,绝大部分OpenStack VM的网络信息是通过 configdrive静态注入 的方式,由 cloutinit 来完成网络的配置的,虽然virtlet的文档里声称支持configdrive,但他们使用的是不同的configdirve的版本,大部分的现有镜像都不能正确拿到configdrive所注入的信息。

因此需要实现另一个版本的configdrive,甚至还能兼容Windows VM。 满足这两个需求,有两个关键的地方:

  • Configdrive盘必须有 config-2 的标签。

  • Configdrive必须是 vfat格式 的(虽然configdrive可以是vfat或者iso,但某些Windows的cloudinit不能识别ISO格式)。

六、可靠性

尽管VM的生命周期用kubernetes来管理,但VM和容器还是有不同的地方: 在VM的生命周期之内,不管是POD重启、virtlet重启以及节点重启,VM的所有数据不能有任何丢失; 而容器在重启之后数据就会消失(不包括host path)。

Virtlet要能用在生产环境,必须做到数据不丢失。 还有节点上的VM能够脱离virtlet运行良好,这样才能给virtlet升级。从一开始,我们就非常关注virtlet的可靠性,也找到了 virtlet可靠性所存在的一些问题

  • 升级virtlet本身,所有的VM也莫名其妙地消失了。

  • 重启节点,VM所有的数据丢失。

  • 停止VM和virtlet,然后再启动virtlet和VM,VM再也不能启动。

如果以上的问题不能解决,virtlet就不能用在生产环境,需要用其它方案甚至重新开发一套来代替。 幸运的是通过积极阅读代码和调试,我们解决了上面的问题,社区也接受了这些补丁。

对于基于virtlet的一些改进和定制,需要保证每次改动不影响已有的功能,从一开始我们就开发了 集成测试端到端测试 来保证 可靠性

七、性能

有了可靠的保障,性能也必须达标,参照物就是已有的OpenStack VM。

  • 我们使用各种基准测试工具对相同CPU、内存以及磁盘的virtlet VM和OpenStack VM进行测试。

  • 使用生产环境的镜像流量来比较两者的CPU和内存使用率,以及 在每秒时间内能够处理的事务(TPS Transaction Per Second)。

比较下来的结果是两者没有差距,达到了我们的预期和要求。

八、结语

Kubernetes愈来愈受各家公司重视,这是未来几年甚至数十年云平台的趋势。但是从老的平台过渡到新的平台需要时间,一刀切的方式会带来无法遇见的风险和额外的耗时,特别是像eBay这样有多样产品和大体量的云平台公司。 用kubernetes来管理VM使这种过渡成为了可能,既不需要同时维护两套平台,也减少了新老交替带来的风险。

分享 | 基于kubernetes的VM解决方案探讨

↓点击 阅读原文 ,一键投递

eBay大量优质职位,等的就是你!

查看原文: 分享 | 基于kubernetes的VM解决方案探讨

  • bigfrog
  • bluefish
需要 登录 后回复方可回复, 如果你还没有账号你可以 注册 一个帐号。