容器技术在 Netflix 基于 AWS EC2 虚拟机打造的全球云平台中大放异彩,并产生了深远影响。之前我们曾分享过不少有关 Netflix 使用容器的故事(视频、幻灯片),本文将深入讨论Netflix 对容器的使用情况,以及Netflix 为基于容器的应用程序打造的底层基础架构Titus。Titus 为Netflix 提供了可伸缩的集群和资源管理能力,增强了容器执行与Amazon EC2 之间的集成度,提供了Netflix 所需的通用基础架构功能。
本月,Netflix 的容器技术迎来两个重大里程碑。首先,我们的平台规模更上一层楼,在一周内顺利扩展至上百万个容器。其次,Titus 现已可为提供流播服务客户体验的功能提供支持。我们将深入介绍Docker 容器的具体使用方法,以及使得该容器运行时显得如此独一无二的原因。
容器的发展历史
基于Amazon 虚拟机(EC2)的基础架构早已成为Netflix 实现各项创新的重要推动力。除了虚拟机,我们还大量使用基于容器的工作负载,这类工作负载为我们提供了独特的价值。容器技术带给我们不菲的收益,对此我们倍感激动,同时容器的用量也经历了爆发式增长,甚至我们自己的开发人员都对这些因素感到吃惊。
虽然EC2 支持对服务进行高级调度,但我们的批处理用户无法从中获益。Netflix 有很多用户需要同时运行多个作业,甚至要通过基于事件的触发器分析数据,执行运算,并将结果发送给其他Netflix 服务、用户,以及报告。我们需要每天多次运行诸如机器学习模型训练、媒体编码、持续集成测试、大数据Notebook,以及CDN 部署分析作业等工作负载。因此我们希望为基于容器的应用程序提供不依赖具体工作负载类型的通用资源调度器,通过更高级的工作流调度器对所有内容进行集中控制。Titus 可同时承担通用部署单位(Docker 镜像)和通用批处理作业调度系统的任务,它的顺利上线帮助Netflix 通过扩展为批处理用例提供了更好的支持。
借助Titus,我们的批处理用户只需要指定自己对资源的需求,即可快速获得成熟的基础架构环境。用户无须选择并维护在规模方面无法与自己的工作负载完美匹配的AWS EC2 实例,而是可以安心地通过Titus 将更大规模的实例“打包”在一起,高效运用于不同类型的工作负载。批处理用户可在本地编写代码,随后立即通过调度通过Titus 进行大规模执行。在容器的帮助下,Titus 可以运行任何批处理应用程序,并且可以明确指定自己需要的应用程序代码和依赖项。例如,在机器学习训练过程中,用户将能配合运行Python、R、Java 和Bash 脚本应用程序。
除了批处理,我们发现其他工作负载也能从更简单的资源管理和本地开发体验等方面获益。通过与Edge、UI 和设备工程团队合作,我们还将这些收益扩展到了服务的使用者群体。目前,我们正在通过重建将面向具体设备的服务器端逻辑部署到API 层,这样即可更充分地利用面向单内核优化的NodeJS 服务器。我们的UI 和设备工程团队还希望获得更好的开发体验,例如与生产环境完全一致,更简单的本地测试环境。
除了一致的环境,开发者还可以在容器技术的帮助下,通过Docker 层镜像和面对容器部署进行优化的预供应虚拟机,更快速地推送新版应用程序。现在,使用Titus 进行的部署可在1-2 分钟内完成,而以往单纯使用虚拟机时往往需要数十分钟。
所有这些改进都源自开发者更快速的创新。现在,批处理用户和服务用户都可以更快速地在本地进行实验和测试,他们还可以更自信地将代码部署到生产环境。这样的速度也可以让Netflix 客户更快获得各类新功能。可以说,容器技术对我们的业务非常重要。
深入了解Titus
上文介绍了我们构建Titus 的原因。下文将深入介绍Titus 到底是如何提供这些价值的。我们将简要介绍Titus 的调度功能和容器的执行如何为服务和批处理作业需求提供支持,具体情况如下图所示。
在处理应用程序的调度工作时,Titus 可对所需资源和可用计算资源进行匹配。Titus 可支持“永久”运行的服务作业,以及“持续运行直到完成”的批处理作业。服务作业可重启动失败的实例,并通过自动伸缩与负载的变化相匹配。批处理作业可根据策略进行重试并一直运行直到完成。
Titus 为资源调度提供了多种 SLA。通过 EC2 的自动伸缩功能,Titus 可根据当前需求为即席(Ad hoc)批处理和非关键内部服务提供按需获取的计算容量。它还能为用户需要执行的工作负载和更关键的批处理任务提供预配置、有保障的容量。调度器可通过集装优化(Bin packing)提高大规模虚拟机的效能,并能通过反关联性(Anti-affinity)实现跨越虚拟机和可用性集的可靠性。这种调度功能源自 Netflix 开发的一个名为 Fenzo 的开源库。
Titus 容器运行在 EC2 虚拟机基础上,并能与 AWS 和 Netflix 基础架构进行集成。我们预测到用户会在很长一段时间内同时使用虚拟机和容器,因此决定尽可能让云平台和运维体验保持简单。使用 AWS 的过程中,我们选择尽可能利用现有的 EC2 服务。例如,我们会使用 Virtual Private Cloud(VPC)获得可路由的 IP,而没有使用单独的网络覆盖(Network overlay)。我们使用 Elastic Network Interface(ENI)以确保所有容器都包含特定应用程序所需的安全组。Titus 提供的元数据代理使得容器可以了解自己运行环境特定的容器视图以及 IAM 凭据。容器无法看到宿主机的元数据(例如 IP、主机名、实例 ID)。我们还配合使用 Linux、Docker,以及自有的隔离技术实施了多租户隔离(CPU、内存、磁盘、网络、安全)。
为了成功地在 Netflix 的环境中应用容器技术,我们还要将其与现有开发工具和运维基础架构无缝集成。例如,Netflix 已经具备持续交付解决方案 Spinnaker 。虽然也可以通过调度器进行滚动更新并实现其他 CI/CD 概念,但通过 Spinnaker 提供这样的功能使得我们的用户可以跨越虚拟机和容器使用一套一致的部署工具。另外还有个例子:服务之间的通信。我们会尽可能避免重新实现服务发现和服务负载均衡工作,取而代之的是提供一个完整的 IP 栈,借此容器将能与现有的 Netflix服务发现和基于DNS(Route 53)的负载均衡机制配合使用。在这些例子中,Titus 成功与否的一个关键原因在于:需要确定那些事情不该通过Titus 来做,而是应该利用其他基础架构团队所提供的相关功能来实现。
继续使用现有系统的代价是:我们需要对这些系统进行扩充,以便能与虚拟机和容器技术配合使用。除了上文列举的例子,我们还需要对遥测、性能自动调优、健康度检查系统、混沌自动化(Chaos automation)、流量控制、区域性故障转移支持、密文管理,以及交互式系统访问等机制进行扩充。另一个代价是:由于需要与Netflix 的这些系统进行深入绑定,这使得我们很难利用其他开源容器解决方案提供容器运行时平台之外的其他功能。
以我们的规模(以及工作负载密度)来说,容器平台的运行还需要密切关注可靠性,并且我们还会在系统的所有层面上遭遇不小的挑战。我们已经顺利解决了Titus 软件,以及所依赖的其他开源软件(Docker Engine、Docker Distribution、Apache Mesos、Snap 和Linux)相关的伸缩性和可靠性问题。我们针对整个系统的所有层面设计了失败处理机制,包括通过协调促进资源管理层和容器运行时之间分布式状态的一致性。通过清晰衡量的服务级别目标(容器发布启动延迟、由于Titus 中问题导致容器崩溃的百分率,以及系统API 整体可用性),我们可以更好地对可靠性和功能进行权衡。
容器技术帮助工程师提高效率的一个关键原因在于开发工具。开发者生产力工具团队构建了一个名为 Newt (Netflix Workflow Toolkit)的本地开发工具。通过本地迭代并借助 Titus 进行部署,Newt 可简化容器开发工作。通过在 Newt 和 Titus 之间实现一致的容器环境,也可以帮助开发者更自信地编写代码。
目前 Titus 的使用情况
为了驱动 Netflix 的服务,我们通过三个 Amazon 区域,用多个测试和生产账户运行了多个 Titus 栈。
2015 年 12 月发布 Titus 后,当时我们每周需要启动数千个容器,用来处理少量工作负载。上周,我们启动了上百万个容器,这些容器中运行了数百个工作负载。一年多时间里,容器的用量增加了 1000 倍,而增长势头依然没有任何放缓的迹象。
为了向批处理用户提供支持,我们在峰值时段运行了 500 个 r3.8xl 实例,这意味着 16,000 个处理器内核,以及 120TB 内存的规模。我们还通过 p2.8xl 实例获得了所需的 GPU 资源,借此支撑基于神经网络和微批(Mini-batch)的深度学习功能。
2017 年上半年,流处理即服务团队决定通过 Titus 为自己基于 Flink 的系统提供更简单快速的集群管理能力。这一决定导致新增了超过 10,000 个长期运行的服务作业容器,并且随着流处理作业的变化,这些容器都需要重新部署。各种服务共使用了数千个 m4.4xl 实例。
虽然上述用例对我们的业务很重要,但这些用例都不会对 Netflix 的客户产生直接影响。不过这种情况最近有了些变化,最近我们开始通过 Titus 容器运行某些直接面向 Netflix 客户的服务。
用于支撑直接面向客户的服务,这个决定必须慎重。过去六个月来,我们一直在对虚拟机和容器之间的实时通信进行复制,并使用复制的流量了解如何更好地运维容器,以验证该平台是否已经面向生产环境做好了准备。通过大量的前期工作,我们已经可以自信地在基础架构中推行如此重大的变动。
Titus 团队
Netflix 得以成功运用 Titus 的原因之一在于,Titus 开发团队所积累的宝贵经验和不断的成长。我们的容器用户坚信不疑地认为,Titus 团队可以通过 Titus 的运维和创新满足自己的需求。
这个团队的后续成长还有很长的路要走,我们也希望能将这个容器运行时和开发者体验扩展到更多领域。
Andrew Spyker 、 Andrew Leung 和 Tim Bozarth 代表整个 Titus 开发团队撰文并发布。
阅读英文原文: The Evolution of Container Usage at Netflix
感谢郭蕾对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论