ElkStack 之 Heartbeat(心跳检测)

3,040 阅读12分钟

Heartbeat是一个轻量级守护程序,安装在远程服务器上以定期检查服务的状态,检查服务是否可用。与Metricbeat不同,Metricbeat只告诉你服务器是启动还是停止,Heartbeat可以告诉你,服务是否可以正常访问

Heartbeat可以帮你验证服务是否可以正常访问,如果你需要验证内部服务时,他还可以用于其它方案,例如,安全用例

你可以配置Heartbeat来Ping指定主机名的所有DNS可解析的IP地址。从而检查所有的负载均衡服务,是否可用

配置Heartbeat时,可以指定用于监控的hosts 。 每个监控器按照你设置的监控计划运行。例如,你可以将一个监控器配置为每10分钟运行一次,并且配置不同的监控器在9:00~17:00运行

Heartbeat目前支持通过以下方式检查hosts

  • ICMP(IPV4/IPV6)回显请求。当你只是想检查服务是否可用时,可以使用icmp。这个监控器需要管理员权限

  • TCP。 tcp监控器是通过TCP协议来连接。可以选择配置tcp监控器,通过发送或接受自定义有效内容(payload)来验证端点(endpoint)是否可用

  • HTTP。使用http监控器是通过http协议进行连接。可以选择配置http监控器来验证服务是否返回预期的响应,例如,特定的状态码,响应头或者内容

tcphttp都支持SSL/TLS和代理设置

安装Heartbeat

Heartbeat检测服务心跳,一般安装在较为稳定的独立服务器上(类似云服务,不断电,不断网)。尽量不要跟被监控的服务放在一个篮子里

下载页面根据系统下载相应的安装包

deb(Debian/Ubuntu)

curl -L -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-5.2.2-amd64.debsudo dpkg -i heartbeat-5.2.2-amd64.deb

rpm(Redhat / Centos / Fedora)

curl -L O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-5.2.2-x86_64.rpmsudo rpm -vi heartbeat-5.2.2-x86_64.rpm

mac

curl -L -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-5.2.2-darwin-x86_64.tar.gztar xzvf heartbeat-5.2.2-darwin-x86_64.tar.gz

windows

  1. 根据具体系统下载 32位系统 https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-{version}-windows-x86.zip或者 64位系统https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-{version}-windows-x86_64.zip 注意将{version}替换成具体版本,格式类似于5.2.1

  2. 将下载的zip解压到指定文件夹,例如 D:\Heartbeat

  3. 以管理员身份打开PowerShell(右键单击PowerShell图标,选择以管理员身份运行)。注意,如果是xp,需要单独安装powershell

  4. 运行以下命令安装为Windows服务

    PS > cd 'D:\Heartbeat'PS D:\Heartbeat> .\install-service-heartbeat.ps1

!> 如果脚本被禁用,或者安装不成功,或者是xp系统,其实可以考虑使用nssm,具体用法,百度之。具体参数为-c D:\Heartbeat\heartbeat.yml -path.home D:\Heartbeat\ -path.data D:\Heartbeat\

测试阶段可以使用 heartbeat.exe -e -f heartbeat.yml

