
哈Ha! 我叫Dmitry,我是ISPsystem的一名开发人员。 最近,我们在Beta测试中发布了新版本的虚拟机控制面板。 今天,我将告诉您我们如何决定从旧产品中获取什么,以及更好地拒绝什么。 我将为我们讲解最重要的问题:一个用于libvirt的库,在产品安装过程中支持各种操作系统,从单片到微服务的过渡以及虚拟机的部署。
本文是关于
VMmanager的 。 这是一个用于管理,部署和监视基于KVM和OVZ虚拟化的虚拟机的系统。 第五代于2012年问世。 从那时起,界面非常过时,并且集中式体系结构阻碍了产品的开发。 现在该制作一个新版本了。
第一个故事。 我们使用家庭小精灵的工作
使用libvirt:考虑选项,选择库
作为管理KVM虚拟化的工具,我们的产品使用libvirt。 在2012年,选择了用C编写的库来使用它,因此对于该开发团队来说更加方便。 结果-大量用C ++编写的代码调用了C库,该库实现了libvirt的直接工作。
现在,在一个新项目的起点上,我们回顾并检查我们的产品,权衡是否值得采用特定的解决方案/技术; 已经证明了自己的东西,需要记住并且永远不会重复的东西。
我们坐下来,对以前版本的产品进行了多年的回顾工作。 我们有耐心,拿贴纸并写三种类型的纸:
- 什么成功了? 用户称赞什么? 从未听到过什么抱怨? 你喜欢自己什么?
- 什么失败了? 经常出现什么问题? 是什么阻碍了这项工作,为什么他们要开设一个新的分支机构?
- 有什么可以改变的? 用户要求什么? 团队成员想改变什么?
热衷于破坏纸张的人应该包括与产品紧密接触了几个世纪的人,以及对产品有新认识的人。 不要忘记功能请求和产品经理。 现成的贴纸粘贴在板上,它们一定会对我们有所帮助。

回到故事。 我们研究一段C ++ 98标准与C库调用和平共处的代码。 我们记得2018年是这一年,决定离开他。 但是,如何重复使用虚拟机(VM)的功能,使代码更紧凑,更方便工作?
我们研究了这个问题,了解到无论选择哪种解决方案和使用哪种语言,它都将成为C库的包装。 作为一个有趣的选项,值得一提的是
DigitalOcean上的Go库 ,它使用RPC协议直接与libvirt通信,但是它有缺点。 我们选择了
Python库 。
结果,我们获得了代码编写速度,易用性和可读性。 值得解释这些美丽的话。
- 速度 。 现在,我们可以直接从调试服务器上的控制台快速使用域的一部分工作进行原型设计,而无需重建主应用程序。
- 简单性 。 我们没有在某个处理程序中调用许多C ++方法,而是通过带有参数传递的Python脚本调用。
- 调试也尽可能快速,轻松。 我认为,从长远来看,这可以带来有趣的用户体验。 想象一下,系统管理员对他的虚拟机在销毁之前正在等待关闭感到不满,然后为host_stop方法重新定义了脚本。
我还能为您编写一个面板吗?
结果,我们得到了一个简单方便的工具,可以在服务器级别使用虚拟机。
第二个故事。 包装良好的产品不需要额外的照顾
产品分发:我们拒绝许多软件包,然后传递给Docker

VMmanager 5作为一组Linux软件包分发。 支持CentOS 6/7和直到最近的Debian 7,这是什么意思? 这意味着更多的CI / CD构建服务器,更多的测试,更多的代码关注。 我们必须记住,在CentOS 7 qemu版本1.5.3的官方存储库中,在CentOS 6中是0.12.1。 同时,用户可以使用此软件包版本更高的存储库。 这意味着在使用VM时,尤其是在迁移期间,您需要支持不同版本的api。 我们必须记住初始化程序(init,systemd)之间的区别,并考虑到包和实用程序名称的区别。 在CentOS上运行的那些实用程序将不能在Debian上运行,或者它们在官方存储库中的版本差异很大。 对于每次推送,您都需要收集所有版本的软件包,建议不要忘记也对其进行测试。
新产品中的所有这些都不适合我们。 为了不支持不同的逻辑,我们放弃了几个系统,只保留了CentOS7。问题是否解决了? 不完全是
我们也不想在安装之前检查操作系统的版本,是否有必要的实用程序,SELinux中安装了哪些规则,以及我们不想重新配置防火墙和存储库列表。 我想一次-仅此而已,只需单击一下即可
销毁每一秒钟,以部署整个环境和产品本身。 据说-完成后,项目被包装在Docker容器中。
现在已经足够做:
面板启动并运行。
当然,我很夸张地说,用户必须自己安装Docker,并且我们有多个容器,并且目前VMmanager作为SaaS服务以群体模式运行。 关于选择Docker时遇到的问题以及解决方法,您可以撰写另一篇文章。
事实本身就是简化开发的重要性,最重要的是,您的产品install.sh的部署曾经占据
2097行 。
结果:
- 同类产品安装环境可简化程序代码并降低组装和测试成本。
- 将应用程序作为docker容器分发使部署简单且可预测。
第三个故事。 与微服务的第一关系
架构:我们放弃了整体,转而支持微服务

