本文已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已不正确。

ShareThis:Kubernetes 在生产中

自从 ShareThis 最初作为一个小型小部件允许您共享到您喜欢的社交服务以来,它已经取得了巨大的发展。它现在每月为超过 450 万个域名提供服务,帮助发布商创建更真实的数字体验。

快速增长也付出了代价。我们利用技术债务来快速扩展和发展我们的产品,尤其是在基础设施方面。随着我们公司的扩张,基础设施成本也在上升 - 无论是在效率低下方面还是在人员成本方面。大约 1 年前,很明显需要做出改变。

简而言之,Kubernetes 一直是我们通过以下方式减少基础设施技术债务的关键组件:

  • 促进 Docker 的采用
  • 简化容器管理
  • 让开发人员加入基础设施建设
  • 解锁持续集成和交付。我们通过彻底采用 Kubernetes 并将我们的 DevOps 团队转换为一个云平台团队来实现这一点,该团队以容器和微服务为单位工作。这包括创建一些工具来绕过我们自己的遗留债务。

问题

唉,云是新的,我们也很年轻。我们从传统的数据中心思维模式开始。我们管理我们所有的自有服务:MySQL、Cassandra、Aerospike、Memcache,应有尽有。我们像传统服务器一样设置虚拟机,在上面安装我们的应用程序,并在 Nagios 或 Ganglia 中管理它们。

不幸的是,这种思维方式与以云为中心的方法背道而驰。我们没有从服务的角度思考,而是从服务器的角度思考。我们没有使用诸如自动缩放、微服务甚至托管虚拟机等现代云方法,而是从脚本设置、服务器部署和避免供应商锁定的角度思考。

这些思维方式本身并不坏,它们只是效率低下。它们没有利用云中快速发生的变化。这也意味着当需要进行更改时,我们将这些更改视为对数据中心的重大缓慢更改,而不是对云的细微快速更改。

解决方案

Kubernetes 作为促进 Docker 采用的工具

随着 Docker 在我们行业中越来越强大,ShareThis 的工程师也开始尝试它,效果很好。很快就显而易见,我们需要为我们公司的每个应用程序提供一个工作容器,这样我们才能简化我们在开发环境中的测试。

一些应用程序因为简单且依赖项少而迅速迁移到 Docker。对于那些依赖关系较小的应用程序,我们能够使用 Fig(Fig 是 Docker Compose 的原始名称)进行管理。尽管如此,我们的许多数据管道或相互依赖的应用程序太复杂而无法直接进行 Docker 化。我们仍然想这样做,但 Docker 还不够。

在 2015 年末,我们对我们的遗留基础设施感到非常沮丧,最终下定了决心。我们评估了 Docker 的工具、ECS、Kubernetes 和 Mesosphere。很明显,对于我们的基础设施而言,Kubernetes 比其竞争对手更稳定且用户友好。作为一家公司,我们可以通过简单地设定将所有基础设施都放在 Kubernetes 上的目标来巩固我们在 Docker 上的基础设施。

工程师们最初持怀疑态度。然而,一旦他们看到应用程序毫不费力地扩展到每个应用程序数百个实例,他们就被迷住了。现在,不仅有推动我们前进到 Docker 并扩展到 Kubernetes 的痛点,而且还有对技术真正兴奋的吸引力。这使我们能够相当快地进行极其困难的迁移。我们现在在多个区域的约 65 个大型虚拟机上运行 Kubernetes,并在未来几个月内增加到 100 多个。我们的 Kubernetes 集群目前每天处理 8 亿个请求,计划在未来几个月内每天处理超过 20 亿个请求。

Kubernetes 作为管理容器的工具

我们最早使用 Docker 在开发方面很有前景,但在生产方面则不然。最大的摩擦点是无法大规模管理 Docker 组件。知道哪些容器在哪里运行、正在运行哪个版本的部署、应用程序处于什么状态、如何管理子网和 VPC 等等,都阻碍了它进入生产的机会。所需的工具将是巨大的。

当您查看 Kubernetes 时,有几个关键特性立即具有吸引力:

  • 它很容易安装在 AWS 上(我们所有的应用程序都在那里运行)
  • 通过 yaml/json 文件,可以直接从 Dockerfile 到复制控制器
  • Pod 可以轻松地扩展数量
  • 我们可以轻松地在 Kubernetes 集群中扩展 AWS 上运行的虚拟机的数量
  • 滚动部署和回滚都内置在工具中
  • 每个 Pod 都通过运行状况检查进行监控
  • 服务端点由该工具管理
  • 有一个活跃且充满活力的社区

