为何我们做了4个月的“无用功”?——构建Packet平台过程中的经验和教训

为何我们做了4个月的“无用功”?——构建Packet平台过程中的经验和教训

Packet是一家成立不久的公司,他们主要是为用户提供基于裸机服务器的IaaS,本文的作者是Packet平台的VP,作者在文中讲述了他们构建Packet平台的动机以及在构建过程中遇到了哪些问题。他们通过借鉴OpenStack已有的服务,如Neutron、Ironic,将OpenStack对于虚拟机集群的管理策略迁移到对物理机集群的管理上,同时作者还分享了在整个平台构建过程中的经验教训。


在去年夏天, Zac 找到了我,他当时正在筹划从头开始构建一个新式的、基于裸机服务器的云服务平台。由于之前我所做的绝大部分的工作都是在构建、支持维护或者使用可扩展性的基础设施服务,在这个领域已经有了一定经验。我开始的时候确实很好奇:我们到底是否需要一个这样的服务?难道不是已经有了许多现成的、优秀的IaaS平台了吗?

随着我们交谈的不断深入,我最终认同了Zac的观点,目前许多共有的云服务并非是用户友好的,并且使用起来有过高的门槛。此外,由于我还是一个早期的Docker使用者,我可以感受到基于容器的服务部署即将给相关领域带来的浪潮。容器技术以指数的方式提高服务器的质量,这比使用DevOps 工具箱的效率更高。此外,针对特定底层设施进行虚拟化的公有云服务,以及针对遗留问题的主机提供商(legacy dedicated hosting providers),都无法灵活地满足不同物理硬件的需求。所以我们认为,在这个领域仍然有许多工作值得我们去做,我们构建Packet的旅程就此开始。

在任务开始之前……

在项目开发前期,我花了一些时间来调研已有的,提供自动化云服务和自动化部署功能的产品,我还查看了一些定制的安装包(bespoke installers),几乎所有的开源云平台,以及我们需要重新构建自己的服务时可能用到的工具。

在Voxel工作期间,我们曾经开发过一个云主机平台,这个平台后来被 Internap所收购。我们当时还构建了自己的软件堆栈,并且我们对于自己平台的各种优势和使用平台可能带来的影响都掌握得一清二楚。我们天真的认为,凭借我们之前的经验,安装服务器集群的工作看起来应该很容易。你以为自己曾经做过一次,自己就是老手了吗?错!实时上,在安装的过程中,我们遇到了无数网络方面的问题,硬件方面不断的变化也经常困扰着我们,此外我们还需要解决由于操作系统的差异所导致的许多问题……不得不说,想要给客户提供一个真正自动化的服务层,并非易事。按照Zac所提出的要求,我们要安装、管理上千台规模的物理服务器集群,同时还要对集群的安全提供保障,每次对集群进行配置,这些工作到要在5分钟之内完成,对于我来说,这并不简单。

如何才能帮助Packet 满足其目标:在24/7 秒的时间内执行上千次的安装服务,并且让这些服务启动,还要运行数月之久?经过之前的调研,我们开始对OpenStack产生兴趣。我们希望借鉴OpenStack在基础设施管理方面的经验,并结合其已有的OpenStack组件,来构建我们自己的服务,我们的服务可能包括:网络自动化、IP管理、流程化安装、硬件生命周期监控、以及产品安装等几部分。如果我们可以依赖OpenStack已有的核心组件,我们的服务就不需要再从头开始构建,我的团队就可以将更多的经历集中于可以给用户带来更多价值的工作上:比如增强平台对底层硬件分析并且添加平台对容器技术的支持等等。

