乐趣区

关于告警:面向多告警源如何构建统一告警管理体系

本文介绍告警对立治理的最佳实际,以帮忙企业更好地解决异构监控零碎所带来的挑战和问题。

背景信息

在云原生时代,企业 IT 基础设施的规模越来越大,越来越多的零碎和服务被部署在云环境中。为了监控这些简单的 IT 环境,企业通常会抉择应用异构监控零碎,例如 Prometheus、Grafana、Zabbix 等,以获取更全面的监控数据,以便更好地理解其 IT 基础设施的运行状况和性能体现。

然而,这种异构监控零碎也带来了一些问题,其中最显着的是告警信息的扩散。因为不同的监控零碎可能会产生不同的告警信息,这些信息可能会扩散在各个系统中,导致企业很难全面理解其 IT 零碎的告警情况。这使得响应告警变得更加艰难,同时也减少了人工治理的复杂性和工作量。

为了解决这些问题,企业须要一种更加对立和集中的告警治理计划,以确保告警信息可能及时达到正确的人员,以便他们可能疾速采取必要的措施来应答潜在的问题。

告警治理的痛点

场景一:企业迁徙上云后,云上产品的告警不对立

在一个典型的云原生业务利用部署架构中,通常会应用到如下产品 ACK、ECS、RDS,利用通过 Kubernetes 部署在阿里云的 ECS 上并拜访云上的 RDS。在这个架构中通常会用到如下监控产品来对系统进行监控。

  • 通过 CloudMonitor 对阿里云基础设施 ECS 和 RDS 进行监控,当资源出现异常时进行告警。
  • 通过 Prometheus 对 Kubernetes 以及部署在 kubernetes 上的 Pod 进行监控,当 Kubernetes 出现异常时进行告警。
  • 通过 ARMS 对部署在 Kubernetes 上的利用进行监控,包含利用间接的调用链。当利用异样时进行告警。
  • 通过 SLS 对利用产生的日志进行监控,当日志出现异常时进行告警。

在这样一个场景下因为用到了多个云产品对整个零碎进行监控会导致使用者须要在多个产品上反复配置联系人、告诉形式、值班等运维配置。且不同零碎之间的告警无奈产生有机联合,当一个问题呈现时不能疾速关联不同告警零碎中的相干告警。

场景二:多云、混合云架构下,异构监控零碎告警不对立

当企业的利用部署在多云环境或混合云环境下时,监控零碎产生的告警可能会更加扩散和简单,给企业的运维工作带来很大的挑战。因为不同的云平台和公有云架构之间的差别,监控数据的采集和解决形式也可能不同,因而,不同监控零碎产生的告警信息也可能体现出差异化,这会带来一系列的问题。

首先,不同监控零碎产生的告警信息扩散在不同的中央,运维人员须要消耗更多的工夫和精力去解决这些信息。其次,不同零碎产生的告警信息难以对立进行治理和剖析,使得问题的诊断和解决更加艰难。此外,因为不同零碎的告警信息可能存在反复或抵触,治理和解决这些信息也会变得更加简单。

场景三:自研监控零碎、自定义事件告警接入

在利用开发运维过程中,随着零碎规模的扩充和复杂度的进步,各个角落中的胶水代码逐步增多。这些代码尽管是连贯不同模块和零碎的重要纽带,但一旦呈现问题,因为扩散在不同的中央,很难立刻发现和解决。这就使得企业难以保证系统的高可用性和稳定性。如何灵便的低成本的接入这部分代码产生的告警也成为企业应用运维的痛点之一。

对立告警治理

在构建对立告警治理平台过程中,不同的监控系统对告警定义、解决流程都不一样,往往会存在上面问题:

  • 不同零碎产生的告警格局不同,接入老本高。
  • 不同零碎间的告警接入后因为格局不对立,难以对立解决逻辑。
  • 不同告警零碎对于告警等级的定义不同。
  • 不同告警零碎对于告警主动复原的解决形式不同。有的告警零碎反对主动复原,有的不反对。

ARMS 告警治理 [1] 设计的集成、事件处理流、告诉策略等性能专门针对告警对立治理的场景,解决了对立治理过程中遇到的诸多问题。

ARMS 告警治理如何接入不同格局的告警?

传统告警通常包含如下一些内容,这种结构化的告警通常只实用于繁多告警源。当多个告警源的数据汇总到一起后通常会导致数据结构的抵触。因而 ARMS 应用了半结构化的数据来存储告警。

阿里云监控告警数据格式:

Zabbix 告警数据格式:

Nagios 告警数据格式:

半结构化的告警数据结构