不幸的是,最大的痛点之一是该工具没有解决我们现有的遗留基础设施,它只是提供了一个可以迁移的基础设施。仍然存在各种网络怪癖,这些怪癖阻止我们直接将应用程序迁移到新的 VPC。此外,对如此多的应用程序进行返工需要开发人员加入到传统上由系统管理员和运营团队解决的问题中。

Kubernetes 作为让开发人员加入基础设施的工具

当我们决定从本质上是 Chef 运行的设置转换为 Kubernetes 时,我认为我们并不了解我们将遇到的所有痛点。我们在各种不同的网络配置中以各种不同的方式运行我们的服务器,这与您在新的 Kubernetes VPC 上找到的干净设置大相径庭。

在生产环境中,我们在多个区域的 AWS VPC 和 AWS classic 中运行。这意味着我们管理着多个具有不同访问控制的子网,这些子网跨不同的应用程序。我们最近的应用程序也非常安全,没有公共端点。这意味着我们结合使用了 VPC 对等连接、网络地址转换 (NAT) 和以各种配置运行的代理。

在 Kubernetes 世界中,只有 VPC。所有 Pod 理论上都可以相互通信,并且明确定义了服务端点。开发人员很容易忽略一些细节,它消除了对运营的需求(主要是)。

我们决定将我们所有的基础设施/DevOps 开发人员转换为应用程序开发人员(真的!)。无论如何,我们已经开始根据他们的开发技能而不是他们的运营技能来招聘他们,所以也许这不像听起来那么疯狂。

然后,我们决定让整个工程组织加入运营。开发人员很灵活,他们喜欢挑战,他们喜欢学习。这真是太棒了。 1 个月后,我们的组织从只有少数 DevOps 人员,到每个工程师都能够修改我们的架构。

在网络、生产化、问题解决、根本原因分析等方面进行入职培训的训练场是将 Kubernetes 大规模投入生产。第一个月之后,我提心吊胆,担心我们的选择。2 个月后,看起来它总有一天可能会可行。3 个月后,我们每周部署 10 次。4 个月后,每周部署 40 个应用程序。只有 30% 的应用程序已迁移,但收益不仅显着,而且令人震惊。Kubernetes 使我们能够从一个基础设施拖累我们的组织转变为一个基础设施加速我们发展的组织!

Kubernetes 作为解锁持续集成和交付的手段

我们是如何实现每周 40 多次部署的?简而言之,持续集成和部署 (CI/CD) 是我们迁移的副产品。我们在 Kubernetes 中的第一个应用程序是 Jenkins,每个添加到其中的应用程序也都添加到了 Jenkins 中。当我们前进时,我们使 Jenkins 更加自动化,直到 Pod 添加和从 Kubernetes 中移除的速度比我们能跟踪的速度还要快。

有趣的是,我们现在在扩展方面的问题是想要一次推出太多更改,并且人们不得不等到轮到他们。我们的目标是通过新基础设施实现每周 100 次部署。如果我们能够继续执行我们的迁移以及我们对 Kubernetes 和 Jenkins 上 CI/CD 流程的承诺,这是可以实现的。

后续步骤

我们需要完成迁移。目前,大部分问题已经解决,最大的困难在于手头任务的繁琐。将内容从遗留基础设施中移出意味着需要更改网络配置,以允许访问 Kubernetes VPC 以及跨区域的访问。这仍然是一个非常实际的难题,我们正在继续解决这个问题。 

有些服务在 Kubernetes 中无法很好地运行——想想有状态的分布式数据库。幸运的是,我们通常可以将这些服务迁移到第三方,让他们为我们管理。在此迁移结束时,我们将只在 Kubernetes 上运行 Pod。我们的基础设施将变得更加简单。

所有这些更改都不是免费的;将整个基础设施投入到 Kubernetes 意味着我们需要有 Kubernetes 专家。 我们的团队在基础设施方面已经不再受阻,他们正忙于通过应用程序开发来增加业务价值(他们应该这样做)。然而,我们(尚未)有专门的工程师来及时了解 Kubernetes 和云计算的变化。 

因此,我们已将一名工程师调到新的“云平台团队”,并将聘请其他几位工程师(我是否提过我们正在招聘!)。他们将负责开发我们可以用来与 Kubernetes 良好交互并管理我们所有云资源的工具。此外,他们还将在 Kubernetes 源代码中工作,参与 Kubernetes SIG,理想情况下,还会向开源项目提交代码。

总结

总而言之,虽然迁移到 Kubernetes 最初看起来令人生畏,但它远没有我们想象的那么复杂和具有破坏性。而最终的回报是一家能够像客户希望的那样快速响应的公司。编者注:在最近的 Kubernetes 聚会上,ShareThis 团队就他们 Kubernetes 的生产使用情况进行了演讲。视频嵌入如下。