03 . Prometheus监控容器和HTTP探针应用

Eeporter是什么及来源?

是什么?

广义上讲全部能够向Prometheus提供监控样本数据的程序均可以被称为一个Exporter。而Exporter的一个实例称为target,以下所示,Prometheus经过轮询的方式按期从这些target中获取样本数据:node

来源有哪些?

社区提供的linux

Prometheus社区提供了丰富的Exporter实现,涵盖了从基础设施,中间件以及网络等各个方面的监控功能。这些Exporter能够实现大部分通用的监控需求。下表列举一些社区中经常使用的Exporter:ios

范围 经常使用Exporter
数据库 MySQL Exporter, Redis Exporter, MongoDB Exporter, MSSQL Exporter等
硬件 Apcupsd Exporter,IoT Edison Exporter, IPMI Exporter, Node Exporter等
消息队列 Beanstalkd Exporter, Kafka Exporter, NSQ Exporter, RabbitMQ Exporter等
存储 Ceph Exporter, Gluster Exporter, HDFS Exporter, ScaleIO Exporter等
HTTP服务 Apache Exporter, HAProxy Exporter, Nginx Exporter等
API服务 AWS ECS Exporter, Docker Cloud Exporter, Docker Hub Exporter, GitHub Exporter等
日志 Fluentd Exporter, Grok Exporter等
监控系统 Collectd Exporter, Graphite Exporter, InfluxDB Exporter, Nagios Exporter, SNMP Exporter等
其余 Blockbox Exporter, JIRA Exporter, Jenkins Exporter, Confluence Exporter等

用户自定义的nginx

除了直接使用社区提供的Exporter程序之外,用户还能够基于Prometheus提供的Client Library建立本身的Exporter程序,目前Promthues社区官方提供了对如下编程语言的支持:Go、Java/Scala、Python、Ruby。同时还有第三方实现的如:Bash、C++、Common Lisp、Erlang,、Haskeel、Lua、Node.js、PHP、Rust等。git

Exporter的运行方式

从Exporter的运行方式来说,又能够分为github

独立使用的

以咱们已经使用过的Node Exporter为例,因为操做系统自己并不直接支持Prometheus,同时用户也没法经过直接从操做系统层面上提供对Prometheus的支持。所以,用户只能经过独立运行一个程序的方式,经过操做系统提供的相关接口,将系统的运行状态数据转换为可供Prometheus读取的监控数据。 除了Node Exporter之外,好比MySQL Exporter、Redis Exporter等都是经过这种方式实现的。 这些Exporter程序扮演了一个中间代理人的角色。正则表达式

集成到应用中的

为了可以更好的监控系统的内部运行状态,有些开源项目如Kubernetes,ETCD等直接在代码中使用了Prometheus的Client Library,提供了对Prometheus的直接支持。这种方式打破的监控的界限,让应用程序能够直接将内部的运行状态暴露给Prometheus,适合于一些须要更多自定义监控指标需求的项目。docker

Exporter规范

全部的Exporter程序都须要按照Prometheus的规范,返回监控的样本数据。以Node Exporter为例,当访问/metrics地址时会返回如下内容:shell

# HELP node_cpu Seconds the cpus spent in each mode.
# TYPE node_cpu counter
node_cpu{cpu="cpu0",mode="idle"} 362812.7890625
# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 3.0703125

这是一种基于文本的格式规范,在Prometheus 2.0以前的版本还支持Protocol buffer规范。相比于Protocol buffer文本具备更好的可读性,以及跨平台性。Prometheus 2.0的版本也已经再也不支持Protocol buffer。数据库

Exporter返回的样本数据,主要由三个部分组成:样本的通常注释信息(HELP),样本的类型注释信息(TYPE)和样本。Prometheus会对Exporter响应的内容逐行解析:

若是当前行以# HELP开始,Prometheus将会按照如下规则对内容进行解析,获得当前的指标名称以及相应的说明信息:

# HELP <metrics_name> <doc_string>

