今天和大家分享的主题是“去哪儿应用运维自动化的演进”。自动化构建过程中遇到的障碍以及我们是如何克服这些障碍的,我们遇到了哪些坑,以及如何填这些坑的过程。2013年加入去哪儿,一直从事运维开发工作。去哪儿网的运维发展有一个特点。所有的开发人员都是PM和QA,没有前端工作和后端工作的区别。用现在比较流行的话来说,我们都是全栈工程师。加入去哪儿这几年,我做的工作比较零碎,有需求就去哪里。综上所述,主要涉及主机管理、应用管理、监控、告警平台的设计、开发和运维。下面简单介绍一下我们的运维团队:我们的运维团队负责公司所有服务器、网络等硬件平台的运维工作。部分人员从事日常运维工作,包括QVS部署、Nginx配置、应用上线支持、存储部署等,以及告警通知、故障通知和跟踪。2013年前后,我们开始研发自己的运维平台。负责公司内网的应用,包括OA系统、HR系统、IT资产管理平台等。去哪儿应用运维平台介绍首先简单介绍一下去哪儿应用运维平台。我们知道,一个应用程序从开发到上线运行的生命周期主要涉及四个部分:应用程序资源管理,这些资源包括应用程序部署所需的主机、应用程序镜像、文件、对象存储所需的存储资源、应用程序通信和其他网络带宽,作为以及应用所需的计算资源等。为提高应用开发效率,保证应用开发规范,我司将提供公共中间件,包括日志采集、应用配置注册、监控告警指标采集、和应用程序调用路径。为了将我们的应用发布到线上,我们需要对应用进行代码管理和构建测试才能发布到线上,这就需要CI/CD持续发布和持续集成。当应用上线后,我们需要对应用的性能指标和业务指标进行监控、告警和分析,因此需要一个应用相关的监控、告警和日志分析平台。去哪儿网的业务也一步步发展起来。机器数量从几十台增长到几万台。我们在开发过程中遇到了很多问题,在不同的阶段我们也提出了不同的解决方案。去哪儿网经历的阶段分为四个部分:运维机数量比较少,大部分工作是应急运维。比如我们发现某个应用程序有问题,我们就登录到这个应用程序的相关机器上,手动执行Linux命令来查看这台机器的资源使用情况。比如CPU是不是太高了,磁盘是不是满了。这个阶段没有用到复杂的脚本,基本都是手工操作,有几十台机器。随着规模的扩大,很多脚本都是手工编写的。通过这些脚本,我们可以批量执行任务,在多台机器上批量部署应用和监控。这个阶段,我们称之为脚本运维阶段,使用脚本,结合开源系统,完成上百台机器的运维。随着规模越来越大,脚本运维不够,远远不能满足需求。脚本可能都是分类脚本,并没有安排好,所以脚本的执行顺序比较重要,安排不当可能会导致一些问题。我们开发一些相关的系统,利用系统将相关的脚本串联起来,排列成单独的操作。例如,机器的创建和删除是单独的操作。如果把这些做成一个系统,运维人员就可以在界面上进行操作。这个阶段,我们称之为离散系统,数据在各个系统之间基本没有很好的共享。现阶段可以运维的主机数量也比较有限,几千台主机比较好。紧接着,去哪儿网机台规模突破万台。这个时候我们就考虑了能不能从一个比较高的角度来合理的设计运维平台。为我们的运维工作提供一站式服务。在一站式服务的基础上,我们实现了数据的互通,这样我们就可以进行交互,做一些自动化的工作。这个时期也是我们今天要讲的,就是运维平台的建设。应用运维平台的三个关键点在运维平台的建设过程中,我们遇到了很多困难和陷阱。在这些难点中,归纳出三个重点:主机管理。监视警报。数据交换。主机管理去哪儿网的主机管理系统基于OpenStack和DNSDB。OpenStack负责调度和创建虚拟机,DNSDB是域名管理系统。通过DNSDB,我们可以将一台机器的名称、部门、用途、所在的机房组合成一个唯一的域名,我们用这个唯一的域名来标识主机。在OpenStack和DNSDB之上,我们编写了大量的脚本文件和工具,将这些脚本文件和工具整理??,并一一打包成操作,并且我们对这些操作赋予了一些相关的权限。我们在日志库中存储主机信息、流转管理、权限配置、操作日志查询等。最后我们会暴露一个主机管理系统的接口给运维人员,运维人员通过这个接口来管理我们的主机。借助主机管理平台,运维人员可以方便地在该平台上创建和销毁主机,查看主机的相关信息,如主机的配置、保外信息等。在添加每台新机器的过程中,我们都会默认给机器添加一个监控告警,当机器有告警时会通知相关负责人。这样做还是会有一个比较大的问题,就是我们的系统是怎么开发出来供运维人员使用的,开发者是没有权限登录这个系统的。如果有开发者提出需求,我要创建主机,需要发邮件给OPS。OPS在创建这个host的时候,并没有具体记录负责人是谁。他可能会写在备注中,随着时间的推移,这个备注可能会变得不准确。因为当时的负责人可能已经离职或者调任了,所以这种情况经常发生。负责这台机器的部门并没有很好的记录下来,因为这个部门大部分只体现在宿主的名字上,但是有可能这台机器在使用过程中被调到其他业务线,这样我们的部门信息得到的也是不准确的。还有一个问题就是DB系统只对运维人员开放,业务线很少涉及。导致整个主机的相关信息其实不够准确,因为OPS人员毕竟有限,不可能把这些信息维护的非常准确。这样,我们想到了一个方案,通过应用树来解决。去哪儿网按照职能领域将业务线划分为BU。应用树BU是第一层,下面有部门,部门下面还有更小的部门。这个级别可能是多个。最后一层是部门负责的应用,应用就是最后一层。我们把各级看做一个节点,每个节点可以绑定一个host,给节点添加负责人,给节点添加审批人。下面介绍审批人的权限和角色。有了这个应用树,业务线的开发参与了宿主的管理,他们的负责人和部门信息更加准确。一台机器出现异常,我觉得很容易很快找到这台机器的负责人。如果宿主机即将到期,我需要找到上面所有虚拟机的负责人,通知这些人进行相关操作,比如下线虚拟机和应用程序,这样就可以避免操作过多导致的故障和维修主机不在保修范围内。因为机器负责人比较精准,我们的告警通知会默认将机器所有的监控告警通知相关负责人,由负责人处理机器相关的基础硬件告警。每个季度都会统计资源的消耗情况,也会对下个季度的机器采购进行规划和预算。如果拿到一个更高级别的部门,比如一个BU节点,通过应用树可以很容易的得到这个部门的机器,以及这个月的增长率,这样我们就可以很容易的预测下一个季度。需要购买多少台机器,这样才能做出更合理的预算。有了用户之后,负责人、部门、机器的关系就比较清晰了。但有一个问题。申请资源的时候还是需要OPS操作,添加账号也是OPS负责。如果一个开发者想要扩展一台机器或者给一台机器添加一个账号,他应该怎么做呢?他需要发邮件给运营OPS的团队,说我想把应用扩展到两个主机,或者给哪个主机加个账号。这样做的缺点是什么?首先,OPS不能实时在线,也不能盯着系统。这样OPS响应很慢,查询邮件也很不方便。而且邮件时间长了可能会丢失,问题也不容易定位。如何解决这个问题呢?接下来我们又做了两个系统:第一个是主机申请系统,第二个是账号申请系统。这两个系统都是以主机管理、应用树、审批中心为基础,调用主机管理、应用树、审批中心为接口,通过调用接口安排一些合理的主机申请和账户申请流程。刚才我们提到宿主申请的时候,谁有申请权限,申请树上每个节点的负责人都有权限申请本部门的宿主或者本申请的宿主,审批人在节点有权限审批本节点下的Hosts。这样OPS就不需要过多参与,他们可以自动申请hosts和account。最后我们做了一个接口,把这个接口暴露给开发者。开发者可以申请主机和账号。应用树、主机管理、主机应用、账号应用四个平台闭环。核心是应用树节点,将四部分串联起来。如果应用程序树节点有任何问题,我们将对其进行更改。比如一开始,一个门户应用被放在了OPS开发下。Portal从运维开发走向运维。还有一个。随着业务的增长,门户的应用范围越来越大。它需要分成几个部分。比如需要拆分成portal-web和portal-api。这个树节点的变化会导致什么?我们每个系统都记录了应用树节点,每个应用树节点变化的时候需要同步每个系统。这就相当于在分布式系统中有一个有状态的模块,就是应用树节点模块。它是有状态的,有状态使我们很难分发。如果我们想把应用树节点扩展到更多的系统,会非常困难,我们会不断面临同步问题。如何解决这个问题,比如对于一个普通居民来说,如何在各个系统之间共享数据,比如我如何在公安系统、户籍系统、银行系统等各个系统之间共享数据我?我的信息。现实中有一个很好的做法,就是使用身份证,身份证是唯一的。有了这样一个唯一的ID,应用程序就可以被识别,而且这个ID永远不会改变。我们如何找到这样的ID?第一种解决方案是使用数据库中的自增ID或UUID来标识应用程序。这样可以保证应用ID唯一不变,但是由于自增ID和UUID在文字上没有明确的含义,我们开发者不容易记住这个ID并与之交流。如果要使用自增ID或者UUID,需要用另外一个系统看看我有多少这样的ID。需要先找到这个ID,然后再与其他系统进行交互通信,非常不方便。第二种方案是在身份证上画,用数字,比如110代表北京,后面是县区,代表自己的出生年月日。借鉴身份证ID,我们使用这样一种称为Appcode的方案来识别应用程序。Appcode基本上是用一条滑线来划分的。第一个是应用所在的部门,第二个是应用的描述。这个级别也可以很长。用这样一个Appcode来代替申请号节点,可以保证唯一性和不可篡改,便于大家记忆,也更容易交流。我们最终选择了第二种方案。监控告警我们来看看我们在运维平台上是如何做监控告警的。作为一家互联网公司,保证7x24小时的服务是最基本的要求。如何保证7x24的服务?如果系统出现问题,我们可以提前预警和发现,当系统真的出现问题时,我们可以及时发现。为了保证这两点,我们需要监控报警系统。去哪儿网的监控报警系统也经历了长期的奋斗。一开始,每个部门都会维护自己的系统。一开始是由Cacti和Nagios这两个模块搭建的。问题是什么?Cacti部署在单机上,无法水平扩展,导致性能较差。如果单机出现异常甚至宕机,那么我们的监控告警系统将完全不可用,所以这是一个非高可用的方案。每个部门都会维护一套自己的监控系统,即使是比较大的部门,比如酒店、机票等大部门,也可能会维护很多套,而每一套都需要专门的人员来运维,而运维人员成本也很高。很高。由于之前的系统没有很好的权限管理,这个系统只能由专人负责,因为把权限放给他人比较危险,可能有人不小心操作了什么,删了报警或者修改了报警配置,所以报警只能找专人。定制一个告警监控沟通成本很高,需要联系我们的相关负责人,然后进行告警配置。开发人员觉得太麻烦,所以根本不做,或者做的很少,导致我们的监控不够完善,有些异常甚至故障可能没有及时发现,效率比较低低的。如何解决这个问题呢?我们搭建了公司级统一监控告警平台Watcher。告警平台有几个目标:高可用,如果一台机器或者几台机器挂了,对我们没有影响或者影响很小。大家配置这个告警还是比较容易的。我们搭建了一个权限管理系统,也是一个基于应用树的树状权限管理系统,并且把整个Watcher接口开放给所有的开发者,让大家使用起来非常方便。自带报警和监控。简单介绍一下守望者。Watcher是基于Graphite深度开发的。Watcher平台不仅支持主机基础监控告警,还支持业务监控告警。他们都在一个统一的平台上。监控告警可以在统一的界面上供开发者查看和查看。配置。Watcher是2014年左右开始的,到现在已经三年了,在公司里推广得很好。现在Watcher接入的应用超过1500个,指标数量超过2000万,告警数量超过40万,接入基础监控的机器数量超过4万。这么大规模的Watcher,我们用什么样的架构呢?这个架构图只是我们Watcher集群的一个架构图。在统计的时候,我们会区分每个指标应该打在哪个簇上。我们如何区分?使用指标作为标识符。例如,所有测试数据测试指标都以t开头,所有主机数据都以h开头。我们用s.flat来代表机票部门。在统计机票部门的所有指标时,必须配置一个服务器。这个服务器也是用域名来表示的,它本身就代表一个机票监控告警集群。在上面的集群架构图中,最下面绿色的是Graphite原有的组件,我们在原有组件的基础上开发了几个相关的组件。第一个是中继。每个指标发出后,我们通过Relay将指标分发到多台机器上。这是通过一致性哈希实现的。拿到号后,Graphite-api部分也是我们自己开发的。Graphite-api也有相同的一致性哈希算法。通过这个算法,我们可以找到索引在集群中的哪台机器上,并在这台机器上调用。api下的graphite-web,然后获取相关数据。这是一个集群架构,我们有多个集群。Watcher需要有一个统一的接口。在该界面配置自己的监控时,选择数据源。对于计数的人来说,他知道指标在哪里。能不能做一个统一的数据源供用户使用,这样我们就可以在组件里面加一个纯指标的数据库,每次有流量过来,我们就把这个指标的名字写到我们的数据库里。还要记录它在哪个集群。这样我们就可以对外报一个统一的Graphite-api。如果我们要对一个指标使用s.flat-xx指标,我们首先调用api查找s.flat-xx指标在什么cluster中,找到ticket中的cluster中,这个index即可通过一致性哈希取出。Graphite-api的第一部分是使用这个Dashboard来报警。下面说说整个Watcher的架构。让我们看看主机监控是如何完成的。首先,有一个硬件管理平台,维护着主机监控的相关信息。最重要的是安排agent,维护agent的版本配置,不断扫描主机,部署到主机上,定期检查指标是否采集到。如果出现断点或者主机指示灯有问题,就会报警检查是Collectd的问题,还是系统的问题,还是网络的问题。在每台主机上部署Collectd后,会根据不同的配置显示不同的指标,如CPU使用率、内存使用率、网络带宽使用率等。这些指标将被标记为Watcher。每个主机的指标可能相同。为了区分不同主机的指标,我们使用主机名作为区分。连接Watcher后,我们就可以在Dashboard上调用api了。业务监控也类似。应用连接后会暴露出api,里面有应用最近1分钟内的监控数据。Qmonitor服务器每分钟从所有机器上拉取这个文件,拿到文件后进行集中分析。分析后,做相应的处理。比如对应用进行统计,计算完成后,以Appcode作为标识,区分不同的指标,将指标推送给Watcher。推送到Watcher后,还可以查询监控,查看应用指标的健康状态。数据互通下面说说我们是如何实现整个运维平台的数据互通的。我们在监控告警和主机管理中提到了一个Appcode,去哪儿网的Appcode到底是什么?事实上,它是唯一的识别应用程序。我们抽象了一个应用,它有更广泛的意义。Qunar.com上的应用程序可以是Web服务、GPU云实例、MySQL实例,甚至是一组交换机,或其他。为什么我们需要像这样抽象应用程序?抽象的好处是我们不需要考虑服务和资源的具体细节。我们使用App来表示服务或资源。在抽象的过程中,我们不需要考虑这个。服务到底是做什么的,这个资源是什么样子的。定义广义应用的公共属性,包括应用负责人、应用权限、应用账单等。有了这些共同的属性,我们就可以在多个系统中扩展Appcode,并将它们分布在各个系统中,实现数据共享。这是做什么的?有了Appcode,我们就可以在我们的各个系统中形成一种通用语言,这个通用语言就是Appcode。有了这种通用语言,我们就可以把各个系统之间的数据连接起来,最终实现数据互通。实现数据互通有什么好处?我们在主机、存储、计算等各个系统中监控Appcode,这些都是应用程序的资源部分。Appcode分布在多个系统中,多个系统相互交互。一个数据分布的节点越多,对这个数据的准确性要求就越高,因为这个数据可能在多个系统之间使用,它的负责人会更加关注这个数据,所以他们更愿意把这个数据做的更好准确的。数据更准确之后,它就变得更有用了。因为数据是准确的,所有的系统都愿意使用这个数据,形成一个相对良性的生态循环。因为数据是互通的,我们可以搭建一个对外暴露统一接口的Portal平台,可以对我们应用涉及的各个部分进行一站式管理。Portal平台简介简单介绍一下目前正在开发中的Portal平台。Portal基于Appcode,在Appcode的基础上连接各种运维系统。例如主机、账号、GPU云、ES云、应用注册、应用配置、应用中间件、环境配置、代码仓库、测试、发布、监控、告警、日志收集、故障管理等。我们将这些系统聚合成一个Portal接口,暴露给开发者。进入这个系统后,开发者可以一站式完成所有想做的应用相关的事情。数据互通还有一个好处就是刚才我们讲主机管理的时候,主机可能有不同的维度来说明主机不一样。例如,当一个应用程序被发布时,有一个发布主机列表。计费时,有一个计费主机列表。收集日志时,还有一个主机列表。在收集监控告警时,还有一个主机列表。只要数据是互通的,我们就可以把这些数据串联起来。比如在我们的应用中,它的主机需要扩容,需要扩容两台主机。扩容后,我们可以根据应用的负责人自动为主机添加相应的账号。这样,其负责人就可以使用该账号登录相应的系统,进行相应的操作。数据库还有IP白名单限制等其他限制。有了数据互通,就不需要在每台主机上记录一个应用的白名单配置,只需要记录在Appcode中即可。在CI/CD部分,应用发布的主机也与Appcode相关联。应用扩展后释放的主机也同步。您可以选择这些主机进行发布,直接发布。您不需要手动填写这些主机的列表。监控分为两个方面,一个是基础监控,一个是业务监控。基础监控也是相关主机的基础监控,可以通过Appcode维度查看。对于业务监控的应用监控指标集合,也可以通过Appcode获取其主机列表,自动将这些机器列表添加到业务监控指标集合中,添加后收集这些应用相关主机的监控指标和日志。告警系统,因为有了Appcode,会对应一些常见的监控告警项,比如Java中的GC告警。我们有了Appcode之后,就可以在每个Appcode上默认给所有机器添加GC告警了。这个GC告警联系人是Appcode的负责人,它的GC告警是每台机器扩容后自动添加的。日志收集也是如此。之前,我们可能还需要手动维护这个平台。使用Appcode,可以同步此列表。数据互操作性还有另一个好处。通过Appcode,我们可以轻松计算出这个应用消耗的账单。为什么要计算应用程序的账单?一方面可以让我们提高成本意识,这也是在选择过程中需要考虑的。例如,业务线有一些数据需要记录。它可以选择任何系统、数据库或Watcher。如果业务访问的频率很低,比如一天几次或者十几次,那么把这些数据记录到Watcher上的成本其实是非常高的,因为Watcher的数据扩展性很强,成本更高-有效选择数据库或日志。第二个可以优化。如果你因为算法的原因使用了很多机器资源,他们拿到单后会自觉地节省成本。有了成本意识,我们才能更合理地分配资源。比如有些应用本身不是很重要,申请了很多机器,机器使用率不高。当你拿到账单的时候,你可以看到这么一个不重要的应用消耗了这么大的账单,然后他们会回收一部分资源。.目前我们在不断接入各种应用账单,比如主机账单、网络带宽账单、监控告警、日志采集、大存储、计算资源账单等一系列账单,会慢慢接入。做一个总结。在去哪儿的运维自动化过程中,我们经历了不同的阶段。我们发现,当应用扩展到一定规模时,需要在平台上进行运维,而自动化或半自动化的方式非常耗费人力,粗略地会发现一些错误甚至故障。去哪儿的运维自动化也很好,怎么体现呢?我是2013年加入公司的,我加入的时候大概有五六个人做日常运维。现在日常运维我们还有六个人。我们又推出了一款运维机器人,运维第七人。我们依然保持着六人的状态。我们的规模扩大了很多倍,从一百到一万,规模扩大了几百倍。但是我们日常的运维人员并没有增加。这就是运维平台自动化带来的好处。.应用的可用性需要监控和报警系统的保证。基本上,一个应用的所有关键告警和监控都会在上线前设置好,这样如果应用出现问题,可以快速回滚或调试。因为我们有完善的监控报警系统,所以去哪儿网出现的故障比较少。平均下来,一天只有两三次失败。但去哪儿网的故障可能与其他故障有所不同。去哪儿网的故障要求比较严格。一旦出现网络故障,我们会批量记录故障。比如Watcher的监控系统是不显示任何图片的。5多分钟后,我们可以排查P1和P2的故障。在这样严格的要求下,我们的过失不会太高。我加入公司四年来,累计故障次数只有3000次左右。为了保证我们整个运维生态的发展,我们需要打通数据,这就需要一个应用的ID。有了这个ID,我们就可以在各个运维系统和平台上共享数据,形成一个良性的生态循环。郑松宽,去哪儿高级运维工程师。2013年加入去哪儿平台事业部,从事运维开发工作。工作中,主要负责公司监控系统的开发,应用管理平台Portal的设计、开发和运维。
