数人云

数人云

数人云官网
用户手册

用户手册

数人云用户手册
Mesos中文文档

Mesos中文文档

开源, 欢迎大家修改优化

微服务转型绕不开的坑——日志记录这样做就对了

宁静胡同 发表了文章 • 0 个评论 • 564 次浏览 • 2016-06-29 10:17 • 来自相关话题

在如今企业纷纷转型微服务的过程中,微服务架构中日志记录的重要性时常会被忽略。本文作者十分关注微服务日志记录,提出了独到的观点,并与大家分享关于微服务日志记录的各种技巧的最佳实践。 

微服务架构是一种软件架构类型,着重于利用大量细分组件进行应用开发,其中每个组件都负责整体业务中的一小部分。这些组件彼此独立,支持在自己的进程之上,且能够相互通信以实现业务目标。


为什么要关注日志记录?


很多企业都开始将整体型应用拆分为微服务形式。而在拆分大型应用时,我们需要建立松散耦合的模块,从而保证其便于测试并降低变更风险。另外,这些模块亦可独立部署以实现横向规模扩展。然而,这也会带来一些初看并不严重,但长远影响极其重大的问题——其中的典型代表就是日志记录。


日志记录存在于一切应用当中,无论其属于整体还是微服务架构。关键在于,当我们将应用拆分为微服务形式时,我们需要投入大量时间来思考业务边界并找寻最理想的应用逻辑拆分方式——但很少有人会对日志记录给予应有的重视。


当然,大家可能会问:日志记录的方式一直没有变化过,为什么现在倒成了需要关注的问题?


理由在于,整体应用内的事务追踪往往比较困难,有时候我们只能依靠日志记录来理解当前状况。另外,当业务逻辑运行在多项服务中时,监控与日志记录的难度也会相应增加。这意味着如果我们没有明智地规划出微服务记录机制,那么最终可能根本无法理解应用的当前运行状态。


正因为如此,我想与大家分享我的个人经验以及作为软件开发者积累到的一点心得。近年来我一直在使用微服务方案,希望大家能够在读完本文后意识到日志记录的重要性与实现难点。


心得一——设立应用实例标识符


在使用微服务时,整套体系往往会同一时间运行同一组件的多个实例。最重要的就是在日志条目中设立实例标识符,从而区分各条目的具体来源。其ID的具体生成方式其实并不重要,只要保证惟一即可,这样我们才能借此回溯到特定服务器/容器以及生成该条目的应用处。在微服务架构中,大家可以利用服务注册表轻松为每项服务分配惟一的标识符。


心得二——坚持使用UTC时间


这项心得不仅适用于微服务架构,在其它场景下也同样值得坚持。任何使用过分布式应用程序——或者组件分散在各处——的朋友,都会意识到各组件使用不同时区进行计时有多么令人头痛。而在微服务架构中,以本地时间记录的日志条目会带来更严重的问题。如果大家确实需要使用本地时间,请在日志条目中以字段形式添加时区,从而简化信息的检索方式。但更重要的是一定要为UTC时间设立时区,并利用它在聚合工具内进行信息排序。

下面来看示例日志信息:







第一部分是由一项运行在新西兰的服务所生成。第二部分则由运行在巴西的服务生成。由于我们使用本地日期,因此由巴西服务生成的信息会早于新西兰信息——但其实际生成时间却恰恰相反。


现在,让我们看看使用UTC时间与时区后的示例信息:








现在两条信息已经得到正确的时间排序,如果大家希望了解信息的本地生成时间,则可将其由UTC转换为特定时区。


心得三——生成请求标识符


在将业务逻辑拆分为多个不同组件时,我们的逻辑最终需要由一个或者多个组件构成。而在追踪这些事务时,我们往往很难对其加以识别。因此,大家应当为每个事务生成一个惟一标识符,并利用其关联事件以及追踪各项事务。


想象一下,如果我们需要利用以下请求序列在某电子商务网站上购买产品:

 





那么我们对于操作的分组方法,显然取决于事务的实际定义(毕竟其也能够进行嵌套)。最重要的是确保在事务开端,我们为其创建一个能够传递下去的标识符,并借此在事务结束之前全程记录日志条目。


一般来讲,我倾向于使用人工生成的ID来区分自己的事务。大家也可以使用user_id或者session_id处理与用户相关的事务。而在进行结算与支付时,大家可以使用order_id来追踪结算与付款操作。不过其前提是大家已经进行了用户登录,或者创建了拥有order_id的订单——但实际情况往往并非如此。在使用手动ID时,大家可以将事务ID从业务逻辑流中解耦出来。


另外需要注意的是,这些ID需要拥有足够的信息以对系统中的各项事务进行区分。有时候事务识别符可能在日志条目中体现为一整套字段组合。


心得四——利用聚合工具进行日志分组


如果大家没有对来自全部微服务的日志条目进行聚合,那么以上提到的心得将毫无意义。要实现这一目标,我们需要使用一款能够轻松实现条目分组与查询的工具。我个人使用ELK堆栈,其效果相当出色。如果大家之前没听过ELK,这里可以稍微解释几句。ELK是三款应用的集合体,由此构成的完整解决方案能够调度日志条目、实现条目存储与索引,而后对信息进行聚合与可视化处理。


我们可以利用ELK对应用程序日志进行多种规模伸缩与分发处理,但这里就不讲太多了。感兴趣的朋友可以查看Logz.io博客上的Logstash教程,其中提到了多项相关使用技巧。另外,我们也可以使用Logz.io等企业服务处理日志基础设施的设置与维护工作,从而确保自己的微服务体系采用最理想的日志记录实践方案。


总结

这篇文章的目的是向大家强调在微服务架构中重视日志记录的必要性,同时分享一些在实际应用当中积累到的最佳实践。但这仅仅是个开始,相信大家能够采用多种其它方式解决日志记录难题。

文章来源:Logz.io  作者  Lucas Saldanha 查看全部

在如今企业纷纷转型微服务的过程中,微服务架构中日志记录的重要性时常会被忽略。本文作者十分关注微服务日志记录,提出了独到的观点,并与大家分享关于微服务日志记录的各种技巧的最佳实践。 

微服务架构是一种软件架构类型,着重于利用大量细分组件进行应用开发,其中每个组件都负责整体业务中的一小部分。这些组件彼此独立,支持在自己的进程之上,且能够相互通信以实现业务目标。


为什么要关注日志记录?


很多企业都开始将整体型应用拆分为微服务形式。而在拆分大型应用时,我们需要建立松散耦合的模块,从而保证其便于测试并降低变更风险。另外,这些模块亦可独立部署以实现横向规模扩展。然而,这也会带来一些初看并不严重,但长远影响极其重大的问题——其中的典型代表就是日志记录。


日志记录存在于一切应用当中,无论其属于整体还是微服务架构。关键在于,当我们将应用拆分为微服务形式时,我们需要投入大量时间来思考业务边界并找寻最理想的应用逻辑拆分方式——但很少有人会对日志记录给予应有的重视。


当然,大家可能会问:日志记录的方式一直没有变化过,为什么现在倒成了需要关注的问题?


理由在于,整体应用内的事务追踪往往比较困难,有时候我们只能依靠日志记录来理解当前状况。另外,当业务逻辑运行在多项服务中时,监控与日志记录的难度也会相应增加。这意味着如果我们没有明智地规划出微服务记录机制,那么最终可能根本无法理解应用的当前运行状态。


正因为如此,我想与大家分享我的个人经验以及作为软件开发者积累到的一点心得。近年来我一直在使用微服务方案,希望大家能够在读完本文后意识到日志记录的重要性与实现难点。


心得一——设立应用实例标识符


在使用微服务时,整套体系往往会同一时间运行同一组件的多个实例。最重要的就是在日志条目中设立实例标识符,从而区分各条目的具体来源。其ID的具体生成方式其实并不重要,只要保证惟一即可,这样我们才能借此回溯到特定服务器/容器以及生成该条目的应用处。在微服务架构中,大家可以利用服务注册表轻松为每项服务分配惟一的标识符。


心得二——坚持使用UTC时间


这项心得不仅适用于微服务架构,在其它场景下也同样值得坚持。任何使用过分布式应用程序——或者组件分散在各处——的朋友,都会意识到各组件使用不同时区进行计时有多么令人头痛。而在微服务架构中,以本地时间记录的日志条目会带来更严重的问题。如果大家确实需要使用本地时间,请在日志条目中以字段形式添加时区,从而简化信息的检索方式。但更重要的是一定要为UTC时间设立时区,并利用它在聚合工具内进行信息排序。

下面来看示例日志信息:


1.PNG


第一部分是由一项运行在新西兰的服务所生成。第二部分则由运行在巴西的服务生成。由于我们使用本地日期,因此由巴西服务生成的信息会早于新西兰信息——但其实际生成时间却恰恰相反。


现在,让我们看看使用UTC时间与时区后的示例信息:


2.PNG



现在两条信息已经得到正确的时间排序,如果大家希望了解信息的本地生成时间,则可将其由UTC转换为特定时区。


心得三——生成请求标识符


在将业务逻辑拆分为多个不同组件时,我们的逻辑最终需要由一个或者多个组件构成。而在追踪这些事务时,我们往往很难对其加以识别。因此,大家应当为每个事务生成一个惟一标识符,并利用其关联事件以及追踪各项事务。


想象一下,如果我们需要利用以下请求序列在某电子商务网站上购买产品:

 
3.png


那么我们对于操作的分组方法,显然取决于事务的实际定义(毕竟其也能够进行嵌套)。最重要的是确保在事务开端,我们为其创建一个能够传递下去的标识符,并借此在事务结束之前全程记录日志条目。


一般来讲,我倾向于使用人工生成的ID来区分自己的事务。大家也可以使用user_id或者session_id处理与用户相关的事务。而在进行结算与支付时,大家可以使用order_id来追踪结算与付款操作。不过其前提是大家已经进行了用户登录,或者创建了拥有order_id的订单——但实际情况往往并非如此。在使用手动ID时,大家可以将事务ID从业务逻辑流中解耦出来。


另外需要注意的是,这些ID需要拥有足够的信息以对系统中的各项事务进行区分。有时候事务识别符可能在日志条目中体现为一整套字段组合。


心得四——利用聚合工具进行日志分组


如果大家没有对来自全部微服务的日志条目进行聚合,那么以上提到的心得将毫无意义。要实现这一目标,我们需要使用一款能够轻松实现条目分组与查询的工具。我个人使用ELK堆栈,其效果相当出色。如果大家之前没听过ELK,这里可以稍微解释几句。ELK是三款应用的集合体,由此构成的完整解决方案能够调度日志条目、实现条目存储与索引,而后对信息进行聚合与可视化处理。


我们可以利用ELK对应用程序日志进行多种规模伸缩与分发处理,但这里就不讲太多了。感兴趣的朋友可以查看Logz.io博客上的Logstash教程,其中提到了多项相关使用技巧。另外,我们也可以使用Logz.io等企业服务处理日志基础设施的设置与维护工作,从而确保自己的微服务体系采用最理想的日志记录实践方案。


总结

这篇文章的目的是向大家强调在微服务架构中重视日志记录的必要性,同时分享一些在实际应用当中积累到的最佳实践。但这仅仅是个开始,相信大家能够采用多种其它方式解决日志记录难题。

文章来源:Logz.io  作者  Lucas Saldanha

关于Docker 1.12中的最新功能,你需要了解这些

宁静胡同 发表了文章 • 0 个评论 • 401 次浏览 • 2016-06-28 10:46 • 来自相关话题

DockerCon已然落幕,留下了无数激动人心的声音。随着Docker1.12版本的发布,众多新功能新提升的出现,无疑将对Docker为中心的生态圈产生不小的影响。今天小数与大家看一看新版本对于存储层面都有哪些影响——



新版本的发布对存储层面来说,最值得关注的自然是分卷驱动器支持能力的强化。这些变更不仅能够使我们对分卷进行标记,从而明确其属于本地抑或全局可访问对象,同时也能够提供与可用分卷相关的驱动器具体信息。另外,1.12版本中还出现了众多提升及修复机制。很明显,部分变更将帮助Docker Swarm更好地完成规模化使命,甚至可以说这一规模化发展思路正是本届DockerCon大会的主旨所在。


值得关注的变化


支持分卷范围(本地/全局)#22077


虽然这一变更谈不到什么飞跃,但如今使用docker分卷(例如swarm)的各服务已经能够将可用分卷识别为本地(特定主机)或全局(全部主机)。过去,当我们在swarm管理器中运行“docker volume ls”时,所有可用于全部swarm代理的全局分卷都会在各主机上被分别列出。这使得我们很难据此构建起可扩展的Docker Swarm集群。现在,新的调整让我们得以轻松区分全局分卷与本地分卷。








支持分卷状态 #21006


过去,每个Docker分卷只包含分卷名称、驱动器名称、安装位置以及基本标签(如果使用)等信息。








而在1.12版本中,我们能够获取更多来自驱动器的各分卷细节信息(嵌套于Status下)。








其它变化


支持ZFS分卷大小 #21946


在1.12版本之前,我们无法强制指定ZFS分卷的大小,但现在已经可以通过“-storage-opts”实现。


支持利用BTRFS实现磁盘配额 #19651


如果利用BTRFS取代devicemapper作为默认docker文件系统,我们将能够为各独立docker容器设置最大大小或容量配额。


分卷名称/驱动器过滤 #21015


新版本提供的增强过滤机制适用于“docker volume”命令/api请求。这意味着我们可以获取更为具体的特定分卷名称信息,或者可由特定分卷驱动器访问的全部分卷。


为分卷安装/卸载请求匹配惟一ID #21015


当分卷安装/卸载请求被发送至分卷驱动器时,系统会同时生成一条惟一ID以确保驱动器对各请求加以追踪。如此一来,分卷驱动器就能够更好地识别安装与卸载请求。


SELinux用户迎来小幅修复 #17262


如果大家在自己的docker主机上使用SELinux,则#17262能够修复将本地目录附加至新容器时z/Z权限选项的使用方式。在原有版本中,由于新容器中不存在启动所需要的文件夹,因此直接附加会导致失败。


本文源自:EMC {code},作者 Chris Duchesne 查看全部
DockerCon已然落幕,留下了无数激动人心的声音。随着Docker1.12版本的发布,众多新功能新提升的出现,无疑将对Docker为中心的生态圈产生不小的影响。今天小数与大家看一看新版本对于存储层面都有哪些影响——



新版本的发布对存储层面来说,最值得关注的自然是分卷驱动器支持能力的强化。这些变更不仅能够使我们对分卷进行标记,从而明确其属于本地抑或全局可访问对象,同时也能够提供与可用分卷相关的驱动器具体信息。另外,1.12版本中还出现了众多提升及修复机制。很明显,部分变更将帮助Docker Swarm更好地完成规模化使命,甚至可以说这一规模化发展思路正是本届DockerCon大会的主旨所在。


值得关注的变化


支持分卷范围(本地/全局)#22077


虽然这一变更谈不到什么飞跃,但如今使用docker分卷(例如swarm)的各服务已经能够将可用分卷识别为本地(特定主机)或全局(全部主机)。过去,当我们在swarm管理器中运行“docker volume ls”时,所有可用于全部swarm代理的全局分卷都会在各主机上被分别列出。这使得我们很难据此构建起可扩展的Docker Swarm集群。现在,新的调整让我们得以轻松区分全局分卷与本地分卷。


1.png



支持分卷状态 #21006


过去,每个Docker分卷只包含分卷名称、驱动器名称、安装位置以及基本标签(如果使用)等信息。



2.png


而在1.12版本中,我们能够获取更多来自驱动器的各分卷细节信息(嵌套于Status下)。


3.png



其它变化


支持ZFS分卷大小 #21946


在1.12版本之前,我们无法强制指定ZFS分卷的大小,但现在已经可以通过“-storage-opts”实现。


支持利用BTRFS实现磁盘配额 #19651


如果利用BTRFS取代devicemapper作为默认docker文件系统,我们将能够为各独立docker容器设置最大大小或容量配额。


分卷名称/驱动器过滤 #21015


新版本提供的增强过滤机制适用于“docker volume”命令/api请求。这意味着我们可以获取更为具体的特定分卷名称信息,或者可由特定分卷驱动器访问的全部分卷。


为分卷安装/卸载请求匹配惟一ID #21015


当分卷安装/卸载请求被发送至分卷驱动器时,系统会同时生成一条惟一ID以确保驱动器对各请求加以追踪。如此一来,分卷驱动器就能够更好地识别安装与卸载请求。


SELinux用户迎来小幅修复 #17262


如果大家在自己的docker主机上使用SELinux,则#17262能够修复将本地目录附加至新容器时z/Z权限选项的使用方式。在原有版本中,由于新容器中不存在启动所需要的文件夹,因此直接附加会导致失败。


本文源自:EMC {code},作者 Chris Duchesne

智能运维 | 如何做好持续集成——Jenkins on Mesos 实践

宁静胡同 发表了文章 • 0 个评论 • 712 次浏览 • 2016-06-24 11:18 • 来自相关话题

今天小数给大家带来的又是十足的干货:当运维遇到云计算,当Docker遇到Mesos和Jenkins,会擦出怎样的火花呢?且看来自数人云运维工程师金烨的演讲实录分享——


持续集成的价值

首先讲一下持续集成的优势。过去公司做测试可能需要十几、二十几个组件,集成一次往往要一两个小时,费力费时,而且复杂容易出错,而一旦配置出错的话耗时会更久。因此,一次集成测试一周才会做一次,测出Bug要到下一周才能更新,再做测试,这个周期会非常漫长。而持续集成的意义就在于减少风险,和重复的过程,最终提高工作效率。

Docker

Docker是现在非常火的一门技术,使用Docker首先解决的是环境的问题。因为开发环境和运维的部署环境千奇百怪,依赖的环境和包各不一样。其次,Docker是可以实现更快速地交付和部署,只要写一个Dockerfile,把服务打成一个镜像,然后再迁移到各种服务器上就行了,部署的过程也非常方便,服务器只要有Docker的环境就可以运行。因为是内核级虚拟化解决方案,Docker利用的额外资源很少,同时,它的更新管理也非常容易,只需要把Dockerfile修改一两行,其他的服务器则不需要做改动,也不需要下载其它的安装依赖包,打好Docker镜像直接就可以部署镜像、直接运行。这些都是它的优势。

Mesos






Apache Mesos是一款开源集群管理软件。Mesos经过了Facebook,Twitter这些大型公司的万台主机验证,在国内,爱奇艺、去哪网,小米网等公司也拥有大规模的Mesos集群应用。Mesos实现了两级调度架构,可以管理多种类型的应用程序。第一级调度是Master的守护进程,管理Mesos集群中所有节点上运行的Slave守护进程。集群由物理服务器或虚拟服务器组成,用于运行应用程序的任务,比如Hadoop和MPI作业。第二级调度由被称作Framework的“组件”组成。Framework包括调度器(Scheduler)和执行器(Executor)进程,其中每个节点上都会运行执行器。Mesos能和不同类型的Framework通信,每种Framework由相应的应用集群管理。图中只展示了Hadoop和MPI两种类型,其它类型的应用程序也有相应的Framework。Mesos支持多种Framework,比如说Hadoop,Spark,Storm等等,各类型的Framework在它上面都可以运行。

Marathon

Marathon是Mesosphere为Mesos生态圈打造的一个轻量级管理服务APP框架,它可以用RESTful API方便地进行操作。

Marathon 协调应用和Frameworks

下图是在Marathon上发布各种的服务,它们都可以通过Marathon发到Mesos的集群资源中。






扩展和故障恢复

例如我们发了三个服务,分别是有一个节点的,三个节点的和五个节点的。

我们想拓展这些服务的话,可以调用Marathon的API进行扩展,秒级扩展到下图。

如果有一台主机宕掉了, Marathon会均匀地把服务迁移到其他的机器上,选择资源有空余的机器进行迁移。这样能就保证服务是动态的调度,保证服务的高可用,并且这些都是它内部自行处理的,不需要手动干预。

Jenkins

介绍

Jenkins是Java开发的一种持续集成的工具,我们在它的基础上做了一些重复的工作,比如版本发布、测试代码,以及调用外部接口。Jenkins支持很多插件,可以很方便地选择使用适合自己团队的插件工具。

问题

Jenkins为我们提供了便利,当然Jenkins本身也有它自己的问题,比如传统的Jenkins是单点的,任务大多是需要排队的,如果每个任务都自己建一套Jenkins的话,资源会非常浪费。为了解决这些问题,我们引入了Jenkins On Mesos。

Jenkins On Mesos

Jenkins 分为Master 节点和Slave 节点,Master 进行调度,Slave节点负责负责执行Job任务。

Jenkins master






首先我们把Jenkins的Master通过Marathon发布,Marathon 去调用 Mesos Master,之后Mesos Master再去Slave节点起Jenkins的Master。这个机制保证了Jenkins Master的高可用,Marathon会监控Jenkins Master的健康状态,当Jenkins Master出现崩溃挂掉,Marathon会自动再启动一个Jenkins Master的任务。Jenkins Master使用Mesos整个大的资源池,Mesos的资源池是一个资源共享的状态,资源利用率也会更高一些。

Jenkins Slave






Jenkins Master做的是调度,Jenkins Slave则是真正执行构建任务的地方。Jenkins Master会在Mesos Master上注册一个它自己的Framework,如果有任务需要构建的话,Jenkins Master 会通知 Jenkins Framework 调用 Mesos Master构建一个任务。之后Mesos Master 再调用 Mesos Slave去起一个Jenkins Slave的节点去构建任务,它是实时的,用户资源可能被分配到各个机器上,在不同的机器上并行存在。此外,Jenkins还具备动态调度功能,也就是说,当任务运行完后一定时间,资源会再返还给Mesos,实现合理地利用整个集群的资源,提高集群的资源利用率。

Mesos 整体流程






这张图是Mesos整体的调度流程。第一步,它的集群有三个Mesos Slave节点资源,资源上报到Mesos Master,Mesos Master收集到这些资源之后把这些资源再提供给Marathon,Marathon如果要发任务,它确认一个Offer1,Offer1足够任务来运行,就拒绝其他的Offer,并把这个任务发送给Mesos Master,之后Mesos Master去找Slave1起Marathon的任务。这是Marathon的任务启动过程。Mesos本身可以和多框架进行通信,Jenkins Master要跑一个任务,Mesos Master同样提供资源给Jenkins,提供的资源包括了Marathon 任务使用剩下的资源,比如Task1 确认的 Offer1没有用完和没有使用的资源,Mesos也会它提供给Jenkins。而Jenkins也会选择,比如Jenkins选择了Offer3,拒绝了其他的Offer,把Jenksin的任务再通过Mesos Master去Mesos Slave中起起来。

Jenkins On Mesos Docker化

Jenkins部署起来非常麻烦,需要安装各种依赖,如果代码是从Git上下载的,那么还需要安装一些Git包。而动态调度需要每台机器上都装这些依赖,为了解决这种问题,我们把服务全部进行了Docker化,主机上只需要有Docker环境就可以运行我们的服务。

遇到的坑

进行Docker化之后就会面临Docker化的问题,因为Docker和 Mesos都是比较新的技术,我们遇到了很多坑,也需要去解决。

我们遇到的第一个问题是Jenkinson Mesos需要调度Mesos的Lib库,如果Docker化之后是隔离的,就调不到Mesos Lib。

第二个问题是Docker化的数据,因为Jenkins是没有数据库的,数据都是存在本地的JENKINS_HOME目录中,如果Jenkins Master挂掉之后,相应的数据就没有了。

第三个问题是Jenkins需要升级,插件也需要升级,而镜像本身没办法自动升级。

解决

为了解决这些问题,首先我们将Mesos打成一个基础镜像,在这个基础镜像上安装Jenkins的服务制作成一个Jenkins的镜像,这样就可以调用Mesos的Lib库文件了。

第二是数据备份,我们在Jenkins上安装了一个插件,就是SCM Sync Configuration Plugin 这个插件,它会同步数据到Github。如果这个Jenkins Master挂掉了,迁移到另外一台主机上,它会从Github上面把数据克隆下来,数据是不会丢失的。此外,如果插件出了故障,或者因为网络问题导致Github访问不了,我们把JENKINS HOME目录挂在主机上进行备份,进行恢复的时候也会很方便。用以上这两点来保证数据的完整性。