[
  {
   "labels": {
    "alertname": "<requiredAlertNames>",
    "<labelnames>": "<labelvalues>",
    ...
   }, 
   "annotations": {"<labelnames>": "<labelvalues>",}, 
   "startsAt": "<rfc3339>",
   "endsAt": "<rfc3339>",
   "generatorURL": "<generator_url>"
  },
  ...
]
  • labels(标签):告警元数据,一组标签惟一标识一个事件,所有标签均雷同的事件为同一个事件,反复上报会进行合并,例如:alertname: 告警名称。
  • annotations(正文):正文是告警事件的附加形容,正文不属于元数据。例如:message: 告警内容。不同工夫点产生的同一个事件他们的标签是雷同的,然而正文能够是不同的。比方告警内容的正文可能不同,例如:“主机 i -12b3ac3* CPU 使用率继续三分钟大于 75%,以后值 82%”。
  • startsAt(告警开始工夫):告警事件开始工夫。
  • endsAt(告警完结工夫):告警事件完结工夫。
  • generatorUrl(事件 URL 地址):告警事件 URL 地址。

如上述代码所示,ARMS 参考开源 Prometheus 告警定义[2],应用一个半结构化的数据结构来形容告警。通过高度可扩大的键值对来形容告警,这样就能够非常灵活的对告警内容进行扩大从而接入不同的数据源产生的告警。

任意 JSON 格局的自定义告警接入能力

ARMS 告警提供了任意一种 JSON 格局接入的能力(自定义集成[3])。只有告警数据结构满足 JSON 格局就能接入。如下图所示,自定义告警接入须要先将告警内的 JSON 数据上传到 ARMS 告警核心后,通过页面编辑字段映射的形式将告警内容中的要害信息映射到 ARMS 告警数据结构中。

ARMS 定义了如 alertname 等关键字段,对于更多的扩大字段,用户能够在集成中通过新增扩大字段的形式进行配置。所有的扩大字段都能够使用到前面的告警解决逻辑中。以下图为例将原始告警报文中的 hostname 字段映射到扩大的 hostname 字段,hostip 字段映射到扩大的 hostip 字段。

罕用监控工具告警快捷接入能力

ARMS 默认提供了云上云下多种监控零碎的告警接入能力,能够参考集成概述 [4] 进行疾速接入。

ARMS 告警治理如何对立告警等级?

ARMS 中将告警分为 P1、P2、P3、P4 四个等级。通过配置映射表,将多个不同类型的等级归一到 P1-P4 四个等级。如下图所示,将 L1、Critical、重大告警这三种不同形容的告警等级都映射为 P1 告警,这样就能够对立不同零碎中对于告警等级的不同定义。

ARMS 告警治理对于不同格局的告警如何对立解决逻辑?

因为 ARMS 告警采纳了半结构化的数据结构,能够通过标签来对立告警的解决逻辑。通常咱们须要至多 2 个标签来对立告警的解决逻辑。一个标签用来决定这个告警应该告诉给哪些人,比方业务标签(service,biz)。另一个标签用来决定这个告警利用通过什么样的形式进行告诉和降级。如下表所示,通常应用告警等级(severity)来定义告警解决的 SLA。

ARMS 设计了告诉策略和降级策略两种策略来满足不同等级的告警的解决要求,您能够参考告诉策略最佳实际 [5] 来进行配置。

标签设计准则

当咱们在设计用于告警解决的业务标签时须要满足如下准则:

  • 互斥准则:指防止对同一个资源应用两个或以上的标签键。例如:如果曾经应用了标签键 service 来标识业务,就不要再应用 biz 或业务等相似的标签键。
  • 个体详尽准则:指所有资源都必须绑定已布局的标签键及其对应的标签值。例如:某公司有 3 个业务,标签键是 service,则应至多有 3 个标签值别离代表这 3 个业务。
  • 无限值准则:指为资源只保留外围标签值,删除多余的标签值。例如:某公司共有 5 个业务,那么应该有且仅有这 5 个业务的标签,方便管理。

除了业务标签也能够定义其余的标签来进行告警的治理,比方应用环境标签来辨别开发和测试环境的告警。这些标签应该满足上述设计准则,这样能够简化告警治理配置的复杂度。

通过事件处理流给告警打标签(富化告警)

当咱们设计好标签后如何对不同告警源的告警打标呢。在 ARMS 告警治理中设计了低代码形式的事件处理流[6],通过利落拽的配置形式能够实现给告警打标签的能力(富化告警)。

场景一:匹配特定条件后给告警打标签

某 xx 业务应用了自研监控零碎,通过自定义集成将自研的告警接入到 ARMS 告警治理中后,须要对这部分告警对立打上业务标签 xx。事件处理流的配置如下:

a. 登录 ARMS 控制台[7],在左侧导航栏抉择告警治理,而后单击新建解决流。

b. 在弹出的面板创立事件处理流,编辑触发条件匹配自定义集成的名称为“xx 自研监控零碎”。

c. 增加设置业务标签动作,将 ”xx” 设置为业务(service)标签值。

场景二:切割字符串,提取标签

某自研告警零碎中所有的主机都应用固定格局进行命名,命名格局为 env−env−{env}-{biz}-app−app−{app}-{group}-${index},须要提取其中的 biz 字段做为业务标签。配置正确的触发条件后,应用宰割内容操作,将 hostname 依据字符 ’-‘ 进行宰割,宰割后的内容顺次填充到 env、service、app、group 字段。

场景三:通过查问 Excel 表格富化告警

某利用监控平台,在产生告警时仅告诉了利用 ID,须要依据 Excel 表格关联到利用名称、利用责任人等信息。

