1.添加Loki收集日志
Loki是什么?
Loki 是和 Prometheus 配套的轻量日志系统,Prometheus 管监控指标,Loki 管日志存储与查询,共用 Grafana 展示。
启动 Docker 版 Grafana 和 Loki
删除之前的grafana容器(如果之前安装过)
docker rm -f grafana
安装Grafana 和 Loki
# 创建一个简单的 docker-compose.yml
cat > docker-compose-logging.yml <<EOF
services:
loki:
image: grafana/loki:latest
container_name: loki
ports:
- "3100:3100"
restart: always
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
restart: always
EOF
docker compose -f docker-compose-logging.yml up -d
打通“三方”数据链路
现在你的“大脑”组件已经就位,我们需要在网页上把它们串起来:
- 访问 Grafana: 浏览器输入
http://192.168.31.136:3000(账号密码 admin/admin)。 - 添加二进制 Prometheus(核心步骤):
Connections->Data Sources->Add data source->Prometheus。- URL 填写:
http://192.168.31.136:9090(注意:这是你二进制 Prometheus 的宿主机地址)。 - 点击
Save & test。
- 添加 Docker Loki:
- 再点
Add data source->Loki。 - URL 填写:
http://loki:3100(因为它们在同一个 Compose 网络里,直接写名字就行)。 - 点击
Save & test。
配置 Promtail 和Nginx export
补齐nginx核心模块
你需要用获取nginx_status的数据需要安装 with-http_stub_status_module 模块我们之前是没有安装的
1. 寻找源码并重新编译
如果你不记得源码在哪,可以尝试用 find / -name "nginx-1.28.1" -type d 找一下。找到后执行以下步骤:
重新配置:
在源码目录下执行,务必加上刚才缺失的模块:
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-http_sub_module \
--with-stream \
--with-stream_ssl_module \
--with-threads \
--with-http_stub_status_module
编译(只make)
make
2.替换旧的二进制文件
编译完成后,我们需要将新生成的二进制文件移动到运行目录。
备份原有的 nginx 程序:
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
替换程序(即使 Nginx 正在运行也可以直接覆盖,Linux 支持此操作):
cp -f objs/nginx /usr/local/nginx/sbin/nginx
3.验证并重启
现在我们来验证 Nginx 是否已经识别了 stub_status 指令。
测试配置文件:
/usr/local/nginx/sbin/nginx -t
如果显示 syntax is ok 和 test is successful,说明模块加载成功了!
平滑重启:
/usr/local/nginx/sbin/nginx
4.最终确认
现在执行你之前失败的那个命令:
curl http://127.0.0.1/nginx_status
你应该能看到类似这样的三行输出:
Active connections: 1
server accepts handled requests
1 1 1
Reading: 0 Writing: 1 Waiting: 0
修改nginx主配置文件为nginx-export提供数据
修改nginx.conf文件(二进制安装通常在/usr/local/nginx/conf/nginx下,yum安装通常在/etc/nginx/nginx.conf下)
server {
listen 80;
server_name localhost;
# 这是你需要增加/修改的核心部分
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1; # 允许本机访问
allow 192.168.31.0/24; # 允许你整个 31 网段(包含堡垒机)访问
# 显式清除继承可能导致的干扰
root /dev/null; # 强制不找物理文件,彻底根治 404
deny all;
}
# ... 其他原本的博客配置 ...
}
执行修改与生效
你可以利用 Ansible 直接在堡垒机上一键更新 131/130 节点,并验证之前的 404 报错是否消失:
- 手动修改:
vi /usr/local/nginx/conf/nginx.conf。 - 语法检查:
/usr/local/nginx/sbin/nginx -t。 - 热加载生效:
/usr/local/nginx/sbin/nginx -s reload。
部署全栈监控 (Playbook)
等你替换完二进制文件并确认 nginx -t 通过后,回到 136 堡垒机。我们将利用你的 Ansible 技能,一次性把 130-135 节点的监控铺开。
创建并运行 **deploy_nginx_full_stack.yml**:
1.在堡垒机(136)准备物料
在 136 上下载好正确的包(堡垒机通常有更好的出口带宽或代理):
cd /prom/
# 下载 Nginx Exporter
wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v1.5.0/nginx-prometheus-exporter_1.5.0_linux_amd64.tar.gz
# 下载 Promtail (用于日志采集)
curl -L -o promtail.zip https://ghproxy.net/https://github.com/grafana/loki/releases/download/v3.0.0/promtail-linux-amd64.zip
# 【关键验证】确保大小正确:Exporter 约 700k,Promtail 约 30MB
ls -lh
2.解压Promtail和Nginx export
yum install -y unzip
tar -xf nginx-prometheus-exporter_1.5.0_linux_amd64.tar.gz
unzip promtail-linux-amd64.zip

