0x00. 写在开头

由于目前需要管理的服务器越来越多,同时这些服务器遍布世界各地,再加上几乎每个节点上都在运行公网 BGP 相关的服务,因此急需一个统一的监控+告警系统。

在反复权衡部署难度和运维成本后,决定使用 Prometheus + Consul + 若干 Exporter 来完成

0x01. Consul

Consul 是一个开源的分布式服务注册和配置管理系统,在这里我们用它配合 Prometheus,让 Prometheus 能从 Consul 获取每个节点上的 Exporter 并拉取数据。

注: 在我们的场景下,Consul 过于的复杂,所以这里不会详细介绍 Consul 的高级用法或完整的分布式部署方案

1. 安装 Consul Server

首先我们直接从 Consul 官网 下载二进制文件: 点我

接下来我们需要编写一个默认 ACL 策略,阻止匿名访问:

1
2
3
4
5
6
# config/consul.hcl
acl {
enabled = true
default_policy = "deny"
down_policy = "extend-cache"
}

在启动 consul 之前,请务必先手动创建好 config 和 data 目录,否则会启动失败,
在目录创建好之后,可以使用下面的命令启动 consul

1
consul agent -server -data-dir=<path to data> -config-dir=<path to config> -bind=<server ip> -client=0.0.0.0 -ui -node=server -bootstrap-expect=1

这一步需要注意的是,-bind 参数中的 IP 地址需要和后续 agent 的完全一致。

然后我们需要先拿到 Bootstrap Token:

1
consul acl bootstrap

这一步输出的内容记得保存下来,后续创建其他 token 以及管理 Consul 时都会需要用到

现在我们需要创建几个 token ,分别给 Prometheus 和 Agent 使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 创建 agent 策略
consul acl policy create \
-token=<BOOTSTRAP_TOKEN> \
-name "agent-policy" \
-rules '
agent_prefix "" {
policy = "write"
}
node_prefix "" {
policy = "write"
}
service_prefix "" {
policy = "write"
}'

# 创建 agent token,记得保存
consul acl token create \
-token=<BOOTSTRAP_TOKEN> \
-description "global-agent-token" \
-policy-name agent-policy

# 创建 prometheus 策略
consul acl policy create -token=<BOOTSTRAP_TOKEN> -name "prom-read" -rules '
node_prefix "" {
policy = "read"
}
service_prefix "" {
policy = "read"
}
query_prefix "" {
policy = "read"
}
agent_prefix "" {
policy = "read"
}
'

# 创建 prometheus token,记得保存
consul acl token create \
-token=<BOOTSTRAP_TOKEN> \
-description "prometheus" \
-policy-name "prom-read"

2. 安装 Consul Agent

这里可以直接使用上一步下载的二进制文件,agent 的启动命令如下:

1
consul agent -data-dir=<path to data> -config-dir=<path to config> -retry-join=<Server IP> -bind <Local IP>

这里的 -retry-join 参数需要和 consul server 的 -bind 参数一致。

然后 -bind 参数中的 IP 必须是 consul server 能访问到的 IP,后续在 consul 中注册的服务会使用这个 IP 进行访问

如果需要自定义一个主机名,可以添加一个 -node 参数

3. 注册服务

对于 Node Exporter 来说,只需要在 Consul 中注册一个服务,并指定端口即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# config/node-exporter.json
{
"service": {
"name": "node-exporter",
"id": "node-exporter",
"port": 9100,
"checks": [
{
"name": "node-exporter-check",
"http": "http://127.0.0.1:9100/metrics",
"interval": "15s",
"timeout": "3s"
}
]
}
}

其他服务也是类似,但是记得修改这里面的服务名、ID、端口、健康检查地址等信息

需要注意的是,在每次修改了配置文件后,需要使用 consul reload 命令来重载配置文件

0x02. Prometheus

Prometheus 的配置非常简单,直接让它使用 token 从 consul 中获取服务列表,并拉取数据即可

对于 Node Exporter 来说,配置大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
global:
scrape_interval: 10s
scrape_timeout: 10s
evaluation_interval: 10s

scrape_configs:
- job_name: prometheus
honor_labels: true
static_configs:
- targets: ["localhost:9090"]

- job_name: "node-exporter"
honor_labels: true
consul_sd_configs:
- server: "<consul ip>:8500"
token: "<PROM_TOKEN>"
services:
- "node-exporter"

metrics_path: /metrics
scheme: http

relabel_configs:
- source_labels: ['__meta_consul_node']
target_label: 'instance'
- source_labels: ['__meta_consul_service']
target_label: 'service'

0x03. Consul UI

如果在第一步启动 consul server 时包含了 -ui 参数,那么 consul server 就会启动一个 UI,访问 http://<consul ip>:8500 就可以看到 consul 的 UI 了

在这里你可以使用之前创建的任意一个 token 登录,需要注意的是,bootstrap token 并不包含所有的权限,所以你可能需要自己创建专门用于 UI 的,包含完全权限的 token