微博基于Docker容器的混合云迁移
发布日期:2016-7-8 9:7:51
一、为何要采用混合云的架构 在过去很长时间内,大部分稍大些的互联网系统包括微博都是基于私有体系的架构,可在某种程度理解成私有云系统。混合云,顾名思义就是指业务同时部署在私有云和公有云(如阿里云),并且支持在云之间切换。实际上“为何要采用混合云”这个问题,就等于“为何要上公有云”。我们的考虑点主要有五个方面: 1、成本优势 对于短期峰值应对,常规部署,离线计算几个场景,我们根据往年经验进行成本对比发现公有云(如阿里云)优势十分明显 2、业务场景 随着微博活跃度的提升,及push常规化等运营刺激,业务应对短时极端峰值挑战,主要体现在两个方面: 高峰值,例如话题经常出现10到20倍流量增长。 时间短,业务需要应对分钟级或者小时级。 3、业界趋势 “Amazon首次公布AWS业绩:2014年收入51.6亿美元,2015年1季度AWS收入15.7亿美元,年增速超40%。”“阿里巴巴旗下云计算业务阿里云营收6.49亿元,比去年同期增长128%,超越亚马逊和微软的云计算业务增速,成为全球增速最快的云计算服务商。”我们预计未来产品技术架构都会面临上云的问题,只是时间早晚问题。 4、效率优势 公有云可实现5分钟千级别节点的弹性调度能力,对比我们目前的私有云5分钟百级别节点的调度能力,也具有明显优势。 5、安全性 基于数据安全的考虑,我们现阶段只会把计算和缓存节点上云,核心数据还放在私有云;另外考虑到公有云的技术成熟度,需支持在多个云服务直接进行业务灵活迁移。 基于上述几点考虑,我们今年尝试了以私有云为主,公有云为辅的混合云架构。核心业务的峰值压力,会在公有云上实现。 下面介绍介绍技术实现。整体技术上采用的是Docker Machine + Swarm + Consul的框架。 二、跨云的资源管理与调度 跨云的资源管理与调度(即上图中的pluto部分)的作用是隔离云服务差异,对上游交付统一的Docker运行环境,支持快速弹性扩缩容及跨云调度。功能上主要包括: 云服务选型 系统初始化 网络 镜像服务 元数据管理 命令行工具 其他 系统初始化 最初技术选型时认为Machine比较理想,仅需SSH通道,不依赖任何预装的Agent。我们也几乎与阿里云官方同时向Docker Machine社区提交了Driver的PR,然后就掉进了大坑中不能自拔。 例举几个坑: 不支持并发,并发创建只能通过启动多个Machine进程的方式,数量多了无法承载。 无法扩展,Machine的golang函数几乎都是小写,即内部实现,无法调用其API进行功能扩展。 不支持自定义,Machine启动Docker Daemon是在代码中写死的,要定义Daemon的参数就非常ugly。 目前我们采用的是Puppet的方案,采用去Master的结构。配置在GitLab上管理,变更会通过CI推送到pluto系统,然后再推送到各实例进行升级。在基础资源层面,我们目前正在进行大范围基础环境从CentOS 6.5升级到CentOS 7的工作。做这个升级的主要原因是由于上层基于调度系统依赖Docker新版本,而新版本在CentOS 6.5上会引发cgroup的bug,导致Kernel Panic问题。 网络 网络的互联互通对业务来说非常关键,通常来说有三种方案:公网,VPC+VPN,VPC+专线。公网因为性能完全不可控,而且云服务通常是按照出带宽收费,所以比较适合相互通信较少的业务场景。VPC+VPN实际链路也是通过公网,区别是安全性更好,而且可以按照私有云的IP段进行网络规划。专线性能最好,但是价钱也比较好,且受运营商政策影响的风险较大。 网络上需要注意的是包转发能力,即每秒可以收发多少个数据包。一些云服务实测只能达到10万的量级,而且与CPU核数、内存无 关。也就是说你花再多的钱,转发能力也上不去。猜测是云厂商出于安全考虑在虚机层面做了硬性限制。我们在这上面也中过枪,比如像Redis主从不同步的问题等等。建议对于QPS压力比较重的实例进行拆分。 镜像服务 为了提升基础资源扩缩容的效率,我们正在构建虚机镜像服务。参考Dockerfile的思路,通过描述文件定义定义虚机的配置,支持继承关系,和简单的初始化指令。通过预先创建好的镜像进行扩缩容,可节省大约50%的初始化时间。 描述文件示意如下: centos 7.0: – dns: 8.8.8.8 – docker: – version: 1.6 – net: host meta: – service: $SRV puppet: – git: git.intra.weibo.com/docker/puppet/tags/$VERSION entrypoint: – init.sh 不过虚机镜像也有一些坑,例如一些云服务会在启动后自行修改一部分配置,例如router, dns, ntp, yum等配置。这就是上面entrypoint的由来,部分配置工作需要在实例运行后进行。 元数据的管理 调度算法需要根据每个实例的情况进行资源筛选,这部分信息目前是通过Docker Daemon的Label实现的,这样做的好处是资源和调度可以Docker Daemon解耦。例如我们会在Daemon上记录这个实例的归属信息: —label srv=$srv #记录所属业务 —label idc=$provider #记录云服务提供商(如阿里云) —label role=ci/test/production… —label ip=$eth0 #记录ip信息 … 目前Docker Daemon最大的硬伤是任何元数据的改变都需要重启。因此我们计划把元数据从Daemon迁移到我们的系统中,同时尝试向社区反馈这个问题,如动态修改Docker Daemon Label的接口(PR被拒,官方虽也看到了问题,但比较纠结是不是要支持API方式),动态修改registry(PR被拒,安全因素),动态修改 Docker Container Expose Port(开发中)。 云服务选型 我们主要使用的是虚机和软负载两种云服务。因为微博对缓存服务已经构建一套高可用架构,所以我们没有使用公有云的缓存服务,而是在虚机中直接部署缓存容器。 虚机的选型我们重点关注CPU核数,内存,磁盘几个方面。CPU调度能力,我们测试总结公有云是私有云的1.2倍,即假设业务在私有云上需要6个核,在公有云上则需要8个。 内存写入速度和带宽都不是问题,我们测试发现甚至还好于私有云,MEMCPY的带宽是私有云的1.2倍,MCBLOCK是1.7倍。所以内存主要考虑的是价钱问题。 磁盘的性能也表现较好,顺序读写带宽公有云是私有云的1.4倍,随机写是1.6倍。唯一要注意的是对于Redis这种业务,需要使用I/O优化型的虚机。 以上数据仅供参考,毕竟各家情况不一样,我们使用的性能测试工具:sysbench, mbw, fio,可自行测试。 CLI客户端(命令行工具) 为了伺候好工程师们,我们实现了简单的命令行客户端。主要功能是支持创建Docker容器(公有云或私有云),支持类SSH登陆。因为我们要求容器本身都不提供SSH(安全考虑),所以我们是用Ruby通过模拟docker client的exec命令实现的,效果如下图: 其他方面 跨域的资源管理和调度还有很多技术环节需要处理,如安全,基础设施(DNS、YUM等),成本核算,权限认证,因为这部分通用性不强,这里就不展开了。 三、容器的编排与服务发现 提到调度就离不开发现,Swarm是基于Consul来做节点发现的。Consul采用raft协议来保证server之间的数据一致性,采用gossip协议管理成员和传播消息,支持多数据中心。Consul集群中的所有请求都会重定向到server,对于非leader的server会将写请求转发给leader处理。 Consul对于读请求支持3种一致性模式: stale :允许所有的server支持读请求,不管它是否是leader。 default :给leader一个time window,在这个时间内可能出现两个leader(split-brain情况下),旧的leader仍然支持读的请求,会出现不一致的情况。 consistent :完全一致,在处理读请求之前必须经过大多数的follower确认leader的合法性,因此会多一次round trip。 我们采用的是default模式。 除了Swarm是基于Consul来做发现,业务直接也是通过Consul来做发现。我们服务采用Nginx来做负载均衡,开源社区的方案例如 Consul Template,都需要进行reload操作,而reload过程中会造成大量的失败请求。我们现在基于Consul实现了一个nginx- upsync-module。 Nginx仅需在upstream配置中声明Consul集群即可完成后端服务的动态发现 upstream test { # fake server otherwise ngx_http_upstream will report error when startup server 127.0.0.1:11111; # all backend server will pull from consul when startup and will delete fake server consul 127.0.0.1:8500/v1/kv/upstreams/test update_timeout=6m update_interval=500ms strong_dependency=off; upstream_conf_path /usr/local/nginx/conf/upstreams/upstream_test.conf; } 这个模块是用C语言实现的,效率已经经过线上验证,目前验证在20W QPS压力没有问题。而且这个模块代码已经开源在Github上,也欢迎大家提Issue:https://github.com/weibocom/nginx-upsync-module。 当然我们的RPC框架motan也会支持Consul,实现机制同样也是利用Consul的long polling机制,等待直到监听的X-Consul-Index位置发生变化,这个功能已经在我们内网验证通过,不过由于依赖整个motan框架,所以目前还没有开源。 Consul的监控 因为Consul处于系统核心位置,一旦出现问题会导致整体所有集群失联,所以我们对Consul做了一系列保障措施,其中所有Consul Server节点监控指标如下 Consul的坑 除了使用不当导致的问题之外,Consul Server节点通信通道UDP协议,偶发会出现server不停被摘除的现象,这个问题官方已在跟进,计划会增加TCP的通道保证消息的可靠性。 业务调度 容器调度是于业务无关,具体串联起资源管理,容器调度,发现等系统,完成业务容器最终跨云部署的是我们的JPool系统。JPool除了完成日常的业务容器上线发布之外,最重要的是完成动态扩缩容功能,使业务实现一键扩容、一键缩容,降低快速扩容成本。 围绕这调度和发现,需要很多工具的支撑: 例如为了使业务接入更加方便,我们提供了自动打包工具,它包括代码打包、镜像打包的解决方案,支持svn、gitlab等代码仓库,业务仅需要在工程中定义pom.xml和Dockerfile即可实现一键打包代码,一键打包镜像,过程可控,接入简单。 我们还对Docker的Registry,我们进行了一些优化,主要是针对混合云跨机房场景,提供跨机房加速功能。 容器调度 容器调度基于Swarm实现,依赖Consul来做节点发现(话说Swarm才刚刚宣布Production Ready)。容器调度分为三级,应用-应用池-应用实例,一个应用下有多个应用池,应用池可以按机房和用途等来划分。一个应用池下有多个Docker容器形式的应用实例。 我们利用Swarm的Filter机制,实现了适应业务的调度算法。整个调度过程分为两步:主机过滤:指定机房、内存、CPU、端口等条件,筛选出符合条件的主机集合;策略选择:对符合条件的主机集合进行打分,选择出最合适的主机,在其上创建容器以部署应用。调度子系统Roam实现了批量的容器调度与编排。 四、混合云监控体系 微博体系在经历了多年的IT建设过程后,已经初步建立了一套完整的信息化管理流程,极大地提升了微博业务能力。同时微博开展了大量的IT基础设施建设(包括网络、机房、服务器、存储设置、数据库、中间件及各业务应用系统等)。 针对于混合云体系,我们提供了一套完整的监控告警解决方案,实现对于云上IT基础架构的整体监控与预警机制,最大程度地保证了微博体系能够稳定地运行在混合云体系上,不间断地为用户提供优质的服务。监控告警解决方案实现了四个级别上的监控与预警: 资源级监控 系统级监控 专线网络监控 业务级监控 系统级监控 混合云体系支持的系统级监控(与新浪sinawatch系统的对接)包括:CPU,磁盘,网卡,IOPS,Load,内存 业务监控 混合云体系集成了目前微博业务监控平台Graphite,自动提供了业务级别(SLA)的实时监控与告警。所有的配置与操作都是系统自动完成的,不需要用户进行额外的配置操作。 业务级别的监控包括: 平均耗时监控: 实时监控业务系统接口的平均耗时时间。 JVM监控: 实时监控堆、栈使用信息、统计gc收集时间、检查JVM瓶颈等。 吞吐量监控: 实时监控业务系统吞吐量(QPS或TPS)。 Slow监控: 监控服务器集群,实时显示当前业务系统中最慢的性能瓶颈。 单机性能监控: 实时监控单台服务器的各种业务指标。 资源监控 混合云体系集成了目前微博资源监控平台sinadsp,自动提供了对各种底层资源的实时监控与告警。所有的配置与操作都是系统自动完成的,不需要用户进行额外的配置操作。 具体的监控指标包括:命中率,QPS/TPS,连接数,上行/下行带宽,CPU,内存。 五、前进路上遇到的那些坑 需要注意的坑,实际在各部分中都有提及。今天分享的主要内容就是这些了,当然业务上云(如阿里云),除了上面这些工作之外,还存在很多技术挑战要解决。如跨云的消息总线,缓存数据同步,流量调度,容量评估,RPC框架,微服务化等。 Q&A Q : 为什么选Consul?看中有对比Zookeeper、etcd,尤其是etcd? A:我们有对比etcd和consul,主要还是看重了consul基于K-V之外额外功能,比如支持DNS,支持ACL。另外etcd不对get request做超时处理,Consul对blocking query有超时机制。 Q : Docker registry底层存储用的是什么,怎么保障高可用的? A:底层使用的Ceph,前端无状态,通过DNS做跨云智能解析,加速下载。 Q: 上面提到的方案主要是Java体系, 对于其他语言(php, nodejs, golang)体系系统的是否有很好的支持(开发、测试、发布部署、监控等)? A:已经在开始php的支持。其实容器化之后,所有语言都是适用的。 Q : 容器跨主机通信是host网络吗? A:对,目前线上采用的是host网络。 Q : Consul temple reload nginx时为什么会造成大量请求失败呢,不是graceful的吗? A:是graceful的,在QPS压力较大的情况下,由于需要进行大量重连,过程中会产生较多失败请求。 Q : 刚才提到的调度系统是自己开发的?还是基于开源改的? A:是基于Swarm二次开发的。 Q : Ceph IO情况怎么?高IO的是不是不太适合用Ceph? A:针对Registry场景Ceph IO是可以胜任的。不过Ceph暂时还没有宣布Production Ready,所以对于极端业务场景,请谨慎。 关于作者 微博研发中心技术经理及高级技术专家。2008年毕业于北京邮电大学,硕士学位。毕业后就职华为北研。2012年加入新浪微博,负责微博Feed、用户关 系和微博容器化相关项目,致力于Docker技术在生产环境中的规模化应用。2015年3月,曾在QClub北京Docker专场分享《大规模 Docker集群助力微博迎接春晚峰值挑战》。
|