搭建Prometheus 和 Grafana
简单来说,Prometheus是用来收集各个被控端的数据,Grafana接入Prometheus来实现数据查看。本篇介绍Grafana和Prometheus的部署、套nginx实现Basic Auth、配置fail2ban实现防爆破、用Prometheus收集node_exporter和mysqld_exporter信息并通过grafnan查看
Prometheus
部署
因为用docker部署,安装目录其实就是数据和配置文件持久化目录
mkdir /opt/prometheus && cd /opt/prometheus
先启动临时容器
docker run --name prometheus -d --rm prom/prometheus
把配置文件复制出来
docker cp prometheus:/etc/prometheus/prometheus.yml /opt/prometheus/
删除容器,因为上面启动的容参数有--rm
,所以停掉它就自动删除了。
docker stop prometheus
部署启动
mkdir /opt/prometheus/data #数据持久化目录
docker run --name prometheus --restart unless-stopped --user "$(id -u)" -d -p 9090:9090 -v /opt/prometheus:/opt/prometheus prom/prometheus --config.file=/opt/prometheus/prometheus.yml --storage.tsdb.path=/opt/prometheus/data
配置nginx
部署完成后访问9090端口即可,但是所有人都能打开,为了安全性,可以套上一层nginx的Basic Auth
这个时候注意网络映射是要改成127.0.0.1:9090:9090
,因为并不想让外部直接访问,所以地址为127.0.0.1,就只能被本地访问。
创建认证,认证文件路径是/usr/local/openresty/nginx/conf/.htpasswd
apt install apache2-utils #安装工具
htpasswd -c /usr/local/openresty/nginx/conf/.htpasswd prometheus
输入密码即可创建完成,后续添加别的用户要去掉-c选项,删除账户把-c换成-D,修改密码就把-c去掉再执行一遍
新建一个nginx配置文件,比如域名是prometheus.example.com,配置一个反代就OK了,此处我还加上了https,更加安全
server {
listen 80;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
ssl_certificate /usr/local/openresty/nginx/conf/ssl/example.com/cert.pem;
ssl_certificate_key /usr/local/openresty/nginx/conf/ssl/example.com/key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_buffer_size 1400;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
server_name prometheus.example.com;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
location / {
proxy_pass http://127.0.0.1:9090;
auth_basic "Prometheus Admin";
auth_basic_user_file /usr/local/openresty/nginx/conf/.htpasswd;
}
}
配置好nginx生效后,此时用浏览器访问域名,就会弹出账号密码框,输入正确的账号密码才能访问
防爆破
可以配合faile2ban来进一步保证安全,这个工具会读取访问日志,指定时间内多次密码错误,就会封锁请求的IP。
这里有之前写过的使用Fail2Ban自动封禁认证失败过多的IP
规则
写一个过滤规则,就是过滤日志中401认证失败的
cat > /etc/fail2ban/filter.d/nginx-401.conf <<EOF
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*" 401 \d+ .*$
ignoreregex =
EOF
测试规则
先清空日志
truncate -s 0 /usr/local/openresty/nginx/logs/access.log
然后打开浏览器隐身请求输入几次错误密码
验证匹配到的和日志中的数量是否一致
fail2ban-regex /usr/local/openresty/nginx/logs/access.log /etc/fail2ban/filter.d/nginx-401.conf
配置
cat > /etc/fail2ban/jail.d/nginx-401.conf <<EOF
[nginx-401]
enabled = true
backend = auto
port = http,https
filter = nginx-401
logpath = /usr/local/openresty/nginx/logs/access.log
maxretry = 5 ; 允许的最大尝试次数
findtime = 600 ; 10分钟内触发规则
bantime = 3600 ; 封禁1小时(单位:秒)
EOF
生效配置
systemctl restart fail2ban
查看封禁状态fail2ban-client status nginx-401
Grafana
部署
和上面Prometheus大同小异
mkdir /opt/grafana && cd /opt/grafana
docker run --name grafana -d --rm grafana/grafana-enterprise
docker cp grafana:/etc/grafana/grafana.ini /opt/grafana/
docker stop grafana
部署启动
docker run -d --restart unless-stopped -p 3000:3000 --user "$(id -u)" --name=grafana -v /opt/grafana/data:/var/lib/grafana -v /opt/grafana/grafana.ini:/etc/grafana/grafana.ini grafana/grafana-enterprise
此时直接访问3000端口就能访问了,初始默认密码和账号是admin admin,登陆上去之后会提示更改密码。
配置nginx
同样套一层nginx,可以提供https访问和一起使用80/443端口。
新建一个nginx配置文件,比如域名是grafana.example.com
反代配置是参考官方教程在这里https://grafana.com/tutorials/run-grafana-behind-a-proxy/
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream grafana {
server localhost:3000;
}
server {
listen 80;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
ssl_certificate /usr/local/openresty/nginx/conf/ssl/example.com/cert.pem;
ssl_certificate_key /usr/local/openresty/nginx/conf/ssl/example.com/key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_buffer_size 1400;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
server_name grafana.example.com;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
location / {
proxy_set_header Host $host;
proxy_pass http://grafana;
}
location /api/live/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_pass http://grafana;
}
}
监控主机
简单实现一个探针。
被监控端
在被监控的服务器安装node_exporter,把数据开放出去。
#持久化配置目录
mkdir /opt/node_exporter && cd /opt/node_exporter
#生成密码哈希
auth_str=`htpasswd -nBC 12 "" | tr -d ':\n' | sed 's/$2y/$2a/'`
#生成配置文件
cat > /opt/node_exporter/web-config.yml <<EOF
basic_auth_users:
prometheus_user: $auth_str
EOF
其中prometheus_user是用户名,可自行修改。
如果提示htpasswd: command not found,就安装软件apache2-utils,apt install apache2-utils
部署启动
docker run --name node-exporter -d --restart unless-stopped --net="host" --pid="host" -v "/:/host:ro,rslave" quay.io/prometheus/node-exporter:latest --path.rootfs=/host --web.config.file=/host/opt/node_exporter/web-config.yml --web.listen-address=":9100"
访问9100端口,然后输入配置文件的用户名和密码,即可看到页面
点击 Metrics 即可看到各项指标,Prometheus就是通过定时访问Metrics这个页面的路径获取数据然后存起来的。
Prometheus端
配置JOB定时去拉取
如果按照上面步骤部署的Prometheus,直接编辑配置文件/opt/prometheus/prometheus.yml
在最后添加配置
- job_name: 'node-exporter'
basic_auth:
username: prometheus_user
password: passwordstr
static_configs:
- targets: ["node-ip:9100"]
重启生效
docker restart prometheus
打开Prometheus页面,在顶部Status -> Target health 就能看到节点
后续继续监控多个机器,就按照相同的方法在被控端部署node_exporter,账户密码要设置一样,然后在Prometheus的配置文件中的targets中追加配置IP和端口即可
Grafana端
把Prometheus的数据接入到Grafana里面,进行可视化查看
登录部署的grafana后台,点击左侧 Connections -> Data sources,然后点击Add data source添加数据源。
里面很多数据源,选择第一个Prometheus,然后填写内容,主要就1项要填,就是地址,填入Prometheus的地址和端口或者域名
如果按照上面步骤套了nginx认证,那就要把认证这一个也填上
然后划到最下面点击Save & test
会弹出来下面这种提示即可
Successfully queried the Prometheus API.
Next, you can start to visualize data by building a dashboard, or by querying data in the Explore view.
接下来就是把数据展示出来,Prometheus里面有各种指标,要形成可视化页面需要各种计算、组装。好在有模板,直接套用
点击左侧菜单的Dashboards,然后点击页面Create dashboard按钮创建控制页面。然后接着选择Import a dashboard这一项,
会弹出问"Do you want to save your changes?"选择DIscard即可。
在https://grafana.com/grafana/dashboards这个上面有很多模板,第一个就是“Node Exporter Full”,点进去查看ID是1860
输入1860然后load加载
选择数据,然后确定
数据出现
监控mysql
使用MySQL Server Exporter
数据库先创建对应账号信息,图方便也可以直接用root
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'XXXXXXXX' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
语句中的exporter是账号,XXXXXXXX是密码。localhost要改成安装MySQL Server Exporter的服务器IP,本机的话就localhost
安装MySQL Server Exporter
mkdir /opt/mysqld_exporter
配置mysql账号
cat > /opt/mysqld_exporter/user_my.cnf <<EOF
[client]
user=exporter
password=XXXXXXXX
EOF
mysqld_exporter默认读取client块的账号和密码。
配置basic auth增加统计数据安全性
auth_str=`htpasswd -nBC 10 "" | tr -d ':\n'`
cat > /opt/mysqld_exporter/web-config.yml <<EOF
basic_auth_users:
prometheus_user: $auth_str
EOF
部署启动
docker run --name mysqld-exporter -d --restart unless-stopped -p 9104:9104 -v /opt/mysqld_exporter:/opt/mysqld_exporter prom/mysqld-exporter --config.my-cnf=/opt/mysqld_exporter/user_my.cnf --web.config.file=/opt/mysqld_exporter/web-config.yml --web.listen-address=:9104 --mysqld.address=localhost:3306
打开服务9104端口,显示是这样的,和node_exporter差不多
接入Prometheus
在Prometheus配置文件加上对应配置
- job_name: mysql
basic_auth:
username: prometheus_user
password: passwordstr
static_configs:
- targets: ["node-ip:9104"]
重启Prometheus之后,在Status -> Target health面板里面就能看到了
Grafana展示
上面的步骤已经接入过Prometheus了。所以直接在Dashboard配置就行了,在https://grafana.com/grafana/dashboards/搜索mysql模板,看到一个是“MySQL Exporter Quickstart and Dashboard”,id是14057,直接导入
监控多个mysql
由于mysqld_exporter使用账号连接上数据库然后读取信息,不依赖宿主机,所以可以同时监控多个数据库而不用一个个部署。
账号密码一致
如果多个数据库都一样的账号密码。在mysqld_exporter的配置文件user_my.cnf中的client块配置好账号密码,就只用改一下Prometheus的配置就行了
- job_name: mysql
metrics_path: /probe
basic_auth:
username: prometheus_user
password: passwordstr
static_configs:
- targets: ["mysql-ip1:3306", "mysql-ip2:3306", "mysql-ip3:3306"]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: node-ip:9104
主要就是metrics_path改成了probe(默认是metrics),下面加了relabel_configs配置进行请求替换。
多个账号密码
如果各个mysql账号密码不一致,先在mysqld_exporter的配置文件中配好多个账号密码。
比如:
[server1]
user=root
password=server1password
[server2]
user=root
password=server2password
重启生效docker restart mysqld-exporter
。
然后修改Prometheus配置进行动态读取。
- job_name: mysql
metrics_path: /probe
basic_auth:
username: prometheus_user
password: passwordstr
static_configs:
- targets: ["mysql-ip1:3306?auth_module=server1", "mysql-ip2:3306?auth_module=server2", "mysql-ip3:3306?auth_module=server1"]
relabel_configs:
- source_labels: [__address__]
regex: '([^?]+)\?auth_module=(.+)'
target_label: __param_target
replacement: '$1'
- source_labels: [__address__]
regex: '([^?]+)\?auth_module=(.+)'
target_label: __param_auth_module
replacement: '$2'
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: node-ip:9104
大概就是使用正则替换,动态设置了auth_module参数(默认auth_module是client)。
重启即可