若是当前行以# TYPE开始,Prometheus会按照如下规则对内容进行解析,获得当前的指标名称以及指标类型:

# TYPE <metrics_name> <metrics_type>

TYPE注释行必须出如今指标的第一个样本以前。若是没有明确的指标类型须要返回为untyped。 除了# 开头的全部行都会被视为是监控样本数据。 每一行样本须要知足如下格式规范:

metric_name [
  "{" label_name "=" `"` label_value `"` { "," label_name "=" `"` label_value `"` } [ "," ] "}"
] value [ timestamp ]

其中metric_name和label_name必须遵循PromQL的格式规范要求。value是一个float格式的数据,timestamp的类型为int64(从1970-01-01 00:00:00以来的毫秒数),timestamp为可选默认为当前时间。具备相同metric_name的样本必须按照一个组的形式排列,而且每一行必须是惟一的指标名称和标签键值对组合。

须要特别注意的是对于histogram和summary类型的样本。须要按照如下约定返回样本数据:

1 . 类型为summary或者histogram的指标x,该指标全部样本的值的总和须要使用一个单独的x_sum指标表示

2 . 类型为summary或者histogram的指标x,该指标全部样本的总数须要使用一个单独的x_count指标表示。

3 . 对于类型为summary的指标x,其不一样分位数quantile所表明的样本,须要使用单独的x{quantile="y"}表示。

4 . 对于类型histogram的指标x为了表示其样本的分布状况,每个分布须要使用x_bucket{le="y"}表示,其中y为当前分布的上位数。同时必须包含一个样本x_bucket{le="+Inf"},而且其样本值必须和x_count相同。

5 . 对于histogram和summary的样本,必须按照分位数quantile和分布le的值的递增顺序排序。

如下是类型为histogram和summary的样本输出示例

# A histogram, which has a pretty complex representation in the text format:
# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320

# Finally a summary, which has a complex representation, too:
# HELP rpc_duration_seconds A summary of the RPC duration in seconds.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3102
rpc_duration_seconds{quantile="0.05"} 3272
rpc_duration_seconds{quantile="0.5"} 4773
rpc_duration_seconds_sum 1.7560473e+07
rpc_duration_seconds_count 2693

指定样式格式的版本
在Exporter响应的HTTP头信息中,能够经过Content-Type指定特定的规范版本,例如:

HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 2906
Content-Type: text/plain; version=0.0.4
Date: Sat, 17 Mar 2018 08:47:06 GMT

其中version用于指定Text-based的格式版本,当没有指定版本的时候,默认使用最新格式规范的版本。同时HTTP响应头还须要指定压缩格式为gzip。

容器监控

Docker是一个开源的应用容器引擎,让开发者能够打包他们的应用以及依赖包到一个可移植的容器中,而后发布到任何流行的Linux/Windows/Mac机器上。容器镜像正成为一个新的标准化软件交付方式。

例如,能够经过一下命令快速在本地启动一个Nginx服务:

安装docker
# 安装一些必要的系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加软件源信息
# docker 官方源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 阿里云源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

sudo yum makecache fast

# CentOS7安装 Docker-ce
yum -y install docker-ce   


mkdir /etc/docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}

# 启动Docker后台服务
systemctl start docker && systemctl enable docker
systemctl daemon-reload                 # 守护进程重启

# 运行一个nginx作测试
docker run -itd nginx

为了可以获取到Docker容器的运行状态,用户能够经过Docker的stats命令获取到当前主机上运行容器的统计信息,能够查看容器的CPU利用率、内存使用量、网络IO总量以及磁盘IO总量等信息。

docker stats
CONTAINER           CPU %      MEM USAGE / LIMIT     MEM %      NET I/O         BLOCK I/O   PIDS
9a1648bec3b2        0.30%      196KiB / 3.855GiB     0.00%      828B / 0B       827kB / 0B  1
# 除了使用命令之外,用户还能够经过docker提供的http api查看容器的监控统计信息.