该产品的第五个版本是带有过时的C ++标准的大型单片系统。 结果,新技术的实施存在问题,重构遗留代码的难度大,水平扩展性差。 在新分支中,他们决定使用微服务方法作为避免此类问题的方法之一。
微服务是一种现代趋势,具有正反两方面的特点。 我将尝试提出我对这种体系结构优势的看法,并讨论解决它给项目带来的问题。 值得一提的是,这将是普通开发人员从实践中首次了解微服务架构。
一篇好评论文章涵盖了我可能不会提及的方面。
正面
小服务给很多机会。除了编写,测试和调试的便利之外,微服务还为该项目引入了一种新的编程语言。 当您的项目是一个整体时,很难想象有一天您会尝试用另一种您感兴趣的语言重写其中的一部分。 在微服务架构中-请。 除了编程语言外,您还可以尝试新技术,唯一需要注意的是,所有这些对于企业都是合理的。 例如,我们在Golang中编写了一些微服务,同时节省了大量时间。
团队规模我们可以将许多曾经致力于一个存储库并试图将整体结构保持在头脑中的人分为几个团队。 每个团队都会参与其中。 此外,由于新人的工作环境有限,因此他的工作变得更加简单和快捷。 另一方面,拥有世界知识的人员聚集者很少,总能从庞大系统的任何方面找到他们。 也许以后我会重新考虑我对此的态度。
独立降级我会将独立降级归因于微服务的积极和消极方面,因为例如,如果存在授权服务,谁需要您的应用程序? 但是,这仍然是积极的一面。 以前,从数百个虚拟机中收集统计信息使我们的整体工作变得很辛苦,在负载高峰时,等待用户请求增加的等待时间大大增加了。 单独的统计信息收集服务可以在不影响其他服务的情况下进行收集,同时仍可以通过添加新硬件或通过增加相同统计信息的收集器数量来进行扩展。 我们甚至可以为Graphite选择一个单独的服务器,该服务在其中记录统计信息。 对于拥有一个基地的整体来说,这是不可能的。
负面
请求上下文我在整体中进行的所有调试都归结为控制台中的两个查询:
做完了! 我可以跟踪整个请求,从接收到系统,直到出现错误为止。
但是现在,当请求从微服务传输到微服务并伴随着对邻近服务的额外调用以及各种数据库中的记录时,该怎么办呢? 为此,我们实现了请求信息,其中包含请求标识符以及有关产生请求的用户或服务的信息。 因此,跟踪整个事件链变得更加容易,但是由于我们毕竟拥有微服务架构,因此迫切需要编写日志聚合服务。 您也可以看一下Elasticsearch,这个问题已经解决,很快就会解决。
资料不一致微服务中的数据是分散的,没有单个数据库可以存储所有信息。 在思考这篇文章时,我想到了微服务之间的主要交互作用-我们可以在其中获得重复项,在这里我们可以使用互联网络交易-并且我意识到我们用整体解决了不一致的问题。
我们实际上建立了一个具有一个主要基础的整体,将其中的大部分交易行为包装其中。 并且在整体附近收集了不影响主数据一致性的所有微服务。 例外是一堆服务授权+整体。 在这种情况下,问题在于基本应用程序数据库不包含用户本身,其角色和其他参数,所有这些都在授权服务中。
系统用户可以在整体中使用虚拟机,而在授权服务中,其权限可能会更改,或者将被完全阻止。 系统必须对此做出及时响应。 在这种情况下,通过在执行任何请求之前检查用户参数来实现数据一致性。
至于其余的微服务,无法在统计服务中注册不会影响虚拟机的操作,并且始终可以重复执行此操作。 好吧,我们正在做一个统计信息收集微服务。 但是定义域服务(使用libvirt创建虚拟机)将永远无法实现,因为谁需要空白的机器而没有它的实际存在。
第四个故事。 新鲜是善良的敌人
VM部署:从映像安装而不是通过网络安装
在产品的第五个版本中,按照实际标准,虚拟机的部署需要相当长的时间。 这样做的原因是通过网络安装操作系统。
对于Centos,Fedora,RedHat是
kickstart方法 :
1.创建一个kickstart文件。
2.在内核参数linux inst.ks = <kickstart文件的链接>中指定响应文件的链接。
3.运行kickstart安装。
Kickstart文件非常灵活,您可以在其中描述安装的所有步骤,从安装方法和设置时区开始,以磁盘分区和设置网络结束。 我们模板中的url参数指示安装来自远程服务器。
对于Debian和Ubuntu,
预装方法:
它与上一个类似,该方法也是围绕配置文件及其内容构建的。 在其中,我们还配置了通过网络的安装。
FreeBSD的安装与此类似,但是没有一个kickstart文件,而是我们自己生产的Shell脚本。
该方法的积极方面
此安装选项使您可以在我们的两个产品中使用一个模板:VMmanager和
DCImanager (专用服务器的管理)。
虚拟机的部署非常灵活,面板管理员可以简单地复制操作系统模板并根据需要更改配置文件。
如果在远程服务器上及时更新所有用户,则他们始终具有最新版本的操作系统。

