作者 郭蕾
Docker提供了一种在安全、可重复的环境中自动部署软件的方式,拉开了基于云计算平台发布产品方式的变革序幕。腾讯内部对Docker有着广泛的使用,其基于Yarn的代号为Gaia的调度平台可以同时兼容Docker和非Docker类型的应用,并提供高并发任务调度和资源管理,它具有高度可伸缩性和可靠性,能够支持MR等离线业务。为了剖析Docker on Gaia背后的实现细节,InfoQ专访了腾讯数据平台部高级工程师罗韩梅。
**InfoQ:能否介绍下目前Gaia平台的状态?你们什么时候开始使用Docker的?有多大的规模?**
> **罗韩梅**:Gaia平台是腾讯数据平台部大数据平台的底层资源管理和调度系统,其上层业务包括离线、实时以及在线service服务,如Hadoop MR、Spark、Storm、Hive以及腾讯内部的Lhotse、Hermes、广点通等业务。最大单集群规模达8800台、并发资源池个数达2500个,服务于腾讯所有事业群。我们是2014年10月份正式上线Docker,之所以选择Docker,一方面是因为Gaia本来就一直在使用cgroups类型的容器,深知其在共享机器资源、灵活、轻量、易扩展、隔离等方面的重要意义。另一重要原因,是Gaia作为一个通用的云操作系统,适合所有类型的业务,但是各个业务的环境依赖是一个比较困扰用户的问题,因此我们引入Docker来解决,主要目的还是通过Docker来将Gaia云平台以更有效的方式呈献给各个业务。
> 我们使用的OS是腾讯内部的tlinux 1.2版本,最新版本正在tlinux2.0上测试,除了Docker,也使用了etcd用来做服务注册和服务发现。我们的集群都是同时兼容Docker应用和非Docker类型的应用的,MR等应用还是使用的cgroups类型的容器,其它服务使用的Docker容器,目前,大概有15000多常驻的Docker容器,还有大量业务接入测试中。由于我们原本就是使用的cgroups容器,所以换成Docker后,性能基本也无损耗,可以满足线上需求。
**InfoQ:腾讯是如何把Yarn与Docker深度结合的?**
> **罗韩梅**:在腾讯的场景下,首先一个特点就是,业务总类极大,尤其是离线处理规模很大,因此Yarn原生的调度器,效率远远跟不上,因此我们开发了自研调度器SFair,解决了调度器效率和扩展性问题。另外,腾讯的业务特性多样,因此我们引入了Docker,虽然Yarn支持不同的应用类型可以实现不同的AM(应用管理器),但是对于绝大多数应用来说,他们并不熟悉Yarn,实现一个支持容灾、可扩展的完善AM,困难较大,因此我们抽象了可以使用Docker的业务,对其进行封装,实现了统一的AM,并且对用户透明,而对用户提供的是另一套全新的基本的、易于理解的高级接口。同时,我们为Docker业务实现了统一的服务注册和发现机制,并也将其封装在了新接口中。另外,在资源管理方面,我们修改了内存管理机制,引入了磁盘和网络带宽管理。
> 除了Yarn之外,其实我们对Docker本身也做了一定的修改和bug修复,对于Registry等服务也做了优化,保证了其服务的高可靠和性能。
> 实现方面,我们并没有使用社区提供的Docker调度器,我们研发Gaia的时候社区还没有相应的调度器,并且我们也有特殊要求,需要同时支持同时支持Docker类型应用和非Docker类型应用。
**InfoQ:你们如何确定哪些业务适合使用Docker?**
> **罗韩梅**:我们认为,Docker提供了一种在安全、可重复的环境中自动部署软件的方式,拉开了基于云计算平台发布产品方式的变革序幕,因此,其实Docker对于Gaia来讲,只是一个选择,我们并不主动向业务推广Docker,而是Docker on Gaia的整套方案,所以,我们对于需要共享资源、降低成本,需要支持快速的动态扩容缩容、容灾容错,以及大规模分布式系统尤为建议使用Docker on Gaia。
**InfoQ:能否详细介绍下你们对Docker以及Registry做了哪些优化?**
> **罗韩梅**:对于Docker,我们主要做了三个方面的优化:首先是bug修复,比如Docker非0退出时rm不生效,对于bindmount为true时config path无法清除等bug。其次是优化Docker的资源管理策略,比如内存的Hardlimit的管理策略,不但使用户进程容易被kill,更加造成了资源的浪费,对用户估计自己业务的资源需求也非常高。Gaia引入了EMC(Elastic Memory Control)的弹性内存管理机制。最后一个方面是资源管理纬度,Docker在资源管理纬度方面只有CPU和内存两个维度,这对于共享的云环境下需要完善,也是目前相对于虚拟机不足的地方。Gaia引入磁盘容量管理,网络出入带宽控制以及磁盘IO的控制维护。其实不仅仅在Docker层做控制,还将会引进调度器,不但实现资源的隔离,还要实现资源的保证。
> 对于Registry的优化,主要有下面几个方面:
> 1. 容量问题。开源的Registry是单机模式,其容量会受单个机器的限制。我们修改存储driver,取缔原有的mount方式,开发后端存储driver,直接使用HDFS,实现了存储的无限容量。
> 1. 可靠性和可用性的问题。单机版本的Docker Registry,其可靠性和可用性都成了最大的问题,我们引入数据平台部的tPG系统,实现Registry server的无状态化,便于实现服务的高可用性。
> 1. 性能问题。将单机版的Registry扩展成Registry集群,并实现在Registry server pool中的负载均衡,提升性能。
> 1. 网络问题。解决了全国不同IDC的Gaia集群对Registry的访问,采取就近访问的原则,不产生跨IDC流量。
> 1. 自动同步官方镜像。Docker提供的官方镜像中,有很多还是非常有价值的,而官方的Registry又在墙外,为此,我们自动同步docker的官方镜像到我们的私有仓库中。
**InfoQ:能否介绍下目前的一个workflow?**
> **罗韩梅**:目前使用Docker on Gaia的方式有三种:1)通过Gaia Portal;2)直接调用Gaia api;3)通过上层各种PaaS平台透明间接使用Gaia。比如在第一种方式中,用户通过Gaia Portal提交应用,之后Gaia调度器会自动分配资源,并且部署、启动Docker容器,用户可以在Portal上直接查看每个实例的状态、日志、异常等,甚至可以直接通过webshell登陆。同时,也可以根据需求对应用进行扩容、缩容、重启,以及灰度变更、停止实例/应用等操作。
**InfoQ:目前平台主要部署了哪些服务?服务之间的调度是如何实现的?**
> **罗韩梅**:目前平台上的服务有Hermes、通用推荐、广点通、游戏云等服务,很多服务都需要多实例部署,因此跨主机部署非常普遍,而不同服务直接也经常会有调用的需求,主要是通过Gaia提供的服务注册和服务发现机制。具体地,NM(Yarn的一个组件)在启动Docker容器时,会将该Docker的真正地址,包括ip和所有的端口映射,都会通过etcd做自动的服务注册。对于Docker内部的服务,我们通过修改Docker源码,扩展了几个Gaia相关的环境变量,将IP以及端口映射传入。服务的注册和发现本质上一种名字服务,因此不难理解为什么在创建应用的时候,让用户填一个应用 name的字段。而这种基于名字的服务是贯穿这个Gaia的过程的:在提交作业时,用户不需要指定Gaia master的地址,而是通过指定Gaia 集群的name即可;在获取应用的地址时,也是通过应用的名字获取;本质上port mapping也是一种名字,只不过是将用户原来expose的端口作为name,将实际端口作为value。至此,不难理解为什么name需要检查冲突。
**InfoQ:万台规模的Docker容器,网络问题是如何解决的?**
> **罗韩梅**:网卡及交换链路的带宽资源是有限的。如果某个作业不受限制产生过量的网络流量,必然会挤占其它作业的网络带宽和响应时延。因此Gaia将网络和CPU、内存一样,作为一种资源维度纳入统一管理。业务在提交应用时指定自己的网络IO需求,我们使用TC(Traffic Control)+ cgroups实现网络出带宽控制,通过修改内核,增加网络入带宽的控制。具体的控制目标有:
> 1. 在某个cgroup网络繁忙时,能保证其设定配额不会被其他cgroup挤占;
> 1. 在某个cgroup没有用满其配额时,其他cgroup可以自动使用其空闲的部分带宽;
> 1. 在多个cgroup分享其他cgroup的空闲带宽时,优先级高的优先; 优先级相同时,配额大的占用多,配额小的占用少;
> 1. 尽量减少为了流控而主动丢包。
### 受访者介绍
**罗韩梅**,腾讯数据平台部高级工程师,任数据中心资源调度组副组长。2009年加入腾讯,主要从事统一资源管理调度平台的开发和运营,承担过腾讯自研云平台“台风”中Torca资源调度子系统的研发,目前主要专注于开源技术、分布式数据仓库、分布式资源调度平台、Docker等领域。