使用CAdvisor

CAdvisor是Google开源的一款用于展现和分析容器运行状态的可视化工具。经过在主机上运行CAdvisor用户能够轻松的获取到当前主机上容器的运行统计信息,并以图表的形式向用户展现。

在本地运行CAdvisor也很是简单,直接运行一下命令便可:

docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest
# 经过访问http://localhost:8080能够查看,当前主机上容器的运行状态.

CAdvisor是一个简单易用的工具,相比于使用Docker命令行工具,用户不用再登陆到服务器中便可以可视化图表的形式查看主机上全部容器的运行状态。

而在多主机的状况下,在全部节点上运行一个CAdvisor再经过各自的UI查看监控信息显然不太方便,同时CAdvisor默认只保存2分钟的监控数据。好消息是CAdvisor已经内置了对Prometheus的支持。访问http://localhost:8080/metrics便可获取到标准的Prometheus监控样本输出:

下面列举了一些CAdvisor中获取的典型监控指标

指标名称 类型 含义
gauge 再过去10秒内容器CPU的平均负载
container_cpu_usage_seconds_total
指标名称 类型 含义
container_cpu_load_average_10s gauge 过去10秒内容器CPU的平均负载
container_cpu_usage_seconds_total counter 容器在每一个CPU内核上的累积占用时间 (单位:秒)
container_cpu_system_seconds_total counter System CPU累积占用时间(单位:秒)
container_cpu_user_seconds_total counter User CPU累积占用时间(单位:秒)
container_fs_usge_bytes gauge 容器中文件系统的使用量(单位:字节)
container_network_receive_bytes_total counter 容器网络累计接受数据总量(单位: 字节)
container_network_transmit_bytes_total counter 容器网络累计传输数据总量(单位: 字节)

与Prometheus集成

修改/etc/prometheus/prometheus.yml,将cAdvisor添加监控数据采集任务目标当中:

- job_name: 'docker'
    static_configs:
    - targets: ['172.19.0.27:8080']

systemctl restart prometheus

启动Prometheus服务,能够在Prometheus UI中看到当前全部的Target状态:

当可以正常采集到cAdvisor的样本数据后,能够经过一下表达式计算容器的CPU使用率.

sum(irate(container_cpu_usage_seconds_total{image!=""}[1m])) without (cpu)

查询容器内存使用量(单位: 字节)

container_memory_usage_bytes{image!=""}

查询容器网络接收量速率(单位: 字节/秒)

sum(rate(container_network_receive_bytes_total{image!=""}[1m])) without (interface)

查询容器网络传输量速率

sum(rate(container_network_transmit_bytes_total{image!=""}[1m])) without (interface)

查询容器文件系统读取速率

sum(rate(container_fs_reads_bytes_total{image!=""}[1m])) without (device)

# 为了方便看出效果,咱们使用dd命令
docker exec -it 628d /bin/bash
dd if=/dev/zero of=test bs=1M count=1000

  • 查询容器文件系统写入速率(单位: 字节/秒)
sum(rate(container_fs_writes_bytes_total{image!=""}[1m])) without (device)

Prometheus网络探测

接下来咱们主要介绍Prometheus下如何进行白盒监控,咱们以前监控主机的资源用量、容器的运行状态、数据库中间件的运行数据。 这些都是支持业务和服务的基础设施,经过白盒可以了解其内部的实际运行状态,经过对监控指标的观察可以预判可能出现的问题,从而对潜在的不肯定因素进行优化。而从完整的监控逻辑的角度,除了大量的应用白盒监控之外,还应该添加适当的黑盒监控。
黑盒监控即以用户的身份测试服务的外部可见性,常见的黑盒监控包括HTTP探针、TCP探针等用于检测站点或者服务的可访问性,以及访问效率等。

黑盒监控相较于白盒监控最大的不一样在于黑盒监控是以故障为导向当故障发生时,黑盒监控能快速发现故障,而白盒监控则侧重于主动发现或者预测潜在的问题。一个完善的监控目标是要可以从白盒的角度发现潜在问题,可以在黑盒的角度快速发现已经发生的问题。