第三对于Jenkins升级或其插件的升级,我们现在的做法是把它重新打一个镜像,重新在Mararhton发布Jenkins Master。

Jenkins Slave On Docker 工作流程






首先Jenkins Master如果要构建一个Job,让Mesos Slave起一个Jenkins Slave这样的容器,容器里面是没有Docker环境的,因为容器里面再装一个Docker环境就太重了。我们现在的做法是把Jenkins Slave用到的命令挂载,其中包括 /usr/bin/docker /var/lib/docker /sys/fs/cgroup /var/run/docker.sock ,这样在容器内部就可以操作主机上的Docker环境,Jenkins Slave 可以在容器内部进行一些Docker Build,Docker Run,Docker Push等工作。

Jenkins Job List






这是我们运维平台一些Job List,左下角是Mesos各个Slave的节点,每一个节点上都有任务,这些任务都是并行的。因为我们的服务模块比较多,可能一个模块一天提交十几次,这么多的模块在一天提交几十次或者上百次的情况也出现过。手动更新、构建的话是非常难做到的。现在,做成Jenkins 分布式执行Job的模式,一天构建几百上千次也没有问题,它会把构建的任务均匀的分布在主机资源里。

数人云运维平台持续集成实践






这是数人云运维平台的持续集成实践。首先讲几个组件,比如Github,它是存储代码的,第二个组件是我们自己开发了的一个Configserver的API,第三个组件是Jenkins和Marathon。第四个组件是我们的私有Registry,是Docker的一个存储镜像的镜像仓库。最右下角是CDN,安装包传送到达的地方。

首先Jenkins触发任务,Jenkins调用Configserver提供的API,这个API就去Github上获取最新代码的Tag,并对比现有的已经更新过的Tag。如果不需要更新,这个任务就完成了,结束了。如果需要更新的话,就进行第三步,把从Github拉的代码放到Configserver上,Jenkins Slave的节点会从Configserver去拉取代码到Slave的容器之中。把代码下载之后再去Pull一个我们编译环境的镜像,然后再用这个镜像去编译我们的代码。比如编译出来一个二进制代码,我们把这个二进制重新打一个运行时的镜像。这个Runtime镜像打好之后我们再使用Docker Push把它推到私有的Registry,镜像Push到Registry后,就可以发布到各种的环境,比如说Dev Demo生产环境,调用Marathon API直接发布就可以了。同样在Jenkins Slave,推完镜像之后就可以去调用。这样一个整体构建镜像再部署的任务就构建完成了。

如果有一些安装包,比如我们的Agent包,它不需要发布Marathon,需要上传到CDN,也是在Jenkins Slave 中执行的。

配置管理

问题

因为我们引入了Docker,而且是分布式动态调度的,传统的配置工具如Ansible、Puppet 、SaltStack都已经不适用了,没办法去管理Docker内部的东西。这些配置文件修改起来非常麻烦。

配置中心一期






讲一下如何进行配置的更新。首先我们做了一个配置中心的一期,把镜像嵌入自己的脚本,这个脚本实现的功能就是 根据传入的ENV CONFIG_SERVER和 SERVICE ,访问 Configserver的API,API返回的数据就是这个服务需要下载的配置文件的列表,以及它需要下载到哪个目录底下。Configserver也非常简单,起一个Nginx,去Vim手动修改。容器一重启,就会自动拉这些配置文件,把配置进行更新。

一期的问题

一期完成之后,因为是多种环境,如Dev Demo环境、预生产环境、生产环境等等,虽然把这些配置都在Configserver上集中配置,但还需要手动修改这些配置。手动修改容易出错,例如Dev更新了一个服务,可能过了一周才会更新到生产环境。那个时候再去修改生产就很容易出错,导致无法运行。此外,如果配置发生了Bug需要回滚,手动修改也是不合适的。

配置中心二期






为了解决这些问题,我们做了ConfigCenter的二期。其中有我们自己开发的一个运维平台,以及Github和Gitlab。Github是个存储项目的代码,Gitlab是用了存储配置模板和最终配置文件的。我们用Jenkins把它们整体的串起来,我们的第一个工作是把所有的配置文件抽象化,各种环境的文件抽象出来一个模板,放在Gitlab上。它的数据是放在数据库里面,这样组合起来是一个完整的配置文件。各个环境的值是不一样的。 我们的运维平台触发Jenkins,Jenkins去调度我们的ConfigCenter API,它传入两个参数,一个是需要更新的环境,第二个是更新哪个服务。之后API去做对比,从数据库去读现有的配置文件的模板Tag,再去读新模板的Tag进行对比。如果这个文件需要更新,把它从数据库拉过来,数据做匹配,渲染成我们最终的配置文件,再传到Gitlab上。剩下的通过Jenkins 触发 Configserver去调Gitlab下载最新的配置文件到Configserver服务器,Jenkins再去调用Marathon去重启服务,服务就会成功更新配置文件。

这里有两个需要注意的点,一方面模板需要更新,另一方面值要更新,这是两种模式。模板更新是所有的流程都要走一遍,如果模板没有更新,只是值更新的话,我们只需要在运维平台上做修改。修改的同时它会做一个标记,说明这个服务配置文件是需要更新的,之后就会生成一个最新的配置继续下面的操作。如果这两个都不需要更新的话就返回,不再操作。

今天的分享就到此为止,谢谢大家。

  查看全部


今天小数给大家带来的又是十足的干货:当运维遇到云计算,当Docker遇到Mesos和Jenkins,会擦出怎样的火花呢?且看来自数人云运维工程师金烨的演讲实录分享——



持续集成的价值

首先讲一下持续集成的优势。过去公司做测试可能需要十几、二十几个组件,集成一次往往要一两个小时,费力费时,而且复杂容易出错,而一旦配置出错的话耗时会更久。因此,一次集成测试一周才会做一次,测出Bug要到下一周才能更新,再做测试,这个周期会非常漫长。而持续集成的意义就在于减少风险,和重复的过程,最终提高工作效率。

Docker

Docker是现在非常火的一门技术,使用Docker首先解决的是环境的问题。因为开发环境和运维的部署环境千奇百怪,依赖的环境和包各不一样。其次,Docker是可以实现更快速地交付和部署,只要写一个Dockerfile,把服务打成一个镜像,然后再迁移到各种服务器上就行了,部署的过程也非常方便,服务器只要有Docker的环境就可以运行。因为是内核级虚拟化解决方案,Docker利用的额外资源很少,同时,它的更新管理也非常容易,只需要把Dockerfile修改一两行,其他的服务器则不需要做改动,也不需要下载其它的安装依赖包,打好Docker镜像直接就可以部署镜像、直接运行。这些都是它的优势。

Mesos

mesos1.jpg


Apache Mesos是一款开源集群管理软件。Mesos经过了Facebook,Twitter这些大型公司的万台主机验证,在国内,爱奇艺、去哪网,小米网等公司也拥有大规模的Mesos集群应用。Mesos实现了两级调度架构,可以管理多种类型的应用程序。第一级调度是Master的守护进程,管理Mesos集群中所有节点上运行的Slave守护进程。集群由物理服务器或虚拟服务器组成,用于运行应用程序的任务,比如Hadoop和MPI作业。第二级调度由被称作Framework的“组件”组成。Framework包括调度器(Scheduler)和执行器(Executor)进程,其中每个节点上都会运行执行器。Mesos能和不同类型的Framework通信,每种Framework由相应的应用集群管理。图中只展示了Hadoop和MPI两种类型,其它类型的应用程序也有相应的Framework。Mesos支持多种Framework,比如说Hadoop,Spark,Storm等等,各类型的Framework在它上面都可以运行。

Marathon

Marathon是Mesosphere为Mesos生态圈打造的一个轻量级管理服务APP框架,它可以用RESTful API方便地进行操作。

Marathon 协调应用和Frameworks

下图是在Marathon上发布各种的服务,它们都可以通过Marathon发到Mesos的集群资源中。

marathon1.png


扩展和故障恢复

例如我们发了三个服务,分别是有一个节点的,三个节点的和五个节点的。

我们想拓展这些服务的话,可以调用Marathon的API进行扩展,秒级扩展到下图。

如果有一台主机宕掉了, Marathon会均匀地把服务迁移到其他的机器上,选择资源有空余的机器进行迁移。这样能就保证服务是动态的调度,保证服务的高可用,并且这些都是它内部自行处理的,不需要手动干预。

Jenkins

介绍

Jenkins是Java开发的一种持续集成的工具,我们在它的基础上做了一些重复的工作,比如版本发布、测试代码,以及调用外部接口。Jenkins支持很多插件,可以很方便地选择使用适合自己团队的插件工具。

问题

Jenkins为我们提供了便利,当然Jenkins本身也有它自己的问题,比如传统的Jenkins是单点的,任务大多是需要排队的,如果每个任务都自己建一套Jenkins的话,资源会非常浪费。为了解决这些问题,我们引入了Jenkins On Mesos。

Jenkins On Mesos

Jenkins 分为Master 节点和Slave 节点,Master 进行调度,Slave节点负责负责执行Job任务。

Jenkins master

jenkins_master.png


首先我们把Jenkins的Master通过Marathon发布,Marathon 去调用 Mesos Master,之后Mesos Master再去Slave节点起Jenkins的Master。这个机制保证了Jenkins Master的高可用,Marathon会监控Jenkins Master的健康状态,当Jenkins Master出现崩溃挂掉,Marathon会自动再启动一个Jenkins Master的任务。Jenkins Master使用Mesos整个大的资源池,Mesos的资源池是一个资源共享的状态,资源利用率也会更高一些。

Jenkins Slave

jenkins_slave.png


Jenkins Master做的是调度,Jenkins Slave则是真正执行构建任务的地方。Jenkins Master会在Mesos Master上注册一个它自己的Framework,如果有任务需要构建的话,Jenkins Master 会通知 Jenkins Framework 调用 Mesos Master构建一个任务。之后Mesos Master 再调用 Mesos Slave去起一个Jenkins Slave的节点去构建任务,它是实时的,用户资源可能被分配到各个机器上,在不同的机器上并行存在。此外,Jenkins还具备动态调度功能,也就是说,当任务运行完后一定时间,资源会再返还给Mesos,实现合理地利用整个集群的资源,提高集群的资源利用率。

Mesos 整体流程

jenkins_on_mesos.png


这张图是Mesos整体的调度流程。第一步,它的集群有三个Mesos Slave节点资源,资源上报到Mesos Master,Mesos Master收集到这些资源之后把这些资源再提供给Marathon,Marathon如果要发任务,它确认一个Offer1,Offer1足够任务来运行,就拒绝其他的Offer,并把这个任务发送给Mesos Master,之后Mesos Master去找Slave1起Marathon的任务。这是Marathon的任务启动过程。Mesos本身可以和多框架进行通信,Jenkins Master要跑一个任务,Mesos Master同样提供资源给Jenkins,提供的资源包括了Marathon 任务使用剩下的资源,比如Task1 确认的 Offer1没有用完和没有使用的资源,Mesos也会它提供给Jenkins。而Jenkins也会选择,比如Jenkins选择了Offer3,拒绝了其他的Offer,把Jenksin的任务再通过Mesos Master去Mesos Slave中起起来。

Jenkins On Mesos Docker化

Jenkins部署起来非常麻烦,需要安装各种依赖,如果代码是从Git上下载的,那么还需要安装一些Git包。而动态调度需要每台机器上都装这些依赖,为了解决这种问题,我们把服务全部进行了Docker化,主机上只需要有Docker环境就可以运行我们的服务。

遇到的坑

进行Docker化之后就会面临Docker化的问题,因为Docker和 Mesos都是比较新的技术,我们遇到了很多坑,也需要去解决。

我们遇到的第一个问题是Jenkinson Mesos需要调度Mesos的Lib库,如果Docker化之后是隔离的,就调不到Mesos Lib。

第二个问题是Docker化的数据,因为Jenkins是没有数据库的,数据都是存在本地的JENKINS_HOME目录中,如果Jenkins Master挂掉之后,相应的数据就没有了。

第三个问题是Jenkins需要升级,插件也需要升级,而镜像本身没办法自动升级。

解决

为了解决这些问题,首先我们将Mesos打成一个基础镜像,在这个基础镜像上安装Jenkins的服务制作成一个Jenkins的镜像,这样就可以调用Mesos的Lib库文件了。

第二是数据备份,我们在Jenkins上安装了一个插件,就是SCM Sync Configuration Plugin 这个插件,它会同步数据到Github。如果这个Jenkins Master挂掉了,迁移到另外一台主机上,它会从Github上面把数据克隆下来,数据是不会丢失的。此外,如果插件出了故障,或者因为网络问题导致Github访问不了,我们把JENKINS HOME目录挂在主机上进行备份,进行恢复的时候也会很方便。用以上这两点来保证数据的完整性。

第三对于Jenkins升级或其插件的升级,我们现在的做法是把它重新打一个镜像,重新在Mararhton发布Jenkins Master。

Jenkins Slave On Docker 工作流程

jenkins_slave_docker.png


首先Jenkins Master如果要构建一个Job,让Mesos Slave起一个Jenkins Slave这样的容器,容器里面是没有Docker环境的,因为容器里面再装一个Docker环境就太重了。我们现在的做法是把Jenkins Slave用到的命令挂载,其中包括 /usr/bin/docker /var/lib/docker /sys/fs/cgroup /var/run/docker.sock ,这样在容器内部就可以操作主机上的Docker环境,Jenkins Slave 可以在容器内部进行一些Docker Build,Docker Run,Docker Push等工作。

Jenkins Job List

jenkins_job_list.png


这是我们运维平台一些Job List,左下角是Mesos各个Slave的节点,每一个节点上都有任务,这些任务都是并行的。因为我们的服务模块比较多,可能一个模块一天提交十几次,这么多的模块在一天提交几十次或者上百次的情况也出现过。手动更新、构建的话是非常难做到的。现在,做成Jenkins 分布式执行Job的模式,一天构建几百上千次也没有问题,它会把构建的任务均匀的分布在主机资源里。

数人云运维平台持续集成实践

sryci.png


这是数人云运维平台的持续集成实践。首先讲几个组件,比如Github,它是存储代码的,第二个组件是我们自己开发了的一个Configserver的API,第三个组件是Jenkins和Marathon。第四个组件是我们的私有Registry,是Docker的一个存储镜像的镜像仓库。最右下角是CDN,安装包传送到达的地方。

首先Jenkins触发任务,Jenkins调用Configserver提供的API,这个API就去Github上获取最新代码的Tag,并对比现有的已经更新过的Tag。如果不需要更新,这个任务就完成了,结束了。如果需要更新的话,就进行第三步,把从Github拉的代码放到Configserver上,Jenkins Slave的节点会从Configserver去拉取代码到Slave的容器之中。把代码下载之后再去Pull一个我们编译环境的镜像,然后再用这个镜像去编译我们的代码。比如编译出来一个二进制代码,我们把这个二进制重新打一个运行时的镜像。这个Runtime镜像打好之后我们再使用Docker Push把它推到私有的Registry,镜像Push到Registry后,就可以发布到各种的环境,比如说Dev Demo生产环境,调用Marathon API直接发布就可以了。同样在Jenkins Slave,推完镜像之后就可以去调用。这样一个整体构建镜像再部署的任务就构建完成了。

如果有一些安装包,比如我们的Agent包,它不需要发布Marathon,需要上传到CDN,也是在Jenkins Slave 中执行的。

配置管理

问题

因为我们引入了Docker,而且是分布式动态调度的,传统的配置工具如Ansible、Puppet 、SaltStack都已经不适用了,没办法去管理Docker内部的东西。这些配置文件修改起来非常麻烦。

配置中心一期

cfgcenter1.png


讲一下如何进行配置的更新。首先我们做了一个配置中心的一期,把镜像嵌入自己的脚本,这个脚本实现的功能就是 根据传入的ENV CONFIG_SERVER和 SERVICE ,访问 Configserver的API,API返回的数据就是这个服务需要下载的配置文件的列表,以及它需要下载到哪个目录底下。Configserver也非常简单,起一个Nginx,去Vim手动修改。容器一重启,就会自动拉这些配置文件,把配置进行更新。

一期的问题

一期完成之后,因为是多种环境,如Dev Demo环境、预生产环境、生产环境等等,虽然把这些配置都在Configserver上集中配置,但还需要手动修改这些配置。手动修改容易出错,例如Dev更新了一个服务,可能过了一周才会更新到生产环境。那个时候再去修改生产就很容易出错,导致无法运行。此外,如果配置发生了Bug需要回滚,手动修改也是不合适的。

配置中心二期

cfgcenter2.png


为了解决这些问题,我们做了ConfigCenter的二期。其中有我们自己开发的一个运维平台,以及Github和Gitlab。Github是个存储项目的代码,Gitlab是用了存储配置模板和最终配置文件的。我们用Jenkins把它们整体的串起来,我们的第一个工作是把所有的配置文件抽象化,各种环境的文件抽象出来一个模板,放在Gitlab上。它的数据是放在数据库里面,这样组合起来是一个完整的配置文件。各个环境的值是不一样的。 我们的运维平台触发Jenkins,Jenkins去调度我们的ConfigCenter API,它传入两个参数,一个是需要更新的环境,第二个是更新哪个服务。之后API去做对比,从数据库去读现有的配置文件的模板Tag,再去读新模板的Tag进行对比。如果这个文件需要更新,把它从数据库拉过来,数据做匹配,渲染成我们最终的配置文件,再传到Gitlab上。剩下的通过Jenkins 触发 Configserver去调Gitlab下载最新的配置文件到Configserver服务器,Jenkins再去调用Marathon去重启服务,服务就会成功更新配置文件。

这里有两个需要注意的点,一方面模板需要更新,另一方面值要更新,这是两种模式。模板更新是所有的流程都要走一遍,如果模板没有更新,只是值更新的话,我们只需要在运维平台上做修改。修改的同时它会做一个标记,说明这个服务配置文件是需要更新的,之后就会生成一个最新的配置继续下面的操作。如果这两个都不需要更新的话就返回,不再操作。

今天的分享就到此为止,谢谢大家。

 

Docker Swarm系列第二部:重新调度Redis

宁静胡同 发表了文章 • 0 个评论 • 342 次浏览 • 2016-06-16 10:48 • 来自相关话题

