Screen_Shot_2014-05-30_at_1.37.33_PM

智能工程博客

我们从Heroku到Kubernetes的旅程

发布的婆罗门参DevOps

2018年12月20日下午2:08:00

这个决定

像许多小型初创公司一样,我们在Heroku上启动了我们的应用,并围绕它的使用积累了大量的技术和社会实践。大约18个月前,Salsify的工程团队意识到,随着我们的团队、产品和用户基础的持续增长,我们将不再适合Heroku。

一个驱动因素是工程团队创建的应用程序(服务)数量的增加。Heroku没有很好的服务发现、协调或依赖管理工具。除了服务管理之外,我们预计还需要更严格地控制资源利用、不同的伸缩场景和安全性。

这一认识导致了一个主要项目的启动,以设计和构建下一个Salsify主机平台,我们将更详细地讨论。


有哪些选择?

我们花了几周时间评估容器编排平台。我们的能力使我们能够创建三个解决方案的概念证明:Docker Swarm,构造Kubernetes和香草Kubernetes。拥有严格的低层次需求有助于大大缩小列表。它需要一个细粒度的许可模型、附加到已部署容器以实现开发敏捷性的能力、在容器级别支持AWS IAM角色,以及一种轻松组织Rails应用程序的机制。我们意识到,不可能有一个单一的解决方案可以满足所有要求,这就促使我们去寻找一些能够提供基本类型的东西,以便我们能够在其上构建其他内容。

一旦意识到这一点,Kubernetes就成为了一个非常吸引人的选择。与Docker Swarm相比,Docker的开发速度令人难以置信且持续,在Github上的可测量活动超过了它一个数量级。Kubernetes作为API首先允许我们开发一个模型,该模型为Heroku的可用性提供了只有在运行自己的PaaS时才能获得的可观察性和配置。

设计

在设计Kubernetes环境时,我们知道这将是一个迭代的过程,因为微服务将逐步向它推出,但是我们希望在各种可能的设计决策上达成共识。通过使用KOPS项目,我们能够相当快地试验集群配置。

例如,为我们的登台和生产环境创建两个逻辑上独立的集群,使我们能够更适应部署,并为我们提供两个相同的环境来测试应用程序运行时的主要更改。我们选择的另一个主要设计原则是将应用程序分成它们自己的名称空间。这意味着后端审计服务及其所有流程和配置都位于名为auditing -service的名称空间中。在一个名称空间中独立运行和扩展deployment,可以有效地将这个集合变成一个Formation。而且,通过使用基于角色的访问控制(RBAC),我们能够复制以前在Heroku中采用的每个应用的细粒度权限模型。

对于身份验证,我们测试了几个不同的解决方案,但最终决定使用谷歌OIDC身份验证。我们将谷歌Apps身份验证用于许多其他服务,因此自然也可以将其扩展到这种情况。这允许我们的客户使用与谷歌帐户绑定的临时密钥来验证Kubernetes API。

在部署方面,我们决定让詹金斯做我们的瑞士军刀。通过使用声明式管道,我们能够捕获所需的所有部署逻辑,并将其扩展到两个Kubernetes环境中部署所有服务。


工具

当提出一个像交换平台这样大的改变时,这真的会破坏工程组织的敏捷性。它需要适应新工件、新工具和新监控等。考虑到这一点,给开发人员提供像kubectl这样的低级API工具不会有最好的初始结果,也不会促进公司所希望的采用。

反过来,我们开始开发内部工具来简化过渡。主要有两个,salsifyk8sksonnify,旨在帮助工程师迁移和操作他们的应用程序。salsifyk8s,包含使用给定环境的当前代码和配置运行rails控制台会话所需的所有逻辑。它还有助于显示进程类型和计数等信息,以及按进程名而不是按部署进行伸缩。Ksonnify,另一方面,它允许轻松创建给定部署所需的配置工件,修改像映像、秘密名称、configmap名称等字段,以及Dockerfile和Kubernetes命名空间的初始引导和RBAC规则。Ksonnify从Heroku所需的Procfile驱动它的初始配置,使迁移应用程序的第一步尽可能简单。

经常升级!

在生产环境中运行了几个月之后,我们决定让升级集群成为家常便饭。一切都很顺利,因此你不应该碰任何东西,这种想法永远不会成为现实。为了真正支持和展示组织,他们不仅可以信任运营部门,也可以信任Kubernetes,我们经历了各种升级。一个有趣的注意事项是,在集群中有了一些服务后,我们意识到通过KOPS将ETCD从2升级到3是很危险的,于是部署了新的集群,并随后编写了一个脚本,每次一个部署将应用程序移植到新的集群。这实际上击中了要害,即为Kubernetes构建的声明性应用程序很容易提升并转移到其他Kubernetes环境。

可观察性

一旦我们开始迁移服务,我们很快就意识到我们当前的监视并不是针对容器的。此外,在《Heroku》中,过程指标的可见性非常有限,我们觉得我们可以做得更好。为了解决这个问题,我们使用Prometheus -operator框架部署了Prometheus。通过一些定制,我们使用Grafana部署了一个监控堆栈,并且每个Kubernetes名称空间可以在很短的时间内向Slack和Pagerduty发出警报。

然而,这也带来了一些我们以前在监控中没有遇到的新问题。例如,我们在捕获容器内存使用情况的指标上设置了警报。然而,这个特定的缓存也包含页面缓存,当在Ruby中处理大量文件时,页面缓存往往会成为内存使用的不准确表示。在一天结束的时候,仅仅通过Kubernetes中的指标获取所有数据,然后在Grafana中将其可视化,这使得我们在评估服务规模时更加主动。不可否认的是,操作仍然是这个监视堆栈的头号用户,尽管随着时间的推移这种变化是自然发生的。

迁移服务

当迁移服务时,我们为自己创建了一个相当简单的流程。由于我们使用了大量的后台工作人员来处理队列中的作业,所以我们可以一个接一个地切换进程,确保事情按照预期工作。为了实现这一点,我们首先扩展了Jenkins管道,以支持同时部署到Heroku和Kubernetes。然后,从低风险流程开始,我们将更新Kubernetes定义,部署应用程序,然后在Heroku中执行该流程。几次之后,这变得舒服和非常重复。最后一个要移动的过程是web进程,当我们准备好时,它被留给了一个简单的DNS切换。

结束

回顾过去18个月,我们几乎成功实现了迁移中的所有初始目标,尽管比我们估计的要慢得多(至少6个月)。在改进开发人员支持方面,我们仍然有工作要做,特别是当它涉及到创建新服务时。在这个过程的不同阶段,我们低估了原型的成本,并在这个过程的早期过度投资于工具。这种过度投资导致了更新我们的工具的持续税收,因为我们的过程和实践改变了,因为我们学到了更多,变得更加固执己见。这些工具过去是,现在也是我们开发者生态系统的重要组成部分,但是如果我们能够从更好的计划和设计中受益,而不是采用更有机的方法。

最终,我们成功地将我们的生产应用程序从一个托管环境迁移到另一个托管环境,并且最小化了停机时间,同时获得了相当多的功能,否则我们将无法获得这些功能。


未来!

既然我们已经度过了迁移本身的主要阶段,我们也对我们可以在这个新平台上做的新事情感到非常兴奋。我们现在有很好的聚合级工具,可以将整个部署作为单个对象来工作,所以我们必须推广这些工具,并将它们的功能集成到我们的工作流程中。我们有一个可靠的用于检查和内省的API,这为监控、服务发现、公告等方面的改进创造了机会。我们的配置时间已经下降到动态配置完整测试环境似乎不再是梦想的地步。在很多方面,完成所有这些困难工作的最好部分之一是……它使道路我们还有更多的工作要做。

Salsify DevOps团队(过去和现在):亚当·贝尔,乔希·布拉纳姆,坦纳·博雅森,努勒斯·乔杜里,詹姆斯·哈林顿,乔·罗伯茨

主题:KubernetesHeroku

评论的Disqus

最近的帖子

    Baidu