安装Blackbox Exporter

Blackbox Exporter是Prometheus社区提供的官方黑盒监控解决方案,其容许用户经过:HTTP、HTTPS、DNS、TCP以及ICMP的方式对网络进行探测。用户能够直接使用go get命令获取Blackbox Exporter源码并生成本地可执行文件:

下载安装blackbox_exporter

wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.16.0/blackbox_exporter-0.16.0.linux-amd64.tar.gz

tar xvf blackbox_exporter-0.16.0.linux-amd64.tar.gz -C /usr/local/prometheus/
mv blackbox_exporter-0.16.0.linux-amd64/ blackbox_exporter
useradd prometheus
chown -R prometheus:prometheus /usr/local/prometheus/

vim /usr/lib/systemd/system/blackbox_exporter.service
[Unit]
Description=blackbox_exporter
After=network.target

[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/prometheus/blackbox_exporter/blackbox_exporter --config.file=/usr/local/prometheus/blackbox_exporter/blackbox.yml
Restart=on-failure

[Install]
WantedBy=multi-user.target

systemctl enable blackbox_exporter.service
systemctl start blackbox_exporter.service

运行Blackbox Exporter时,须要用户提供探针的配置信息,这些配置信息多是一些自定义的HTTP头信息,也多是探测时须要的一些TSL配置,也多是探针自己的验证行为。在Blackbox Exporter每个探针配置称为一个module,而且以YAML配置文件的形式提供给Blackbox Exporter。 每个module主要包含如下配置内容,包括探针类型(prober)、验证访问超时时间(timeout)、以及当前探针的具体配置项:

# 探针类型:http、 tcp、 dns、 icmp.
prober: <prober_string>
# 超时时间
[ timeout: <duration> ]
# 探针的详细配置,最多只能配置其中的一个
[ http: <http_probe> ]
[ tcp: <tcp_probe> ]
[ dns: <dns_probe> ]
[ icmp: <icmp_probe> ]

下面是一个简化的探针配置文件blockbox.yml,包含两个HTTP探针配置项

modules:
  http_2xx:
    prober: http
    http:
      method: GET
  http_post_2xx:
    prober: http
    http:
      method: POST

经过运行一下命令,并指定使用的探针设置文件启动Blockbox Exporter实例:

blackbox_exporter --config.file=/etc/prometheus/blackbox.yml
or
systemctl restart blackbox_exporter.service

启动成功后,就能够经过访问http://172.19.0.27:9115/probe?module=http_2xx&target=baidu.com对baidu.com进行探测。这里经过在URL中提供module参数指定了当前使用的探针,target参数指定探测目标,探针的探测结果经过Metrics的形式返回:

# HELP probe_dns_lookup_time_seconds Returns the time taken for probe dns lookup in seconds
# TYPE probe_dns_lookup_time_seconds gauge
probe_dns_lookup_time_seconds 0.004359875
# HELP probe_duration_seconds Returns how long the probe took to complete in seconds
# TYPE probe_duration_seconds gauge
probe_duration_seconds 0.046153996
# HELP probe_failed_due_to_regex Indicates if probe failed due to regex
# TYPE probe_failed_due_to_regex gauge
probe_failed_due_to_regex 0
# HELP probe_http_content_length Length of http content response
# TYPE probe_http_content_length gauge
probe_http_content_length 81
# HELP probe_http_duration_seconds Duration of http request by phase, summed over all redirects
# TYPE probe_http_duration_seconds gauge
probe_http_duration_seconds{phase="connect"} 0.00105657
probe_http_duration_seconds{phase="processing"} 0.039457402
probe_http_duration_seconds{phase="resolve"} 0.004359875
probe_http_duration_seconds{phase="tls"} 0
probe_http_duration_seconds{phase="transfer"} 0.000337184
# HELP probe_http_last_modified_timestamp_seconds Returns the Last-Modified HTTP \
response header in unixtime
# TYPE probe_http_last_modified_timestamp_seconds gauge
probe_http_last_modified_timestamp_seconds 1.26330408e+09
# HELP probe_http_redirects The number of redirects
# TYPE probe_http_redirects gauge
probe_http_redirects 0
# HELP probe_http_ssl Indicates if SSL was used for the final redirect
# TYPE probe_http_ssl gauge
probe_http_ssl 0
# HELP probe_http_status_code Response HTTP status code
# TYPE probe_http_status_code gauge
probe_http_status_code 200
# HELP probe_http_uncompressed_body_length Length of uncompressed response body
# TYPE probe_http_uncompressed_body_length gauge
probe_http_uncompressed_body_length 81
# HELP probe_http_version Returns the version of HTTP of the probe response
# TYPE probe_http_version gauge
probe_http_version 1.1
# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6
# TYPE probe_ip_protocol gauge
probe_ip_protocol 4
# HELP probe_success Displays whether or not the probe was a success
# TYPE probe_success gauge
probe_success 1

从返回的样本中,用户能够获取站点的DNS解析耗时,站点响应时间,HTTP响应状态码等等和站点访问质量相关的监控指标,从而帮助管理员主动的发现故障和问题.

Prometheus集成

接下来,只须要在Prometheus下配置对Blockbox Exporter实例的采集任务便可、最直观的配置方式.

- job_name: 'baidu_http2xx_probe'
    params:
      module:
      - http_2xx
      target:
      - baidu.com
    metrics_path: /probe
    static_configs:
    - targets: ['172.19.0.27:9115']

  - job_name: 'prometheus_http2xx_probe'
    params:
      module:
      - http_2xx
      target:
      - prometheus.io
    metrics_path: /probe
    static_configs:
    - targets: ['172.19.0.27:9115']

systemctl restart prometheus

这里分别配置了名为baidu_http2x_probe和prometheus_http2xx_probe的采集任务,而且经过params指定使用的探针(module)以及探测目标(target).

那问题就来了,假如咱们有N个目标站点且都须要M种探测方式,那么Prometheus中将包含N * M个采集任务,从配置管理的角度来讲显然是不可接受的。这里咱们也能够采用Relabling的方式对这些配置进行简化,配置方式以下:

- job_name: 'blackbox'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
        - http://prometheus.io    # Target to probe with http.
        - https://prometheus.io   # Target to probe with https.
        - http://example.com:8080 # Target to probe with http on port 8080.
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: 172.19.0.27:9115

这里针对每个探针服务(如http_2xx)定义一个采集任务,而且直接将任务的采集目标定义为咱们须要探测的站点,在采集样本数据以前经过relabel_configs对采集任务进行动态配置.

* 第一步, 根据Target实例的地址,写入__param_target标签中,__param_<name>形式的标签来表示,
	# 在采集任务时会在请求目标地址中添加<name>参数,等同于params的设置.
* 第二步,  获取__param_target的值,并覆写到instance标签中.
* 第三步,  覆写Target实例的__address__标签值为BlockBox Exporter实例的访问地址.

HTTP探针

HTTP探针是进行黑盒监控时最经常使用的探针之一,经过HTTP探针可以网站或者HTTP服务创建有效的监控,包括其自己的可用性,以及用户体验相关的如响应时间等等。除了可以在服务出现异常的时候及时报警,还能帮助系统管理员分析和优化网站体验。

Blockbox Exporter中全部的探针均是以Module的信息进行配置。以下所示,配置了一个最简单的HTTP探针:

modules:
  http_2xx_example:
    prober: http
    http:

经过prober配置项指定探针类型。配置项http用于自定义探针的探测方式,这里有没对http配置项添加任何配置,表示彻底使用HTTP探针的默认配置,该探针将使用HTTP GET的方式对目标服务进行探测,而且验证返回状态码是否为2XX,是则表示验证成功,不然失败。

自定义HTTP请求

HTTP服务一般会以不一样的形式对外展示,有些可能就是一些简单的网页,而有些则多是一些基于REST的API服务。 对于不一样类型的HTTP的探测须要管理员可以对HTTP探针的行为进行更多的自定义设置,包括:HTTP请求方法、HTTP头信息、请求参数等。对于某些启用了安全认证的服务还须要可以对HTTP探测设置相应的Auth支持。对于HTTPS类型的服务还须要可以对证书进行自定义设置。

以下所示,这里经过method定义了探测时使用的请求方法,对于一些须要请求参数的服务,还能够经过headers定义相关的请求头信息,使用body定义请求内容:

http_post_2xx:
    prober: http
    timeout: 5s
    http:
      method: POST
      headers:
        Content-Type: application/json
      body: '{}'

若是HTTP服务启用了安全认证,Blockbox Exporter内置了对basic_auth的支持,能够直接设置相关的认证信息便可:

http_basic_auth_example:
    prober: http
    timeout: 5s
    http:
      method: POST
      headers:
        Host: "login.example.com"
      basic_auth:
        username: "username"
        password: "mysecret"

对于使用了Bear Token的服务也能够经过bearer_token配置项直接指定令牌字符串,或者经过bearer_token_file指定令牌文件。

对于一些启用了HTTPS的服务,可是须要自定义证书的服务,能够经过tls_config指定相关的证书信息:

http_custom_ca_example:
    prober: http
    http:
      method: GET
      tls_config:
        ca_file: "/certs/my_cert.crt"
  • 自定义探针行为
  • 在默认状况下HTTP探针只会对HTTP返回状态码进行校验,若是状态码为2XX(200 <= StatusCode < 300)则表示探测成功,而且探针返回的指标probe_success值为1。
  • 若是用户须要指定HTTP返回状态码,或者对HTTP版本有特殊要求,以下所示,可使用valid_http_versions和valid_status_codes进行定义:
http_2xx_example:
    prober: http
    timeout: 5s
    http:
      valid_http_versions: ["HTTP/1.1", "HTTP/2"]
      valid_status_codes: []

默认状况下,Blockbox返回的样本数据中也会包含指标probe_http_ssl,用于代表当前探针是否使用了SSL:

# HELP probe_http_ssl Indicates if SSL was used for the final redirect
# TYPE probe_http_ssl gauge
probe_http_ssl 0

而若是用户对于HTTP服务是否启用SSL有强制的标准。则可使用fail_if_ssl和fail_if_not_ssl进行配置。fail_if_ssl为true时,表示若是站点启用了SSL则探针失败,反之成功。fail_if_not_ssl恰好相反。

http_2xx_example:
    prober: http
    timeout: 5s
    http:
      valid_status_codes: []
      method: GET
      no_follow_redirects: false
      fail_if_ssl: false
      fail_if_not_ssl: false

除了基于HTTP状态码,HTTP协议版本以及是否启用SSL做为控制探针探测行为成功与否的标准之外,还能够匹配HTTP服务的响应内容。使用fail_if_matches_regexp和fail_if_not_matches_regexp用户能够定义一组正则表达式,用于验证HTTP返回内容是否符合或者不符合正则表达式的内容。

http_2xx_example:
    prober: http
    timeout: 5s
    http:
      method: GET
      fail_if_matches_regexp:
        - "Could not connect to database"
      fail_if_not_matches_regexp:
        - "Download the latest version here"

最后须要提醒的时,默认状况下HTTP探针会走IPV6的协议。 在大多数状况下,可使用preferred_ip_protocol=ip4强制经过IPV4的方式进行探测。在Bloackbox响应的监控样本中,也会经过指标probe_ip_protocol,代表当前的协议使用状况:

# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6
# TYPE probe_ip_protocol gauge
probe_ip_protocol 6

除了支持对HTTP协议进行网络探测之外,Blackbox还支持对TCP、DNS、ICMP等其余网络协议![]

相关文章
相关标签/搜索