在生产环境中不用 Docker Compose

Python 项目容器化实践 (一) - Docker Compose 一文中提到我的观点:

如果想在生产中使用容器,应该选择 Kubernetes 来编排容器。

为什么呐?其实也蛮好理解的: Docker Compose 是单机版的开发套件,类似于容器环境下的 Systemd。在实际的生产环境中即便是初创公司往往也有多台服务器 (物理机),需要运行少则几百多则几万的容器,这面临非常多的问题,举几个例子:

  • 跨越多台服宿主机对容器管理 (增删改查)。
  • 不同服务器上的容器之间的通信问题。Compose 定义的多服务从通信方式、依赖关系上限制是单机部署
  • 应用的自动化弹性伸缩 (扩容 / 缩容)。应用应该在监测指标值超过设定的上限或者低于设定的下限时实现容器数量的弹性伸缩,而 Compose 虽然提供了 docker-compose scale 实现规模伸缩,但是不能自动完成
  • 实现「零停机时间 (Downtime) 部署」方案复杂成本高。上线过程或者灰度发布时需要零停机时间部署,而应用往往占用某个 (些) 端口,这样其他容器就没法同时使用这个端口了。虽然可以使用「蓝绿部署」(延伸阅读链接 1) 的方式实现不停机上线,但是非常麻烦。
  • 资源控制。一台主机上可能会运行几百个容器,容器之间虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘等资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,这回导致容器资源使用不公平,甚至导致主机和集群资源耗尽,服务完全不可用。在 V2 版本的 Compose 配置文件中可以用 mem_limit 等参数限制,而在现在最新的 V3 中需要在 Swarm 模式下使用,Compose 对此就没有办法了,只能借助外部的资源管理方案。

说回来,如果不是多服务器,说明业务和架构非常简单,这种情况下我认为完全没有必要上 Docker:

  • 如果是自己的服务器。物理机上直接使用 Ansbile/Puppet 甚至用简单的 Fabric 之类的工具直接部署即可,比用 Docker 直观和方便。在这个前提下,公司小、代码逻辑相对简单且核心开发者都了解,开发测试环境我觉得自己就应该搞定,不需要用 Docker 做成统一镜像。
  • 如果使用云服务。其中的数据库 (MySQL)、Redis、消息队列等往往都直接使用云产品了,自己只需要维护云服务器中的应用,安装依赖、设置配置再启动就可以了,好简单。

如果业务中有 10 个容器和 3 个服务,编排的价值很小,但当你有 1000 个容器和 300 个服务 (以及更多),当你进行大规模操作的时候,容器编排就是至关重要的了。

容器编排 (Orchestration)

什么是编排?

本意:为管弦乐中的「配器法」,主要是研究各种管弦乐器的运用和配合方法,通过各种乐器的不同音色,以便充分表现乐曲的内容和风格。

计算机领域:引申为描述复杂计算机系统和软件的自动化的配置、协调和管理。

所以容器编排就是有关管理容器生命周期的全部工作。包含但不限于:

  • 可以自动调配和部署容器
  • 保证容器的可用性
  • 平衡工作负载
  • 服务发现和高可用
  • 弹性伸缩
  • 解决容器资源分配问题
  • 容器和主机的健康监控

你们可能听过 Docker Swarm、Mesos+Marathon 和 Kubernetes (以下简称 k8s) 是三大主流编排方案,其实这是过时的说法,因为从来没听过有那个知名公司或者团队在生产环境使用Docker Swarm(上篇已经介绍过 Swarm 模式)。其实Mesos+Marathon这个方案现在用的也很少了,Marathon 项目下有一个使用的公司列表 (延伸阅读链接 2),一番搜索下发现之前应用这个方案的最主要的 Twitter、Airbnb、豆瓣、小米、唯品会、知乎、七牛云、携程、Pinterest 等公司在今年 (2019 年) 都已经转向 k8s 并取得成果,可见 k8s 已经非常成熟和被市场认可,另外也证明 k8s 可以替代 Marathon。可以说现在你只应该选择 k8s。

不过我还是要介绍Mesos+Marathon方案,因为这曾经是我瓣的选择,了解这些内容有助于理解我瓣基础设施上的一些设计和实现。限于篇幅下篇文章再着重介绍 k8s。

Mesos

Mesos 是 Apache 下的开源分布式资源管理框架,负责调度集群内的 CPU、内存、磁盘和端口等资源。你之前可能听过很多大数据处理框架 (如 Hadoop MapReduce, Spark、Storm、Flink 等)、数据存储库 (如 Kafka、ElasticSearch) 等,但是为这些应用每个都搭建单独的集群非常地浪费资源,也无法实现数据共享,而 Mesos 的设计初衷就是提供跨数据中心和云的资源管理调度能力,让不同的分布式计算框架能够共享一个集群。官网对其的描述非常直观:

英: Program against your datacenter like it’s a single pool of resources 中:像用一个资源池 (一个电脑) 一样对你的数据中心编程

可以通过架构图来理解它:

这个图一眼看去不好理解,我之前学习的时候看过一篇《煮饺子和 MESOS 之间妙不可言的关系 》(延伸阅读链接 4,找不到原文了) 的文章,介绍的非常好,大家可以看看。在这里我还是帮助大家来理解一下:

  • Mesos Master。Mesos 是 Master-Agent 架构,Mesos 由一个 Master Daemon 来管理 Agent Daemon 在每个集群节点上的运行,同时它确定每个节点的可用资源
  • Standby Master。Master 支持高可用,通过 Zookeeper (一个知名分布式应用程序协调服务) 完成的主节点选举。这 2 个目前 Standby master 是替补,如果 Mesos master 出问题,会从它俩中选择一个作为新的 Master
  • Mesos Agent。Mesos 框架 (Framework) 在这些代理上运行任务 (Tasks)

Mesos 只做资源调度,要做什么事情是 Framework 决定的,如图中的 Hadoop、MPI 都是对应的框架。Framework 包含 2 部分:

  • Scheduler。调度器,会注册到主节点,等待分配资源。如图中左上角的 Hadoop Scheduler 和 MPI Scheduler
  • Executor。执行器,就是执行框架任务,如图中下部的 Hadoop Executor 和 MPI Executor

Agent 会周期性的向 Master 汇报自己可用的资源,Master 会根据当前节点的资源情况发出资源邀约 (Resource Offers) 给框架,如果框架接受这个邀约 (如果不符合框架资源要求可以拒绝),对应 Scheduler 会答复 Master 需要什么样的资源,Master 会把这些任务下 Agent,收到消息的 Agent 会启动相应框架的 Exexutor 去执行任务。

看官网给的例子:

流程是这样的:

  • Agent 1 向 Master 报告,说节点有 4 个 CPU 和 4GB 内存可用
  • Master 发送一个资源邀约给 Framework1,描述 Agent 1 有多少可用资源
  • FrameWork1 接受了这个邀约,FW Scheduler 会答复 Master:「我有两个 Task 需要运行在 Agent 1,一个 Task 需要 & lt;2 个 cpu,1 GB 内存 & gt;,另外一个 Task 需要 & lt;1 个 cpu,2 GB 内存 & gt;
  • Master 发送这些 Tasks 给 Agent 1。此时 Agent 1 还有 1 个 CPU 和 1 GB 内存没有使用,所以分配模块可以把这些资源作为邀约发给 Framework2
  • 当任务完成和有新的空闲资源时,资源邀约会不断重复这一个过程

Marathon

说到这里要转入正题。Mesos 并不能单独的存在,必须要有 Framework 配合存在,前面提到的 Hadoop 和 MPI 都是数据处理框架,但是还有一类常驻服务的框架,其中最知名的是 Marathon - 一个跑在 Mesos 上的容器编排平台

它适合长期运行的项目 (如数据库,应用服务等)。主要的特性如下:

  • 高可用
  • 良好的容器支持
  • 支持服务发现和负载平衡,相当于服务的注册中心。
  • 健康检查
  • 配置约束
  • 支持有状态服务,如数据库
  • 易于使用的 Web 用户界面
  • 支持事件订阅,方便推送到 Graphite、StatsD 等系统,也可以使用 Prometheus 对其进行抓取。
  • 有完整的 REST API,易于集成和编写脚本。

这些特性对于管理大规模的 Docker 容器化应用都非常有价值:

不过可惜,现在有个更好的 k8s。写这篇文章时我试图找到各厂为什么要从 Mesos 迁移到 k8s,但是除了知乎没有人提到😓。知乎的理由是:

  • 调度速度遇到瓶颈,影响大业务的部署速度。
  • 不能很好的支持有状态服务

也请教了我厂的平台同事,促使他们转向 k8s 的理由如下:

  • Marathon 占用资源过多。看了一下内部数据,k8s 基本不怎么吃资源,现在内存降了约 90%👍
  • k8s 功能丰富,降低定制开发成本
  • 社区来看,k8s 越来越成为主流,而相对的 Mesos 越来越不活跃 (也可以看最近几年的 Google Trends 辅证)
  • 做 Mesos 的公司 mesosphere 都改做 k8s 了

所以目前看,容器调度上 k8s 已经一统天下了~

延伸阅读

  1. https://martinfowler.com/bliki/BlueGreenDeployment.html
  2. https://github.com/mesosphere/marathon#companies-using-marathon
  3. http://mesos.apache.org/documentation/latest/architecture/
  4. http://www.sohu.com/a/45669475_208510
  5. https://www.digitalocean.com/community/tutorials/an-introduction-to-mesosphere
  6. http://mesosphere.github.io/marathon/