a. 创立 Excel 数据源,并上传 app_cmdb.xlsx 文件。

b. 配置事件处理流,增加字段丰盛操作,抉择数据源为第一步创立的数据源。编辑匹配字段为 appId,将 Excel 表中其余字段别离填充到 appName、owner、ownerPhone 扩大字段中。

场景四:通过 Serverless(FunctionCompute)调用内部服务富化告警

同上述场景三,当告警中缺失的数据须要从 CMDB 等内部零碎获取时,能够通过 API 类型的数据源来进行告警富化。

a. 创立函数计算利用[8],开发一个 HTTP 服务,接支出参为 appId,返回出参为 appName、owner、ownerPhone 等参数。如下截图仅为示例代码。

b. 创立 API 类型的数据源,URL 地址为第一步中开发的函数。

c. 配置事件处理流,增加字段丰盛操作,抉择数据源为上一步创立的数据源。编辑匹配字段为 appId,将 Excel 表中其余字段别离填充到 appName、owner、ownerPhone 扩大字段中。

ARMS 告警治理如何配置告警主动复原?

不同的监控系统对告警主动复原的解决逻辑大不相同。如 Prometheus 告警不会发送特定格局的复原告警,仅通过告警工夫来标识告警是否完结。阿里云云监控 [9] 中告警是否复原的状态合并到了告警等级中,如下所示。

  • 参数:triggerLevel
  • 数据类型:String
  • 本次触发报警的级别。取值:
  1. CRITICAL:重大
  2. WARN:正告
  3. INFO:信息
  4. OK:失常

不同场景下的告警在解决是否复原的逻辑可能也会有所区别。如阈值类型的告警,当监控值不满足阈值条件期间望立刻复原告警。然而对于事件类型的重要告警,告警产生只在一瞬间,并没有复原的过程。须要运维人员人工确认事件产生的影响曾经打消后能力复原告警。

场景一:针对不会复原的告警,配置主动复原时长,告警依照工夫主动复原

针对事件类型的告警,通常须要人工确认事件的影响范畴后再解决告警。这时告警主动复原可能会导致须要被解决的事件没有被人工解决。针对这种状况须要在接管到告警后不进行主动复原或者至多在一个长周期内不主动复原,给解决人员肯定的工夫来确认该告警的影响。

ARMS 自定义集成配置告警主动复原工夫截图:

场景二:配置复原告警字段,接管到复原事件后复原告警

在 ARMS 的告警集成中,能够通过配置告警复原字段,当告警内容中某个字段的值满足条件时,视为复原告警。依据该告警的其余字段的内容寻找对应的告警进行复原。告警被动复原的示意图如下所示:

ARMS 控制台配置形式截图:

告警复原须要满足如下 2 点,能力正确的复原对应的告警。

  • 如果没有定义去重字段,那么告警和复原告警的标签须要完全一致能力正确复原告警。
  • 如果定义了去重字段,那么告警和复原告警的去重字段须要完全一致能力正确复原告警。

阐明:当配置了某个字段如(status)做完告警复原字段时,请不要将这个字段增加到告警的映射规定中。通常会导致告警与复原告警字段不匹配,从而复原失败。

补充信息

FunctionCompute 示例代码:

# -*- coding: utf-8 -*-

import logging
import json

def handler(environ, start_response):
    context = environ['fc.context']
    request_uri = environ['fc.request_uri']
    body_str = get_request_body(environ)
    id = json.loads(body_str).get('appId')
    # 这一行为伪代码,示例通过查问 cmdb 获取利用详细信息, 获取到的 app 格局如下
    # {"appId":"b38cdf95-2526-4d7a-9ea9-ffe7b32*****", "appName": "iot-iam", "owner":"王五", "ownerPhone": "130xxxx1236"}
    app = cmdb.getApp(id)
    ret = json.dumps(app)
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return [ret.encode('utf-8')]

def get_request_body(environ):
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0
    request_body = environ['wsgi.input'].read(request_body_size)
    return request_body

相干链接:

[1] ARMS 告警治理

https://help.aliyun.com/document_detail/214753.htm?spm=a2c4g….

[2] Prometheus 告警定义

https://prometheus.io/docs/alerting/latest/clients/#sending-a…

[3] 自定义集成

https://help.aliyun.com/document_detail/251850.htm?spm=a2c4g….

[4] 集成概述

https://help.aliyun.com/document_detail/260831.htm?spm=a2c4g….

[5] 告诉策略最佳实际

https://help.aliyun.com/document_detail/456953.htm?spm=a2c4g….

[6] 事件处理流

https://help.aliyun.com/document_detail/311905.htm?spm=a2c4g….

[7] ARMS 控制台

https://account.aliyun.com/login/login.htm?oauth_callback=htt…

[8] 函数计算利用

https://help.aliyun.com/document_detail/51783.htm?spm=a2c4g.2…

[9] 阿里云云监控

https://help.aliyun.com/document_detail/60714.htm?spm=a2c4g.2…

点击立刻收费试用云产品 开启云上实际之旅!

原文链接

本文为阿里云原创内容,未经容许不得转载。

退出移动版