负面
如实践所示,VMmanager用户不需要安装灵活性:与专用服务器相比,很少有人担心虚拟机的特定kickstart文件设置。 但是,等待操作系统的安装确实是不可接受的。 与操作系统相关的另一面是,安装程序的一部分在网络上,而一部分在
initrd本地。 并且它们的版本必须匹配。
这些是可解决的问题。 您可以创建一个已安装计算机的池,并为操作系统创建自己的存储库,但这需要额外的费用。
如何在不创建存储库和池的情况下解决这些问题? 我们选择了操作系统映像文件。 现在安装过程如下所示:
1.将操作系统映像复制到虚拟机磁盘。
2.复制后,将图像的主要部分增加可用空间的大小。
3.基本设置(设置密码,时区等)。
一切新事物都被遗忘了。 我们在VMmanager的前身VDSmanager-Linux中使用了OS映像。
但是安装灵活性又如何呢? 实践表明,大多数用户对虚拟机上的特定网络设置和磁盘映射不感兴趣。
和数据的相关性? 可以通过在存储库中使用具有最新OS版本的映像来实现,并且可以在初始配置脚本中安装较小的更新。 因此,虚拟机将已经创建并正在运行,转到虚拟机,您将发现有条件的yum更新正在运行。
作为回报,我们得到了一个现成的虚拟机,其虚拟部署仅取决于复制磁盘,增加磁盘分区和启动操作系统。 这种使用机器的方法的实现为我们提供了创建自己的图像并共享它们的机会。 用户可以在虚拟机上安装
LAMP捆绑软件或某些复杂的环境,然后制作该计算机的映像。 现在,其他人将不必浪费时间安装必要的实用程序。
我们使用
libguestfs套件中的实用程序实现了分区的配置和修改。 例如,在Linux机器上更改密码,将40行代码(包括mount,chroot和usermod)变成一行:
command = "/usr/bin/virt-customize --root-password password:{password} --domain '{domain_name}'".format(password=args.password, domain_name=args.domain_name)
结果,我们使尽快完成的虚拟机。 值得一提的是,通过网络设置和内部脚本的安装,部署时间略有增加。 我们通过在前端显示安装步骤来解决此问题,从而填补了从创建到机器准备就绪之间的停顿。
我们还获得了一种更为灵活的虚拟机部署方法,在此基础上可以方便地在必要的环境中创建自己的映像。
你做了什么
在产品的第六版中,我们尝试考虑了第五版的主要缺点:用户与产品交互的复杂性。 我们减少了关键行动的准备时间。 与无阻塞接口一起,这使得无需强制等待即可使用面板。 容器化使产品安装过程更加轻松便捷。 现代技术和各种编程语言的使用简化了对程序员和技术支持专家的支持和维护。 切换到微服务可以快速添加新功能,并且有较小的限制。
最后,我想说的是,新产品是尝试其他开发方法,新技术的好机会。 值得记住的是您为什么这样做,它将为您和您的用户带来什么新事物。 加油!
我们邀请Habr社区查看VMmanager 6的测试版,并留下您的反馈。 为此,请访问my.saasvm.com ,登录并连接专用服务器(CentOS 7 x64,Internet访问,公共IP地址)。
如果您没有服务器,请发送电子邮件至help@ispsystem.com或在网站上聊天,我们将提供合作伙伴Selectel的测试设备。
在ISPsystem网站上的新闻中阅读更多内容。