万节点规模云服务的 SRE 能力建设
简介: 随着越来越多企业以容器作为系统底座,那么阿里云的云服务又是如何进行SRE规划呢?下文将由资深SRE工程师拆解2 万节点规模云服务背后的 SRE 能力建设,立即点击观看!
作者:宋傲(凡星)
背景及现状
系统架构简介
上图为阿里云内部实际使用的系统架构,系统主要用途为实时数据流的计算和存储。使用阿里云的容器服务 ACK 作为系统底座,容器化的部署、发布、管控等全部基于 K8s 标准。使用自己开发的 Gateway service 作为系统流量入口,并基于 LoadBalancer 类型的 service 部署。
此架构也是应用 K8s 做系统较为常见的做法,通过 ACK 提供的 CCM 组件自动将 service 和底层 SLB 实例进行绑定,通过此实例承接外部流量。Gateway 收到上报的数据流后,将数据放入 Kafka 并在某个 topic 中进行数据缓冲。当 Consumer 感知到数据流的上报后,则会从 Kafka 相应的 topic 中对数据进行进一步计算处理,并将最终结果写入存储介质。
此处存在两种存储介质:其中阿里云块存储 ESSD 相对较快,但价格较高;文件存储 NAS 主要用于存放性能要求较低的数据。元数据由 ACM 进行管理,自研的组件 Consumer 和 Center 负责从存储介质中查询计算结果,并返回给用户。
系统现状
系统目前为全球开服,部署在全球将近 20 个 region 中,从图中也可以间接看出数据读写链路较长,需要经过多个组件的处理。监控对象也较为复杂,包括基础设施(调度、存储、网络等)、中间件(Kafka)、业务组件(Gateway、Center、Consumer)。
工作内容
- 可观测数据的收集
可观测性主要包含Metrics、Tracing 和 Logging三类数据。三类数据各司其职,相辅相成。
Metrics 负责回答系统是否出现问题,它也是系统的自监控体系入口。针对 Metrics 做异常的告警或问题的排查,可以快速确定系统是否有问题,是否需要人为介入处理。
Tracing 负责回答系统问题出现在什么位置,它能够提供组件之间的调用关系、每一次请求以及哪两个组件之间的调用过程出现了问题等具体细节。
找到出现问题的组件后,需要通过最详细的问题日志即 Logging 来定位问题根因。
- 数据可视化&问题排查
收集到三类数据后,下一步需要通过大盘将数据用可视化的方式展现,能够一眼确定问题所在,使问题排查更高效。
- 告警&应急处理
确定问题后,需要通过告警和应急处理流程来解决问题。
应急处理过程主要有以下几个要点:
第一,需要分级的告警通知和升级策略,能够快速找到相应的人员处理告警。与此同时,若原定人员因为某些原因无法及时处理,还需将告警升级到其他人员以及时处理。
第二,问题认领和处理流程标准化。
第三,事后统计及复盘。系统出现故障并解决后,还需要事后的统计以及复盘工作,让系统通过故障和教训避免后续再出现相同的问题,让系统更稳定。
第四,运维处理工具化、白屏化,尽量减少手动输入命令的工作,将整套标准的处理动作用工具进行固化。
实践经验分享
可观测数据收集&接入
- 指标(Metrics)数据
监控的第一步是收集可观测数据,这些数据在系统里可以分为三个层面。
最上层为应用层,主要关心核心业务接口的健康度,通过RED(Rate、Error、Duration)三个黄金指标进行衡量。其中 Rate 指接口的 QPS 或 TPS ,Error 指错误率或错误数,Duration 指接口在多长时间内能够返回。可以通过黄金指标来定义 SLO 并分配 Error Budget 。如果 Error Budget 很快耗尽,则应及时调整 SLO,直到系统优化到足够完善后,再将其调高。也可以通过 Apdex Score 衡量服务的健康度,计算公式如上图所示。此外,应用层也会关心与业务强相关的指标,比如营收、用户数、UV、PV 等。
中间层为中间件和存储,主要关心系统里大量应用的 Kafka client 端消费位点的提交状况、生产者缓冲区的占用率、是否会提前将缓冲区占满导致新的消息进不来、消费延迟、平均消息大小等,比如 Kafka Broker 端的水位、读写流量、磁盘使用率等,再比如云盘 ESSD 的挂载成功率、IOPS、磁盘空余空间等。
最下层是基础设施层,关心的指标较为复杂,典型的有比如 ECS(K8s Node) CPU 内存水位、重启次数、定时运维事件等,比如 K8s 核心组件的 API server、 ETCD、调度相关指标等,比如业务 Pod 的 Pending 状态、是否有资源可供足够的调度、OOMKilled 事件、Error 事件等,再比如 VPC/SLB 相关的出口带宽、丢弃连接数等。
监控 ECS 节点需要使用 node-exporter Daemonset 的方式部署,K8s 云原生的核心组件可以通过 Metrics 接口将指标暴露,供 Prometheus 抓取。Kafka 或存储组件由于使用了阿里云的云产品,本身提供了基础监控指标,可以直接接入。ACK 对 CSI 存储插件也提供了非常核心的指标比如挂载率、iops、空间占用率等,也需要接入。应用层包括 Java 应用和 Go 应用,Java 使用 MicroMeter 或 Spring Boot Actuator 做监控,Go 应用直接使用 Prometheus 官方 SDK 做埋点。
基于 ACK 和 K8s 体系, Metrics 协议的最佳选型即 Prometheus。开源自建的 Prometheus 与云托管的接入难度不相上下,但可靠性、运维成本等方面,云托管的 Prometheus 更优于自建。比如使用 ARMS 体系,可以直接在集群里安装非常轻量级的探针,然后将数据中心化存储在全托管的存储组件,并围绕它做监控、告警、可视化等,整个过程非常方便,不需要自建开源组件。云托管在采集能力和存储能力上也更有优势。
Prometheus 针对 ECS 节点、K8s 核心组件、Kafka 和存储组件都提供了一键接入的能力。
K8s 基础监控和节点状态接入主要通过 ACK 组件管理中心,只需简单地安装相关组件,即可使用该能力。
Kafka 的接入主要通过 Prometheus 云服务实例,云服务实例目前已经接入阿里云非常完整的 PaaS 层云产品。接入 Kafka 时,所需填写的指标都为常见指标,无需额外学习成本。
云盘 ESSD 监控的接入主要通过 CSI 存储插件监控。ACK 里的 csi-provisioner 组件提供了很有用的可观测性能力,可以通过它提供的信息及时查看哪块盘没有挂载上、哪块盘挂在后 iops 达不到要求或配置告警,以及时发现云盘的异常状况。
通过 ARMS Prometheus 接入,预置采集的 job 比如 K8s cluster 级别、node 级别的 PV 状态都可以很方便地进行监控。
应用层不存在一键接入的便捷方式,需要通过应用埋点+服务发现的方式,将整个应用的 Metrics 接口暴露出来,提供给 ARMS Prometheus 的探针抓取。
Java 应用需要使用 MicroMeter 或 Spring Boot Actuator 进行埋点。
以上图代码为例,MicroMeter 中很多 JVM 相关信息可以简单地通过几行代码进行暴露,其他更有帮助的信息,比如进程级别的 memory 或 thread、system 信息等也可以通过很简单的方式将其接入。设置完埋点后,需要在内部启动 server ,将 Metrics 信息通过 HTTP 接口的方式暴露,最后绑定指定的端口。至此,埋点流程结束。
此外,如果有业务指标,只需将自己的指标注册到全局的 Prometheus Registry 即可。
ARMS 探针抓取暴露的端点,只需添加 ServiceMonitor ,由 ServiceMonitor 直接通过控制台白屏化的方式,简单地写几行 YAML 的定义,即可完整地将整个监控的采集、存储和可视化跑通。
Go 应用与 Java 大同小异,只是埋点方式有所区别,主要使用 Prometheus 官方的 SDK 埋点。
以上图为例,比如系统里有一个查询组件关心每一条查询的时间分布,可以使用 Prometheus 里面直方图类型的指标,记录每个请求的时间分布,并在埋点的时候指定常用的分统进行统计。再由 ServiceMonitor 将 Go 应用的 endpoint 写入,最终在控制台上完成整套应用的接入。
ARMS 还提供了基于 eBPF 的无侵入可观测性实现方案,主要适用于不希望修改代码的场景,使用无侵入的方式监控系统接口的 RED,通过 ARMS Cmonitor 探针结合 eBPF 的方式,通过系统内核的 filter 实现信息的抓取和存储。
使用上述方式需要在集群里额外安装 Cmonitor App,安装后可在 Daemonset 看到 Cmonitor Agent,每个节点都需要启动 Cmonitor Agent,作用是通过 eBPF 的方式注册到系统内核中,抓取整台机器的网络流量,然后过滤出想要的 service 网络的拓扑等信息。如上图,它可以监控整个系统的 QPS 、响应时间的分布等信息。
- 链路(Trace)和日志(Log)数据
Trace 也使用 Cmonitor 来实现相关能力。日志方面,系统组件的日志、K8s 控制面的日志、JVM 的 DCLog 等,主要通过 arms-Promtail (采集应用日志的探针)将日志投递到 Loki 内做长期存储。
K8s 系统事件的日志,主要基于 ARMS 事件中心的功能对 K8s 的关键事件、Pod 调度上的 OOM 、Error 等事件进行监护。
- 读写链路监控和问题定位
上图为部分系统截图。
比如 trace 相关控制台可以查看每个请求经过的组件、接收用时、处理时长、回应耗时等标准信息。
- 组件运行日志收集和存储
日志收集方面,通过在 Grafana 里配置 Loki 的数据源,即可轻松根据关键字或 Pod 标签快速获取到 Pod 或某个 service 下挂载的 Pod 日志,对排查问题提供了极大便利。
- K8s 运行事件收集和监控
上图为 ARMS 提供的事件中心工作台截图。工作台提供了关键事件列表,可以对等级较高的事件进行订阅,订阅只需简单几步:填写基本规则,选择需要匹配事件的模式,选择告警发送对象,即可对关键事件进行监控,实现及时响应的目的。
数据可视化及问题排查
- Grafana 大盘配置实践
完成数据收集后,下一步需要打造高效可用的数据可视化和问题排查工具。
Prometheus 与 Grafana 是一对黄金搭档,因此我们也选择了 Grafana 作为数据可视化的工具。上图列举了大盘配置过程中的要点:
- 加载大盘时需要控制每个 panel 上的查询时间线,避免在前端展现过多时间线,导致浏览器渲染压力大。而且,对于问题排查而言,一次性显示多时间线并没有帮助。
- 大盘配置了很多灵活的 Variable ,可以随意在一张大盘上切换各种数据源和查询条件。
- 使用 Transform 让 Table Panel 灵活展现统计信息。
- 分清 Range 和 Instant 查询开关,避免无用的范围查询拖慢大盘显示速度。
K8s集群总览
上图为监控节点信息、 K8s 集群 Pod 信息的大盘。整体布局一目了然,通过不同颜色对关键信息进行标记,通过 Grafana 的动态阈值功能将数字以不同的形式展现,提升问题排查效率。
节点水位
上图为节点水位大盘,展示了磁盘iops 、读写时间、网络流量、内存使用率、CPU使用率等重要信息。
全局 SLO
上图为全局 SLO 大盘 。通过 Grafana 托管服务配置自定义大盘,这也是 ARMS 最新上线的功能,在云上托管 Grafana 实例,即可通过云账号直接登录到 Grafana 界面,其中包含阿里云定制的特有功能。
大盘中包含了全局 latency、QPS、成功率、错误码的分布情况、QPS 的变化趋势,以及一些较细粒度的信息,比如单分片、负载均衡、Gateway 组件、center 组件等。如遇发版,可以通过带上版本号查看前后版本的区别,可以在 pannel 中以变量的形式展现 datasource,也可以选择全球各个 region 进行切换查看。
Kafka 客户端及服务端监控
集群中依赖 Kafka 客户端和服务端,其监控来源于云监控集成。
内部组件强依赖于 Kafka,通过指标监控 Kafka 以及它与 broker 之间的连接数、平均消息长度、位点提交速率、消费流量等。Producer 端提供了缓冲区的占用率、活跃的 producer 数等信息。
Java 应用运行情况监控
如果组件使用 Java 编写,还需要监控 JVM 相关的 GC 情况,大盘能够提供 JVM memory 的情况、GC 相关情况、CPU 使用率、线程数、线程状态等。此外,比如发版或有动态加载的类,在加载类的统计中可以查看是否存在持续上升的状态等。
Table 格式的错误类型复盘统计表
如果希望使用电子表格统计集群中的安装状态或重点客户状态,可以使用 Grafana 的 transform 功能将整个大盘打造成电子表格式的体验。可以用 transform 将字段映射到一张电子表格上,打开 filter 后还可通过筛选各种字段得出查询结果。
- 问题排查案例分享
日志信息的展示需要通过在 Grafana 里查询 Loki 的数据,比如 center 里有查询日志,其中包含很多原始信息,比如此次查询的时间、UID 等。通过后处理的方式,首先将想要的日志按行的方式进行筛选,然后通过模式匹配提取信息,后续还可以按照 PromQL 将其中某些字段的做大小关系的匹配,最终将匹配出来的日志格式进行二次处理。
告警和分级响应机制
上图为告警和分级响应机制流程,依次为告警配置、人员排班、告警触发、应急处理、事后复盘和机制优化,最后将机制优化体现在告警配置上,形成完整的闭环。
以上流程是自建的告警系统,通过依赖自建系统定时跑任务检查指标,然后调用钉钉的 webhook 或其他运维系统的 webhook 发出告警,流程中存在几点不足:
1. 自建系统的稳定性需要自己负责,如果告警系统的稳定性比运维系统更差,则告警系统的存在无意义。其次,随着整个集群开服的 region 越来越多,配置越来越复杂,自己维护配置并保证配置全球生效难以实现。
2. 依赖手工排班,极易出现漏排或 backup 缺失。
3. 告警触发阶段触发条件非常单一,难以在告警触发链路上增加额外的业务逻辑,如动态阈值、动态打标等。
4. 应急处理阶段,信息发送非常频繁,无法主动认领和主动关闭。系统出现问题时,同类告警会在群里高密度发送,无法主动屏蔽告警也是缺陷之一。
5. 事后复盘优化的时候没有数据支撑,无法根据已有的告警统计信息来优化整个流程。
因此,我们选择基于 ARMS 来建立告警系统。ARMS 强大的告警和分级响应机制为我们带来了诸多便利:
1. 告警模板全球生效功能:只需配置一次告警规则,即可使不同的集群生效告警规则。比如没有告警模板时需要对每个 cluster 里的指标单独配置告警。而有了模板后,只需通过告警规则模板的方式将 PromQL 或告警的 AlertRule apply 到全球各个 region 集群,非常方便。
2. 告警排班表和动态通知:系统能够动态实现轮班替班工作,比手工排班更靠谱。
3. 事件处理流和告警富化:可以通过 ARMS 的事件处理流、告警中心的事件处理流和告警富化功能,在告警触发后动态地打上标记,并且做分级处理。如上图,可以给告警打上优先级标签,优先级较高的告警等级升级为 P1,并且可以动态地修改告警接收人。
为了实现上述功能,首先需要有数据源来提供打标的依据。在告警运维中心的控制台上有数据源的功能,告警触发时可以通过 HTTP 请求或 RPC 请求调用数据源,而后可以从 HTTP URL 里获取打标的结果。此接口的实现主要通过 IFC 轻量工具在线写好代码,代码主要负责读取 ACM 配置中心里的信息配置项,然后读取配置项并对外暴露 HTTP 接口,提供给告警运维中心动态地调用。
完成以上步骤后,还需配置事件处理流,将需要的信息通过匹配更新模式的方式传递到上述接口,并返回优先级,最终打到告警上。
4. 告警的认领、关闭和屏蔽:ARMS 提供了认领、关闭、关注、屏蔽等实用功能,显著提升了告警质量。
5. 告警的认领接手率统计大盘:复盘的时候需要知道每个人处理了多少告警、处理时长、告警平均恢复时间等,引入了认领、关闭、恢复、屏蔽机制后,ARMS告警中心在后台记录了事件的日志,通过对日志的分析即可提供有用的复盘信息。
得到告警信息后,用户希望可以在白屏化的界面上处理问题,因此我们引入了基于 Grafana 的白屏化运维工具链。其原理为,在配置大盘的时候引入动态信息,并将其以链接的形式拼接到大盘里。
我们内部有各种系统,如果没有官方的链接拼接,则需要自己首拼 URL 或手动搜索,效率非常低。而通过在 Grafana 里嵌入链接的方式,将运维动作固化成链接之间的跳转,对于效率的提升非常有帮助。能够通过 Grafana 一套工具将所有工作完成,将运维动作标准化、固化,减少人工出错的可能性。
总结和未来工作
第一,告警准确度和接手率的优化。目前还没有很好的方式能够将告警的复盘信息高效地利用起来,未来我们将尝试通过告警准确度和接手率的信息,及时调整不合理的告警阈值,也可能会尝试多阈值的告警,比如告警在 A 到 B 范围之内是多少等级,在 B 以上是多少等级。
第二,多类型数据联动。比如在排查问题的时候,除了 Metrics 、Trace 和 Log 之外,还有 profiler、CPU 的火焰图等信息,而目前这些信息与可观测数据的联动较低。提升数据联动,可以提升问题排查效率。
第三,埋点成本控制。对于外部客户而言,埋点成本直接关系到客户使用阿里云的成本。我们将定期地对自监控指标的维度、发散的维度等进行针对性的治理,并且对于无用的维度进行数据清理,将埋点成本控制在较低水平。
钉钉扫码,入群了解更多可观测实践
万节点规模云服务的 SRE 能力建设的更多相关文章
- [转帖]单集群10万节点 走进腾讯云分布式调度系统VStation
单集群10万节点 走进腾讯云分布式调度系统VStation https://www.sohu.com/a/227223696_355140 2018-04-04 08:18 云计算并非无中生有的概念, ...
- 阿里云 EMAS HTTPDNS 联合函数计算重磅推出 SDNS 服务,三大能力获得突破
1. 什么是 HTTPDNS ? 传统的 DNS(Domain Name System)使开发者常面临着域名劫持.调度不精准的问题. HTTPDNS 使用 HTTP 协议替换常用的 UDP 协议,完成 ...
- 评判云服务靠谱程度 -- Coding 安全那些事
本文依据孙宇聪在 SegmentFault D-Day 北京场的演讲内容整理,并授权首发于“高效运维”公众号.10月11日,SegmentFault 将在上海举办D-Day,围绕 Docker 主题. ...
- 当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题?
作者 | 阿里云容器平台高级技术专家 曾凡松(逐灵) 本文主要介绍阿里巴巴在大规模生产环境中落地 Kubernetes 的过程中,在集群规模上遇到的典型问题以及对应的解决方案,内容包含对 etcd.k ...
- 备战双 11!蚂蚁金服万级规模 K8s 集群管理系统如何设计?
作者 | 蚂蚁金服技术专家 沧漠 关注『阿里巴巴云原生』公众号,回复关键词"1024",可获取本文 PPT. 前言 Kubernetes 以其超前的设计理念和优秀的技术架构,在容器 ...
- [转帖]当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题?
改天学习一下. https://www.cnblogs.com/alisystemsoftware/p/11570806.html 当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题 ...
- 英特尔内存革新助平安云 Redis 云服务降本增效
英特尔内存革新助平安云 Redis 云服务降本增效 英特尔 傲腾 数据中心级持久内存的引入,为平安云的降本增效开启了一条新的道路.通过对平安云 Redis 数据库产品的支持,用户能享受到性能优异且价格 ...
- 基于AWS的云服务架构最佳实践
ZZ from: http://blog.csdn.net/wireless_com/article/details/43305701 近年来,对于打造高度可扩展的应用程序,软件架构师们挖掘了若干相关 ...
- 一种面向云服务的UCON多义务访问控制方法及系统
)设置每一云服务的义务项:建立每一云服务所包含的义务图:2)根据用户所请求的云服务查找该云服务的所有强制义务图和可选义务图,并提取该用户对该云服务的历史完成情况:3)对每一强制义务图,监控其每一义务项 ...
- Amazon EMR(Elastic MapReduce):亚马逊Hadoop托管服务运行架构&Hadoop云服务之战:微软vs.亚马逊
http://s3tools.org/s3cmd Amazon Elastic MapReduce (Amazon EMR)简介 Amazon Elastic MapReduce (Amazon EM ...
随机推荐
- 安装debian后,发现进入不了root
回想了一下,自己安装的时候,没有设置root密码! 解决方法: sudo passwd root 随后设置密码: 再次su 就可以进入root目录了!
- 基于python的socket通信之阿里云socket端口不通的解决方案
问题描述: 使用python脚本进行socket业务流程,前几天还可以通信很好的,今天突然发现端口不通了.那就排查端口为啥不通了呢? 方案一:设置阿里云安全组 这个网上不少例子,笔者也按照这个操作过, ...
- ble的notification和indication的区别和联系
Ble服务端传输消息有两个常用手段,notification和indication.那么这两者之间有什么区别呢? Notification 不需要应答,所以服务端发送的消息,它自己并不知道消息是否发送 ...
- day17--Java常用类05
Java常用类 5.其他常用类 5.1Math类 java.lang.Math提供了一系列静态方法用于科学计算:其方法的参数和返回值类型一般为double型.如果需要更加强大的数学运算能力,计算高等数 ...
- 记录--Vue使用CDN引入,响应式失效?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 背景 最近心血来潮,想要在本地开发时,也用CDN的方式引入 Vue,想着既然通过CDN引入了,那么在项目中就没必要再 import Vue ...
- vue前端项目中遇到的问题以及解决方案-不定时更新
1.vue-cli创建vue项目中全局使用mixin 首先需要安装插件 npm install style-resources-loader vue-cli-plugin-style-resource ...
- QT数据库学习笔记
简介 QT通过模块化管理,对于某种模块需要添加对应的模块实现.QT SQL也是需要增加对应的模块来实现.QT数据库的层次关系为: 驱动层:数据库到SQL语言之间的桥梁 SQL API层: SQL语句的 ...
- DARTS:基于梯度下降的经典网络搜索方法,开启端到端的网络搜索 | ICLR 2019
DARTS是很经典的NAS方法,它的出现打破了以往的离散的网络搜索模式,能够进行end-to-end的网络搜索.由于DARTS是基于梯度进行网络更新的,所以更新的方向比较准确,搜索时间相当于之前的方法 ...
- KingbaseES 数据库连接
一.数据准备: create table student( id int , s_name varchar(20), t_id int ); create table teacher( id int ...
- c语言的printf常用的一些转换说明符及其含义
整数类型: %d: 十进制整数 (decimal: 十进制的) %u: 无符号整数 (unsigned: 无符号的) %i: 十进制整数 (integer: 整数) %o: 八进制数 (octal: ...