如果已经安装服务,可以使用net start heartbeat(使用管理员权限的cmd或者powershell或者从服务(Win+R输入services.msc,找到heartbeat服务手动开启)

配置Heartbeat

可以通过编辑heartbeat.yml来配置heartbeat。heartbeat.full.yml里面有所有可用的选项,可以作为参考

Heartbeat提供在指定的间隔时间检测主机心跳状态的监控,可以单独配置每个监控。Heartbeat目前提供ICMP,TCP 和HTTP 的监控(更多有关监控的信息,参见 简介

要启用的监控列表,使用(-) 开头(yaml中的数组),以下表示的用Heartbeat监控ICMPTCP

heartbeat.monitors:- type: icmp  schedule: '*/5 * * * * * *'   #1  hosts: ["myhost"]- type: tcp  schedule: '@every 5s'         #2  hosts: ["myhost:7"]  # default TCP Echo Protocol  mode: any                     #3  check.send: "Check"  check.receive: "Check"- type: http  schedule: '@every 5s'  urls: ["http://localhost:80/service/status"]  check.response.status: 200heartbeat.scheduler:  limit: 10
  1. 这个ICMP监控,每五秒钟运行一次(e.g. 10:00:00,10:00:05 …) schedule选项是类cron语法。具体参见this cronexpr implementation

  2. 这个TCP监控也是每5秒运行一次。Heartbeat添加了@every关键词添加到了conexpr包里

  3. mode指定是否用来ping一个ip(any)或全解析IPS(all) 。

原版配置

监控选项

type
  • icmp(IPV4/IPV6)回显请求。当你只是想检查服务是否可用时,可以使用icmp。这个监控器需要管理员权限

  • tcptcp监控器是通过TCP协议来连接。可以选择配置tcp监控器,通过发送或接受自定义有效内容(payload)来验证端点(endpoint)是否可用

  • http。使用http监控器是通过http协议进行连接。可以选择配置http监控器来验证服务是否返回预期的响应,例如,特定的状态码,响应头或者内容

tcphttp都支持SSL/TLS和代理设置

name

监控器名字

enabled

Boolean值,指定监控模块是否启用,默认为true

schedule

类cron表达式

ipv4

Boolean值,如果指定了host,是否使用ipv4协议进行pin,默认为true

ipv6

Boolean值,如果指定了host,是否使用ipv4协议进行pin,默认为true

mode

any或者all,默认为any。如果是any,监控器对指定的主机名只ping一个ip地址。如果是all,则ping所有dns能解析出来的ip地址。对于负载均衡监控很有用

watch.poll_file

此为实验功能。未来可能更改或删除

这是JSON格式的监控器配置文件。可以包含多个需要监控的对象。Heartbeat定期检查此文件。Heartbeat会合并heartbeat.yml和json中的配置,有新增的则新增监控实例。josn文件中删除实例后,heartbeat会停止监控该实例。

每个监控器用协议,主机,端口等参数作为唯一id。如果存在相同的,则使用合并后的最后一个json定义的设置。(以json中定义的为准)。所以为了不重启heartbeat,建议使用watch.poll_file进行配置,但是需要注意,这个是实验室功能,后期可能会修改或者变更

heartbeat.monitors:- type: tcp  schedule: '*/5 * * * * * *'  hosts: ["myhost"]  watch.poll_file:    path: {path.config}/monitors/dynamic.json    interval: 5s
path

    指定的JSON文件地址

interval

    指定间隔时间

JSON文件内容如下

{"hosts": ["myhost:1234"], "schedule": "*/15 * * * * * *"}     #1{"hosts": ["tls://otherhost:479"], "ssl.certificate_authorities": ["path/to/ca/file.pem"]}      #2

  1. 检查到文件变更后,heartbeat会重启该监控器,并改为每15秒钟运行一次
  2. heartbeat新增一个监控,使用带有ca证书的基于TLS的连接
ICMP选项

type设置为icmp时,该项生效。Heartbeat使用ICMP(v4和v6)回显请求来检查配置的主机

hosts

需要ping的主机列表

wait

等待时间,默认1s

TCP 选项

type设置为tcp时,该项生效。通过tcp协议发送或接受自定义内容来验证端点是否可用。

hosts

需要ping的主机列表。

  • 简单的主机名,例如localhost 或者ip地址。如果你指定了这个选项,你必须在指定ports选项。如果监控器配置了使用ssl,heartbeat使用基于ssl、tls的连接。否则的话,使用普通的tcp连接
  • 主机名+端口,例如localhost:8080。heartbeat根据主机名和端口号进行连接。如果监控器配置了使用ssl,heartbeat使用基于ssl、tls的连接。否则的话,使用普通的tcp连接
  • 完整的URL,语法为 scheme://<host>:[port]
    • schemetcp,plain,ssl或者tls。如果指定的是tcp或者plain,heartbeat使用tcp连接即使监控器配置为使用ssl,如果指定了tls或者ssl,heartbeat建立ssl连接。但是如果监控器没用ssl,则使用系统默认值(暂不支持windows)
    • host是主机名。
    • port是端口号。
ports

如果hosts中没指定端口,则在此需要配置需要ping的端口列表。例如检查 80,9200,5044端口

- type: tcp  schedule: '@every 5s'  hosts: ["myhost"]  ports: [80, 9200, 5044]

check

验证发送到主机的有效内容(payload)和预期的响应。如果未指定有效内容(payload),一旦连接成功,则视为可用。如果只指定了发送,未指定接收。接收到任何响应都视为成功。如果只指定接收内容,未指定发送内容。不发送payload,但是在连接中,客户端希望接收到的内容为hello message或者banner(原文: If receive is specified without send, no payload is sent, but the client expects to receive a payload in the form of a “hello message” or “banner” on connect.)

- type: tcp  schedule: '@every 5s'  hosts: ["myhost"]  ports: [7]  check.send: 'Hello World'  check.receive: 'Hello World'

proxy_url

只可以用socks5代理。

proxy_url: socks5://user:password@socks5-proxy:2233

使用代理时,主机名实在代理服务器上解析,而不是在客户端解析。可以通过设置 proxy_use_local_resolver来修改

proxy_use_local_resolver

Boolean值,用于确定主机名是否本地解析还是在代理服务器解析。默认值为false,即在代理服务器解析。

ssl

TLS/SSL连接设置。如果check未配置,则监控器将仅检查是否可以建立SSL/TLS连接。此检查可能在TCP级别或在证书验证期间失败

- type: tcp  schedule: '@every 5s'  hosts: ["myhost"]  ports: [80, 9200, 5044]  ssl:    certificate_authorities: ['/etc/ca.crt']    supported_protocols: ["TLSv1.0", "TLSv1.1", "TLSv1.2"]
HTTP选项

type设置为http时,该项生效。通过http协议验证host是否返回预期响应。

urls

用于连接的URLs列表

- type: http  schedule: '@every 5s'  urls: ["http://myhost:80"]
proxy_url

http代理url。选填项。如果不设置,默认使用系统环境中的HTTP_PROXY

username

选填项。用来请求身份验证的服务。如果验证身份的服务不指定,很可能返回403

password

选填项。同username

ssl 同tcp ssl
check(咳咳,划重点)

选填项。发送request到远程服务,并接受期望响应response

- type: http  schedule: '@every 5s'  urls: ["http://myhost:80"]  check.request.method: HEAD  check.response.status: 200
  • check.request 选项

    • method - HTTP方法。支持HEAD,GETPOST
    • headers - 设置请求头
    • body - 选填请求体(用于POST方法)
  • check.response 选项

    • status - 期望的响应码。未设置或者设置的是0,除404以外状态码均可
    • headers - 必须响应的header头信息
    • body - 必须的响应体
- type: http  schedule: '@every 5s'  urls: ["https://myhost:80"]check.request:  method: GET  headers:    'X-API-Key': '12345-mykey-67890'check.response:  status: 200  body: '{"status": "ok"}'
Scheduler 选项
heartbeat.scheduler:  limit: 10  location: 'UTC-08:00'

示例中设置limit为10,确保只有10个IO任务处于活动状态。IO任务可以是通过DNS实际检查或者解析地址

limit

允许Heartbeat执行的并发IO任务数。如果为0,则没有限制。默认值为0。大多数操作系统文件,将文件描述符限制设置为1024。为了Heartbeat正确运行并且不意外组织输出。应该将limit的值设置低于ulimit

location

设置时区。默认使用本地实际 localtime

发送到Elasticsearch

output.elasticsearch:  hosts: ["192.168.1.42:9200"]  template.name: "heartbeat"                #1  template.path: "heartbeat.template.json"  #2

1,2处是自动在Elasticsearch中加载索引模板,详细信息参见官网文档

如果是要输出到Logstash,参见配置Heartbeat使用Logstash

如果要测试配置,在heartbeat可执行目录下,运行./heartbeat -configtest -e

运行Heartbeat

deb :

sudo /etc/init.d/ start

rpm :

sudo /etc/init.d/heartbeat start

mac :

sudo ./heartbeat -e -c heartbeat.yml -d "publish"

win : 管理员权限

net start heartbeat

Windows默认将log输出在${Heartbeat_home}\Logs文件夹

目前为止,Heartbeat已经开始检查你的服务状态并且发送相应的数据到你定义的输出点了(logstash/elasticsearch)

命令行选项

命令行运行./heartbeat -h查看完整的选项列表

-E <setting>=<value>

覆盖配置文件中的某个配置例如 `./heartbeat -c heartbeat.yml -E name=mybeat`

-N

禁止发送数据到指定的输出。这个选项在测试Beat时很有用

-c <file>

指定heartbeat配置文件

configtest

测试配置文件是否可用,然后退出。在排除配置文件错误时很有用

-cpuprofile <output file>

将cpu配置信息输出到指定文件。在排除故障的时候很有用

-d <selectors>

使用指定的选择器进行调试。参数用逗号隔开,或者使用 `-d "*"`调试所有的组件。例如`-d "publish"`显示所有`"publish"`相关的信息

-e

禁用syslog/file输出,只记录到stderr

-httpprof [<host>]:<port>

启动http服务器进行性能分析

-memprofile <output file>

将内存配置信息写入到指定文件。

-path.config

设置配置文件的路径

-path.data

设置data文件路径

-path.home

设置可执行文件所在路径

-path.logs

设置日志文件的路径

-v

启用详细输出,以显示INFO级别日志

-version

显示beat版本并退出

本文只是针对官网文档进行了部分翻译。其他像是输出到logstash,redis等配置信息以及Processors部分 Exported Fields部分,Securing Heartbeat暂不翻译

Heartbeat+ElastAlert 心跳报警

ElastAlert如何使用, 参见另外一篇文章

监控服务(主机能否ping通,端口是否开放,http响应是否合法)。使用Heartbeat如果up=true则说明验证通过。服务可用。common fields#_up

使用ElastAlert的change rule。具体示例参见 example_rules/example_change.yaml文件。为啥用change rule,是因为一般服务就两种状态,up/down 我们只需要在状态切换(可用->不可用/不可用->可用)时获取到通知即可

我的配置如下

# Alert when some field changes between documents# This rule would alert on documents similar to the following:# {'username': 'bob', 'country_name': 'USA', '@timestamp': '2014-10-15T00:00:00'}# {'username': 'bob', 'country_name': 'Russia', '@timestamp': '2014-10-15T05:00:00'}# Because the user (query_key) bob logged in from different countries (compare_key) in the same day (timeframe)# (Optional)# Elasticsearch host# es_host: elasticsearch.example.com# (Optional)# Elasticsearch port# es_port: 14900# (Optional) Connect with SSL to Elasticsearch#use_ssl: True# (Optional) basic-auth username and password for elasticsearch#es_username: someusername#es_password: somepassword# (Required)# Rule name, must be uniquename: heartbeat-monitor# (Required)# Type of alert.# the change rule will alert when a certain field changes in two documents within a timeframetype: change# (Required)# Index to search, wildcard supportedindex: heartbeat-*# (Required, change specific)# The field to look for changes incompare_key: up# (Required, change specific)# Ignore documents without the compare_key (country_name) fieldignore_null: true# (Required, change specific)# The change must occur in two documents with the same query_keyquery_key: monitor# (Required, change specific)# The value of compare_key must change in two events that are less than timeframe apart to trigger an alertnum_events: 1timeframe:    minutes: 1# (Required)# The alert is use when a match is foundalert:#- "email"#- "debug"- "elastalert_modules.wechat_qiye_alert.WeChatAlerter"#后台登陆后【设置】->【权限管理】->【普通管理组】->【创建并设置通讯录和应用权限】->【CorpID,Secret】#设置微信企业号的appidcorp_id: xxx#设置微信企业号的Secretsecret: xxx#后台登陆后【应用中心】->【选择应用】->【应用id】#设置微信企业号应用idagent_id: xxx#如果标签下无用户,则推送到部门#party_id: xxx#如果标签下无用户,则推送到用户#user_id: xxxtag_id: xxx

不过elastalert有个代码逻辑错误。我已提交Pull request#926Issue#925 。 如果官方不采纳的话,可以手动修改elastalert\ruletypes.py#L135not val改成 val is None具体原因参见Issue#925

如果正常的话,先将Heartbeat监听的服务启动,输出到Elasticsearch后,再停用。再次写入到Elasticsearch后。Elastalert控制台也会提示xx hits/xx hits并发送微信。

snipaste20170303_134853.png