欢迎回来,我们继续本系列的第二篇教程。今天我们将主要关注[Redis](http://shurenyun.com),希望大家还记得第一部分的主要内容——了解如何安装我们将要使用的环境。

传送门: Docker Swarm系列第一部:利用Flocker部署多节点Cassandra集群

在发生节点故障时利用Swarm对Redis服务器进行重新调度

如果大家认真阅读了第一部分,应该记得我们在Swarm部署中使用了--experimental标记。其中包括Swarm 1.1.0中的一项功能——在节点故障时对容器进行重新调度。

今天,我们将关注如何部署Redis容器并测试当前实验性重新调度功能的当前状态。

注意:重新调度尚处于实验阶段,其中存在bug。我们将在示例过程中的对应位置提醒大家可能出现的bug。

如果大家希望在Swarm主机发生故障时对容器进行重新调度,则需要在容器部署中使用特定标记。作为可行方案之一,我们可以使用以下标记:--restart=always -e reschedule:on-node-failure或者类似于-l 'com.docker.swarm.reschedule-policy=["on-node-failure"]'的标签。以下示例将使用环境变量方法。

首先,我们使用重新调度标记与由Flocker管理的分卷进行Redis容器部署。








接下来,利用SSH接入Docker主机内的Redis容器运行位置,并查看Redis始终使用的appendonly.aof文件内容。该文件应当位于Flocker分卷中,作为容器起始点存在且不包含任何数据。








然后接入Redis服务器并添加一些键/值对。而后,再次查看appendonly.aof文件内容以确保Redis以正确方式存储数据。








在Flocker分卷中查看数据以验证Redis正确运行。








测试故障转移

现在我们将测试故障转移场景,确保我们的Flocker分卷能够将存储在Redis中的数据正确迁移至Swarm重新调度容器的新Docker主机上。

要实现这一目标,我们在Swarm管理器中指定Docker,并利用docker events命令监控各项事件。

要开始测试,首先在运行有Redis容器的Docker主机上运行shutdown -h now以模拟节点故障。大家应该看到与该节点及容器相关的各项事件。

这些事件在告知我们,该容器及其资源由于遭遇故障(包括网络与分卷)需要被移除、断开连接或者卸载。我们看到的事件如下:

Container Kill
Container Die
Network Disconnect
Swarm Engine Disconnect
Volume Unmount
Container Stop  








在Docker主机关闭一段时间之后,大家应该会最终看到故障容器正在进行重新调度(即重新创建)。在这里需要提醒的是,在测试中我们发现Swarm 1.1.3版本中仍然存在问题,即其仍然会在被创建在新Docker主机上的容器中运行 Start 。

大家应该会在查看到Create事件记录的同时发现docker events,而后者的作用是对容器重建以及Flocker分卷移动进行初始化。

我们发现,大家可能需要在重新调度完成后,在新主机上手动Start该容器。

注意:容器创建过程中存在一些问题,但在测试中我们并未在容器启动时发现问题。

此事件代表着我们的容器已经经过重新调度并自动创建于新的Docker主机之上。请注意,最新信息中的IP地址发生了变化,这是因为容器被调度到了新的Docker主机中。








回顾

下面来看流程回顾:









如果我们对Swarm运行docker ps,则会看到该Redis容器为Created。在这种情况下,我们可以手动进行启动,而Redis也将恢复并运行在新节点上。

 








下面接入该Redis服务器以确保我们添加的数据仍然存在。







数据仍然存在!不过考虑到重新调度情况,我们不建议大家直接使用这些数据。

在测试当中,大部分用户反映容器能够在新节点上正常启动。但也确实有部分用户指出重新调度机制并未生效,或者是在Docker主机恢复后出现了两套容器。无论如何,工作当中显然还存在着问题,而社区的作用也正在于此——帮助测试、报告并修复这些问题,从而确保其运行效果更为可靠。 查看全部
欢迎回来,我们继续本系列的第二篇教程。今天我们将主要关注[Redis](http://shurenyun.com),希望大家还记得第一部分的主要内容——了解如何安装我们将要使用的环境。

传送门: Docker Swarm系列第一部:利用Flocker部署多节点Cassandra集群

在发生节点故障时利用Swarm对Redis服务器进行重新调度

如果大家认真阅读了第一部分,应该记得我们在Swarm部署中使用了--experimental标记。其中包括Swarm 1.1.0中的一项功能——在节点故障时对容器进行重新调度。

今天,我们将关注如何部署Redis容器并测试当前实验性重新调度功能的当前状态。

注意:重新调度尚处于实验阶段,其中存在bug。我们将在示例过程中的对应位置提醒大家可能出现的bug。

如果大家希望在Swarm主机发生故障时对容器进行重新调度,则需要在容器部署中使用特定标记。作为可行方案之一,我们可以使用以下标记:--restart=always -e reschedule:on-node-failure或者类似于-l 'com.docker.swarm.reschedule-policy=["on-node-failure"]'的标签。以下示例将使用环境变量方法。

首先,我们使用重新调度标记与由Flocker管理的分卷进行Redis容器部署。


1.PNG



接下来,利用SSH接入Docker主机内的Redis容器运行位置,并查看Redis始终使用的appendonly.aof文件内容。该文件应当位于Flocker分卷中,作为容器起始点存在且不包含任何数据。


2.PNG



然后接入Redis服务器并添加一些键/值对。而后,再次查看appendonly.aof文件内容以确保Redis以正确方式存储数据。


3.PNG



在Flocker分卷中查看数据以验证Redis正确运行。


4.PNG



测试故障转移

现在我们将测试故障转移场景,确保我们的Flocker分卷能够将存储在Redis中的数据正确迁移至Swarm重新调度容器的新Docker主机上。

要实现这一目标,我们在Swarm管理器中指定Docker,并利用docker events命令监控各项事件。

要开始测试,首先在运行有Redis容器的Docker主机上运行shutdown -h now以模拟节点故障。大家应该看到与该节点及容器相关的各项事件。

这些事件在告知我们,该容器及其资源由于遭遇故障(包括网络与分卷)需要被移除、断开连接或者卸载。我们看到的事件如下:

Container Kill
Container Die
Network Disconnect
Swarm Engine Disconnect
Volume Unmount
Container Stop  


55.jpg



在Docker主机关闭一段时间之后,大家应该会最终看到故障容器正在进行重新调度(即重新创建)。在这里需要提醒的是,在测试中我们发现Swarm 1.1.3版本中仍然存在问题,即其仍然会在被创建在新Docker主机上的容器中运行 Start 。

大家应该会在查看到Create事件记录的同时发现docker events,而后者的作用是对容器重建以及Flocker分卷移动进行初始化。

我们发现,大家可能需要在重新调度完成后,在新主机上手动Start该容器。

注意:容器创建过程中存在一些问题,但在测试中我们并未在容器启动时发现问题。

此事件代表着我们的容器已经经过重新调度并自动创建于新的Docker主机之上。请注意,最新信息中的IP地址发生了变化,这是因为容器被调度到了新的Docker主机中。


6.PNG



回顾

下面来看流程回顾:


00.jpg




如果我们对Swarm运行docker ps,则会看到该Redis容器为Created。在这种情况下,我们可以手动进行启动,而Redis也将恢复并运行在新节点上。

 

7.PNG




下面接入该Redis服务器以确保我们添加的数据仍然存在。

8.PNG



数据仍然存在!不过考虑到重新调度情况,我们不建议大家直接使用这些数据。

在测试当中,大部分用户反映容器能够在新节点上正常启动。但也确实有部分用户指出重新调度机制并未生效,或者是在Docker主机恢复后出现了两套容器。无论如何,工作当中显然还存在着问题,而社区的作用也正在于此——帮助测试、报告并修复这些问题,从而确保其运行效果更为可靠。

圆桌论坛实录 | 从容器生态圈解析容器之热现象

宁静胡同 发表了文章 • 0 个评论 • 223 次浏览 • 2016-06-08 15:33 • 来自相关话题

5月26日,数人云产品战略发布会在北京万达索菲特酒店举行,发布会最后一个环节圆桌论坛可谓大咖云集,小数为大家在第一时间带来了实录分享,快来感受下容器生态圈的激情碰撞吧——






主持人:谢乐冰 数人云COO

圆桌嘉宾:

王雷 央视网(CNTV)运维总监

刘少壮 环信联合创始人&CTO

华琨 UCloud 联合创始人&COO

王瑞琳 EasyStack联合创始人&COO

张峻 VMware 中国先进技术中心主任

陈昱 云启资本 VP

EasyStack:物理机、虚拟机和容器的兼容整合

谢乐冰:各位好,今天我们讲讲干货。第一位我想有请EasyStack的王总回答,容器在2015年变成了和OpenStack一样火的技术,前一阵的奥斯汀OpenStack大会上也有很多关于容器的议题。我的第一个问题是,您认为对于一个完整的数据中心操作系统来说,用物理机跑原生Docker与通过OpenStack跑Docker有什么区别?

王瑞琳:今年的奥斯汀OpenStack峰会做了一次OpenStack用户调查,根据调查结果,在OpenStack用户关注的技术里,容器技术排在首位。你提的这个问题排在第三位,它们是客户最关注三大问题中的两个。

我认为OpenStack跟容器技术解决的是不同的问题,容器解决的是应用的高并发管理、CI/CD、快速发布,也就是说,它是更面向应用的。然而,OpenStack是要解决的是云数据中心层面的问题。从云数据中心的两个维度去看,第一它向下加强各种硬件的管理,向上支持数据中心各种业务场景。所以从这两点上看,OpenStack更多的是面向基础设施,而容器则是面向应用的,这两个技术本身互不矛盾,这也是为什么OpenStack峰会对容器的关注已经持续很多年,在去年东京的峰会上容器也是OpenStack整个峰会的热点之一。

最近两届的OpenStack峰会对容器的关注点也越来越多地集中在容器和OpenStack集成的应用场景实现上,刚刚Mesos国外的专家也谈到,Mesos也好、Kubernetes也好,它们要管理越来越多不同类型的容器。同样,OpenStack在数据中心控制层面也要解决不同场景的应用,一般来说大家谈到OpenStack对于容器的支持,大多集中在虚拟机上。但是作为数据中心的总控,OpenStack要管理的对象除了虚拟机,也有容器,还有物理机。OpenStack有一个主件叫Ironic,它可以管理裸机,并在上面部署容器。所以OpenStack和容器技术并不是矛盾体,它们是兼容并整合的关系。

VMware:容器与虚拟化在一起会更好

谢乐冰:对于一个完整的数据中心操作系统来说,IaaS负责基础架构层面的服务,PaaS则偏重应用层面。第二个问题是我们与客户沟通过程中经常遇到的一个问题,也就是说,我们是不是把容器当成虚拟机在使用。VMware有一个非常完整的支撑容器的基础架构,可以非常好地把容器当作虚拟机。而现在IaaS和PaaS之间的界限越来越模糊,从长期来看,作为一个全球领先的IaaS厂商,VMware认为,IaaS是否也有可能进入schedule调度,甚至进入微服务这个层面?

张峻:刚刚主持人提到一点,容器作为虚拟机是可以的,但是现在在微服务化场景下把容器当成虚拟机使用并不合适。因为我们希望它能够切得更小,然后每一个微服务都通过容器来实现。容器跟虚拟化是解决不同问题的,从这一点来看与OpenStack有相似之处,我认为虚拟化解决的一个重大问题是隔离和安全的问题,而容器则解决的是快速交付的问题。所以它们并不矛盾,只是解决的问题分别在IaaS和PaaS两个层次上。所以我的想法是虚拟化和容器技术在一起会更好,因为它们是解决不同的问题,在一起的好处是同时解决了容器技术潜在的安全性和隔离性的问题。众所周知,容器都是基于共享内核的,是有一定程度上的安全问题,因为容器潜在的特性是共享的。所以,想要同时兼具安全性并做到快速交付,就可以在下层使用虚拟机,并在它的上面搭容器。所以基于这样的想法,不管用户之前是否使用vSphere,我们都有很好的产品解决方案去应对各种业务场景。

同时在虚拟机上面搭建容器的另一个好处是从运维方面,大家可以把容器和虚拟机在统一的管理平台上一同进行管理,把所有未容器化的应用与现在已经容器化的应用统一管理起来,大大提高便利性。同时也可以应用一些虚拟化比较成熟的技术,包括容器的HA、容器的热迁移,现在也都具备一些初步的方案。但是企业需要的是成熟的方案,比如说数人云选择了Mesos技术,而不是Kubernetes,就是因为Mesos相对来说更为成熟。对于企业来说,成熟稳定是非常重要的,因而用虚拟化成熟的下层IaaS解决方案再加上上层的容器技术的便利快捷,是一个非常好的组合。

UCloud:自然过渡的混合云时代

谢乐冰:在我们接触的企业中,互联网公司的大部分应用还处于云就绪状态,云原生应用还不是特别多。在这种情况下,我们认为IaaS可以解决底层网络和存储的大部分问题,可以帮助企业平滑上云。我们在给客户做方案的过程中意识到,未来向公有云延伸非常需要协同的能力,如今,容器技术越来越被认为是一种云端应用交付的标准手段,UCloud是国内领先的公有云公司,华琨总您认为容器技术会给公有云带来怎样的新机遇?

华琨:就像前面嘉宾说的,Docker是面向应用的、一种非常灵活的场景,我非常认同张总所说的,应该把容器和虚拟化技术结合在一起。有越来越多的用户找到我们,表示非常想在公有云上使用容器,这样做面临以下几个问题:首先是便利性,VM与IaaS的关系更密切,VM有一个好处就是管理起来很方便,同时它也很符合广大工程师的使用习惯。但是现在,大家的兴趣点和很多的应用场景都在Docker上,那么首当其冲要去解决的就是管理上的便利性,需要解决外网访问的问题,并结合VM的隔离安全性。

另外,容器技术还需要结合IaaS的其它优势。公有云厂商在资源的管理调度上做了大量工作,在资源的提供上具有很大的优势。我们很早就在VM层面实现了热迁移,可以在业务无感知的情况下把一个VM迁移到另外一个位置上。同样的技术我们也可以应用到Docker上,包括向其他产品提供负载均衡,在Docker环境下,这也是一个非常典型的场景。如何将这两个技术进行结合,让整体的可视化管理做的更好,这些都是公有云厂商擅长的领域。我们想把它们更好的结合起来,让广大的用户可以不用去关注底层技术细节。当然,原理的学习是一回事,实践起来的话还是会有很多的门槛,而这些都可以通过公有云的一些专业技术去实现。我们希望让用户更多地去享受Docker技术所带来的应用场景的便利性,这是我们想去做的一件非常重要的事情。

谢乐冰:华总,您认为混合云的时代会在什么时候到来呢,现在已经有一些什么样的实例?

华琨:我们认为,混合云的混合有很多种,包括公有云和私有云的混合,物理机和虚拟机的混合,甚至是IaaS和PaaS的混合。在我们看来,这些都已经有很多的应用场景了,其中,我们在五年前就推出了物理机和虚拟机的混合,并受到了用户的欢迎,有一些用户出于使用习惯或者设备的限制选择了混合云,我们为他们提供了一个兼容的方案。整个云计算的发展也是这样的一个过程,用户需要慢慢地接受,因而有很多的应用场景在兼容。实际上,公有云厂商也在做更多的兼容过渡方案,去匹配这当中五到十年的各种应用场景的过渡。公有云和私有云的结合推动打通了各种层面的VPC,这是非常实用的,我觉得这也是非常合理的。尤其在中国,很多的场景都需要混合云来解决,否则问题就会僵持不下。我想这种混合,在未来会越来越多地体现在IaaS跟PaaS融合的方面。

CNTV:企业级客户对容器的需求和探索

谢乐冰:刚才三位是我们的IaaS合作伙伴,我们看到不管是单独用PaaS,或者IaaS+PaaS,最后的目标都是让客户不用再去特别关心底层实现,而是说哪一种方案最能达到目标就选哪种。下面我们会有几个比较难的话题,这个话题落到使用者身上——CNTV的王总身上,CNTV是一个既代表互联网,又跨广电的企业,在容器和相应的PaaS技术落地过程中,我们都有哪些应用场景,碰到了哪些问题?例如这个流程需不需要变化,软件代码需不需要更改等等?

王雷:刚才几位嘉宾是属于这个行业的从业人员,我是属于使用者,属于企业用户。CNTV的中文名字叫中国网络电视台,另外一个名称叫央视网。我们其实是两个牌子,都属于中央电视台的网络传播中心,同时也是中央电视台的新媒体传播机构。从归属上大家可以看到,既然是中央电视台的新媒体传播机构,同时也是国家重点新闻网站,所以我们对安全性的要求非常高。而且每年伴随央视很多的重大的活动,包括每年的春晚、即将召开的今年的欧洲杯、奥运会,我们都会在新媒体层面大力地进行宣传报道。

我们虽然是一个比较偏向于传统媒体的新媒体公司,但是我们对整个行业、新技术非常关注。自从Docker诞生,我们一直都很关注,但是因为Docker那时不够成熟,所以我们基本上还属于观望。从去年我们开始测试Docker平台,经过大概一年多的测试,我们也发现了一些现阶段的需求,比如CI/CD。我是负责公司运维平台的,运维和开发是一对矛盾体,开发者有要求,但我们公司对运维和保障的要求更高。在使用Docker一段时间之后,我们发现开发和运维之间不像以前那么矛盾,通过CI/CD让大家看到这个东西其实是非常好用的。

另外,我们更关注的问题集中在很多的重大活动、重大赛事上,包括春晚这种传统活动。所以我们对弹性,对支撑能力的要求是非常高的。因为在重大活动期间,突发访问可能一下子会增加到平常的十倍、甚至百倍,Docker的弹性和快速扩展满足了我们的需求。通过一段时间的测试,我们现在基本上已经确定会把一些前端的业务逐渐往Docker上转移。现在我们接口层的一些业务,包括一些传统服务已经在Docker上运行,效果非常好,同时我们也在测试在Docker上跑Hadoop,但是这涉及到很多缓存层、中间层的系统,可能我们还要更慎重一些。

我认为现在Docker还有很多不完善的地方,包括监控层面还有安全层面,也包括刚才海外的Mesos专家说的整个调试方面的一些问题,这些我们都是很关注的。比如我的集群上跑了很多业务,但是哪个容器出现问题了导致这个平台的效率变得非常低下,能否及时发现问题并把它踢出去,是我们所关注的。但是这种技术确实已经在很多方面对我们有所帮助,所以我们选择逐渐容器化。因为从另外一个层面来说,做好容器化的同时,我们也在用大量的虚拟化技术,它使我们整个企业可以节省更多的硬件设备开销,更多地地提高资源使用率,这个也是每个企业都希望的。

谢乐冰:还有一个小问题,过去我认为虚拟化是非常简单的事情,但是实际上我发现各个企业也是做了一些相应的流程,甚至也有一些软件技术层面的改造工作,您预计未来容器+PaaS对于开发部门来说会有什么样的变化?

王雷:我认为这是一个趋势,很多新技术改变了人们的观念和操作方式,只有不断地适应才能更好地做好本职的工作。不管是对个人还是对于企业,只要能提高效率,能有更大的产能,大家都是十分乐意的。有很多的业务的改变需要很长时间,我认为从新业务上我们可能会从架构层面就开始规划,可以容器化的就直接做这样的改变。

环信:IT服务商的企业定制与术业专攻

谢乐冰:我们与客户沟通的时候,大家会经常问一个问题,你们是一家做容器的公司,那么,什么是容器的公司?只说是做容器的公司就像说自己是一家做JAVA的公司一样,等于什么都没有说。做容器的公司要解决的是,容器在生产环境上的大规模运行,并给企业提供上云的最佳实践,这才叫一个做容器的公司。不管是做IaaS还是做PaaS的公司,我们做的所有事情实际上都是一起帮助企业的整个IT架构向云端迁移。下面一个话题谈到怎么挣钱这个问题,环信是行业内领先的PaaS公司,是一家为数不多能从互联网公司身上赚到IT服务费的公司。为互联网提供IT服务是一个非常难的事情,不管是互联网公司还是大中型企业都涉及到一个定制问题,一定程度上大家认为定制是非常合理的,因为每个企业的流程是不一样的。所以我想请问一下刘总,你们是如何解决这个问题的?

刘少壮:环信是这样考虑定制这个事情的,首先我们做的产品是即时通讯云和移动客服。我们的目标是PaaS和SaaS的方向,这个选择决定了我们不会做太多的定制。但是做企业服务,尤其是像做移动互联网企业的企业服务,每一家企业都有不同的业务流程和业务需求。比如说我们的移动客服,或者说往更下层的容器技术,再比如说数人云提供的PaaS平台服务,或者是像UCloud提供的IaaS服务,都要满足企业各种不同的需求。

从环信的角度来讲,第一,要通过我们的产品设计和技术手段来保证系统的开放性,同时要更加灵活地提供所有的API和SDK,在系统设计之初就把所有的使用范围都考虑到。第二,我们确实是有所为有所不为,因为一家公司不可能把所有的事情都做完。我们也在往上游发展众多的合作伙伴,开创一个生态圈,往下游联合合作伙伴一起为客户服务。比如前一段我们提供的红包功能,就是环信和其他公司一起合作完成的。再往上层,我们接到很多定制各种企业客户端和微信客户端的要求,但是我们拒绝了。因为我认为一个企业要有所为有所不为,并且要专注,这也是我们一直关注数人云的原因。因为现在术业有专攻成为了一个趋势,每个公司都应该专注各自的领域服务好自己的客户。

谢乐冰:从这个角度我们也有同样的想法,我认为PaaS或者是IaaS的核心就是API,第一我们会专注于我们的核心API,同时开放出好的的API,希望合作伙伴能够通过我们的核心API来实现一些定制。现在很多甲方都有自己的开发能力,又有非常强烈的开发意愿,希望自己能够在这一波开源的大潮中能够获得更多的自主性,所以这也是一种有效的解决方法。

刘少壮:确实如此,比如我们一直在和数人云接触,打算以后逐步推进与数人云的合作,用数人云的服务来替换我们当前底层的服务,同时我们也在积极推进跟UCloud的合作。为什么说我们能做企业服务赚移动互联网公司的钱?因为我们能够给移动互联网公司解决他们的痛点问题。比如我们之前每一家客户都是自己做聊天功能,但是这些企业并没有意识到他们自己做的聊天系统可能有丢消息、延迟大、乱序等各种问题。他们发现了很多问题无法解决,而且其中很多甚至没有意识到这些问题。

从环信自身的角度来说,好一点的是我们意识到了,我们用的云平台包括我们整个的运维架构和运维技术,需要像数人云、Mesos、Docker等等这样的底层技术来支持我们更好的发展。我们不可能把所有的都做了,我们也是想把自身所有的力量,投入到我们自己更擅长的PaaS IM领域和移动客服功能上。我们不想投入太多的精力在其他地方,比如自己建一个物理机房,我们很早就讨论过这个问题,有的同事跟我说,建一个物理机房能够省掉四分之一、甚至三分之一的费用。但是我认为对一个创业公司来说,人是更宝贵的,如果有别的更专业的公司提供服务,就应该去选择更专业的人来做。

资方:关注开源技术,期待行业独角兽

谢乐冰:最后的一个圆桌话题回到行业,行业的趋势问题一般都是由投资人来回答。我们看到2014年下半年产生了五家到六家的容器创业公司,我们数人云也是其中之一。一个非常好的消息是这五到六家,出乎意料地都活到了现在,并且都拿到了A轮融资,这是市场对大家的认可。我们请陈总从投资的角度谈一下整个容器行业的发展趋势。

陈昱:我希望容器这个行业能够更加规范化。其实Docker代表着一类资本非常关注的事物就是开源技术。资本非常喜欢开源技术,因为它技术优秀,能够解决实际问题,并且有活跃的社区还有广泛的应用群体。容器是这一类技术里面非常好的代表,这项技术在实际落地的过程中有很多的问题。企业虽然能够免费获得技术,但是在落地的时候,他们可能并没有人力精力去用好这项技术,企业其实是非常需要像数人云这样的技术公司给他们提供一个企业级的解决方案,提供相应的培训和后续的支持。只有这样,优秀的开源技术才能够实现落地。

而像数人云这样的公司也能够通过这样的商业模式变现,最终实现成长。但是这类软件不会是一家独大的状况,而会是百花齐放。就像Docker一样,国内就有五六家不错的Docker公司,以Hadoop为例,在美国我们同样也能看到有很多家公司,他们每一家都有数千个客户,每年有上亿美元的营收,在资本市场表现非常好,Docker也是类似的。他们能运营良好的原因,第一是市场庞大,没有一家公司能够服务所有的客户;第二是在整个构架里面,各个公司从产品从技术和销售策略上都有一定的差异化,就像数人云选择的是Docker加Mesos,而其他竞争对手可能选择的是切入一体机的解决方案,或者提供一个Container as a Service服务这样的一个路线,最终大家都能够在资本市场上取到不错的表现。既然像Hadoop这种技术可以产生好几家独角兽公司,那么Docker一样在中国也可以产生独角兽公司,我希望数人云就是其中的一家。

谢乐冰:不管是做IaaS、PaaS还是大数据,我们希望所有做开源商业化技术的公司都能够竞争合作,一起推动整个时代向一个分布式云端的架构前进,谢谢大家。 查看全部
5月26日,数人云产品战略发布会在北京万达索菲特酒店举行,发布会最后一个环节圆桌论坛可谓大咖云集,小数为大家在第一时间带来了实录分享,快来感受下容器生态圈的激情碰撞吧——

520952144917949177.jpg


主持人:谢乐冰 数人云COO

圆桌嘉宾:

王雷 央视网(CNTV)运维总监

刘少壮 环信联合创始人&CTO

华琨 UCloud 联合创始人&COO

王瑞琳 EasyStack联合创始人&COO

张峻 VMware 中国先进技术中心主任

陈昱 云启资本 VP

EasyStack:物理机、虚拟机和容器的兼容整合

谢乐冰:各位好,今天我们讲讲干货。第一位我想有请EasyStack的王总回答,容器在2015年变成了和OpenStack一样火的技术,前一阵的奥斯汀OpenStack大会上也有很多关于容器的议题。我的第一个问题是,您认为对于一个完整的数据中心操作系统来说,用物理机跑原生Docker与通过OpenStack跑Docker有什么区别?

王瑞琳:今年的奥斯汀OpenStack峰会做了一次OpenStack用户调查,根据调查结果,在OpenStack用户关注的技术里,容器技术排在首位。你提的这个问题排在第三位,它们是客户最关注三大问题中的两个。

我认为OpenStack跟容器技术解决的是不同的问题,容器解决的是应用的高并发管理、CI/CD、快速发布,也就是说,它是更面向应用的。然而,OpenStack是要解决的是云数据中心层面的问题。从云数据中心的两个维度去看,第一它向下加强各种硬件的管理,向上支持数据中心各种业务场景。所以从这两点上看,OpenStack更多的是面向基础设施,而容器则是面向应用的,这两个技术本身互不矛盾,这也是为什么OpenStack峰会对容器的关注已经持续很多年,在去年东京的峰会上容器也是OpenStack整个峰会的热点之一。

最近两届的OpenStack峰会对容器的关注点也越来越多地集中在容器和OpenStack集成的应用场景实现上,刚刚Mesos国外的专家也谈到,Mesos也好、Kubernetes也好,它们要管理越来越多不同类型的容器。同样,OpenStack在数据中心控制层面也要解决不同场景的应用,一般来说大家谈到OpenStack对于容器的支持,大多集中在虚拟机上。但是作为数据中心的总控,OpenStack要管理的对象除了虚拟机,也有容器,还有物理机。OpenStack有一个主件叫Ironic,它可以管理裸机,并在上面部署容器。所以OpenStack和容器技术并不是矛盾体,它们是兼容并整合的关系。

VMware:容器与虚拟化在一起会更好

谢乐冰:对于一个完整的数据中心操作系统来说,IaaS负责基础架构层面的服务,PaaS则偏重应用层面。第二个问题是我们与客户沟通过程中经常遇到的一个问题,也就是说,我们是不是把容器当成虚拟机在使用。VMware有一个非常完整的支撑容器的基础架构,可以非常好地把容器当作虚拟机。而现在IaaS和PaaS之间的界限越来越模糊,从长期来看,作为一个全球领先的IaaS厂商,VMware认为,IaaS是否也有可能进入schedule调度,甚至进入微服务这个层面?

张峻:刚刚主持人提到一点,容器作为虚拟机是可以的,但是现在在微服务化场景下把容器当成虚拟机使用并不合适。因为我们希望它能够切得更小,然后每一个微服务都通过容器来实现。容器跟虚拟化是解决不同问题的,从这一点来看与OpenStack有相似之处,我认为虚拟化解决的一个重大问题是隔离和安全的问题,而容器则解决的是快速交付的问题。所以它们并不矛盾,只是解决的问题分别在IaaS和PaaS两个层次上。所以我的想法是虚拟化和容器技术在一起会更好,因为它们是解决不同的问题,在一起的好处是同时解决了容器技术潜在的安全性和隔离性的问题。众所周知,容器都是基于共享内核的,是有一定程度上的安全问题,因为容器潜在的特性是共享的。所以,想要同时兼具安全性并做到快速交付,就可以在下层使用虚拟机,并在它的上面搭容器。所以基于这样的想法,不管用户之前是否使用vSphere,我们都有很好的产品解决方案去应对各种业务场景。

同时在虚拟机上面搭建容器的另一个好处是从运维方面,大家可以把容器和虚拟机在统一的管理平台上一同进行管理,把所有未容器化的应用与现在已经容器化的应用统一管理起来,大大提高便利性。同时也可以应用一些虚拟化比较成熟的技术,包括容器的HA、容器的热迁移,现在也都具备一些初步的方案。但是企业需要的是成熟的方案,比如说数人云选择了Mesos技术,而不是Kubernetes,就是因为Mesos相对来说更为成熟。对于企业来说,成熟稳定是非常重要的,因而用虚拟化成熟的下层IaaS解决方案再加上上层的容器技术的便利快捷,是一个非常好的组合。

UCloud:自然过渡的混合云时代

谢乐冰:在我们接触的企业中,互联网公司的大部分应用还处于云就绪状态,云原生应用还不是特别多。在这种情况下,我们认为IaaS可以解决底层网络和存储的大部分问题,可以帮助企业平滑上云。我们在给客户做方案的过程中意识到,未来向公有云延伸非常需要协同的能力,如今,容器技术越来越被认为是一种云端应用交付的标准手段,UCloud是国内领先的公有云公司,华琨总您认为容器技术会给公有云带来怎样的新机遇?

华琨:就像前面嘉宾说的,Docker是面向应用的、一种非常灵活的场景,我非常认同张总所说的,应该把容器和虚拟化技术结合在一起。有越来越多的用户找到我们,表示非常想在公有云上使用容器,这样做面临以下几个问题:首先是便利性,VM与IaaS的关系更密切,VM有一个好处就是管理起来很方便,同时它也很符合广大工程师的使用习惯。但是现在,大家的兴趣点和很多的应用场景都在Docker上,那么首当其冲要去解决的就是管理上的便利性,需要解决外网访问的问题,并结合VM的隔离安全性。

另外,容器技术还需要结合IaaS的其它优势。公有云厂商在资源的管理调度上做了大量工作,在资源的提供上具有很大的优势。我们很早就在VM层面实现了热迁移,可以在业务无感知的情况下把一个VM迁移到另外一个位置上。同样的技术我们也可以应用到Docker上,包括向其他产品提供负载均衡,在Docker环境下,这也是一个非常典型的场景。如何将这两个技术进行结合,让整体的可视化管理做的更好,这些都是公有云厂商擅长的领域。我们想把它们更好的结合起来,让广大的用户可以不用去关注底层技术细节。当然,原理的学习是一回事,实践起来的话还是会有很多的门槛,而这些都可以通过公有云的一些专业技术去实现。我们希望让用户更多地去享受Docker技术所带来的应用场景的便利性,这是我们想去做的一件非常重要的事情。

谢乐冰:华总,您认为混合云的时代会在什么时候到来呢,现在已经有一些什么样的实例?

华琨:我们认为,混合云的混合有很多种,包括公有云和私有云的混合,物理机和虚拟机的混合,甚至是IaaS和PaaS的混合。在我们看来,这些都已经有很多的应用场景了,其中,我们在五年前就推出了物理机和虚拟机的混合,并受到了用户的欢迎,有一些用户出于使用习惯或者设备的限制选择了混合云,我们为他们提供了一个兼容的方案。整个云计算的发展也是这样的一个过程,用户需要慢慢地接受,因而有很多的应用场景在兼容。实际上,公有云厂商也在做更多的兼容过渡方案,去匹配这当中五到十年的各种应用场景的过渡。公有云和私有云的结合推动打通了各种层面的VPC,这是非常实用的,我觉得这也是非常合理的。尤其在中国,很多的场景都需要混合云来解决,否则问题就会僵持不下。我想这种混合,在未来会越来越多地体现在IaaS跟PaaS融合的方面。

CNTV:企业级客户对容器的需求和探索

谢乐冰:刚才三位是我们的IaaS合作伙伴,我们看到不管是单独用PaaS,或者IaaS+PaaS,最后的目标都是让客户不用再去特别关心底层实现,而是说哪一种方案最能达到目标就选哪种。下面我们会有几个比较难的话题,这个话题落到使用者身上——CNTV的王总身上,CNTV是一个既代表互联网,又跨广电的企业,在容器和相应的PaaS技术落地过程中,我们都有哪些应用场景,碰到了哪些问题?例如这个流程需不需要变化,软件代码需不需要更改等等?

王雷:刚才几位嘉宾是属于这个行业的从业人员,我是属于使用者,属于企业用户。CNTV的中文名字叫中国网络电视台,另外一个名称叫央视网。我们其实是两个牌子,都属于中央电视台的网络传播中心,同时也是中央电视台的新媒体传播机构。从归属上大家可以看到,既然是中央电视台的新媒体传播机构,同时也是国家重点新闻网站,所以我们对安全性的要求非常高。而且每年伴随央视很多的重大的活动,包括每年的春晚、即将召开的今年的欧洲杯、奥运会,我们都会在新媒体层面大力地进行宣传报道。

我们虽然是一个比较偏向于传统媒体的新媒体公司,但是我们对整个行业、新技术非常关注。自从Docker诞生,我们一直都很关注,但是因为Docker那时不够成熟,所以我们基本上还属于观望。从去年我们开始测试Docker平台,经过大概一年多的测试,我们也发现了一些现阶段的需求,比如CI/CD。我是负责公司运维平台的,运维和开发是一对矛盾体,开发者有要求,但我们公司对运维和保障的要求更高。在使用Docker一段时间之后,我们发现开发和运维之间不像以前那么矛盾,通过CI/CD让大家看到这个东西其实是非常好用的。

另外,我们更关注的问题集中在很多的重大活动、重大赛事上,包括春晚这种传统活动。所以我们对弹性,对支撑能力的要求是非常高的。因为在重大活动期间,突发访问可能一下子会增加到平常的十倍、甚至百倍,Docker的弹性和快速扩展满足了我们的需求。通过一段时间的测试,我们现在基本上已经确定会把一些前端的业务逐渐往Docker上转移。现在我们接口层的一些业务,包括一些传统服务已经在Docker上运行,效果非常好,同时我们也在测试在Docker上跑Hadoop,但是这涉及到很多缓存层、中间层的系统,可能我们还要更慎重一些。

我认为现在Docker还有很多不完善的地方,包括监控层面还有安全层面,也包括刚才海外的Mesos专家说的整个调试方面的一些问题,这些我们都是很关注的。比如我的集群上跑了很多业务,但是哪个容器出现问题了导致这个平台的效率变得非常低下,能否及时发现问题并把它踢出去,是我们所关注的。但是这种技术确实已经在很多方面对我们有所帮助,所以我们选择逐渐容器化。因为从另外一个层面来说,做好容器化的同时,我们也在用大量的虚拟化技术,它使我们整个企业可以节省更多的硬件设备开销,更多地地提高资源使用率,这个也是每个企业都希望的。

谢乐冰:还有一个小问题,过去我认为虚拟化是非常简单的事情,但是实际上我发现各个企业也是做了一些相应的流程,甚至也有一些软件技术层面的改造工作,您预计未来容器+PaaS对于开发部门来说会有什么样的变化?

王雷:我认为这是一个趋势,很多新技术改变了人们的观念和操作方式,只有不断地适应才能更好地做好本职的工作。不管是对个人还是对于企业,只要能提高效率,能有更大的产能,大家都是十分乐意的。有很多的业务的改变需要很长时间,我认为从新业务上我们可能会从架构层面就开始规划,可以容器化的就直接做这样的改变。

环信:IT服务商的企业定制与术业专攻

谢乐冰:我们与客户沟通的时候,大家会经常问一个问题,你们是一家做容器的公司,那么,什么是容器的公司?只说是做容器的公司就像说自己是一家做JAVA的公司一样,等于什么都没有说。做容器的公司要解决的是,容器在生产环境上的大规模运行,并给企业提供上云的最佳实践,这才叫一个做容器的公司。不管是做IaaS还是做PaaS的公司,我们做的所有事情实际上都是一起帮助企业的整个IT架构向云端迁移。下面一个话题谈到怎么挣钱这个问题,环信是行业内领先的PaaS公司,是一家为数不多能从互联网公司身上赚到IT服务费的公司。为互联网提供IT服务是一个非常难的事情,不管是互联网公司还是大中型企业都涉及到一个定制问题,一定程度上大家认为定制是非常合理的,因为每个企业的流程是不一样的。所以我想请问一下刘总,你们是如何解决这个问题的?

刘少壮:环信是这样考虑定制这个事情的,首先我们做的产品是即时通讯云和移动客服。我们的目标是PaaS和SaaS的方向,这个选择决定了我们不会做太多的定制。但是做企业服务,尤其是像做移动互联网企业的企业服务,每一家企业都有不同的业务流程和业务需求。比如说我们的移动客服,或者说往更下层的容器技术,再比如说数人云提供的PaaS平台服务,或者是像UCloud提供的IaaS服务,都要满足企业各种不同的需求。

从环信的角度来讲,第一,要通过我们的产品设计和技术手段来保证系统的开放性,同时要更加灵活地提供所有的API和SDK,在系统设计之初就把所有的使用范围都考虑到。第二,我们确实是有所为有所不为,因为一家公司不可能把所有的事情都做完。我们也在往上游发展众多的合作伙伴,开创一个生态圈,往下游联合合作伙伴一起为客户服务。比如前一段我们提供的红包功能,就是环信和其他公司一起合作完成的。再往上层,我们接到很多定制各种企业客户端和微信客户端的要求,但是我们拒绝了。因为我认为一个企业要有所为有所不为,并且要专注,这也是我们一直关注数人云的原因。因为现在术业有专攻成为了一个趋势,每个公司都应该专注各自的领域服务好自己的客户。

谢乐冰:从这个角度我们也有同样的想法,我认为PaaS或者是IaaS的核心就是API,第一我们会专注于我们的核心API,同时开放出好的的API,希望合作伙伴能够通过我们的核心API来实现一些定制。现在很多甲方都有自己的开发能力,又有非常强烈的开发意愿,希望自己能够在这一波开源的大潮中能够获得更多的自主性,所以这也是一种有效的解决方法。

刘少壮:确实如此,比如我们一直在和数人云接触,打算以后逐步推进与数人云的合作,用数人云的服务来替换我们当前底层的服务,同时我们也在积极推进跟UCloud的合作。为什么说我们能做企业服务赚移动互联网公司的钱?因为我们能够给移动互联网公司解决他们的痛点问题。比如我们之前每一家客户都是自己做聊天功能,但是这些企业并没有意识到他们自己做的聊天系统可能有丢消息、延迟大、乱序等各种问题。他们发现了很多问题无法解决,而且其中很多甚至没有意识到这些问题。

从环信自身的角度来说,好一点的是我们意识到了,我们用的云平台包括我们整个的运维架构和运维技术,需要像数人云、Mesos、Docker等等这样的底层技术来支持我们更好的发展。我们不可能把所有的都做了,我们也是想把自身所有的力量,投入到我们自己更擅长的PaaS IM领域和移动客服功能上。我们不想投入太多的精力在其他地方,比如自己建一个物理机房,我们很早就讨论过这个问题,有的同事跟我说,建一个物理机房能够省掉四分之一、甚至三分之一的费用。但是我认为对一个创业公司来说,人是更宝贵的,如果有别的更专业的公司提供服务,就应该去选择更专业的人来做。

资方:关注开源技术,期待行业独角兽

谢乐冰:最后的一个圆桌话题回到行业,行业的趋势问题一般都是由投资人来回答。我们看到2014年下半年产生了五家到六家的容器创业公司,我们数人云也是其中之一。一个非常好的消息是这五到六家,出乎意料地都活到了现在,并且都拿到了A轮融资,这是市场对大家的认可。我们请陈总从投资的角度谈一下整个容器行业的发展趋势。

陈昱:我希望容器这个行业能够更加规范化。其实Docker代表着一类资本非常关注的事物就是开源技术。资本非常喜欢开源技术,因为它技术优秀,能够解决实际问题,并且有活跃的社区还有广泛的应用群体。容器是这一类技术里面非常好的代表,这项技术在实际落地的过程中有很多的问题。企业虽然能够免费获得技术,但是在落地的时候,他们可能并没有人力精力去用好这项技术,企业其实是非常需要像数人云这样的技术公司给他们提供一个企业级的解决方案,提供相应的培训和后续的支持。只有这样,优秀的开源技术才能够实现落地。

而像数人云这样的公司也能够通过这样的商业模式变现,最终实现成长。但是这类软件不会是一家独大的状况,而会是百花齐放。就像Docker一样,国内就有五六家不错的Docker公司,以Hadoop为例,在美国我们同样也能看到有很多家公司,他们每一家都有数千个客户,每年有上亿美元的营收,在资本市场表现非常好,Docker也是类似的。他们能运营良好的原因,第一是市场庞大,没有一家公司能够服务所有的客户;第二是在整个构架里面,各个公司从产品从技术和销售策略上都有一定的差异化,就像数人云选择的是Docker加Mesos,而其他竞争对手可能选择的是切入一体机的解决方案,或者提供一个Container as a Service服务这样的一个路线,最终大家都能够在资本市场上取到不错的表现。既然像Hadoop这种技术可以产生好几家独角兽公司,那么Docker一样在中国也可以产生独角兽公司,我希望数人云就是其中的一家。

谢乐冰:不管是做IaaS、PaaS还是大数据,我们希望所有做开源商业化技术的公司都能够竞争合作,一起推动整个时代向一个分布式云端的架构前进,谢谢大家。

新瓶装旧酒?从微服务同步REST的天然缺陷说起

宁静胡同 发表了文章 • 0 个评论 • 288 次浏览 • 2016-05-10 20:17 • 来自相关话题

今天小数给大家带来的干货来自国外一个小组会议上的分享。目前,大部分微服务架构都会使用REST协议以实现不同服务之间的通信,但是它却有天然的缺陷——怎样的缺陷?如何解决?请看下文。

最近,Lightbend技术负责人James Roper在纽约Java特别兴趣小组会议上分享了一个观点:

现在许多人正着手将传统的整体式应用拆分成微服务集合,但如果这些微服务组件都通过REST(即表述性状态转移)实现彼此通信,那么它依然只是一款整体式的应用程序。








Roper表示自己是异步通信的铁杆支持者——Lightbend(前身为Typesafe)推出的一套名为Lagom的Scala微服务平台正好是基于异步通信所打造。

何谓异步通信

这里提到的“异步通信”与我们常说的“异步I/O”并不是一回事。异步I/O的实质在于避免因等待进程线程完成而导致的操作停止。而作为微服务中的重要组成部分,异步通信则旨在设计出一套系统,其中某项服务的执行无需等待另一项任务的完成。

“使用异步通信,如果用户向某项服务提出一条请求,而该服务又需要向另一服务发出请求,那么前一服务的通信无需受阻即可向用户直接返回响应,”Roper解释称。

REST的固有缺陷

目前,大部分微服务架构都会使用REST协议以实现不同服务之间的通信(取代对象调用)。尽管REST较其它常规方式(例如基于XML的SOAP)更为简单,但其同步特性仍然成为固有缺陷——换言之,它天然拥有同步属性,而非异步。

“当客户端发出一条请求,服务器则发出一条响应,”Roper这样形容REST的工作原理。






一项服务发生故障,即会导致操作整体瘫痪。

面向用户的服务通常包含大量以同步方式通信的微服务,这意味着各微服务彼此依赖。这种处理方式在各服务皆能正常运转时并不会带来什么麻烦,然而一旦某项服务发生故障,即会引发不可阻挡的故障链并导致最终用户面临拒绝服务状况。

同样的,如果某项微服务速度缓慢,则响应时间也会被同时拖累。

使用REST等同步通信机制,Roper指出,“从技术角度讲,我们仍然相当于构建了一款整体式方案。无论各组件是否被拆分为独立服务,系统本身还是会像整体应用那样高度关联。”

异步通信来填坑

而在异步通信中,各服务间仍然彼此依赖,但不再因相互等待结果而导致响应速度缓慢。因此,如果一项服务发生故障,其不会影响到其它服务,瓶颈与单点故障问题也将不复存在。

利用基于Java的一套类Twitter服务演示,Roper解释了如何通过多种方式实现代码中的异步调用。方法之一在于确保每项微服务都在信息更新时对其进行发布,而非等待其它微服务针对该信息提出请求。通过这种办法,假设通讯服务需要一份用户的“好友”列表,则可使用由“好友”相关微服务提供的最新信息,而非直接指向该服务发出请求。

来自异步通信的挑战

Roper坦言,异步通信带来的最大挑战在于如何确保最终用户始终能够获得最新信息。很多社交网络都会使用最终一致性机制,并不保证每位用户都能够获得最新版本信息。

另外,REST调用由于极易实现而使用户产生了稳定的使用习惯。一位与会者提到,需要经过大量编码工作才能实现异步通信。

实时REST调用应该被取代吗?
Roper指出,像Apache Kafka这样的软件能够自动处理异步服务中的低级细节,“如果使用简单的REST调用,大家的服务有可能瘫痪。而通过这种方式,情况就不会那么糟糕。” 查看全部
今天小数给大家带来的干货来自国外一个小组会议上的分享。目前,大部分微服务架构都会使用REST协议以实现不同服务之间的通信,但是它却有天然的缺陷——怎样的缺陷?如何解决?请看下文。

最近,Lightbend技术负责人James Roper在纽约Java特别兴趣小组会议上分享了一个观点:

现在许多人正着手将传统的整体式应用拆分成微服务集合,但如果这些微服务组件都通过REST(即表述性状态转移)实现彼此通信,那么它依然只是一款整体式的应用程序。


2.png



Roper表示自己是异步通信的铁杆支持者——Lightbend(前身为Typesafe)推出的一套名为Lagom的Scala微服务平台正好是基于异步通信所打造。

何谓异步通信

这里提到的“异步通信”与我们常说的“异步I/O”并不是一回事。异步I/O的实质在于避免因等待进程线程完成而导致的操作停止。而作为微服务中的重要组成部分,异步通信则旨在设计出一套系统,其中某项服务的执行无需等待另一项任务的完成。

“使用异步通信,如果用户向某项服务提出一条请求,而该服务又需要向另一服务发出请求,那么前一服务的通信无需受阻即可向用户直接返回响应,”Roper解释称。

REST的固有缺陷

目前,大部分微服务架构都会使用REST协议以实现不同服务之间的通信(取代对象调用)。尽管REST较其它常规方式(例如基于XML的SOAP)更为简单,但其同步特性仍然成为固有缺陷——换言之,它天然拥有同步属性,而非异步。

“当客户端发出一条请求,服务器则发出一条响应,”Roper这样形容REST的工作原理。

3.png


一项服务发生故障,即会导致操作整体瘫痪。

面向用户的服务通常包含大量以同步方式通信的微服务,这意味着各微服务彼此依赖。这种处理方式在各服务皆能正常运转时并不会带来什么麻烦,然而一旦某项服务发生故障,即会引发不可阻挡的故障链并导致最终用户面临拒绝服务状况。

同样的,如果某项微服务速度缓慢,则响应时间也会被同时拖累。

使用REST等同步通信机制,Roper指出,“从技术角度讲,我们仍然相当于构建了一款整体式方案。无论各组件是否被拆分为独立服务,系统本身还是会像整体应用那样高度关联。”

异步通信来填坑

而在异步通信中,各服务间仍然彼此依赖,但不再因相互等待结果而导致响应速度缓慢。因此,如果一项服务发生故障,其不会影响到其它服务,瓶颈与单点故障问题也将不复存在。

利用基于Java的一套类Twitter服务演示,Roper解释了如何通过多种方式实现代码中的异步调用。方法之一在于确保每项微服务都在信息更新时对其进行发布,而非等待其它微服务针对该信息提出请求。通过这种办法,假设通讯服务需要一份用户的“好友”列表,则可使用由“好友”相关微服务提供的最新信息,而非直接指向该服务发出请求。

来自异步通信的挑战

Roper坦言,异步通信带来的最大挑战在于如何确保最终用户始终能够获得最新信息。很多社交网络都会使用最终一致性机制,并不保证每位用户都能够获得最新版本信息。

另外,REST调用由于极易实现而使用户产生了稳定的使用习惯。一位与会者提到,需要经过大量编码工作才能实现异步通信。

实时REST调用应该被取代吗?
Roper指出,像Apache Kafka这样的软件能够自动处理异步服务中的低级细节,“如果使用简单的REST调用,大家的服务有可能瘫痪。而通过这种方式,情况就不会那么糟糕。”

实录分享 | Google Borg 系统 与 Coding Docker 实践

宁静胡同 发表了文章 • 0 个评论 • 256 次浏览 • 2016-05-05 20:27 • 来自相关话题

本文是数人云深圳技术分享课上Coding CTO 孙宇聪的演讲实录,小数带你走近这位诙谐幽默的大牛,领略他深入的见解和丰富的实践经验。


非常感谢今天有这个机会,数人云的CEO是我前同事王璞,他原来是Google的,我是在Google云计算部门,我们合作非常紧密。

创业也是非常好的机会,Coding是关注于开发者、生产力、效率。数人云会关注真正从代码到研发、落地,这一系列的事情,这简直就是绝配。刚才听了谢乐冰的演讲我觉得很多东西和我们的思路非常像,从我回国到现在大概有一年多的时间。我一直在改造Coding原来的业务、架构,包括新业务的架构设计。对我来讲他讲的很多东西我们已经实践过了,只不过采用的方法可能不太一样,用名词来说就是殊途同归,条条大路通罗马。

今天我从研发的角度讲一讲,把一个所谓的代码变成无服务、无状态、分布式,我们是怎么想的。我们很遗憾的是跟他不是一同开始,我们没利用他们的东西,现在我们也非常想能够把我们这些经验和他们的经验结合起来,给大家提供一个完整的,从开发一直到最后的体验。

个人介绍——从Google到Coding

先吹吹牛,介绍一下我自己。我原来在Google,2007年加入的Google,2009年去的Google美国总部。我去了以后参加两个大项目,一个项目是YouTube国内不存在的视频网站,当年经历了YouTube爆发式增长的阶段,从无到有的过程,这个经历是值得一提的。应该是2010年左右,当时YouTube每个月的上传量已经超过1个PB,这个数字目前没几个人达到。我们建了CDN网络,当时我们有一万个节点,10000台机器,都是部署在每个SP自己的机房里,当时的峰值流量就达到10T,一回国都是2M的小水管,当时流量是10个TbpS,可能80%的流量都是小猫视频,大家上YouTube最多的事是看小猫视频。

后来转到Google cloud platform,当时做的主要是Google所有内部百万台服务器的运维服务,要管理机器从工厂造出来那一刻,接上电源以后,然后安装、部署,包括运行软件,最后都要销毁,当时两个团队20人,管全球100多万台机器,我们不是管机器的,是让系统管机器。

后来国内炒的很火的Borg,Omega,Google所有的任务都是集中在这两个任务分发系统上,Borg已经很牛了,Omega又很牛,但是不幸的是Omega已经早就被cancel了。Omega这伙人写Borg写烦了,就想重写一下,这帮人写了大概两三年,最后没能解决什么实际问题。这个事情在Google内部结果是不太好的,就被cancel了。更搞笑的是,写Omega这伙人一看公司不让我写了,我改成写Kubernetes。原班人马写Kubernetes,把这个思想带过去,重新用go又写了一遍。市面上的容器化管理平台又有几个,我的看法是Kubernetes现在不是很靠谱,起码现在不是很靠谱,大家就知道选什么好了。

回国以后,我们主要干了Coding这个事,主要是做了所谓的众包平台,可以让需求方在上面找到程序员做事,程序员也可以接到私活,有点像软件行业的房屋中介。

Coding基于终端业务是码市,用张老板的话说让自由人自由连接,需求方找到程序员,程序员找到需求方。我们开发针对很多程序员的生产力工具,我回国以后最大的感受,国内的程序员是太敬业了,比国外敬业多,我们早上10点多公司,下午3点多就回家了,国内的程序员什么时候干过这个事,996,10、10、7,都干过的。很多时候老板招程序员是来干活,他一是不关心你用什么工具干活,二是不关心你怎么干的,效率高不高。我们是给程序员提供好的工具,提高生产力,解放生产力,让成程序员效率提高。

基于这个我们做了项目管理、代码仓库、在线开发的WebIDE、演示平台。很多东西目前还是秘密,但是我们也秘密研发中,今年下半年很多东西要上线。
Google Borg——Millions Job Every Day

今天主题主要是讲Borg和Coding的实践。Google的Borg系统是什么东西?Google Borg系统是整个公司的任务分发系统,你在Google里面写程序必须在Borg这个平台上运行,怎么做到的?你买不到机器,公司不给你批钱买机器,必须从Borg买资源。当一个东西成为一个公司标准的时候就好办了,否则你永远是买一台机器瞎配一下,永远所做不到所谓的PaaS,或平台化。







   
Google的数据中心,或者说它的架构层面是什么样的?它也非常简单,Google有几个名词可以解释一下,首先是Google的机器,每一台都是没有外壳的机器,因为外壳对Google来说一点用没有,因为它要求随时可以操作。所有这些机器组成一排,很多排的机器组成所谓的集群,两三个集群组成所谓的数据中心,数据中心放在一起就组成一个园区。

为什么说这件事?Google的一大理念是分层或分区,相当于从上到下都是一个经过顶层设计的状态,不会是说有的公司是从前到后都搅在一起,你要说我做一个业务,业务从买机器到布线,到供电,都是连在一起的,全都是一个部门搞的,这样搞出来的东西可能效率稍微高一点点,但是复杂度高非常难以扩展。Google分层的理念和容器化的理念一样,容器化本身是要分层,只有分层才能降低复杂度,每一层都给每一层提供不同的接口。这个是每一排机器是连到一个供电设备上,每一个集群,每一个Cluster是一个完整的Borg Cluster,好几个数据中心有好几个Borg Cluster。给应用开发者提供了一个稳定、抽象的平台,你不用担心我具体找哪台机器,而是把任务运行到哪个集群中,然后自动在集群中给你分配资源,这是Google的生产环境是这样的组织过程。








当Google一个请求来的时候,Google都涉及到哪些东西,一直到最后的服务层涉及到什么条件和环节。Google有所谓的B2、B4,可以理解为一个是公有网络,一个是私有网络。B2是和各大运营商接的网络,B4是数据中心的骨干网。数据包从ISP,或从用户直接到达Google数据中心以后一定会进入Borg Cluster,所有任务都在Borg Cluster这个集群里。Borg里运行了GFE,GFE它相当于一个前端,有GSLB是负载均衡系统,告诉用户你应该访问哪些机器,或者是怎么样,这个请求到达应用程序的后端,存储层读数据,最后反馈给用户。

在Google看来,一个业务应用应该是分层的,每一层都是一个所谓的服务,刚才谢乐冰讲的所谓服务化和异步化,不会把这些东西从前到头搅在一起,这样非常难以扩展。把整个的所有流程切片以后,每一层都可以横向扩展,处理很多应用,效率也非常高。这就是Google做分布式,就是靠一层层切分,每一层都有不同的团队负责,这层和那层有明确的接口,接口是异步的,非常清晰的,所以才能大规模扩张。








今天讲的重点是Google的Borg是干什么用的,Borg内部架构是什么样?首先里面有几个比较大的东西,第一个东西就是所谓的Borg master,有五个方框,因为实际就是跑在5台机器上的。Borg master是基于所谓的Paxos协议,把一个状态可以安全地复制到5个机器上,只要5个机器有3个正常工作,这个集群就能正常工作,这就是Borg master,把集群的所谓状态,什么东西运行在什么地方,一个任务运行几份,运行在哪,什么状态,都记在Borg master上。Borg Master有对应的Borglet,就是Borg slave,运行在集群的小节点上执行任务的东西, Borg master负责发指令,Borg slave负责执行。Google这个模型运行十年多,每一个集群大概有10000台机器,这个模型是经过验证的,每一个集群里开始是10000,后来涨到30000-50000台机器,这个规模是非常可观的。

还有Scheduler,选择每个机器去运行,这个细节就不说了。和用户的接口,Borg有个所谓的config,config就是你写了一下我现在有一个东西要运行,这个东西有什么运行条件,通过工具推到Borg Master上,Borg Master给你安排一个机器,如果这个机器突然间挂了,就可以把任务迁到别的机器上运行。Borg Cluster的模式,给上层的应用提供了一个接口,你只要告诉我你运行什么,我不关心你具体运行在哪。大家可以看Google特别吹牛的文章,我们每个月有20亿的任务在运行,实际上有很多任务是运行1秒就崩溃,然后又重新运行,里面数据有点浮高。但是这个模型是Google经过实践得出的,因为开发者真的不关心具体的机器是哪个,只关心我需要2G内存,一个CPU,塞到机器上跑就可以了,不关心机器上还运不运行其他的东西。

理都懂,城会玩,臣妾做不到——土制一些吧

Borg模型比较难,Borg Master也是Google内部工具。我回国以后遇到最大的问题,这些东西都玩不了,就得土制。因为你没有一个完整的解决方案做这个事,我们自己得把这个东西搭起来。搭起来得需要一些东西,分为三大块,第一大块是所谓的Run time,这解决容器化的运行时环境。二是在Run time运行就得涉及到镜像,或镜像分发的机制,有一个东西要运行,可以把它运行到某一个机器上。最后是有Orchestration,就是编排系统,即有一个人,一个程序,决定这个东西运行在什么地方,然后是下载镜像,然后去执行。在2015年初的时候发现,目前符合这个模式的东西就是Docker,我们先试试Docker什么样。








2015年上半年,基本上大上半年的时间,我们搞了所谓的Docker化,最开始我们内部使用的都是一个所谓单机部署,每个人都要自己拷贝这样的文件,然后执行命令。我们后来搞了一个Docker化,Docker化的结果是,所有的代码打包成了Docker Image。Docker生产环境有自己的私有Registry,用Docker container运行代码。最后还写了生产环境的容器编排系统,这个做得很烂,没有数人云做得好,但是勉强解决了我们手动执行的一些问题。搞完这个东西以后,我们发现Docker到处是坑。

小姐身子丫鬟命——Docker Engine (Runtime)

然后我来讲讲填了哪些坑。Docker daemon,也就是运行时,当时大家觉得很厉害,一开始都说你用容器必须用Docker,后来发现Docker daemon不是唯一的一个启动容器的途径,跟以前搞的都是一回事。Docker daemon会遇到一个问题,任何人用Docker第一天都发现,Docker 里面没有init,daemon也没有reap子进程,如果程序fork很多进程,会在系统中出现很多僵尸进程,最终导致 docker daemon 出现问题,国内目前也没有把这个问题解决。每次跑一个Docker程序的时候都要担心,我们会担心这个Docker有没有处理好僵尸进程的问题。二是Docker后面的存储系统没有一个靠谱的,用AUFS,很多垃圾文件不清理,我从事软件开发这么多年从来没有过,很少见,大部分都是已经打包好的程序,不会占用很多磁盘iNode。最新版OverlayFS产生一些死锁还有崩溃,BTRfs也是。当时我们对人生产生了怀疑,为什么我们要自找这么多事,我们原来跑得好好的,为什么搞到Docker上来,遇到了一些新问题。我们甚至把Docker daemon改成Open SSH,但Docker daemon和Open SSH其实是一回事,就是提供远程命令执行的工具。你也可以理解为一个木马,发一个指令就跑一个程序,而且跑的还有问题,我们不如直接SSH连接上运行这个程序,都比这个靠谱,当时很难受。后来Docker daemon本质上是一个所谓的系统工具,它不停地扫描系统中的文件路径,进入这个状态。它有两个问题,一是原子性操作的问题,你Docker删除一堆事,要删目录,调一堆系统API,任何一个地方出现问题都会造成垃圾,造成系统死锁。Docker daemon一重启,别的肯定也会要重启,对我的个人声誉在团队里造成很大的影响。








Docker daemon有很多问题,Docker是当时可选的东西,给我们带来好处,但是随之而来的也有一些问题。Docker团队自己也意识到有问题,后来美国的神仙打一下架,觉得我们同意搞一个所谓的OCI,它成立了一个标准,就产生了一个Runc的东西,Runc就是一个具体执行container的东西,Docker一听说这个东西就赶紧把代码捐出来,给了Runc,好处是他对代码很熟悉,赶紧搞了一个containerD,是grpc warpper,通过grpc访问的一个服务,最后用户还保证Docker不变。对Docker来说OCI像毒药,逼着他吃,但是吃完也对他本身造成威胁。对最终用户是好事,如果我们发现Docker不靠谱,就直接用containerd交流,如果containerd也不靠谱,就绕过去让他和Runc交流,你不再绑在一个Docker。跟虚拟化是一样的,以前大家觉得虚拟化就是Vmware,必须得用Vmware的一套东西才能看得见。现在分层,先有KVM,然后有QEMU和containerD差不多,再上面有Openstack。和Google的东西一样,把逻辑分层,不再是一团,从上到下捅到底,每一层都被替换,灵活性更高、性能也会更好。

鸡肋的Docker Image——一个不那么圆的轮子

而后我们又发现Docker Image本身也不怎么样,最后大家的评论是非常鸡肋。Docker Image就是一个压缩包,如果你想把一个东西传给另一个人打一个包压缩一下发过去,是一样的,Image又能分层,又能节省传输,这个东西都是扯淡,因为我们内网一秒好几百M,省出10M的磁盘空间对我们来说是省几毫秒。Docker Image来自于DockerFile,Dockerfile有一些表面问题,首先是不会写,这个东西是他自己发明的,对于开发者来说,这个东西对你是有学习障碍的东西。你学习过程中荡涤了你的灵魂,又开始怀疑人生。所以用Docker就经常怀疑人生,你觉得以前学的东西都不好使了,用了一段时间以后发现这些都是骗人的,你要干的事还是一样。Docker的核心问题,或者是Image核心问题一是编译代码,二是打包成镜像发出去。怎么编译,怎么打包,这两件事是完全分开的,不应该搀在一起。你下次写Docker Image的时候,发现写DockerFile,既做编译,又做打包,恭喜你,你已经成功地给自己挖很多坑,运行的时候发现打包一次需要好几小时,下载一堆东西,最后打包的镜像好几十G,这些事情我们都干过。我们第一个镜像是打包完3G多,当时我们震惊了,这么辛苦写了这么多的代码吗,运行程序就达到3G。

Coding 实践1:Build&Package&Run

最后我们理解了,你要做好一个事情,Build和Package要分家,先Build好代码,再把编译的结果赛到Image运行,Build要灵活,要针对你的所有系统来做,你的代码是什么样就应该怎么Build,你要写Java,最后产生一个结果是Java包,如果不是就说明你的代码写得有问题,你应该在这个问题上解决,最后就产生Java包,Package就是把Java和Java包放在一起运行。

Coding最后的Dockerfile就三行,第一行是from某个基础镜像,一个Java运行时,第二行是add某个Java包,第三是CMD运行。DockerFile基本上我们处于鸡肋状态,用它还可以利用它去推代码,这部分功能还是有点用的。但是真正用DockerFile,我们不会用它做复杂逻辑。

把Build和Package分开,我们用的所有编程语言都已经把编译工具搞好,所有的编译工具都能产生一个单独的包。我们尝试用DockerFile同时解决build和package这两个问题,真是没事找事。你用Docker的时候发现我干了一堆事,看起来很牛,但是实际效果并不好。作为程序员得审视这个问题,就是能不能产生价值,如果不产生价值你是在给Docker打工,盲目跟从Docker,他说这么干就这么干,他如果改了你这些东西就浪费了。如果你抓住本质,Docker怎么改对你就没有影响。

Package的构成我们还是用的Docker image的方式,写了三行,一是Java的运行时环境,二是Java包,三是怎么运行Java,这是所谓的Package。后来发现三行太多,应该写两行,他让我们写一行就写一行。为什么第三行不用写,Java程序执行起来都一样,都是Java -jar这些东西,你要加一些参数。不会写到Image里会发现,Java调一下内存要重新打包吗?太不合理了。最后CMD就不写了,Docker直接执行,在配置文件里执行。基本上所有的服务,要么是三行,要么是两行。

Coding实践2:去其糟粕,取其精华

在使用的过程中我们发现,Docker有很多花里胡哨的东西,结果却是什么也没用,我们用的是非常简单的,就把Docker当成容器。为什么呢?第一点你看到大部分文章讲Docker作为公有云平台我们应该如何使用Docker,这是国内公司的通病。搞Docker的部门大部分是公司的运维部门,国内的运维部门没有权限改代码,只能改自己的平台,作为公司的平台部门得提供各种SDN的服务,研发人员根本不需要这东西,如果你没有SDN,就是主机,就是host网络模式,给你分配一个端口,保证你的端口是可用的,这个就行了,以前Borg就是这样,Google搞了十年,每个开发的人都知道,我们启动的时候得找一下本地端口什么样,要么可以配置,要么可以自动寻找一个可用端口。Docker来了说你不用干这个事,我给你一个IP,给你一个80,你永远可以访问这个。但是他没有做到,做了很多后面的东西,SDN,各种打包,性能很差,这个事一般他不告诉你,当你上了贼船以后,为什么我们的程序性能这么差。他说困难是暂时的,面包会有的,未来两年这个性能就提高了。我说未来两年我们程序都不用了,早就换了,这个明显是不合理的。

经常有人问我你们用Docker这么多,怎么解决共享存储的问题。我说我们没有共享存储,以前是什么样还是什么样。很多程序,共享存储一是要改代码,或者说有一个很牛的,我们能够申请一个文件系统,自动挂载上面。后来我们发现这个东西没有一个有用的,对我们来说没有区别。我们的编程模型还是针对本地服务,我们在编程的时候已经考虑到如果本地文件不存在怎么办,迁移数据怎么办,我们都有现成的解决方案,为什么要换,我们还是用Host模型。数据就是写在机器上,如果你要迁移这台机器,如果这个东西有状态,你就应该处理这个状态,而不是运维部门帮你解决处理状态的问题,这是公司里效率最低的方式,它得跟运维部门协调,我们要迁移了,运维部门说我帮你把数据拷过去,这个是不行的。

Docker有一个更大的坑,我把这个东西都转成Docker运行,你一看时区都是GMT时区,有种到了爱尔兰的感觉,所有的log时间对不上了。Docker没告诉你,主机里的locale,你的编码设置、时区设置,每个用户passwd都是用的默认的设置。这给我们造成很大困扰。每一个打包的人得关心到底是什么样,到底怎么正确设置时区,密码这些东西。后来我们直接就mount,跟主机一样,如果今天这个程序运行在中国的一台主机上,他就应该用这台主机的模式。我们用容器,很多时候变成我们真的只关心,第一是运行时的版本,第二是代码的版本,只有这两个东西是会变的,其他东西都是跟着主机一起走,这个模型是最简单,最有利于推广云计划、分布式计算的。

不管你做不做容器都应该往几个方向努力,一是所谓的对生产环境的管理模式。宠物式管理和放牛式管理,宠物式管理是你搞一台机器,给这个机器起好听的名,很多公司有专门的机器叫数据库,这个机器有特殊的人调试。突然有一天这个机器挂了,你得把这个机器修好,这是宠物式管理,你得把这个东西修好,不修好整个业务就停了,数据库是最典型的。除了数据库外我们采用的所有管理方式都是放牛式管理,你放一百头牛,有一只牛吃完口吐白沫倒下了,你的第一反应不是你的牛吃病了,一定是咔,然后再拿一头新牛过来,如果做到这一点很多事就很简单。你随时保证资源,保证有一百头牛在跑就行了。

二是在国内公有云平台上,最依赖的还是静态手动资源配置。因为我们大部分业务都是所谓的daemon job,服务型任务,你的东西一启动它就要一直运行,占用一定的数量的内存,一定数量的CPU,就持续提供服务。所以这个东西要迁移对你没有任何好处,可能能够提高你资源利用率,如果你搞一台新机器把这个东西分过去。但是同样的,你在这也是用CPU,那也是用CPU,对你来说花钱一样花。所以很多时候动态调配在daemon job是没意义的,除非不停地有机器挂,公有云虚拟化了,已经减少了很多这方面的问题。我们最关心的是留出足够的富裕量,搞出冗余,不受任何一个单独虚拟机的影响。动态调配对我们意义不大,动态调配唯一有用的地方是你有批处理、周期性任务,他运行时间比较短,你又不关心在什么地方运行,这是容器平台截然不同的两个的使用场景,这两个应用场景可能有不同的方案解决。

Coding 实践3:工具化、代码化、半自动化

最后得出的结论,算我提出的一个口号,怎么样能够减轻你运维的压力,或提高你开发的效率。你是要把所有做的事情,所有需要人力参与的事情工具化、代码化、半自动化,完全自动化这个事很难,涉及到你要通过实践积累,把各种各样的边缘情况考虑到。现在对我们来说,80%的是半自动化,执行的时候不出错,很快地执行。这是我们所谓开发编排系统的主要目标。在一个公司里什么任务运行在什么机器上,很多时候存在开发人员的脑袋里,比如数据库的IP是什么,你如果能想起来,这就说明你们公司的代码化不够。代码化把人才知道的东西都写到机器里,对我来说不关心数据库的IP是什么,我只要知道它的域名找到对应的机器连接就行了。








对我们的生产环境,第一什么东西跑在什么机器上,怎么连接。二是搞出常用的属性管理,比如名字是什么,端口是什么,有什么特点。三是我们仿照Google搞了一个Jobs/Tasks的抽象层,Google里面最大的抽象层,你一个任务可以有多个副本在运行,这个任务今天跑5个副本,明天跑100个,这个集群可以直接搞定,我们把这个概念抄过来,相当于每一个任务都有2-3个Tasks。最后把数据写进代码化的配置文件里时,你发现集群可以复制,你在这个集群上可以跑,在那个集群上只要调调资源的对应关系,具体跑在什么地方,你就会发现这个就是所谓的可复制集群,你本地也可以跑一套,在生产环境、配置文件都可以跑一套。这是最关键的点,不管你怎么干,你最后都要干一个类似的事,就是把生产环境代码化。

接下来,基于刚才的知识搞了一个小工具,这些工具是提供原子性的操作。up是启动,down是干掉,rollingupdate是一个个更新,保证每个更新完了可以启动进行下一个更新,对研发来说就需要这个东西,他们都理解。你说我有一个网易UI页面,你点鼠标,他很不理解,他不知道产生什么事情。任何一个集群管理系统,就是要设置所谓的接口,你要提供一些原子化、半自动操作,去协助开发者达到他想要干的事,这是所谓的编排系统最应该提供的东西。

后来我们应该有一个所谓的diff,运行过程中怎么有配置的改变,改变要看一下先改什么,然后再真正应用这些改变。后来又搞了网页系统,可以用网页看,以前连网页都没有,后来觉得还是不太方便。在网页系统,以前连网页都没有,上可以直接看log,甚至远程登在某个容器进行操作。这是最小的功能机,最有用的。

Coding实践总结








最后总结一下,第一点,想要把容器化、或想要把分布式系统做好,你要定死接口,放手实现,对你来说只需要三个接口,build、package、run,能满足效果,能运行就行了,每个项目都有不同的需求,不可能强求它完全一致。

第二个,生产环境容器化。很多业务有本地依赖,不能挪动。但是最好的情况,第一,你一定要做到软件把它包起来,你软件用到的所有资源、所有的文件都是集中在container这个里面的,不会用到别人的东西,中间不会产生交集,这是包起来第一步。这一步很难,很多应用配置文件都写在系统的不同地方,这个机器上可以跑,那个机器跑不起来,只有包起来才能挪动,别的东西能正常访问,这是最重要的。如果这两个东西都做成以后,这个东西做成可复制,可以延伸、可以扩展、可以复制,这就是容器化做好了。

针对DEVOPS实现代码化、工具化,最后实现自动化就行了。 查看全部


本文是数人云深圳技术分享课上Coding CTO 孙宇聪的演讲实录,小数带你走近这位诙谐幽默的大牛,领略他深入的见解和丰富的实践经验。



非常感谢今天有这个机会,数人云的CEO是我前同事王璞,他原来是Google的,我是在Google云计算部门,我们合作非常紧密。

创业也是非常好的机会,Coding是关注于开发者、生产力、效率。数人云会关注真正从代码到研发、落地,这一系列的事情,这简直就是绝配。刚才听了谢乐冰的演讲我觉得很多东西和我们的思路非常像,从我回国到现在大概有一年多的时间。我一直在改造Coding原来的业务、架构,包括新业务的架构设计。对我来讲他讲的很多东西我们已经实践过了,只不过采用的方法可能不太一样,用名词来说就是殊途同归,条条大路通罗马。

今天我从研发的角度讲一讲,把一个所谓的代码变成无服务、无状态、分布式,我们是怎么想的。我们很遗憾的是跟他不是一同开始,我们没利用他们的东西,现在我们也非常想能够把我们这些经验和他们的经验结合起来,给大家提供一个完整的,从开发一直到最后的体验。

个人介绍——从Google到Coding

先吹吹牛,介绍一下我自己。我原来在Google,2007年加入的Google,2009年去的Google美国总部。我去了以后参加两个大项目,一个项目是YouTube国内不存在的视频网站,当年经历了YouTube爆发式增长的阶段,从无到有的过程,这个经历是值得一提的。应该是2010年左右,当时YouTube每个月的上传量已经超过1个PB,这个数字目前没几个人达到。我们建了CDN网络,当时我们有一万个节点,10000台机器,都是部署在每个SP自己的机房里,当时的峰值流量就达到10T,一回国都是2M的小水管,当时流量是10个TbpS,可能80%的流量都是小猫视频,大家上YouTube最多的事是看小猫视频。

后来转到Google cloud platform,当时做的主要是Google所有内部百万台服务器的运维服务,要管理机器从工厂造出来那一刻,接上电源以后,然后安装、部署,包括运行软件,最后都要销毁,当时两个团队20人,管全球100多万台机器,我们不是管机器的,是让系统管机器。

后来国内炒的很火的Borg,Omega,Google所有的任务都是集中在这两个任务分发系统上,Borg已经很牛了,Omega又很牛,但是不幸的是Omega已经早就被cancel了。Omega这伙人写Borg写烦了,就想重写一下,这帮人写了大概两三年,最后没能解决什么实际问题。这个事情在Google内部结果是不太好的,就被cancel了。更搞笑的是,写Omega这伙人一看公司不让我写了,我改成写Kubernetes。原班人马写Kubernetes,把这个思想带过去,重新用go又写了一遍。市面上的容器化管理平台又有几个,我的看法是Kubernetes现在不是很靠谱,起码现在不是很靠谱,大家就知道选什么好了。

回国以后,我们主要干了Coding这个事,主要是做了所谓的众包平台,可以让需求方在上面找到程序员做事,程序员也可以接到私活,有点像软件行业的房屋中介。

Coding基于终端业务是码市,用张老板的话说让自由人自由连接,需求方找到程序员,程序员找到需求方。我们开发针对很多程序员的生产力工具,我回国以后最大的感受,国内的程序员是太敬业了,比国外敬业多,我们早上10点多公司,下午3点多就回家了,国内的程序员什么时候干过这个事,996,10、10、7,都干过的。很多时候老板招程序员是来干活,他一是不关心你用什么工具干活,二是不关心你怎么干的,效率高不高。我们是给程序员提供好的工具,提高生产力,解放生产力,让成程序员效率提高。

基于这个我们做了项目管理、代码仓库、在线开发的WebIDE、演示平台。很多东西目前还是秘密,但是我们也秘密研发中,今年下半年很多东西要上线。
Google Borg——Millions Job Every Day

今天主题主要是讲Borg和Coding的实践。Google的Borg系统是什么东西?Google Borg系统是整个公司的任务分发系统,你在Google里面写程序必须在Borg这个平台上运行,怎么做到的?你买不到机器,公司不给你批钱买机器,必须从Borg买资源。当一个东西成为一个公司标准的时候就好办了,否则你永远是买一台机器瞎配一下,永远所做不到所谓的PaaS,或平台化。


Coding-2016-数人云-技术分享_0008.jpg


   
Google的数据中心,或者说它的架构层面是什么样的?它也非常简单,Google有几个名词可以解释一下,首先是Google的机器,每一台都是没有外壳的机器,因为外壳对Google来说一点用没有,因为它要求随时可以操作。所有这些机器组成一排,很多排的机器组成所谓的集群,两三个集群组成所谓的数据中心,数据中心放在一起就组成一个园区。

为什么说这件事?Google的一大理念是分层或分区,相当于从上到下都是一个经过顶层设计的状态,不会是说有的公司是从前到后都搅在一起,你要说我做一个业务,业务从买机器到布线,到供电,都是连在一起的,全都是一个部门搞的,这样搞出来的东西可能效率稍微高一点点,但是复杂度高非常难以扩展。Google分层的理念和容器化的理念一样,容器化本身是要分层,只有分层才能降低复杂度,每一层都给每一层提供不同的接口。这个是每一排机器是连到一个供电设备上,每一个集群,每一个Cluster是一个完整的Borg Cluster,好几个数据中心有好几个Borg Cluster。给应用开发者提供了一个稳定、抽象的平台,你不用担心我具体找哪台机器,而是把任务运行到哪个集群中,然后自动在集群中给你分配资源,这是Google的生产环境是这样的组织过程。


Coding-2016-数人云-技术分享_0009.jpg



当Google一个请求来的时候,Google都涉及到哪些东西,一直到最后的服务层涉及到什么条件和环节。Google有所谓的B2、B4,可以理解为一个是公有网络,一个是私有网络。B2是和各大运营商接的网络,B4是数据中心的骨干网。数据包从ISP,或从用户直接到达Google数据中心以后一定会进入Borg Cluster,所有任务都在Borg Cluster这个集群里。Borg里运行了GFE,GFE它相当于一个前端,有GSLB是负载均衡系统,告诉用户你应该访问哪些机器,或者是怎么样,这个请求到达应用程序的后端,存储层读数据,最后反馈给用户。

在Google看来,一个业务应用应该是分层的,每一层都是一个所谓的服务,刚才谢乐冰讲的所谓服务化和异步化,不会把这些东西从前到头搅在一起,这样非常难以扩展。把整个的所有流程切片以后,每一层都可以横向扩展,处理很多应用,效率也非常高。这就是Google做分布式,就是靠一层层切分,每一层都有不同的团队负责,这层和那层有明确的接口,接口是异步的,非常清晰的,所以才能大规模扩张。


Coding-2016-数人云-技术分享_0010.jpg



今天讲的重点是Google的Borg是干什么用的,Borg内部架构是什么样?首先里面有几个比较大的东西,第一个东西就是所谓的Borg master,有五个方框,因为实际就是跑在5台机器上的。Borg master是基于所谓的Paxos协议,把一个状态可以安全地复制到5个机器上,只要5个机器有3个正常工作,这个集群就能正常工作,这就是Borg master,把集群的所谓状态,什么东西运行在什么地方,一个任务运行几份,运行在哪,什么状态,都记在Borg master上。Borg Master有对应的Borglet,就是Borg slave,运行在集群的小节点上执行任务的东西, Borg master负责发指令,Borg slave负责执行。Google这个模型运行十年多,每一个集群大概有10000台机器,这个模型是经过验证的,每一个集群里开始是10000,后来涨到30000-50000台机器,这个规模是非常可观的。

还有Scheduler,选择每个机器去运行,这个细节就不说了。和用户的接口,Borg有个所谓的config,config就是你写了一下我现在有一个东西要运行,这个东西有什么运行条件,通过工具推到Borg Master上,Borg Master给你安排一个机器,如果这个机器突然间挂了,就可以把任务迁到别的机器上运行。Borg Cluster的模式,给上层的应用提供了一个接口,你只要告诉我你运行什么,我不关心你具体运行在哪。大家可以看Google特别吹牛的文章,我们每个月有20亿的任务在运行,实际上有很多任务是运行1秒就崩溃,然后又重新运行,里面数据有点浮高。但是这个模型是Google经过实践得出的,因为开发者真的不关心具体的机器是哪个,只关心我需要2G内存,一个CPU,塞到机器上跑就可以了,不关心机器上还运不运行其他的东西。

理都懂,城会玩,臣妾做不到——土制一些吧

Borg模型比较难,Borg Master也是Google内部工具。我回国以后遇到最大的问题,这些东西都玩不了,就得土制。因为你没有一个完整的解决方案做这个事,我们自己得把这个东西搭起来。搭起来得需要一些东西,分为三大块,第一大块是所谓的Run time,这解决容器化的运行时环境。二是在Run time运行就得涉及到镜像,或镜像分发的机制,有一个东西要运行,可以把它运行到某一个机器上。最后是有Orchestration,就是编排系统,即有一个人,一个程序,决定这个东西运行在什么地方,然后是下载镜像,然后去执行。在2015年初的时候发现,目前符合这个模式的东西就是Docker,我们先试试Docker什么样。


Coding-2016-数人云-技术分享_0012.jpg



2015年上半年,基本上大上半年的时间,我们搞了所谓的Docker化,最开始我们内部使用的都是一个所谓单机部署,每个人都要自己拷贝这样的文件,然后执行命令。我们后来搞了一个Docker化,Docker化的结果是,所有的代码打包成了Docker Image。Docker生产环境有自己的私有Registry,用Docker container运行代码。最后还写了生产环境的容器编排系统,这个做得很烂,没有数人云做得好,但是勉强解决了我们手动执行的一些问题。搞完这个东西以后,我们发现Docker到处是坑。

小姐身子丫鬟命——Docker Engine (Runtime)

然后我来讲讲填了哪些坑。Docker daemon,也就是运行时,当时大家觉得很厉害,一开始都说你用容器必须用Docker,后来发现Docker daemon不是唯一的一个启动容器的途径,跟以前搞的都是一回事。Docker daemon会遇到一个问题,任何人用Docker第一天都发现,Docker 里面没有init,daemon也没有reap子进程,如果程序fork很多进程,会在系统中出现很多僵尸进程,最终导致 docker daemon 出现问题,国内目前也没有把这个问题解决。每次跑一个Docker程序的时候都要担心,我们会担心这个Docker有没有处理好僵尸进程的问题。二是Docker后面的存储系统没有一个靠谱的,用AUFS,很多垃圾文件不清理,我从事软件开发这么多年从来没有过,很少见,大部分都是已经打包好的程序,不会占用很多磁盘iNode。最新版OverlayFS产生一些死锁还有崩溃,BTRfs也是。当时我们对人生产生了怀疑,为什么我们要自找这么多事,我们原来跑得好好的,为什么搞到Docker上来,遇到了一些新问题。我们甚至把Docker daemon改成Open SSH,但Docker daemon和Open SSH其实是一回事,就是提供远程命令执行的工具。你也可以理解为一个木马,发一个指令就跑一个程序,而且跑的还有问题,我们不如直接SSH连接上运行这个程序,都比这个靠谱,当时很难受。后来Docker daemon本质上是一个所谓的系统工具,它不停地扫描系统中的文件路径,进入这个状态。它有两个问题,一是原子性操作的问题,你Docker删除一堆事,要删目录,调一堆系统API,任何一个地方出现问题都会造成垃圾,造成系统死锁。Docker daemon一重启,别的肯定也会要重启,对我的个人声誉在团队里造成很大的影响。


Coding-2016-数人云-技术分享_0016.jpg



Docker daemon有很多问题,Docker是当时可选的东西,给我们带来好处,但是随之而来的也有一些问题。Docker团队自己也意识到有问题,后来美国的神仙打一下架,觉得我们同意搞一个所谓的OCI,它成立了一个标准,就产生了一个Runc的东西,Runc就是一个具体执行container的东西,Docker一听说这个东西就赶紧把代码捐出来,给了Runc,好处是他对代码很熟悉,赶紧搞了一个containerD,是grpc warpper,通过grpc访问的一个服务,最后用户还保证Docker不变。对Docker来说OCI像毒药,逼着他吃,但是吃完也对他本身造成威胁。对最终用户是好事,如果我们发现Docker不靠谱,就直接用containerd交流,如果containerd也不靠谱,就绕过去让他和Runc交流,你不再绑在一个Docker。跟虚拟化是一样的,以前大家觉得虚拟化就是Vmware,必须得用Vmware的一套东西才能看得见。现在分层,先有KVM,然后有QEMU和containerD差不多,再上面有Openstack。和Google的东西一样,把逻辑分层,不再是一团,从上到下捅到底,每一层都被替换,灵活性更高、性能也会更好。

鸡肋的Docker Image——一个不那么圆的轮子

而后我们又发现Docker Image本身也不怎么样,最后大家的评论是非常鸡肋。Docker Image就是一个压缩包,如果你想把一个东西传给另一个人打一个包压缩一下发过去,是一样的,Image又能分层,又能节省传输,这个东西都是扯淡,因为我们内网一秒好几百M,省出10M的磁盘空间对我们来说是省几毫秒。Docker Image来自于DockerFile,Dockerfile有一些表面问题,首先是不会写,这个东西是他自己发明的,对于开发者来说,这个东西对你是有学习障碍的东西。你学习过程中荡涤了你的灵魂,又开始怀疑人生。所以用Docker就经常怀疑人生,你觉得以前学的东西都不好使了,用了一段时间以后发现这些都是骗人的,你要干的事还是一样。Docker的核心问题,或者是Image核心问题一是编译代码,二是打包成镜像发出去。怎么编译,怎么打包,这两件事是完全分开的,不应该搀在一起。你下次写Docker Image的时候,发现写DockerFile,既做编译,又做打包,恭喜你,你已经成功地给自己挖很多坑,运行的时候发现打包一次需要好几小时,下载一堆东西,最后打包的镜像好几十G,这些事情我们都干过。我们第一个镜像是打包完3G多,当时我们震惊了,这么辛苦写了这么多的代码吗,运行程序就达到3G。

Coding 实践1:Build&Package&Run

最后我们理解了,你要做好一个事情,Build和Package要分家,先Build好代码,再把编译的结果赛到Image运行,Build要灵活,要针对你的所有系统来做,你的代码是什么样就应该怎么Build,你要写Java,最后产生一个结果是Java包,如果不是就说明你的代码写得有问题,你应该在这个问题上解决,最后就产生Java包,Package就是把Java和Java包放在一起运行。

Coding最后的Dockerfile就三行,第一行是from某个基础镜像,一个Java运行时,第二行是add某个Java包,第三是CMD运行。DockerFile基本上我们处于鸡肋状态,用它还可以利用它去推代码,这部分功能还是有点用的。但是真正用DockerFile,我们不会用它做复杂逻辑。

把Build和Package分开,我们用的所有编程语言都已经把编译工具搞好,所有的编译工具都能产生一个单独的包。我们尝试用DockerFile同时解决build和package这两个问题,真是没事找事。你用Docker的时候发现我干了一堆事,看起来很牛,但是实际效果并不好。作为程序员得审视这个问题,就是能不能产生价值,如果不产生价值你是在给Docker打工,盲目跟从Docker,他说这么干就这么干,他如果改了你这些东西就浪费了。如果你抓住本质,Docker怎么改对你就没有影响。

Package的构成我们还是用的Docker image的方式,写了三行,一是Java的运行时环境,二是Java包,三是怎么运行Java,这是所谓的Package。后来发现三行太多,应该写两行,他让我们写一行就写一行。为什么第三行不用写,Java程序执行起来都一样,都是Java -jar这些东西,你要加一些参数。不会写到Image里会发现,Java调一下内存要重新打包吗?太不合理了。最后CMD就不写了,Docker直接执行,在配置文件里执行。基本上所有的服务,要么是三行,要么是两行。

Coding实践2:去其糟粕,取其精华

在使用的过程中我们发现,Docker有很多花里胡哨的东西,结果却是什么也没用,我们用的是非常简单的,就把Docker当成容器。为什么呢?第一点你看到大部分文章讲Docker作为公有云平台我们应该如何使用Docker,这是国内公司的通病。搞Docker的部门大部分是公司的运维部门,国内的运维部门没有权限改代码,只能改自己的平台,作为公司的平台部门得提供各种SDN的服务,研发人员根本不需要这东西,如果你没有SDN,就是主机,就是host网络模式,给你分配一个端口,保证你的端口是可用的,这个就行了,以前Borg就是这样,Google搞了十年,每个开发的人都知道,我们启动的时候得找一下本地端口什么样,要么可以配置,要么可以自动寻找一个可用端口。Docker来了说你不用干这个事,我给你一个IP,给你一个80,你永远可以访问这个。但是他没有做到,做了很多后面的东西,SDN,各种打包,性能很差,这个事一般他不告诉你,当你上了贼船以后,为什么我们的程序性能这么差。他说困难是暂时的,面包会有的,未来两年这个性能就提高了。我说未来两年我们程序都不用了,早就换了,这个明显是不合理的。

经常有人问我你们用Docker这么多,怎么解决共享存储的问题。我说我们没有共享存储,以前是什么样还是什么样。很多程序,共享存储一是要改代码,或者说有一个很牛的,我们能够申请一个文件系统,自动挂载上面。后来我们发现这个东西没有一个有用的,对我们来说没有区别。我们的编程模型还是针对本地服务,我们在编程的时候已经考虑到如果本地文件不存在怎么办,迁移数据怎么办,我们都有现成的解决方案,为什么要换,我们还是用Host模型。数据就是写在机器上,如果你要迁移这台机器,如果这个东西有状态,你就应该处理这个状态,而不是运维部门帮你解决处理状态的问题,这是公司里效率最低的方式,它得跟运维部门协调,我们要迁移了,运维部门说我帮你把数据拷过去,这个是不行的。

Docker有一个更大的坑,我把这个东西都转成Docker运行,你一看时区都是GMT时区,有种到了爱尔兰的感觉,所有的log时间对不上了。Docker没告诉你,主机里的locale,你的编码设置、时区设置,每个用户passwd都是用的默认的设置。这给我们造成很大困扰。每一个打包的人得关心到底是什么样,到底怎么正确设置时区,密码这些东西。后来我们直接就mount,跟主机一样,如果今天这个程序运行在中国的一台主机上,他就应该用这台主机的模式。我们用容器,很多时候变成我们真的只关心,第一是运行时的版本,第二是代码的版本,只有这两个东西是会变的,其他东西都是跟着主机一起走,这个模型是最简单,最有利于推广云计划、分布式计算的。

不管你做不做容器都应该往几个方向努力,一是所谓的对生产环境的管理模式。宠物式管理和放牛式管理,宠物式管理是你搞一台机器,给这个机器起好听的名,很多公司有专门的机器叫数据库,这个机器有特殊的人调试。突然有一天这个机器挂了,你得把这个机器修好,这是宠物式管理,你得把这个东西修好,不修好整个业务就停了,数据库是最典型的。除了数据库外我们采用的所有管理方式都是放牛式管理,你放一百头牛,有一只牛吃完口吐白沫倒下了,你的第一反应不是你的牛吃病了,一定是咔,然后再拿一头新牛过来,如果做到这一点很多事就很简单。你随时保证资源,保证有一百头牛在跑就行了。

二是在国内公有云平台上,最依赖的还是静态手动资源配置。因为我们大部分业务都是所谓的daemon job,服务型任务,你的东西一启动它就要一直运行,占用一定的数量的内存,一定数量的CPU,就持续提供服务。所以这个东西要迁移对你没有任何好处,可能能够提高你资源利用率,如果你搞一台新机器把这个东西分过去。但是同样的,你在这也是用CPU,那也是用CPU,对你来说花钱一样花。所以很多时候动态调配在daemon job是没意义的,除非不停地有机器挂,公有云虚拟化了,已经减少了很多这方面的问题。我们最关心的是留出足够的富裕量,搞出冗余,不受任何一个单独虚拟机的影响。动态调配对我们意义不大,动态调配唯一有用的地方是你有批处理、周期性任务,他运行时间比较短,你又不关心在什么地方运行,这是容器平台截然不同的两个的使用场景,这两个应用场景可能有不同的方案解决。

Coding 实践3:工具化、代码化、半自动化

最后得出的结论,算我提出的一个口号,怎么样能够减轻你运维的压力,或提高你开发的效率。你是要把所有做的事情,所有需要人力参与的事情工具化、代码化、半自动化,完全自动化这个事很难,涉及到你要通过实践积累,把各种各样的边缘情况考虑到。现在对我们来说,80%的是半自动化,执行的时候不出错,很快地执行。这是我们所谓开发编排系统的主要目标。在一个公司里什么任务运行在什么机器上,很多时候存在开发人员的脑袋里,比如数据库的IP是什么,你如果能想起来,这就说明你们公司的代码化不够。代码化把人才知道的东西都写到机器里,对我来说不关心数据库的IP是什么,我只要知道它的域名找到对应的机器连接就行了。


Coding-2016-数人云-技术分享_0027.jpg



对我们的生产环境,第一什么东西跑在什么机器上,怎么连接。二是搞出常用的属性管理,比如名字是什么,端口是什么,有什么特点。三是我们仿照Google搞了一个Jobs/Tasks的抽象层,Google里面最大的抽象层,你一个任务可以有多个副本在运行,这个任务今天跑5个副本,明天跑100个,这个集群可以直接搞定,我们把这个概念抄过来,相当于每一个任务都有2-3个Tasks。最后把数据写进代码化的配置文件里时,你发现集群可以复制,你在这个集群上可以跑,在那个集群上只要调调资源的对应关系,具体跑在什么地方,你就会发现这个就是所谓的可复制集群,你本地也可以跑一套,在生产环境、配置文件都可以跑一套。这是最关键的点,不管你怎么干,你最后都要干一个类似的事,就是把生产环境代码化。

接下来,基于刚才的知识搞了一个小工具,这些工具是提供原子性的操作。up是启动,down是干掉,rollingupdate是一个个更新,保证每个更新完了可以启动进行下一个更新,对研发来说就需要这个东西,他们都理解。你说我有一个网易UI页面,你点鼠标,他很不理解,他不知道产生什么事情。任何一个集群管理系统,就是要设置所谓的接口,你要提供一些原子化、半自动操作,去协助开发者达到他想要干的事,这是所谓的编排系统最应该提供的东西。

后来我们应该有一个所谓的diff,运行过程中怎么有配置的改变,改变要看一下先改什么,然后再真正应用这些改变。后来又搞了网页系统,可以用网页看,以前连网页都没有,后来觉得还是不太方便。在网页系统,以前连网页都没有,上可以直接看log,甚至远程登在某个容器进行操作。这是最小的功能机,最有用的。

Coding实践总结


Coding-2016-数人云-技术分享_0031.jpg



最后总结一下,第一点,想要把容器化、或想要把分布式系统做好,你要定死接口,放手实现,对你来说只需要三个接口,build、package、run,能满足效果,能运行就行了,每个项目都有不同的需求,不可能强求它完全一致。

第二个,生产环境容器化。很多业务有本地依赖,不能挪动。但是最好的情况,第一,你一定要做到软件把它包起来,你软件用到的所有资源、所有的文件都是集中在container这个里面的,不会用到别人的东西,中间不会产生交集,这是包起来第一步。这一步很难,很多应用配置文件都写在系统的不同地方,这个机器上可以跑,那个机器跑不起来,只有包起来才能挪动,别的东西能正常访问,这是最重要的。如果这两个东西都做成以后,这个东西做成可复制,可以延伸、可以扩展、可以复制,这就是容器化做好了。

针对DEVOPS实现代码化、工具化,最后实现自动化就行了。

技术干货 | 微服务架构软件的持续集成与交付

宁静胡同 发表了文章 • 0 个评论 • 437 次浏览 • 2016-05-05 14:16 • 来自相关话题

美好的五一假期结束啦,大家玩得怎么样?今天小数给大家带来的是数人云架构师周伟涛在CSDN做Mesos生态圈系列技术分享的第二期,讨论他在微服务架构方面的经验心得以及一些具体问题的解决。
Mesos生态圈系列第一期传送门:   畅谈Mesos生态圈
微服务架构概述

今天是 Mesos 生态圈系列的第二次分享,这次分享的内容是微服务架构软件的持续交付,我首先解释下标题与 Mesos 生态圈的关系。微服务架构是近几年讨论比较多或者说比较受欢迎的一种软件架构风格,但是该架构有一些缺点,譬如运维复杂度提高,交付次数频繁等,我们可以利用 Mesos 配合一些工具搭建持续交付平台来弥补这些缺点。这里我将以具体实践为例,讨论微服务架构的一些经验心得,然后着重介绍如何利用 Docker,Jenkins 来解决一些具体问题,实现微服务软件的持续交付。
 
首先介绍下微服务架构的优势与劣势。相较于单体应用来说,微服务架构有这么几个优点:
易于开发、理解。 由于每个服务只负责单一功能,开发者可以聚焦于自己负责的几个服务模块,对于其他服务,只需要理解接口即可。当然,单体应用经过良好设计也可以达到这个效果,但是,与单体应用的进程内通信或单机内的进程间通信不同的是,微服务的各服务之间一般采用 RESTfulAPI或者异步消息队列进行通信,无论 RESTful接口还是异步消息队列都是开发语言无关的,极易理解的通信方式。
 
全局稳定性提高。由于每个服务负责的功能单一,各服务的资源需求也相对更低。从而可以选择将服务分散的部署到多台中低配的服务器上,而不是一台高配的机器上。如果某个机器上的服务故障,譬如说内存泄漏,故障只会影响该机器上的某一个或几个服务,对全局影响不大。不受限于任何技术栈,极大的提高团队搭建的速度。这一点对初创公司尤为重要,组建开发团队对初创公司来说本来就是个头疼的问题,如何还要求团队的技术栈一致,招聘难度可想而知。但是,如果产品架构采用微服务架构,那么我们可以允许不同的服务模块采用不同的技术栈,只需要定义好对外接口即可。局部的修改很容易部署,从而大大的提高了功能的交付效率。
 
说完了微服务架构的优点,我们再来讨论下其缺点或者说复杂的地方:
如何确定软件功能切分的粒度,边界。太多的微服务模块会导致服务间通信成本和运维成本的增加,过犹不及;但是若粒度过大,又违背了微服务的初衷。多种技术栈(譬如 C,Java,Python,Scala 等)我们需要为每种语言准备编译环境,运行环境等,增加了维护成本。这个可以通过Docker 隔离来解决,我们后面会详细展开。微服务模块多了,会导致全局的上线次数变多,从而需要更复杂的版本管理和 Bug跟踪等,间接导致项目管理成本增加。






持续交付

持续集成和交付(CI/CD)是一种软件开发实践,使用得当,它会极大的提高软件开发效率并保障软件开发质量;持续集成和交付分为持续集成和持续交付两部分,这里我们不再具体探讨这两者的区别,统一按持续交付来处理。Jenkins是一个开源项目,它提供了一种易于使用的持续集成系统;除 Jenkins 外,常见的持续集成系统还有:

Travis: https://travis-ci.com/
Codeship: https://codeship.com/
Stridercd: http://stridercd.com/
 
另外,常见的交付方式一般有:
源代码交付: 源代码交付需要将源代码以 tar 包等方式 download 到服务器,然后在服务器上借助程序的构建脚本去构建可执行程序,显然这种方式会经常因服务器环境差异,构建环境初始化失败等问题导致无法构建可执行程序。严重依赖于构建脚本的完备程度。 Linux 标准包交付:  将项目的依赖通过 Linux deb 或者 rpm 来管理,由于这种方式更符合 Linux 规范,间接的提高了项目在服务器上部署的成功率,但是有些时候仍然需要解决包冲突问题。虚拟镜像交付: 虚拟镜像交付指的是我们将项目在虚拟机里测试成功后直接将该虚拟镜像部署到服务器上。显然,这种方式部署成功率接近100%而且隔离性好。但是随之而来的问题就是虚拟镜像本身对服务器资源的消耗。docker image 交付: docker image 交付是虚拟镜像交付的进一步演进,在保证系统隔离的同时,docker image 对服务器的资源消耗更低。当然,docker 的隔离机制是进程级别的,可能不适合一些强隔离场景。我们团队目前正在使用这种方式进行交付。







上图(图片来自于网络)展示了围绕 Docker 镜像仓库的持续交付流程:
首先开发者将代码推送到代码仓库,譬如github代码仓库的更新会触发新的代码构建,生成新的 docker 镜像并推送到 docker 镜像仓库接下来会基于新的 docker 镜像进行集成测试测试通过后,docker 镜像被交付到公有或者私有云上
 
通过上述持续交付的方式交付微服务架构的软件,能够很好的解决前面提到的第二与第三个问题,即
结合 Docker 解决多技术栈的环境维护问题;按微服务模块交付来提高软件的交付效率引入“版本服务”来可视化各微服务的版本信息引入“ReleaseNote服务”来发布各微服务的 feature 更新

实践

微服务架构有多种,数人云的微服务架构有如下特点:
RESTAPI 与 消息队列 结合使用。微服务与外部用户通过 RESTAPI 通信,内部微服务之间通过消息队列通信。全部 Docker 交付,这解决了多技术栈的环境维护问题。 一个微服务对应于一个持续交付的 Job,这保证了各服务在交付环节无相互依赖,单独触发。同时可以利用不同的 Docker 镜像为不同的 Job 提供相应环境。版本信息自动更新ReleaseNote 自动发布构建环境 Docker 化,与底层隔离,保证宿主机环境的一致性,降低运维成本利用 Docker-compose 维护本地开发环境,从而实现开发环境与生产环境的逻辑一致性






数人云的架构设计模式如图所示。用户通过浏览器或者直接通过 RESTAPI 与后台通信,后台是一个微服务集合,对外服务的接口一律采用 RESTAPI, 内部服务之间的接口采用消息队列。各微服务负责维护自身的状态集,有自己独立的缓存和 DB (如有必要)。微服务本身尽量无状态化,以保证横向扩展能力。






上图是我们目前采用的持续交付架构图。A, B, C, D 四个 github 代码库分别存储着四个微服务的源代码,相应的我们为每一个代码库创建了独立的构建作业,代码更新触发构建时,构建作业将执行如下的大致步骤:
从 Docker 私有镜像仓库拉取相应的构建镜像从 github 源码库拉取相应代码并挂载到构建容器里,触发特定脚本来执行构建若构建成功,立刻从 Docker 私有镜像仓库拉取相应的 runtime 镜像,将构建成功的可执行程序 Docker 化成新一版的微服务镜像将上述微服务镜像推送到 Docker 私有镜像仓库

若已经设置了自动交付
则通过 Marathon 的 RESTful API 接口触发线上微服务的更新更新版本服务里面对应微服务的版本信息自动更新 ReleaseNote 服务里面对应微服务的 ReleaseNote。 开发者在实现了相应功能时已经将对应的 ReleaseNote 放在了代码库特定目录下面(这个后面会详细提到) 
 







另外,从架构图中我们可以看出,程序的构建环境和运行环境正在共享同一个 Mesos 资源池,提高了资源利用率。
 
把 Jenkins 运行在 Mesos 上有如下几个考虑:
把Jenkins运行到 Apache Mesos上,或者说利用 Apache Mesos 向 Jenkins 提供 slave 资源,最主术栈的软件情况下尤其重要,可以极大降低运维成本。Marathon会对发布到它之上的应用程序进行健康检查,从而在应用程序由于某些原因意外崩溃后自动重启该应用。这样,选择利用Marathon管理 Jenkins Master 保证了该构建系统的全局高可用。而且,Jenkins Master 本身也通过 Marathon 部署运行在 Mesos 资源池内,进一步实现了资源共享,提高了资源利用率。



关于怎样将 jenkins 运行在 mesos 上,大家可以参考我以前在csdn发布的一篇文章http://www.csdn.net/article/2015-06-18/2824998
Docker 承担了什么角色
Docker 在整个体系中承担了如下几个角色:

各代码库的编译载体: 我们已经提前将各代码库的编译环境制作成了 docker 镜像
交付介质: 编译成功的可执行程序将被打包成 docker 镜像, 镜像的 tag 对应于程序版本信息
Runtime 环境: 运行环境已经被打包到 docker 镜像中了,启动的 docker 容器将作为微服务的 runtime 环境
资源隔离: docker 本身支持进程级别隔离,已经满足内部应用需求
为了保证单机开发环境与线上环境的配置/架构一致,我们在单机开发环境利用 docker-compose 来编排整个微服务环境,以便于调试

版本调试

在实践微服务架构时,我们碰到了这么一个问题:各微服务模块频繁交付,如何确认线上各微服务的版本, 即我们需要对各微服务进行版本控制。

目前团队迭代出了如下解决方案:交付成功后,交付 job会截取 docker 镜像里相应的 tag(代表着版本信息),并把该信息推送到一个 NginxServer 的静态文件里面, 前端页面访问该静态文件来获取相应微服务的版本信息。另外,同一个微服务会部署到开发,测试和生产三个环境上,所以基于不同的环境,我们会维护三个不同的静态文件 。
 
ReleaseNote 服务

在多人协作的微服务项目开发中,由于多人频繁的 merge 代码,ReleaseNote 的管理也会成为团队的负担。我这里推荐的做法是这样:

文档规约:团队达成一个 agreement: 对重大 feature 或 bug-fix 的提交都需要在目录 pending-release 里面创建相应的 markdown 文件,并将改动添加到里面。这样,我们可以控制交付 Job 在交付时扫描 pending-release 目录并将其中的文本 merge 到一起生成这次交付的 ReleaseNote。
git pre-commit-hook:同时,为了避免团队成员忘记这个agreement,我们还可以在本地的 git-precommit-hook 中添加相应的扫描提醒。

配置中心服务

目前网络上关于配置管理的解决方案已经非常成熟,我这里就不过多解释了。唯一需要提到的就是, 我们的配置中心服务还没有完全融入到整个交付过程中来,微服务的配置文件仍然需要手工介入。

持续集成的消息通知

显然,团队希望 CI 服务器在执行了持续集成后能够及时的将集成结果通知团队成员, Jenkins 本身是有 irc notification 插件的,但是国内开发者可能使用 IRC 的并不多;微信是小团队使用比较多的沟通工具,我们可以使用微信公众号进行消息通知;或者使用国内的 LessChart 等交流工具,它们本身支持 webhook 调用。

开发环境的搭建

微服务架构导致软件模块增多,增加了开发环境搭建的难度,同时也导致了团队新成员上手门槛的提高。我们目前是利用 docker-compose 维护本地开发环境来解决这个问题的。它不仅实现了开发环境与生产环境的逻辑一致性,同时也可以让相应模块的开发者聚焦于自己的业务,不必纠结于如何启停其它微服务。下面是我们的 docker-compose 文件的一部分。






问题及解决
在具体实践中,还有如下几个难题。
 
MQ 消息格式统一的困境
微服务间的消息传递需要根据业务变动而频繁改动,尤其是前期,这带来了极大的沟通成本,目前没有好办法解决。
 
微服务的功能粒度切分问题
如何界定各微服务承担的功能,每个微服务的功能粒度切分,微服务间的边界定义,这也是我们团队一直在摸索的问题。
 
参考链接:
1. http://microservices.io/
2.http://www.infoq.com/cn/news/2 ... cture 查看全部
美好的五一假期结束啦,大家玩得怎么样?今天小数给大家带来的是数人云架构师周伟涛在CSDN做Mesos生态圈系列技术分享的第二期,讨论他在微服务架构方面的经验心得以及一些具体问题的解决。
Mesos生态圈系列第一期传送门:   畅谈Mesos生态圈
微服务架构概述

今天是 Mesos 生态圈系列的第二次分享,这次分享的内容是微服务架构软件的持续交付,我首先解释下标题与 Mesos 生态圈的关系。微服务架构是近几年讨论比较多或者说比较受欢迎的一种软件架构风格,但是该架构有一些缺点,譬如运维复杂度提高,交付次数频繁等,我们可以利用 Mesos 配合一些工具搭建持续交付平台来弥补这些缺点。这里我将以具体实践为例,讨论微服务架构的一些经验心得,然后着重介绍如何利用 Docker,Jenkins 来解决一些具体问题,实现微服务软件的持续交付。
 
首先介绍下微服务架构的优势与劣势。相较于单体应用来说,微服务架构有这么几个优点:
  • 易于开发、理解。 由于每个服务只负责单一功能,开发者可以聚焦于自己负责的几个服务模块,对于其他服务,只需要理解接口即可。当然,单体应用经过良好设计也可以达到这个效果,但是,与单体应用的进程内通信或单机内的进程间通信不同的是,微服务的各服务之间一般采用 RESTfulAPI或者异步消息队列进行通信,无论 RESTful接口还是异步消息队列都是开发语言无关的,极易理解的通信方式。

 
  • 全局稳定性提高。由于每个服务负责的功能单一,各服务的资源需求也相对更低。从而可以选择将服务分散的部署到多台中低配的服务器上,而不是一台高配的机器上。如果某个机器上的服务故障,譬如说内存泄漏,故障只会影响该机器上的某一个或几个服务,对全局影响不大。
  • 不受限于任何技术栈,极大的提高团队搭建的速度。这一点对初创公司尤为重要,组建开发团队对初创公司来说本来就是个头疼的问题,如何还要求团队的技术栈一致,招聘难度可想而知。但是,如果产品架构采用微服务架构,那么我们可以允许不同的服务模块采用不同的技术栈,只需要定义好对外接口即可。
  • 局部的修改很容易部署,从而大大的提高了功能的交付效率。

 
说完了微服务架构的优点,我们再来讨论下其缺点或者说复杂的地方:
  • 如何确定软件功能切分的粒度,边界。太多的微服务模块会导致服务间通信成本和运维成本的增加,过犹不及;但是若粒度过大,又违背了微服务的初衷。
  • 多种技术栈(譬如 C,Java,Python,Scala 等)我们需要为每种语言准备编译环境,运行环境等,增加了维护成本。这个可以通过Docker 隔离来解决,我们后面会详细展开。
  • 微服务模块多了,会导致全局的上线次数变多,从而需要更复杂的版本管理和 Bug跟踪等,间接导致项目管理成本增加。


1.webp_.jpg


持续交付

持续集成和交付(CI/CD)是一种软件开发实践,使用得当,它会极大的提高软件开发效率并保障软件开发质量;持续集成和交付分为持续集成和持续交付两部分,这里我们不再具体探讨这两者的区别,统一按持续交付来处理。Jenkins是一个开源项目,它提供了一种易于使用的持续集成系统;除 Jenkins 外,常见的持续集成系统还有:

Travis: https://travis-ci.com/
Codeship: https://codeship.com/
Stridercd: http://stridercd.com/
 
另外,常见的交付方式一般有:
  • 源代码交付: 源代码交付需要将源代码以 tar 包等方式 download 到服务器,然后在服务器上借助程序的构建脚本去构建可执行程序,显然这种方式会经常因服务器环境差异,构建环境初始化失败等问题导致无法构建可执行程序。严重依赖于构建脚本的完备程度。
  •  Linux 标准包交付:  将项目的依赖通过 Linux deb 或者 rpm 来管理,由于这种方式更符合 Linux 规范,间接的提高了项目在服务器上部署的成功率,但是有些时候仍然需要解决包冲突问题。
  • 虚拟镜像交付: 虚拟镜像交付指的是我们将项目在虚拟机里测试成功后直接将该虚拟镜像部署到服务器上。显然,这种方式部署成功率接近100%而且隔离性好。但是随之而来的问题就是虚拟镜像本身对服务器资源的消耗。
  • docker image 交付: docker image 交付是虚拟镜像交付的进一步演进,在保证系统隔离的同时,docker image 对服务器的资源消耗更低。当然,docker 的隔离机制是进程级别的,可能不适合一些强隔离场景。我们团队目前正在使用这种方式进行交付。



2.webp_.jpg


上图(图片来自于网络)展示了围绕 Docker 镜像仓库的持续交付流程:
  • 首先开发者将代码推送到代码仓库,譬如github
  • 代码仓库的更新会触发新的代码构建,生成新的 docker 镜像并推送到 docker 镜像仓库
  • 接下来会基于新的 docker 镜像进行集成测试
  • 测试通过后,docker 镜像被交付到公有或者私有云上

 
通过上述持续交付的方式交付微服务架构的软件,能够很好的解决前面提到的第二与第三个问题,即
  • 结合 Docker 解决多技术栈的环境维护问题;
  • 按微服务模块交付来提高软件的交付效率
  • 引入“版本服务”来可视化各微服务的版本信息
  • 引入“ReleaseNote服务”来发布各微服务的 feature 更新


实践

微服务架构有多种,数人云的微服务架构有如下特点:
  • RESTAPI 与 消息队列 结合使用。微服务与外部用户通过 RESTAPI 通信,内部微服务之间通过消息队列通信。
  • 全部 Docker 交付,这解决了多技术栈的环境维护问题。
  •  一个微服务对应于一个持续交付的 Job,这保证了各服务在交付环节无相互依赖,单独触发。同时可以利用不同的 Docker 镜像为不同的 Job 提供相应环境。
  • 版本信息自动更新
  • ReleaseNote 自动发布
  • 构建环境 Docker 化,与底层隔离,保证宿主机环境的一致性,降低运维成本
  • 利用 Docker-compose 维护本地开发环境,从而实现开发环境与生产环境的逻辑一致性


3.webp_.jpg


数人云的架构设计模式如图所示。用户通过浏览器或者直接通过 RESTAPI 与后台通信,后台是一个微服务集合,对外服务的接口一律采用 RESTAPI, 内部服务之间的接口采用消息队列。各微服务负责维护自身的状态集,有自己独立的缓存和 DB (如有必要)。微服务本身尽量无状态化,以保证横向扩展能力。

4.webp_.jpg


上图是我们目前采用的持续交付架构图。A, B, C, D 四个 github 代码库分别存储着四个微服务的源代码,相应的我们为每一个代码库创建了独立的构建作业,代码更新触发构建时,构建作业将执行如下的大致步骤:
  • 从 Docker 私有镜像仓库拉取相应的构建镜像
  • 从 github 源码库拉取相应代码并挂载到构建容器里,触发特定脚本来执行构建
  • 若构建成功,立刻从 Docker 私有镜像仓库拉取相应的 runtime 镜像,将构建成功的可执行程序 Docker 化成新一版的微服务镜像
  • 将上述微服务镜像推送到 Docker 私有镜像仓库


若已经设置了自动交付
  • 则通过 Marathon 的 RESTful API 接口触发线上微服务的更新
  • 更新版本服务里面对应微服务的版本信息
  • 自动更新 ReleaseNote 服务里面对应微服务的 ReleaseNote。 开发者在实现了相应功能时已经将对应的 ReleaseNote 放在了代码库特定目录下面(这个后面会详细提到) 

 


5.webp_.jpg


另外,从架构图中我们可以看出,程序的构建环境和运行环境正在共享同一个 Mesos 资源池,提高了资源利用率。
 
把 Jenkins 运行在 Mesos 上有如下几个考虑:
  • 把Jenkins运行到 Apache Mesos上,或者说利用 Apache Mesos 向 Jenkins 提供 slave 资源,最主术栈的软件情况下尤其重要,可以极大降低运维成本。
  • Marathon会对发布到它之上的应用程序进行健康检查,从而在应用程序由于某些原因意外崩溃后自动重启该应用。这样,选择利用Marathon管理 Jenkins Master 保证了该构建系统的全局高可用。而且,Jenkins Master 本身也通过 Marathon 部署运行在 Mesos 资源池内,进一步实现了资源共享,提高了资源利用率。




关于怎样将 jenkins 运行在 mesos 上,大家可以参考我以前在csdn发布的一篇文章http://www.csdn.net/article/2015-06-18/2824998
Docker 承担了什么角色
Docker 在整个体系中承担了如下几个角色:

各代码库的编译载体: 我们已经提前将各代码库的编译环境制作成了 docker 镜像
交付介质: 编译成功的可执行程序将被打包成 docker 镜像, 镜像的 tag 对应于程序版本信息
Runtime 环境: 运行环境已经被打包到 docker 镜像中了,启动的 docker 容器将作为微服务的 runtime 环境
资源隔离: docker 本身支持进程级别隔离,已经满足内部应用需求
为了保证单机开发环境与线上环境的配置/架构一致,我们在单机开发环境利用 docker-compose 来编排整个微服务环境,以便于调试

版本调试

在实践微服务架构时,我们碰到了这么一个问题:各微服务模块频繁交付,如何确认线上各微服务的版本, 即我们需要对各微服务进行版本控制。

目前团队迭代出了如下解决方案:交付成功后,交付 job会截取 docker 镜像里相应的 tag(代表着版本信息),并把该信息推送到一个 NginxServer 的静态文件里面, 前端页面访问该静态文件来获取相应微服务的版本信息。另外,同一个微服务会部署到开发,测试和生产三个环境上,所以基于不同的环境,我们会维护三个不同的静态文件 。
 
ReleaseNote 服务

在多人协作的微服务项目开发中,由于多人频繁的 merge 代码,ReleaseNote 的管理也会成为团队的负担。我这里推荐的做法是这样:

文档规约:团队达成一个 agreement: 对重大 feature 或 bug-fix 的提交都需要在目录 pending-release 里面创建相应的 markdown 文件,并将改动添加到里面。这样,我们可以控制交付 Job 在交付时扫描 pending-release 目录并将其中的文本 merge 到一起生成这次交付的 ReleaseNote。
git pre-commit-hook:同时,为了避免团队成员忘记这个agreement,我们还可以在本地的 git-precommit-hook 中添加相应的扫描提醒。

配置中心服务

目前网络上关于配置管理的解决方案已经非常成熟,我这里就不过多解释了。唯一需要提到的就是, 我们的配置中心服务还没有完全融入到整个交付过程中来,微服务的配置文件仍然需要手工介入。

持续集成的消息通知

显然,团队希望 CI 服务器在执行了持续集成后能够及时的将集成结果通知团队成员, Jenkins 本身是有 irc notification 插件的,但是国内开发者可能使用 IRC 的并不多;微信是小团队使用比较多的沟通工具,我们可以使用微信公众号进行消息通知;或者使用国内的 LessChart 等交流工具,它们本身支持 webhook 调用。

开发环境的搭建

微服务架构导致软件模块增多,增加了开发环境搭建的难度,同时也导致了团队新成员上手门槛的提高。我们目前是利用 docker-compose 维护本地开发环境来解决这个问题的。它不仅实现了开发环境与生产环境的逻辑一致性,同时也可以让相应模块的开发者聚焦于自己的业务,不必纠结于如何启停其它微服务。下面是我们的 docker-compose 文件的一部分。

6.webp_.jpg


问题及解决
在具体实践中,还有如下几个难题。
 
MQ 消息格式统一的困境
微服务间的消息传递需要根据业务变动而频繁改动,尤其是前期,这带来了极大的沟通成本,目前没有好办法解决。
 
微服务的功能粒度切分问题
如何界定各微服务承担的功能,每个微服务的功能粒度切分,微服务间的边界定义,这也是我们团队一直在摸索的问题。
 
参考链接:
1. http://microservices.io/
2.http://www.infoq.com/cn/news/2 ... cture

技术干货 | 如何规划基于Docker的微服务架构

宁静胡同 发表了文章 • 0 个评论 • 368 次浏览 • 2016-04-26 19:28 • 来自相关话题

今天小数又漂洋过海给大家运来一篇干货,在今天的文章中,我们将一同了解如何在Docker上规划一套成功的微服务架构。

Docker的人气仍然持续升温,这主要归功于其易于打包且能够在任意环境下实现代码分发的强大能力。而在结合微服务架构的前提下,Docker足以帮助开发者们利用小型模块化组件构建软件,并充分发挥各组件功能以应对各类复杂难题。

不过要真正实现微服务架构,我们需要通过前期规则避免将其误解为分布式整体应用,否则碎片化问题也将随之而来。从服务设计到部署再到监控,利用Docker进行微服务架构部署中存在着多个需要认真考量的关键点。

为每套容器设计一项服务

在创建新的微服务时,在单一容器内部署多项服务似乎是种颇具吸引力的优化方式。然而,存在于同一容器实例中时,各服务将无法独立实现规模伸缩。

规划技巧一: 采取每个容器一项服务的做法能够有效支持微服务的按需规模伸缩,且无需面对由多服务容器带来的内存与CPU过度占用问题。

建立服务发现方案

为了实现规模化与高可用性要求,微服务需要跨越多台Docker主机进行分布。请注意,千万不要在服务当中使用硬编码形式的主机名称或者容器IP地址。相反,大家应当在代码以及负责管理一个或者多个容器实例的Docker基础设施当中建立服务发现机制,即根据名称进行服务定位。

规划技巧二: 选定一项服务发现策略,并确保其能够根据容器实例的规模伸缩进行自动调整。具体选项包括:ZooKeeper、Consul、Etcd、Eureka或者使用内部DNS策略。

通过CDN实现共享资产分发

对于大多数Web应用,其中都会涉及共享资产,例如图片、样式表以及JavaScript库。如果大家使用的是Ruby on Rails之类的框架,那么asset pipeline将成为管理这一流程的有效工具。然而,其在生产环境下的管理工作仍然相当困难。由该pipeline在单一容器内生成的资产无法为其它容器所共享。解决方案分为两种:其一,确保每个容器实例都能够生成并使用资产(不推荐);其二,将资产推送至单一共享位置。

规划技巧三: 利用CDN打理静态及动态生成的资产。通过这种方式,我们能够改进浏览性能,同时帮助专门设计用于处理输入API请求的容器实例减轻负担。其还能简化容器基础设施,意味着我们不再需要为跨容器实例资产共享设计额外的实现方式。

外部化、监控并管理微服务

在一套典型云原生架构当中,进来的的HTTP请求需要跨越各服务器实例进行负载均衡。然而,大多数基于云的负载均衡器都只能将请求路由至服务器,而非单一服务器上的多个容器。通过在基于HTTP的微服务之前安装反向代理,输入的请求可被正确分发至多Docker主机上的任意数量容器实例当中。

除了负载均衡,基于HTTP的微服务可能还需要使用验证、授权以及速率限制等功能。将服务开放给移动或者公众/合作开发者时,我们还需要预防DoS攻击,并将来自单一外部URL结构的负载路由至内部微服务(例如http://api.example.com/products/ -> http://products.myapp.local/)。

规划技巧四: 安装反向代理及/或API管理平台。目前市面上存在着多种商用及免费开源的产品供选择,包括:3scale、Apigee、Kong等,也可以通过nginx的定制化调整实现。

将数据库部署在容器之外

与配备有网络块存储设备的传统云服务器不同,容器自身拥有一套独立于主机之外的隔离化文件系统。容器内的数据会在容器本身被销毁后一并消失。另外,我们不可能长时间将容器运行在同一主机当中。因此,在没有做大量的额外工作的情况下,将主机文件系统作为外部卷并不能完全保障生产数据的持久化。我们需要更好的数据库方案,来保障数据的安全和高性能。

规划技巧五: 在容器之外设置并部署数据库。使用数据库即服务方案能够帮助我们摆脱管理自有实例的困扰,当然立足于容器外建立自己的托管数据库方案也是可行的。惟一的例外就是,如果大家的微服务中包含只读数据,则可将其在镜像创建过程中打包在容器之内。 查看全部

今天小数又漂洋过海给大家运来一篇干货,在今天的文章中,我们将一同了解如何在Docker上规划一套成功的微服务架构。



Docker的人气仍然持续升温,这主要归功于其易于打包且能够在任意环境下实现代码分发的强大能力。而在结合微服务架构的前提下,Docker足以帮助开发者们利用小型模块化组件构建软件,并充分发挥各组件功能以应对各类复杂难题。

不过要真正实现微服务架构,我们需要通过前期规则避免将其误解为分布式整体应用,否则碎片化问题也将随之而来。从服务设计到部署再到监控,利用Docker进行微服务架构部署中存在着多个需要认真考量的关键点。

为每套容器设计一项服务

在创建新的微服务时,在单一容器内部署多项服务似乎是种颇具吸引力的优化方式。然而,存在于同一容器实例中时,各服务将无法独立实现规模伸缩。

规划技巧一: 采取每个容器一项服务的做法能够有效支持微服务的按需规模伸缩,且无需面对由多服务容器带来的内存与CPU过度占用问题。

建立服务发现方案

为了实现规模化与高可用性要求,微服务需要跨越多台Docker主机进行分布。请注意,千万不要在服务当中使用硬编码形式的主机名称或者容器IP地址。相反,大家应当在代码以及负责管理一个或者多个容器实例的Docker基础设施当中建立服务发现机制,即根据名称进行服务定位。

规划技巧二: 选定一项服务发现策略,并确保其能够根据容器实例的规模伸缩进行自动调整。具体选项包括:ZooKeeper、Consul、Etcd、Eureka或者使用内部DNS策略。

通过CDN实现共享资产分发

对于大多数Web应用,其中都会涉及共享资产,例如图片、样式表以及JavaScript库。如果大家使用的是Ruby on Rails之类的框架,那么asset pipeline将成为管理这一流程的有效工具。然而,其在生产环境下的管理工作仍然相当困难。由该pipeline在单一容器内生成的资产无法为其它容器所共享。解决方案分为两种:其一,确保每个容器实例都能够生成并使用资产(不推荐);其二,将资产推送至单一共享位置。

规划技巧三: 利用CDN打理静态及动态生成的资产。通过这种方式,我们能够改进浏览性能,同时帮助专门设计用于处理输入API请求的容器实例减轻负担。其还能简化容器基础设施,意味着我们不再需要为跨容器实例资产共享设计额外的实现方式。

外部化、监控并管理微服务

在一套典型云原生架构当中,进来的的HTTP请求需要跨越各服务器实例进行负载均衡。然而,大多数基于云的负载均衡器都只能将请求路由至服务器,而非单一服务器上的多个容器。通过在基于HTTP的微服务之前安装反向代理,输入的请求可被正确分发至多Docker主机上的任意数量容器实例当中。

除了负载均衡,基于HTTP的微服务可能还需要使用验证、授权以及速率限制等功能。将服务开放给移动或者公众/合作开发者时,我们还需要预防DoS攻击,并将来自单一外部URL结构的负载路由至内部微服务(例如http://api.example.com/products/ -> http://products.myapp.local/)。

规划技巧四: 安装反向代理及/或API管理平台。目前市面上存在着多种商用及免费开源的产品供选择,包括:3scale、Apigee、Kong等,也可以通过nginx的定制化调整实现。

将数据库部署在容器之外

与配备有网络块存储设备的传统云服务器不同,容器自身拥有一套独立于主机之外的隔离化文件系统。容器内的数据会在容器本身被销毁后一并消失。另外,我们不可能长时间将容器运行在同一主机当中。因此,在没有做大量的额外工作的情况下,将主机文件系统作为外部卷并不能完全保障生产数据的持久化。我们需要更好的数据库方案,来保障数据的安全和高性能。

规划技巧五: 在容器之外设置并部署数据库。使用数据库即服务方案能够帮助我们摆脱管理自有实例的困扰,当然立足于容器外建立自己的托管数据库方案也是可行的。惟一的例外就是,如果大家的微服务中包含只读数据,则可将其在镜像创建过程中打包在容器之内。

实录分享 | IBM马达:Kubernetes/Swarm on Mesos

宁静胡同 发表了文章 • 0 个评论 • 335 次浏览 • 2016-04-22 18:09 • 来自相关话题

4月17日,Mesos爱好者在北京P2联合创业办公社迎来了第四次Mesos User Group约会,下面是来自IBM马达的分享实录。

作者介绍:马达,IBM 高级软件工程师,Kubernetes/Mesos代码贡献者。

很高兴参加这次活动,之前我一直从事分布式计算;从硕士阶段就开始在做分布式资源的调度及优化这一块,当时是基于Globus做跨机群的资源调度。毕业时加入了百度,后来进入了Platform Computing公司;Platform Computing是一家有着20多年分布式经验的公司;2012年Platform Computing被IBM收购,现在做为IBM一个子部门继续从事分布式相关的工作。凭借我们在分布式方面非常丰富的经验,我们在与分布式相关的开源项目都有比较多的贡献,这次主要讲与Mesos, Kubernetes,Swarm相关,还有其它团队在做Spark相关的项目。我会介绍一下Kubernetes和Swarm与Mesos的集成;比如说在公司的选型上谈一下我自己的想法,大家可以一起交流,如果有一些其他的想法,大家也可以一起讨论。







我先简单介绍一下这三个产品,然后讲一讲为什么要把Kubernetes和Swarm集成到Mesos上;然后介绍一些集成的细节,后面还有一些遇到的Challenge。最后,我们已经有一款自己的产品,叫EGO,和Mesos比较像。后续会逐渐将我们的经验及想法贡献到社区,我们做的主要是资源的调度,提高云和集群中资源的使用效率。







首先介绍一下三个产品;Kubernetes是Google推出的,参考Google Borg的开源实现,现在支持它的有红帽、惠普、华为等企业。Swarm是Docker下的项目,Swarm的目标是100%兼容Docker API,现在已经达到90%多;有些API在分布式环境中比较难处理,后面会有介绍。Mesos是这次演讲的重点,Mesos由Mesosphere公司来支持,第二大的commiter是Twitter,第三大的社区贡献者是IBM。IBM上个季度贡献了200多代码。Mesos主要是为了将资源抽象出来,尤其是CPU这些资源抽象出来,使整个集群看起来就像一台机器;用户只要关心他使用什么样的资源就可以了,这是Mesos的作用,也就是进行资源的调度和编排,提高整个资源的使用率,减少IO,最终降低开发和运维的成本。

我原来在百度的时候,百度的运维团队非常庞大,研发要给他写一个脚本,也就是上线步骤,告诉他第一步怎么办,第二步怎么办,第三步怎么办,运维人员按照这个脚本来执行。业务上线以后,通知研发检查有没有问题。现在跟原来的同事聊,有了很大的变化,很多东西都有自动化的脚本,包括资源的利用,大概需要什么样的资源,它会自动的支撑脚本。Mesos就是做这件事,把整个资源的运维用机器做起来,减少手动。







说一下为什么集成到Mesos上,Kubernetes和Swarm最主要的目标是Container,我们希望对资源可以共享,比如说双十一,会有峰值的时候;系统在平时会有一个估值,提供基本的服务资源;剩下的机器做一些线下的分析。Mesos为这样的需求提供了一种解决方案。


“Auto-Scaling”和“不依赖于特殊网络”;这两种个原因说服力不强:网络自己用脚本就可以做了,Auto-Scaling用脚本也差不多;主要优势还是资源共享,在DCOS上资源共享相对来说比较重要。现在大部分的公司还在专注于网络和存储,可以将容器连接进来并可以访问共享数据;但是过一段时间你会发现,网络和存储不是大的问题以后,大家会关心资源的利用率;如果10台机器的资源利用率提高10%,带来的好处并不明显,但如果是1万台机器能提高10%的利用率,那集群相当于多了1000台机,带来的效果还是很明显的。







这是Kubernetes在Mesos的一个结构图,Kubernetes最左边这个地方就是Kubernetes自己本身的一些Master的东西,其实在Master最主要的是资源调度Scheduler这一块,Scheduler的资源是Mesos Master分出来的,所以在Kubernetes对Mesos来说只是其中的一个framework,Kubernetes和Spark可以共享资源。Kubernetes提供的CloudProvide很多,它可以跟其他的云厂商可以进行集成。在调度资源里面,Kubernetes还会遵循现有的调度策略。但是有一个问题,就是Scheduler在计算的时候,分配的资源只是基于Mesos给它的东西,比如Mesos分给Scheduler机器A,但是可能机器B上有一个更优的资源,它其实是拿不到的。

Scheduler拿到资源以后还是通过Mesos来启动计算节点,Kubernetes的Master相当于Mesos的一个Framework。这个计算节点的executor其实这个做的还是蛮不错的。在Kubernetes 中提供了一个Kubelet的库用于容器的管理,这个集成项目把Kubernetes和mesos的Executor做了集成,两边做的都是蛮好的。最开始以为是Slave再去起一个Kubernetes 的 Agent,那样计算节点的开销会很大。现在的解决方案相当于是把Kubernetes集中到Mesos的Executor。Kubernetes On Mesos,自己做了Executor,改了Scheduler,基本上还保持了Kubernetes原有的功能,对原来的支持还是蛮不错的。







集成的问题,其实从总体架构来看,大家都是提供了集成的方法,但彼此的集成方案很难统一。而且在概念和功能上也有很大的区别,比如说Namespace和Quota,这是Kubernetes自己的功能,这两个彼此的资源都看不到。但是这个集成方案中,他并没有映射到Mesos自己的Role,整个Kubernetes映射成一个Role,这个Role能拿到多少Quota,就是Kubernetes 的资源。


另外就是刚才说的关于Optimistic Offer、Revocable resources。所谓资源共享,是Mesos上的一个Framework可以把自己不用的资源借出去,但是当我要的时候,我应该可以把资源抢占回来。而且当资源被抢占的时候需要给出一定的时间进行清理。Optimistic Offer现在会直接把资源抢回来,而且没有一个接口通知相应的作业进行后续的清理工作。比如说我要删某一个进程我应该告诉你怎么删,我要做一些东西。Kubernetes没有对Revocable resources做这些相应的处理。

另外,Mesos自己对Revocable Resources的支持力度也不是特别大。现在支持一种Revocable Resource:当机器分出去的Resources,但是没有用,也可以做Revocable resources。现在和Committer交流,我们经常提这个功能,他们并没有意识到资源的使用率对整个集群有多重要。集成的时候,Unified Container,把镜像下下来去解析。作为Unified Container,它并没有提供API, Kubernetes要用Docker的API完成这些工作,如果想把这些引到你的Unified Container,就意味着你的Unified Container要支持Docker的API,这对Mesos来说是很重要的。Docker的API最大问题是并没有一个统一的标准,它的镜像是可以下载下来的执行,但是Docker本身的API没有标准,Mesos的Unified Container要去兼容它的API是一件很繁重的工作。

另外就是Persistent Volume,Mesos自己提供了Persistent Volume,这个作业在机器上重启以后,这个资源所使用的文件会被留下来;如果没有Persistent Volume,则沙箱里的数据都会被删掉,这一块并没有跟Kubernetes自己的Persistent Volume集成在一块,Kubernetes自己的Persistent Volume做的事情是把Volume做成一种资源,比如说是1G或者2G,然后可以请求和作用这些资源;其实跟Mesos的功能是从想法上是完全一致的。但这里有一个效率的问题,Kubernetes自己Persistent Volume能够拿到全局所有的资源,但是如果基于Mesos的话,只能拿到Mesos固定的一些资源,所以这个Kubernetes只能基于不是最优集成拿到最好。其实最主要的大家都有自己的概念和想法,是没有一个人去做两边的集成,大家都认为应该跟随,到底谁应该跟随谁。






Swarm相对来说还简单一点,Swarm对于资源还好,最开始的时候其实Swarm他会去发一个请求,这个请求还是自己Mesos的系统,他会自己做一个Schedule,告诉Master。因为Swarm运行Docker UPS,有一个路径,所以这个东西资源分配给Swarm Cluster,这个资源分到Swarm,资源分到这,Swarm会告诉他在哪一台机器上,然后Swarm会连这台机器上的Container。再取那个信息,整个的过程是达到Swarm拿到这个机器以后会告诉Master,Run就基于Mesos自己对Docker的支持。透过这个信息也会告诉你连这个Docker,把这个信息盖了,这个集成会比较简单一点。

Swarm这一块相对来说做的稍微好一些,它会抽象成一个集群,它跟Mesos相对来说关系比较好的。但是Swarm本身的功能相对来说比较少,需要依赖于Docker,才能搭一个大的环境。集成的时候,我们有相似的这些东西,也有相似的问题,尤其是Docker API,比如说我先推一个,等我Run的时候,如果那个资源一直留在那儿的时候,这个资源一直留着,因为也不知道什么时候开始,不知道什么时候把容器起起来,这个CPU有可能闲了两天,还是用Mesos其他的功能来弥补。后面有Role和Quota,Swarm在很早的时候不支持Role,Swarm提供了基于Mesos的Role的支持。

现在Mesos和Swarm有一个集成,你经常会看到Kubernetes发一个新的版本,Mesos过两天就说我支持这个版本,最明显的是Kubernetes 1.1,Mesos马上跳出来说我支持1.1了。而Kubernetes最近发了1.2,但是Mesos却没有动静了。

Swarm最新版本我记不住了,Swarm现在还是以Docker为主。其实后面Unified Container对它来说是比较麻烦的一件事情。刚才我们说了Swarm会连机器,如果你用Unifed Container,最后Swarm就没有办法集成。我个人猜,过一段时间Mesos如果这个集成还再继续往前走,Docker Executor有可能会跟Swarm集成放在一块去,不用Unifed Container。其实Kubernetes、Swarm这些都是依赖于Docker镜像做出来的。这一块现在有压力,现在没有一个人跳出来说这个事情到底应该怎么办。

Pesistent Volume包括有一些Role,不知道它后续想怎么去做这些新的东西,因为Swarm现在它们的集成也不是特别的安全。

Challenges这部分,对新的东西的集成,其实这种集成现在跟的特别紧。包括像Security是集成的挑战。Mesos告诉你自己想做什么样的Security就去做,你加一个用户或者改一个权限的话,它俩的集成这一块现在其实还在调查之中,自己玩一玩还好。

Multi-Tenant我刚才也说的,该怎么做决定,尤其是多层级的资源调度。比如说有一个部门,这个部门下面有三个人,每个人用到的资源我们也是在这里做,其实这种role就是一层,如果是三级部门去做这种资源分配还是很好做的。集成我们现在两个在一起做,Mesos我们会推这些资源容器,Kubernetes这一块现在是还在做的一个事情。新的集成这个只能说有新功能找新的解决方案,按案例来做。另外,集成的时候,大家都会用到Kubernetes有自己的UI,这些都是社区的,都是分开的。所以你做Monitoring要自己去做,包括集成的时候,把它的信息全都抓起来观察整个集群的信息,不能单看一个,要把所有的东西全抓住,分析整个系统资源和环境资源,是不是使用率最高的,就是说有没有错误,或者说不是按照小范围来分的。这些都是Mesosphere自己来做的。现在在社区里面其实主要支持这张PPT的上面这三个。







IBM我们自己在做分布相关的产品,我们做了Mesos on EGO,在资源调度、分配、共享等方面有很大的优势。我们在做了Mesos on EGO以后,我们会有一个统一的资源管理系统提供资源计划,资源抢占等;其实我们在EGO里面其实已经做出来了。还有资源的分配,我们原来做企业级的产品,当时最大的客户应该有300多个Role来进行资源的分配和共享。我们现在做这种Policy,我们自己的产品跟Mesos集成,另外一个也会做一些相关的通用的功能。我主要讲的内容就是这么多。谢谢大家! 查看全部
4月17日,Mesos爱好者在北京P2联合创业办公社迎来了第四次Mesos User Group约会,下面是来自IBM马达的分享实录。

作者介绍:马达,IBM 高级软件工程师,Kubernetes/Mesos代码贡献者。

很高兴参加这次活动,之前我一直从事分布式计算;从硕士阶段就开始在做分布式资源的调度及优化这一块,当时是基于Globus做跨机群的资源调度。毕业时加入了百度,后来进入了Platform Computing公司;Platform Computing是一家有着20多年分布式经验的公司;2012年Platform Computing被IBM收购,现在做为IBM一个子部门继续从事分布式相关的工作。凭借我们在分布式方面非常丰富的经验,我们在与分布式相关的开源项目都有比较多的贡献,这次主要讲与Mesos, Kubernetes,Swarm相关,还有其它团队在做Spark相关的项目。我会介绍一下Kubernetes和Swarm与Mesos的集成;比如说在公司的选型上谈一下我自己的想法,大家可以一起交流,如果有一些其他的想法,大家也可以一起讨论。

yanse马达_k8s_mesos0001.jpg



我先简单介绍一下这三个产品,然后讲一讲为什么要把Kubernetes和Swarm集成到Mesos上;然后介绍一些集成的细节,后面还有一些遇到的Challenge。最后,我们已经有一款自己的产品,叫EGO,和Mesos比较像。后续会逐渐将我们的经验及想法贡献到社区,我们做的主要是资源的调度,提高云和集群中资源的使用效率。


yanse马达_k8s_mesos0002.jpg


首先介绍一下三个产品;Kubernetes是Google推出的,参考Google Borg的开源实现,现在支持它的有红帽、惠普、华为等企业。Swarm是Docker下的项目,Swarm的目标是100%兼容Docker API,现在已经达到90%多;有些API在分布式环境中比较难处理,后面会有介绍。Mesos是这次演讲的重点,Mesos由Mesosphere公司来支持,第二大的commiter是Twitter,第三大的社区贡献者是IBM。IBM上个季度贡献了200多代码。Mesos主要是为了将资源抽象出来,尤其是CPU这些资源抽象出来,使整个集群看起来就像一台机器;用户只要关心他使用什么样的资源就可以了,这是Mesos的作用,也就是进行资源的调度和编排,提高整个资源的使用率,减少IO,最终降低开发和运维的成本。

我原来在百度的时候,百度的运维团队非常庞大,研发要给他写一个脚本,也就是上线步骤,告诉他第一步怎么办,第二步怎么办,第三步怎么办,运维人员按照这个脚本来执行。业务上线以后,通知研发检查有没有问题。现在跟原来的同事聊,有了很大的变化,很多东西都有自动化的脚本,包括资源的利用,大概需要什么样的资源,它会自动的支撑脚本。Mesos就是做这件事,把整个资源的运维用机器做起来,减少手动。


yanse马达_k8s_mesos0003.jpg


说一下为什么集成到Mesos上,Kubernetes和Swarm最主要的目标是Container,我们希望对资源可以共享,比如说双十一,会有峰值的时候;系统在平时会有一个估值,提供基本的服务资源;剩下的机器做一些线下的分析。Mesos为这样的需求提供了一种解决方案。


“Auto-Scaling”和“不依赖于特殊网络”;这两种个原因说服力不强:网络自己用脚本就可以做了,Auto-Scaling用脚本也差不多;主要优势还是资源共享,在DCOS上资源共享相对来说比较重要。现在大部分的公司还在专注于网络和存储,可以将容器连接进来并可以访问共享数据;但是过一段时间你会发现,网络和存储不是大的问题以后,大家会关心资源的利用率;如果10台机器的资源利用率提高10%,带来的好处并不明显,但如果是1万台机器能提高10%的利用率,那集群相当于多了1000台机,带来的效果还是很明显的。


yanse马达_k8s_mesos0004.jpg


这是Kubernetes在Mesos的一个结构图,Kubernetes最左边这个地方就是Kubernetes自己本身的一些Master的东西,其实在Master最主要的是资源调度Scheduler这一块,Scheduler的资源是Mesos Master分出来的,所以在Kubernetes对Mesos来说只是其中的一个framework,Kubernetes和Spark可以共享资源。Kubernetes提供的CloudProvide很多,它可以跟其他的云厂商可以进行集成。在调度资源里面,Kubernetes还会遵循现有的调度策略。但是有一个问题,就是Scheduler在计算的时候,分配的资源只是基于Mesos给它的东西,比如Mesos分给Scheduler机器A,但是可能机器B上有一个更优的资源,它其实是拿不到的。

Scheduler拿到资源以后还是通过Mesos来启动计算节点,Kubernetes的Master相当于Mesos的一个Framework。这个计算节点的executor其实这个做的还是蛮不错的。在Kubernetes 中提供了一个Kubelet的库用于容器的管理,这个集成项目把Kubernetes和mesos的Executor做了集成,两边做的都是蛮好的。最开始以为是Slave再去起一个Kubernetes 的 Agent,那样计算节点的开销会很大。现在的解决方案相当于是把Kubernetes集中到Mesos的Executor。Kubernetes On Mesos,自己做了Executor,改了Scheduler,基本上还保持了Kubernetes原有的功能,对原来的支持还是蛮不错的。


yanse马达_k8s_mesos0005.jpg


集成的问题,其实从总体架构来看,大家都是提供了集成的方法,但彼此的集成方案很难统一。而且在概念和功能上也有很大的区别,比如说Namespace和Quota,这是Kubernetes自己的功能,这两个彼此的资源都看不到。但是这个集成方案中,他并没有映射到Mesos自己的Role,整个Kubernetes映射成一个Role,这个Role能拿到多少Quota,就是Kubernetes 的资源。


另外就是刚才说的关于Optimistic Offer、Revocable resources。所谓资源共享,是Mesos上的一个Framework可以把自己不用的资源借出去,但是当我要的时候,我应该可以把资源抢占回来。而且当资源被抢占的时候需要给出一定的时间进行清理。Optimistic Offer现在会直接把资源抢回来,而且没有一个接口通知相应的作业进行后续的清理工作。比如说我要删某一个进程我应该告诉你怎么删,我要做一些东西。Kubernetes没有对Revocable resources做这些相应的处理。

另外,Mesos自己对Revocable Resources的支持力度也不是特别大。现在支持一种Revocable Resource:当机器分出去的Resources,但是没有用,也可以做Revocable resources。现在和Committer交流,我们经常提这个功能,他们并没有意识到资源的使用率对整个集群有多重要。集成的时候,Unified Container,把镜像下下来去解析。作为Unified Container,它并没有提供API, Kubernetes要用Docker的API完成这些工作,如果想把这些引到你的Unified Container,就意味着你的Unified Container要支持Docker的API,这对Mesos来说是很重要的。Docker的API最大问题是并没有一个统一的标准,它的镜像是可以下载下来的执行,但是Docker本身的API没有标准,Mesos的Unified Container要去兼容它的API是一件很繁重的工作。

另外就是Persistent Volume,Mesos自己提供了Persistent Volume,这个作业在机器上重启以后,这个资源所使用的文件会被留下来;如果没有Persistent Volume,则沙箱里的数据都会被删掉,这一块并没有跟Kubernetes自己的Persistent Volume集成在一块,Kubernetes自己的Persistent Volume做的事情是把Volume做成一种资源,比如说是1G或者2G,然后可以请求和作用这些资源;其实跟Mesos的功能是从想法上是完全一致的。但这里有一个效率的问题,Kubernetes自己Persistent Volume能够拿到全局所有的资源,但是如果基于Mesos的话,只能拿到Mesos固定的一些资源,所以这个Kubernetes只能基于不是最优集成拿到最好。其实最主要的大家都有自己的概念和想法,是没有一个人去做两边的集成,大家都认为应该跟随,到底谁应该跟随谁。

yanse马达_k8s_mesos0006.jpg


Swarm相对来说还简单一点,Swarm对于资源还好,最开始的时候其实Swarm他会去发一个请求,这个请求还是自己Mesos的系统,他会自己做一个Schedule,告诉Master。因为Swarm运行Docker UPS,有一个路径,所以这个东西资源分配给Swarm Cluster,这个资源分到Swarm,资源分到这,Swarm会告诉他在哪一台机器上,然后Swarm会连这台机器上的Container。再取那个信息,整个的过程是达到Swarm拿到这个机器以后会告诉Master,Run就基于Mesos自己对Docker的支持。透过这个信息也会告诉你连这个Docker,把这个信息盖了,这个集成会比较简单一点。

Swarm这一块相对来说做的稍微好一些,它会抽象成一个集群,它跟Mesos相对来说关系比较好的。但是Swarm本身的功能相对来说比较少,需要依赖于Docker,才能搭一个大的环境。集成的时候,我们有相似的这些东西,也有相似的问题,尤其是Docker API,比如说我先推一个,等我Run的时候,如果那个资源一直留在那儿的时候,这个资源一直留着,因为也不知道什么时候开始,不知道什么时候把容器起起来,这个CPU有可能闲了两天,还是用Mesos其他的功能来弥补。后面有Role和Quota,Swarm在很早的时候不支持Role,Swarm提供了基于Mesos的Role的支持。

现在Mesos和Swarm有一个集成,你经常会看到Kubernetes发一个新的版本,Mesos过两天就说我支持这个版本,最明显的是Kubernetes 1.1,Mesos马上跳出来说我支持1.1了。而Kubernetes最近发了1.2,但是Mesos却没有动静了。

Swarm最新版本我记不住了,Swarm现在还是以Docker为主。其实后面Unified Container对它来说是比较麻烦的一件事情。刚才我们说了Swarm会连机器,如果你用Unifed Container,最后Swarm就没有办法集成。我个人猜,过一段时间Mesos如果这个集成还再继续往前走,Docker Executor有可能会跟Swarm集成放在一块去,不用Unifed Container。其实Kubernetes、Swarm这些都是依赖于Docker镜像做出来的。这一块现在有压力,现在没有一个人跳出来说这个事情到底应该怎么办。

Pesistent Volume包括有一些Role,不知道它后续想怎么去做这些新的东西,因为Swarm现在它们的集成也不是特别的安全。

Challenges这部分,对新的东西的集成,其实这种集成现在跟的特别紧。包括像Security是集成的挑战。Mesos告诉你自己想做什么样的Security就去做,你加一个用户或者改一个权限的话,它俩的集成这一块现在其实还在调查之中,自己玩一玩还好。

Multi-Tenant我刚才也说的,该怎么做决定,尤其是多层级的资源调度。比如说有一个部门,这个部门下面有三个人,每个人用到的资源我们也是在这里做,其实这种role就是一层,如果是三级部门去做这种资源分配还是很好做的。集成我们现在两个在一起做,Mesos我们会推这些资源容器,Kubernetes这一块现在是还在做的一个事情。新的集成这个只能说有新功能找新的解决方案,按案例来做。另外,集成的时候,大家都会用到Kubernetes有自己的UI,这些都是社区的,都是分开的。所以你做Monitoring要自己去做,包括集成的时候,把它的信息全都抓起来观察整个集群的信息,不能单看一个,要把所有的东西全抓住,分析整个系统资源和环境资源,是不是使用率最高的,就是说有没有错误,或者说不是按照小范围来分的。这些都是Mesosphere自己来做的。现在在社区里面其实主要支持这张PPT的上面这三个。


yanse马达_k8s_mesos0010.jpg


IBM我们自己在做分布相关的产品,我们做了Mesos on EGO,在资源调度、分配、共享等方面有很大的优势。我们在做了Mesos on EGO以后,我们会有一个统一的资源管理系统提供资源计划,资源抢占等;其实我们在EGO里面其实已经做出来了。还有资源的分配,我们原来做企业级的产品,当时最大的客户应该有300多个Role来进行资源的分配和共享。我们现在做这种Policy,我们自己的产品跟Mesos集成,另外一个也会做一些相关的通用的功能。我主要讲的内容就是这么多。谢谢大家!