我也曾经被警告过,OpenStack中可能确实存在许多“陷阱”。但我还是花了几周的时间来阅读OpenStack最新提交的代码,我还在官方的IRC频道中与其他开发者交流,并且还尝试运行DevStack。无论是OpenStack已有的核心项目,还是在过去2年之内突然成熟起来的新项目,我对它们都非常熟悉。此外,对于我们构建Packet项目而言,似乎时机刚好:Rackspace最近推出了OneMetal服务,他们还通过博客公开了他们是如何在裸机云服务器上运行 Ironic服务的,此外,他们将要推出一个新的、重要的发行版:Juno ,这一系列举措似乎与我们的想法不谋而合,这看起来正是我们开发Packet项目的黄金时间。所以我和我的团队坚信,我们应该借鉴OpenStack的已有服务来完成我们对裸机服务器的部署。

故事是这样的……

我知道 OpenStack的学习曲线很陡峭,并且我需要掌握的是每一个项目的核心原理,并非仅仅是对项目进行简单的安装部署,于是我挨个地钻研OpenStack的项目,对于某些特别的项目,我需要通过反复使用来对它们有更好的理解,比如:Nova、 Ironic 驱动,以及 Neutron。我们不仅仅想要借鉴Ironic在裸机上安装提供的便利,我们还需要支持 Packet的主机级别的网络模型,特别是要避免通过两层网络或者是VlAN的方式,我们要将三层的网络模型直接构建在每个主机上。

对于我上面所提到的经历,你的第一反应可能是:“喔!相对于需要学习的内容而言,目前可以参考的文档是在是少之又少!”然而经过了一个多月的学习,我最大的感受就是,我所阅读的文档之中,许多文档都是过期的,有的文档内容甚至完全不准确!这强迫我不断地筛选质量更好的文档,文档的来源从 wiki百科到IRC上的日志,再到开源项目中最新提交的信息。我不断地从中筛选出“真实可靠的信息”。 除了经过初步的信息筛选,我还需要花费许多时间进行python debug,只是为了验证不同文章中对于功能可用性的互相矛盾的表述。比如,“到底XXX功能有没有作用?” 等等,整个过程进展得很慢。

值得注意的是,有许多开发者和公司有丰富的OpenStack使用经验。特别是针对Nova组件和标准的Neutron组件的实现方面。然而,几乎很少人对于Ironic在生产环境中使用有实际经验。虽然与其他的开源项目相比,OpenStack的开发者社区规模很大,但是我在对OpenStack组件研究的过程中仍然会遇到一些问题,甚至是一些项目的核心的开发者都无法帮助我们解决,在Google上搜索相关的错误结果,所能找到的相关错误信息也很少。

Lesson 1:OpenStack是一个庞大的、年轻的、发展迅速的项目,如果之前没有一定的知识储备,文档看起来可能会有很多“陷阱”。

我强迫自己对于Ironic的研究更深入一点,于是我把Neutron留给我的一个同事来研究(通过之前的教训得到的启示)。事实上,对于OpenStack的每一个组件,我们都需要安排一个专门的开发人员来负责研究。开发人员不仅要理解该组件的核心代码库,同时还要能跟上整个项目的发展进度。此外开发人员还要灵活地将对应组件进行调整并且运用到我们自己的项目的开发中。把Neutron的研究任务交给其他同事之后,我就可以更加专注于Ironic的研究工作,我花费了许多时间,通过IRC、邮件、并且在OpenStack开发者论坛上,同 Rackspace的OnMetal团队成员进行了很多的交流。我还阅读了许多相关的文档,我确定自己在论坛中发的每个帖子,以及通过Google可以搜索到的,我通过debug得到的每个结果,都会帮助Ironic构建其新的版本。

从Nova 的baremetal驱动逐步发展成为一流的Ironic项目,这整个过程中,社区的工作功不可没。虽然社区已经做了许多工作,但是OpenStack在整体的设计上,仍然保持着以虚拟化为中心的理念。如果拿Nova的 baremetal驱动和Ironic相比,很多特性都发生了改变。其中一个变化就是Ironic对网络方面的支持有限。通过Ironic 网络会根据modular layer 2 (ML2)插件被分成 openvswitch以及linuxbridge 两种代理模式。而我们的网络模型与这个分类有着很严重的冲突,我还发现,Neutron不仅缺乏对特定厂商的交换机的支持而且扩展到不同的网络模型的能力也有限。

