8月19日数人云Meetup上来自当当网的高洪涛老师做了《当当云原生DevOps实践》的主题分享,从应用改造入手,重点讲述了运维核心—监控的相关内容。
数人云提醒:8000字长文值得分享与收藏!
今天跟大家分享下,目前比较流行的云原生概念个人关注要点:
- 首先:在于整个应用的改造,包括Infrastructure,有12个要素
- 其次:运维的核心——监控,主要讲一下核心指标如何确定
- 第三:当当运维网络采用的Service Mesh架构相关内容
- 第四:日志的搜集等
云原生即Cloud Native,最早来源于如Landscape此类做微服务的公司,线路图包括几层:
第一层:应用的定义与开发,开发要符合云原生的标准,如何让应用在开发阶段达到此标准,是本次分享首先要探讨的内容。
第二层:编排和管理,大家对这个概念了解较多,如DCOS、Kuberentes、Mesos以及Docker Swarm,包括像Docker Conpose的一些配置化管理可能也会在编排里。
第三层:运行态,环境从外部获得相关的一些概念。
第四层:迷你环境的配置与安装,一部分人可能原来用过,最早如Puppet、Self以及最近的Ansible,此类组件都会作为这一层使用。
最底层:普通的IaaS层、包括逻辑、运营商。
若应用符合多层的规范,即可轻松的横向扩展、在不同云间做迁移,能在公有或私有云上跑,但这比较难,因为很多应用上云之前要经过改造,所以个人认为云原生本身是对架构的挑战,其让应用可以在云中间来回穿梭,而不会不适应。
上图是网上的开源图:Cloud Native Computing Foundation即常说的CNSAD,一个云原生基金会组织,其实就是一些云原生品牌大联盟,若从上到下都使用此体系,那么你也是云原生的了。
例如,最左边是语言,最顶级为GO语言,号称最适合做微服务的语言,然后是一些编排工具:持续集成工具,以及比较流行基于服务的中间件,第二层编排工具,首先是Nginx,如常用的Mesos、Nomad,中间是配置工具:Etcd、ZK,后面是一些网络服务管理,当当使用比较多的是GRPC,以及本次分享会涉及到的Linkerd,它旁边是Buoynt,也是Linkerd的开发者。
对于运行态来说,基础的运行S3较为常见,如Docker、Rkt就是运行环境的容器,云原生目前提供几个方便的如CALICQ(当当目前正在研究),OVS,再底层是构建工具:如ANSIBLE。最底层如微软的相关产品,AWS进入中国后发展也比较迅速。另外还有阿里云、京东云等类似的公有基础服务平台对外提供一些服务,供商家运行调用,以及一些边缘服务,如Splunk、如当当的Elastic流水线。
云原生应用的12条军规
前面的整套产品线用下来,即可认为应用是云原生的,而什么是云原生标准的套路呢?个人认为有12个因素,即云原生应用的12条军规,有些概念和微服务重合,但云原生的概念要大于微服务。
上图是当当目前内部运维的作业平台,整合了整个DevOps理念,有人讲DevOps时首先强调的是Developer和Operater,但我认为其核心在于测试,当当内部以测试为核心带动开发和运维,保证服务的可用性,三个团队紧密配合将整个服务推向一个稳定的局面。
上图是12条因素即12条军规,这里挑几个重要进行讲解:
Codebase:和整个测试环境有关,大家拉基线是为了整个版本的稳定性。
依赖:要解决依赖的问题,若用Java的话,意义不大,原始上会有依赖管理,但电商公司有各种语言都非常原始,直接依赖于源代码,若其版本发生变化,有些API就编译不过去。
Configuration:Java和其他语言非常冲突就在于此,做Java的同学都知道配置一般都会打在根应用的生产日报里,会有大量的配置文件,上到云应用,让底层人员运行作业炸包,首先就要配置文件,一切配置要么走配置中心,连访问配置中心的地址可能也是外部注入进来,不用再去配置上声明整个中心是什么;要么是所有的配置都由平台帮助注入,不能自己携带相关的Jap去做,原来整个构建,底下会有一些构建的模式,之前构建最早版本非常有意思,比如大了一个测试环境的炸包,若没问题,即可交给运维,因为配置VI里面完全不一样,会在应用和部署的公共机器时,有自动替换配置文件的动作,要替换的配置文件其实也是预先上传到平台上的,整个发布平台会帮助做一个配置文件的替换,方式很原始,不是运行它去改配置,因为包本质上是变化的,配置文件属于包的一部分,因此它也是变动的,等于整个包的密封性被打破了,此时去上一个云原生的平台,首先要做的是灭配置文件,要通过环境变量或启动平参数的模式去启动应用,这时平台能自动地把整个环境——生产、预发布、测试、以及延长等环境,将不同的配置设置好,所以这一点对开发来说改动比较大,正常上这种云应用,最难的是将配置问题解决,因为大量的Java配置都是在文件中进行,包括内部有框架的,特定的文件,将这些都清除掉。
Backing Services:即不要把依赖服务完全写死,依赖服务也是通过环境注入进来,如数据库连接,可以通过外部配置进来。
构建、发布和运行:要流程化。
进程:进程是微服务的根基,应用应以进程的级别运行,跟原来的方式不同,很多功能都是达到一个进程,通过不同的线程运行,但有几个不好的地方,类似于微服务,发布可能会影响不应影响的一些部分,追踪也不是很好做,比如当当最近在做内部的Tracing,目前只能做到进程间的Tracing,如果内部的线程Tracing需要改造,还是有一些麻烦的。
端口:类似于一种端口的绑定解决方案,是由编排工具动态注入,要动态监听一些要发布的端口信息。日志:不应生成文件,而是通过服务的方式将其进行传递,整个管理平台应有自动收集日志的功能,这也达到了云原生的态度,要将所要定位的信息不和应用绑在一起,因为应用很快会启动或注销,那么整个轨迹要持久化的保留,所以日志是整个云原生问题的核心,后面会进行详细的讲解。
上图是当当内部培训的图,浅蓝色是线下操作,是在云平台之外的,因为都是第三方组件,包括开发、构建过程,接着在云平台上配置作业。蓝色部分是开发或由测试提交,黄色部分由运维操作。团队之间会通过这样的配置去调整和审核,控制整个平台的用量,因为用Mesos跟Lite版本不一样的地方在于声明时要声明CPU和内存,还会定义一些特性资源如:NFS,包括一些共享的存储,这些会配置到配置里,此时也要有一个审核,让其之间做个比较完美的交互。
监控——核心指标设定
上面讲了Dev,剩下的几个环节讲一下Ops有关内容,首先:核心指标的设定。
上图是我自己画的云图,来源于Diggtal Dog网站,它有一篇Blog讲运维监控指标,基本上是暗词的权重,除了这个云层,另外比较主要的是Mertics,其实应该过滤掉,如Error的数量,Success等各种指标,画上图最大的用意是让大家看到——乱。
因为指标很多,Mesos所有的净化API有20多个,它的指标可能有30—40个,但如此多的指标,每天都有大量的信息,各个指标间有很多联动关系,大数据可以去联系、判断哪种指标在日常组合的情况下是影响系统发挥的,但目前的技术仍然难以做到,最简单的方式是从这些纷繁的指标中找一个最适合自身的,在构建自身监控指标时,一定要找到一个上帝指标,若有人说,现在某个作业有问题,优先看这项指标,如果这个指标没有问题,那么状况应该不大。
SLO=>SLA
这个指标其实就是SLA,使用比较多,SRE对SLO到SLA的推导是有过程的:SLO是服务质量的目标,在运维各个系统时,系统的服务质量需求不同,某人过来找你,某作业非常重要,如果一天不运行,会丢掉多少单,但若细聊,会发现每个人的服务指标不一样,能忍受的指标也各不相同,跟他去叹号你的服务指标,是3个9、4个9或50%都可以,有些作业只要70%就够,虽然偶尔失败,或者70%的成功也不会影响服务,将SLO设定好,即可推到SLA是什么,一旦确定,就是跟开发之间建立了一个生死契约,但跟市场不同,市场跟客户签,对方场上会写个SLA,当然一般也不会去评估,开发不同,开发签指标后,是要算绩效的,所以一旦跟他说了能达到几个9,就一定要做到,否则自己的奖金也发不出来。
好处是会约定双方,开发不会提出过分的要求,比如偶然宕机,也不会找你,因为还未达到它的底线,如果有些严格指标,需要提供更好的服务给他,比如调度时会给他分配更好的服务器,做一些预先的割裂,将其和一些作业隔离开。
SLA=ST/ET
SLA指标在做系统时要注意怎么设置,平时方法很简单,WEB应用很好设置,访问10次,有9次返回404,那这个SLA才10%,但作业其实不好衡量,本来说是每5分钟要运行一次,但如何衡量?是处理数据量的多少吗?自己的指标需要自己去设定,这个是ST/ET,S是真正运行次数,即在10分钟内根据表达式,成功运行多少次,是有标准的。E是期望这段时间内运行多少次,有一个口号表达式去计算即可在一个时间范围内算出应该运行多少次,所以和一些应用不同,这个有平台的特点,是针对定制作业设计的SRE指标。
给大家分享一个实例,可以看到出了故障,目前已经降到53%了,具体的作业已经抹掉,由于自身写错应用有BUG,造成执行失败,上面的曲线是Grafana的一个图,整个SLA有时会100%有时会降到50%几,下面是用来显示SLA如何计算的绿线,可见除了偶尔波动外,比较均匀。底下这条线是实际运行次数,偏离度较大,因此可以得出,在哪个时间段出了问题,帮助进一步定位。
所以关键的监控指标,对于轻量级监控是非常重要的,为什么只抓一个指标就够?Mesos给的官方建议是如果集群内的任务快速失败,就会报警,当当基于此建立了报警,有时会出现报警,查一下这个指标,如果没有问题,就可以认为是由于偶然的情况下做了一些失败的专一,不会有太大的影响,这就是设置关键指标的好处。
监控——监控监控系统
监控系统是否需要被监控?这是一个老生常谈的问题,首先监控系统也是系统,是需要被监控的。这里进行一下反推,如果监控系统万一Down了就只能再加一层了,下面是Prometheus去采集整个Mesos集群的白核监控数据,发给Master做告警,接到内部的Tracker的系统会根据告警级别去发送邮件、短信或电话。上面有个叫雷达的系统,目前监控整套的监控系统,已经用了很多年,因为Prometheus也是整套的监控系统,再由它去监控一个监控系统,如果雷达也Down怎么办?不管做了HA或其他,仍然会有Down的几率,但如果两个系统同时Down了呢?
大家可以回溯一下刚才讲过这个问题,监控系统本身也是一个系统,到底要提供多大的SLA,要提供对外监控4个9的目标吗?另外上一套系统可以保证4个9,因为每套系统每年都会算一个SLA,将这个指标用上去以后,系统的可用度会上升,所以对系统的可用要量化、要度量,系统只要能用目前的方案达到SLA设置的目标,就可以停了,如果达不到就不能停。
再回到上面这个图,后来之所以加了一档,因为Prometheus最早上线那版,为了块它是个单点,无法保证线程目标,所以又加了一套监控系统,如果将Prometheus、Alertmanager在一开始就构建比较完整的服务,那么可以不用第二层监控。
Service Mesh实践
接下来是Service Mesh,APM 最近在北京召开,这是一个全国比较大型的监控告警的会议,会上当当总监讲了一下这个概念,这概念是当时运营整个Mesos的后台,引用到内部服务范根的,所以再给大家案例一下相关的技术。
上Kubernetes或Mesos集群的话,都会遇到一种网络问题,如果对容器的编排调度都感兴趣,可以在网上搜:Kubernetes网络、容器网络、会有一大堆的概念,上去会告诉你OAS怎么配,FLANNEL性能会损失多少,Calico怎么用的BTP协议,其实刚才看了第一个图,将的网络其实解决的是整个网络IP层的问题,会让机器有多少个IP,为什么要解决IP层的问题呢,因为因为容器。比如一台容器一驱10,一驱12,一1驱15可能是最高的,原来有1万的集群节点,那么现在要乘10,网络规模翻了10倍,IP地址同样也翻了10倍,所以一些公有云的同志们会非常恐慌,因为最早的虚拟协议支持不了这么多的节点,因此提出了容器网络,包括CNI、CNM的标准,账户要解决IP不够用的问题,其实这个网络还有另外一套问题:容器起来后IP也会变,会有一些别的技术保证IP也会变,那服务要怎么办?如何去发现,如果后台比如有10个WEB应用去访问,此时如何去负载均衡,如果有个服务长时间有问题,如何提供整个服务集群,如何做熔断,这些都是微服务常见的网络概念。
Service Mesh主要就是解决者方面的问题,即使底层用最原始的完全不用它自身的网络方案,照样可以使用,如图,最外层如Nginx,作为一个边缘节点,会将流量通过Service Mesh打到集群内部的服务,它们之间也通过Service Mesh互相访问,然后集群外面来说,换成淡蓝色不能用外部服务,就是通过Service Mesh向外去访问。
这里总结了三点功能:
第一点是Service Discovery即服务发现,和正常的如微服务的发现不太一样,微服务发现用Cloud基本上也会存一些中间的存储,ETCD比较多,包括DK,Consul这些,有人用Redis也存过,怎么也得把服务之间的调用关系存起来,这个Service Mesh大多是从第三方平台获得服务之间的IP地址和联系,第三方平台包括Kubernetes,包括这里写的DCOS,DCOS是另外一个概念,即Mesos加Marathon再加一套新构建的组件,合起来可能就是DCOS,从这里面把相关的服务信息采集出来就能做服务发现,比如注册个应用,每次启动时,这个应用本身的IP地址,可能端口通过Mesos或Nginx分配的很明显,因此如Linkerd、Istio就可以把IP地址获取下来,当你访问时组件是知道的,这是它大部分做服务发现的原理。
第二点是负载均衡和健康检查,上面说过,一个服务可能是3个实例、10个实例去对外提供服务,那本身应用基本轩哪个服务就涉及到负载均衡,如果应用上调不通,会踢出集群,这就是健康检查。这部分可能分为两大流派,第一大流派是做用户层的,就是七层负载,比较传统,我们用的跟NG差不多,因为我们还会有其他别的信息;另外一种是使用本地IP Temple进行转发,此时更像原生的另外一个部署模式,包括像DCOS本身有一个Minuteman的组件,转发的速度会很快,但这种有一个问题,服务失败就是失败了,通过这个端自己增加处置机制,还有HA的功能也不能做,所以它有一些限制。
最后比较重要的是Metrics和Tracing的对外暴露,像是这种新一代服务的组件,对外暴露各种Metrics的指标,如Linkerd,包括Istio都会暴露Prometheus的这些监控,还会自带一些Tracing的功能,是一种广播级的追踪,linkerd目前只能支持一种,因为它来自推特,推特的组件叫ZK,Tracing技术比较特别,需要修改服务的Hander,然后去加一些额外的信息,因此虽然Linkerd在官方主页上公开了Metric,比如说Tracing是插件式的,但需要Tracing的服务去支持SPIN的协议才可以,这个比较坑。我目前正在给我们用的Tracing的截杀软件,会截掉一部分Linkerd的Scalar代码,将它的整个Hunter协议改掉,这样才能支持别的协议模式,目前正在内部试运行,后续用Linkerd较多的话,会向它提一些PR,让它将整个Tracing开源。
这是在官网上截的一个图,可以让大家更深刻地理解,用过Kuber-Proxy的同学知道,这是和它一样的,在机器上,服务过来先找它,通过代理模式再打到另外一台服务的Linkerd,每次的服务访问,被访问其实都是通过本地的其他技术去发起的。
目前在跟进Skywalking,它是另外一个开源组织。不知道大家对Tracing有多少了解,要不是用手工的方式将监控数据往外发,如果不想修改代码,目前只能用Java,要根据不同组件做埋点,需要看埋点插件的丰富度了,但埋点了以后会对性能稍微有一些影响,目前做的事是将整个Tracing的插件直接做到Linkerd上,服务之间调用,可能整个Tracing图没有了,但整个访问统计还在,因此这个意义很大,如果完全不想动代码的结构,直接上我们的整个组件,自身就带了Tracing的过程。
离线与在线日志
离线和在线日志目前也是云原生比较重要的一环,先解释下Mesos Sandbox,Mesos会把待执行的包下载到本地,生成一个临时目录,目录很长,有很多CP数,这里面就是Sandbox,原理和Docker一样。日志要打到Sandbox里,否则就没法看到日志,可能有些人原来不应用,会打到某些固定的路径,这时会要求打到相对应的路径里,此时会提供两个文件:STD error、STD on,把标准输入和标准输出写到这个文件里。当当目前只采集标准输出或标准出错,所以原来如果写了一些特定格式的日志,会被要求改掉,其实开发还是很高兴的,因为开发环境一般都是标准输入和标准出错的,开发那套关于日志配置不必修改,直接打到包里,上面说第一步要改应用,首先把配置去文件化,日志的配置不用改,因为线上也只采集这两个文件。
流程从右向左,Filebeat目前是整个集群比较常用的组件,Logstsh是一个Transform,发到Elastic Search里,最后有Kibana提供服务,中间缓冲用的是卡夫卡,此时运维和开发都可以通过两种模式看日志,日译中模式是直接访问刚才的Sandbox,访问的页面通过整个运维平台,直接点到页面里面。
另外通过ERK平台,在线看日志可能类似于上图这样一种格式,一行行打印出来,然后web页面能自动滚动,可以看一些即时日志。
搜索统计还是走Kibana,上图是测试环境的Kibana,会统计一些相关的日志指标。
高洪涛老师将多年的运维及开发相关想法融入到本次演讲当中,如云原生应用的12条军规,当当监控指标制定规则,以及当当网的Service Mesh实践进行了详细地分享,小数希望大家在看完这篇长文后能够有所收获。