简单来说,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端口,然后输入配置文件的用户名和密码,即可看到页面

2025-07-19_185959_862.jpg

点击 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"]

2025-07-19_191035_669.png

重启生效

docker restart prometheus

打开Prometheus页面,在顶部Status -> Target health 就能看到节点

2025-07-19_191525_037.png

2025-07-19_191949_838.jpg

后续继续监控多个机器,就按照相同的方法在被控端部署node_exporter,账户密码要设置一样,然后在Prometheus的配置文件中的targets中追加配置IP和端口即可

Grafana端

把Prometheus的数据接入到Grafana里面,进行可视化查看

登录部署的grafana后台,点击左侧 Connections -> Data sources,然后点击Add data source添加数据源。

里面很多数据源,选择第一个Prometheus,然后填写内容,主要就1项要填,就是地址,填入Prometheus的地址和端口或者域名
如果按照上面步骤套了nginx认证,那就要把认证这一个也填上

2025-07-19_192915_016.jpg

然后划到最下面点击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加载

2025-07-20_015758_668.jpg

选择数据,然后确定

2025-07-20_015854_004.jpg

数据出现

2025-07-20_020128_913.jpg

监控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差不多

2025-07-20_025630_232.jpg

接入Prometheus

在Prometheus配置文件加上对应配置

  - job_name: mysql
    basic_auth:
      username: prometheus_user
      password: passwordstr
    static_configs:
      - targets: ["node-ip:9104"]

重启Prometheus之后,在Status -> Target health面板里面就能看到了

wechat_2025-07-20_030420_679.jpg

Grafana展示

上面的步骤已经接入过Prometheus了。所以直接在Dashboard配置就行了,在https://grafana.com/grafana/dashboards/搜索mysql模板,看到一个是“MySQL Exporter Quickstart and Dashboard”,id是14057,直接导入

2025-07-20_033127_551.jpg

监控多个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)。

重启即可

标签: Nginx, MySql, Fail2ban, Prometheus, Grafana, mysqld_exporter, node_exporter

添加新评论

Loading...
Fullscreen Image