相关领域的大公司(比如Rackspace) 对Openstack的核心代码有着更深刻的理解,它们可以将OpenStack中的大部分组件进行很高程度的定制化,以使得这些组件部署在物理服务器或者是真是的物理网络环境中。虽然其中一些用于定制的补丁项目已经开源,但是许多重要的补丁还没有开源。 对于一些重要的补丁,可能还需要重新开始构建,并且可能在新的OpenStack发行版本中对其进行维护。

Lesson2: OpenStack的项目全是基于虚拟机的,如果你的情况不是这样,那么祝你好运!

在这一点上,我也认真考虑了很多,怎么在我们的产品上改善OpenStack的安装过程。 这个过程中,需要操作的资源数量很庞大,并且保持每个服务之间的同步也需要很大的工作量。我开始感觉到我们需要对与Nova和Ironic项目的定制化工作绝非是简单的修修补补。巨大的工作量可能会抵消开源项目自身所特有的优势,同时也可能会减弱开发者的动力动力。

然而我任务全部理解Neutron中的细节是很重要的,在我的个人计划中,这也是一个最关键部分。

在物理交换机和服务器的世界中,安装服务并不是很非常的困难。这样可以提供可靠的服务,但在另一方面,这个工作做起来也并不容器,你需要一系列的工具来帮助你完成自动化的操作。并且根据我的经验,对于大多数基础设置的部署来说,最容易出错的地方就是网络方面的配置。你可以看到,就支持最新的自动化操作和API交互而言,物理交换机操作系统还有很多地方需要被加强(Juniper的即将到来的 14.2 JUNOS加强了对REST API的支持)事实上,在使用其他的网络自动化工具时,有许多令人沮丧的经历,这也是一个促使我调研OpenStack的一个主要原因。并且Neutron项目有一个很吸引人的标题 :“通过已实现服务及其绑定的函数库,来提供给你即时的、可扩展的、以及技术不受限(technology-agnostic)的网络抽象能力”当时看到这个标题,我就毫不犹豫加入进来。

然而,实时并非像他们所许诺的那样。之前讨论的大多数关于软件自定义网络的问题,它们大部分都需要在虚拟网络的环境下才能解决。这需要将网络建立在 hypervisor之上,而并非是使用真实的物理交换机。不仅仅是我们交换机的提供方(Juniper)对于Neutron的驱动已经完全过时,当我们使用最新的OpenStack的Juno发行版本后,相关支持仍然只是很小一部分。此外 Neutron 仅实现了一个网络间的、初级的 IP地址管理器(IPAM)。并且没有考虑对于从外部接入进来的IP进行行分配、报告、或者对指定的IP地址提供权限许可。如果让我们通过降低用户体验,来满足Neutron所提供的有限的特性,这对我们来说是不可接受的。

Lesson3 :Neutron对物理网络的支持要具体情况具体分析,使用之前先要检查你的交换机。

我们到底是怎么做的?

长话短说,我们在圣诞节之前我们又花了整整一周时间对OpenStack进行研究,之后我们用了接下来的三周时间来开发一个定制发布的自动化的平台。在去年12月份的早些时候,再构建了我们自己的IP Manager之后, 团队被鼓励在已经定制好的工具的基础上进行开发。我们是一个100%向前看的公司,并且我们感觉到,在探索和部署OpenStack的过程中,我们已经把大多数的陷阱都填平了,我们构建了一个灵活的服务提供级别的(service-provider grade)IPAM(我们称它为万能IP) ,一个用户和权限模型(在我们自己的SWITCH OSS基础上构建),并且在我们的设备管理平台和我们的物理基础设施之间有很好的结合。

有些时候,存在的不一定就是足够好,或者完全适合我们的需求。我们通过Packet项目对OpenStack进行改进,就是一个很好的例子。我们也期望在社区中发行我们自己的Neutron插件,并且紧随OpenStack项目的发展,现在我们也在继续前进。