3.利用 Ansible安装nginx-exporter(安装在web机器上)
既然你已经有 dmz 的主机组,我们直接写一个 Playbook,把物料推送到 130、131 所有的机器上。
创建 deploy_latest_exporter.yml:
---
- hosts: 192.168.31.131,192.168.31.130
become: yes
tasks:
- name: 1. 推送二进制文件
copy:
src: "/prom/nginx-prometheus-exporter"
dest: /usr/local/bin/nginx-prometheus-exporter
mode: '0755'
- name: 2. 配置 Systemd 服务文件
copy:
dest: /etc/systemd/system/nginx_exporter.service
content: |
[Unit]
Description=Nginx Prometheus Exporter
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/nginx-prometheus-exporter -nginx.scrape-uri=http://127.0.0.1/nginx_status
Restart=on-failure
[Install]
WantedBy=multi-user.target
- name: 3. 启动并开机自启
systemd:
name: nginx_exporter
state: restarted
enabled: yes
daemon_reload: yes
执行脚本
ansible-playbook deploy_latest_exporter.yml
4.利用 Ansible安装promtail
创建一个promtail-config.yml配置文件
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://192.168.31.136:3100/loki/api/v1/push
scrape_configs:
- job_name: nginx-logs
static_configs:
- targets:
- localhost
labels:
job: nginx-access
host: 192.168.31.131
__path__: /usr/local/nginx/logs/*.log
自动化部署(所有DMZ机器都需要装)
创建 deploy_promtail.yml:
---
- hosts: all
become: yes
tasks:
- name: 1. 推送 Promtail 二进制文件
copy:
src: "/prom/promtail"
dest: /usr/local/bin/promtail
mode: '0755'
- name: 2. 创建配置目录并推送配置
file:
path: /etc/promtail
state: directory
- name: 3. 推送配置文件
copy:
src: "/prom/promtail-config.yml"
dest: /etc/promtail/config.yml
- name: 4. 配置 Systemd 服务
copy:
dest: /etc/systemd/system/promtail.service
content: |
[Unit]
Description=Promtail service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/promtail -config.file=/etc/promtail/config.yml
Restart=on-failure
[Install]
WantedBy=multi-user.target
- name: 5. 启动并开机自启
systemd:
name: promtail
state: restarted
enabled: yes
daemon_reload: yes
执行脚本
ansible-playbook deploy_promtail.yml
添加权限
- 检查进程:
ansible 192.168.31.131 -m shell -a "systemctl status promtail" - 检查日志读取权限:Promtail 需要有权限读取
/usr/local/nginx/logs/下的文件。如果日志权限是700,Promtail 会报错。 - 快速修正:
ansible 192.168.31.131 -m shell -a "chmod -R 755 /usr/local/nginx/logs/"
修改防火墙规则放行9113端口的流量(在堡垒机上执行)
# 永久放行 9113 端口并立即生效
ansible 192.168.31.131,192.168.31.131 -m shell -a "firewall-cmd --permanent --add-port=9113/tcp && firewall-cmd --reload"
同步时间
1. 使用 Chrony 同步时间
既然 yum 找不到 ntpdate,请直接在 136 上尝试安装并运行 chronyd:
Bash
# 安装 chrony (通常系统自带)
yum install -y chrony
# 立即与阿里云时间服务器同步一次
# -q 代表 quit, -t 代表 timeout
chronyd -q 'server ntp.aliyun.com iburst'
2. 给 130/131 等节点一键配置
同样地,我们可以用 Ansible 批量让所有节点都切换到 Chrony 模式,这样比 ntpdate 更稳定:
Bash
# 1. 给所有节点安装并启动 chrony
ansible all -m shell -a "yum install -y chrony && systemctl enable --now chronyd"
# 2. 强制所有节点立即同步一次
ansible all -m shell -a "chronyc makestep"
3. 彻底对齐时区(关键步)
由于你之前的日志显示时间差了一个小时,很大可能是时区设置不统一。请务必执行这一步,确保全集群都在“北京时间”:
ansible all -m shell -a "timedatectl set-timezone Asia/Shanghai"
4. 终极验证
执行这条命令,观察每台机器返回的最后一行:
ansible all -m shell -a "date"
如果所有机器返回的时间(秒级误
