解析 Netflix Titus - 容器管理工具软件的设计
Netflix 在2018年4月开源了他们的容器管理工具 Titus。同类的产品有 Google 的 Kubernetes 和 Apache 的 Mesos。在下面这个演讲中, Netflix 介绍了他们如何设计 Titus 这个软件的。
首先我们来看看 Titus 的使用情况:
- 1000+ 多个应用
- Netflix 的 API,基于 node.js
- 机器学习(使用GPU)
- 编码视频文件
- Netflix Studio,一个云端的视频(更准确的应该说是剧集)制作平台
- CDN 跟踪和计划
- 持续集成工具
- 大数据
截止2018年第一季度的使用率:
- 每天 176k 个 job
- 1k+ 个 docker image
下图是 Titus 的软件架构:

软件的入口是 CI/CD 或者 batch/workflow system。它们发送job 给 control plane。CI/CD 是持续集成部署,会生成类似于部署服务器这样的 job。而 batch/workflow system 生成其他的业务相关的 job。
下图是 Control plane 部分的结构:

在 Netflix ,要在 cluster 上运行一个 container,必须通过发送 API request 给 Titus,API request 中包含了 一个job的描述。Titus 分析 job 后分成一系列 task,然后部署到 AWS 生成 container。
TItus gateway 接受 REST API request 或者 gRPC。在更高 throughput 的场景下, gRPC 比 API request 更好。
Titus Master 是整个软件主要的组成部分。下面来分组件介绍:
Job management:管理 job
job 分为两类。一类叫做 batch job,比如一段 script,或者 elasticsearch indexing job。
另一类是 service job。比如一个job 是运行一个 service。job 描述中定义了,最少需要多少 server ,最多不能超过多少 server 。job management 负责保证 service 按照它的需求运行。
Scheduler

Netflix 开源了他们的 scheduler,Fenzo。它可以用在 Mesos 之上。
上图中,画了一个 4x4 的矩阵,可以理解为16台 virtual server。假设此时我们打算 deploy 一个 service,这个 service 需由3个不同的 container 组成。scheduler 需要解决的问题就是,如何把这3个 container 放到 servers 中最合理最优化。这里就有 scheduling 算法的问题了。算法要考虑 service 所需要的 reliability,service 启动时间,以及部署上去后的经济成本。

这个 scheduling 算法的大致思路如上图所示,scheduler 通过已知的 tasks 信息,以及所管理的服务器当前的状况(图中称为 agent),首先过滤(filtering)出可行的 agent。然后系统给各个 server 计算出一个匹配分数,最后deploy container 到最高分的一个 agent。
Filtering 过程主要考虑以下问题:
- server 的 CPU, 内存,硬盘,带宽,网络接口是否符合 service 的要求
- server 的安全策略是否符合要求
- server 是否通过 health check
- server 是否忙
Scoring 过程:
- 对于 batch job,我们希望占用最少的 server
- 而对于 service,有时候对 reliability 有更高的要求,我们会尽量把它部署在一定数量的服务器上
- 如果一台 server 上已经拥有了所需于的 image,那么它的 priority 会更一些,因为不再需要下载 image。
一个 container 的生命周期是:
- 在server 上配置网络
- 下载 image
- 运行 container
Agent management:管理服务器的状态

Agent management 对外提供服务器的状态信息。比如 scheduler 要分配服务器时,会通过 agent management 做 health check。
Capacity management:管理服务器的可用资源
TItus 管理的服务器被划分为不同等级,来确保 services 对不同运行能力的需求。
- Critical 关键级,类似 AWS EC2 的 reserved instance
- 确保了高速启动
- 预留一部分空间(计算空间或存储空间等)
- Flex 弹性级:自动伸缩
- Opportunistic 投机级:尽量使用已有的空闲 server
在 Netflix 使用 Titus
Titus 被很多内部的 service 使用。一个设计理念是,要使其他团队的成员花最少的精力,能够将自己的项目和 Titus 集成起来。

Netflix 有一个内部工具 newt,用来开发和部署用。 newt 通过命令行调用 CI 工具 Spinnaker 。 Spinnaker 可以选择是要 deploy 到 AWS EC2 的一个新的 vm 上,还是通过 Titus deploy 一个 container。
假设我们已经把 container 部署到云端了,下一步就是要让其他服务知道这个 container 的存在,也就是 service discovery。这是通过 Netflix 另一个开源项目 Eureka 来实现的。Eureka 可以发现 AWS 上的 vm 或者 Titus 上的 container。

Netflix 也使用了 AWS 的 load balancer。但 AWS 的 load balancer 只能分配流量到 server ,而在 Titus 的使用场景下,一台 vm instance 可能运行了很多 service。为了解决这个问题,Netflix 和 AWS ALB 团队合作,创造了一个叫做 IP target group 的新功能。这个功能能把流量导向给一个制定的 Titus container。
Titus 还通过创建 AWS auto scaling policy ,实现了在AWS的设施上进行 auto scaling。
Titus 还集成了内部时序数据库 Atlas,使用 Atlas 收集了 container 的状态信息,并展示在前端。如果服务器负载过高,会trigger Pagerduty 服务。

其他Titus 资料: