实训04 企业监控与运维工具部署 — 操作文档
拓扑:VM1 网关 10.4.0.1 / VM2 Web文件服务 10.4.0.10 / VM3 数据库缓存 10.4.0.20,网段 10.4.0.0/24 部署目标:VM3 上新增 Prometheus、Grafana、Jenkins、Harbor;Node Exporter 装在三台 VM 上
说明:本文档只列操作步骤,执行时按任务顺序来。涉及 VM 操作统一用 scripts/ssh_run.py(vm1/vm2/vm3 三个主机),二进制下载如果 VM3 没外网,先在笔记本下载再用 scp 传上去。
服务规划
| 服务 | 软件 | 端口 | 装在哪 | 用途 |
|---|---|---|---|---|
| 监控采集 | Prometheus | 9090 | VM3 | 采集+存储指标 |
| 可视化 | Grafana | 3000 | VM3 | 仪表盘 |
| 指标采集器 | Node Exporter | 9100 | VM1/VM2/VM3 | 上报本机指标 |
| 持续集成 | Jenkins | 8090 | VM3 | CI/CD(8080 已被 Apache 占,用 8090) |
| 镜像仓库 | Harbor | 80/443 | VM3 | Docker 镜像管理 |
前置检查(VM3)
# 确认三套数据库在跑
ss -tlnp | grep -E '3306|6379|27017'
# 剩余内存和磁盘
free -h
df -h /
# 三台之间内网互通(在 VM3 上分别 ping)
ping -c2 10.4.0.1
ping -c2 10.4.0.10
# 确认 Docker 已装(Jenkins/Harbor 要用)
docker --version
docker-compose --version
如果 Docker 没装,先在 VM3 装:
apt-get update
apt-get install -y docker.io docker-compose-plugin
systemctl enable --now docker
第一层级:监控数据采集
任务1:部署 Node Exporter + Prometheus
1.1 三台 VM 都装 Node Exporter
在 VM1、VM2、VM3 各执行一遍(把 --host 换成对应主机):
# 下载(VM3 无外网就笔记本下好 scp 过去)
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-1.8.2.linux-amd64.tar.gz
cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
useradd -rs /usr/sbin/nologin node_exporter
systemd 服务文件 /etc/systemd/system/node_exporter.service:
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
Restart=always
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now node_exporter
systemctl status node_exporter
ss -tlnp | grep 9100
三台都确认 9100 监听后,用 curl 自测一下:
curl -s http://localhost:9100/metrics | head -5
1.2 VM3 装 Prometheus
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz
tar xzf prometheus-2.53.0.linux-amd64.tar.gz
cp prometheus-2.53.0.linux-amd64/prometheus /usr/local/bin/
cp prometheus-2.53.0.linux-amd64/promtool /usr/local/bin/
mkdir -p /etc/prometheus /var/lib/prometheus
useradd -rs /usr/sbin/nologin prometheus
chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus
配置文件 /etc/prometheus/prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
monitor: 'mxdx-monitor'
scrape_configs:
- job_name: 'node'
static_configs:
- targets:
- '10.4.0.1:9100' # VM1
- '10.4.0.10:9100' # VM2
- '10.4.0.20:9100' # VM3
systemd 服务文件 /etc/systemd/system/prometheus.service:
[Unit]
Description=Prometheus
After=network.target
[Service]
User=prometheus
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus \
--storage.tsdb.retention.time=15d \
--web.listen-address=0.0.0.0:9090
Restart=always
[Install]
WantedBy=multi-user.target
chown prometheus:prometheus /usr/local/bin/prometheus
systemctl daemon-reload
systemctl enable --now prometheus
systemctl status prometheus
ss -tlnp | grep 9090
1.3 验证
浏览器开 http://10.4.0.20:9090 → Status → Targets,三个 target 应为绿色 UP。 Graph 页面试查:
100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes
node_filesystem_avail_bytes{fstype=~"ext4|xfs"} / node_filesystem_size_bytes{fstype=~"ext4|xfs"}

Graph 页查询 node_cpu_seconds_total 等 PromQL 验证指标正常:

第二层级:可视化面板
任务2:部署 Grafana
2.1 安装(VM3)
apt-get install -y apt-transport-https software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | gpg --dearmor -o /usr/share/keyrings/grafana-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/grafana-archive-keyring.gpg] https://packages.grafana.com/oss/deb stable main" > /etc/apt/sources.list.d/grafana.list
apt-get update
apt-get install -y grafana
systemctl enable --now grafana-server
ss -tlnp | grep 3000
2.2 配数据源
浏览器开 http://10.4.0.20:3000,默认 admin/admin(首次登录强制改密码)。 Connections → Add data source → Prometheus,URL 填 http://localhost:9090,Save & test 显示绿色。
2.3 导入通用面板
Dashboards → Import,输入 Dashboard ID 1860(Node Exporter Full)或 11074,数据源选 Prometheus。导入后应能看到三台机器的 CPU/内存/磁盘/网络/负载曲线。

2.4 自建面板
New → New dashboard,加三个 panel:
-
CPU 使用率(Time series):
100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) -
内存使用率(Time series):
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 -
磁盘使用率(Gauge):
(1 - node_filesystem_avail_bytes{fstype=~"ext4|xfs",mountpoint="/"} / node_filesystem_size_bytes{fstype=~"ext4|xfs",mountpoint="/"}) * 100
Legend 里用 {{instance}} 区分三台机器,不同颜色自动区分。

第三层级:告警配置
任务3:Prometheus 告警规则
3.1 告警规则文件 /etc/prometheus/alert.rules.yml
groups:
- name: node_alerts
rules:
- alert: HighCpuUsage
expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
for: 5m
labels:
severity: warning
annotations:
summary: "CPU 使用率超过 90%({{ $labels.instance }})"
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "内存使用率超过 85%({{ $labels.instance }})"
- alert: HighDiskUsage
expr: (1 - (node_filesystem_avail_bytes{fstype=~"ext4|xfs"} / node_filesystem_size_bytes{fstype=~"ext4|xfs"})) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "磁盘使用率超过 80%({{ $labels.instance }})"
- alert: NodeExporterDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Node Exporter 掉线({{ $labels.instance }})"
在 prometheus.yml 里挂上规则文件:
rule_files:
- "/etc/prometheus/alert.rules.yml"
重载使生效:
promtool check config /etc/prometheus/prometheus.yml
systemctl reload prometheus
3.2 验证告警
浏览器开 Prometheus → Alerts,应看到 4 条规则(状态 Inactive)。 在 VM1 上停掉 Node Exporter 模拟故障:
ssh vm1
systemctl stop node_exporter
回到 Alerts 页面,对应 NodeExporterDown 会从 Inactive → Pending → Firing(红色)。 恢复:systemctl start node_exporter,告警自动回 Inactive。
Alerts 页面 4 条规则默认 Inactive(绿色):

停掉 VM1 Node Exporter 后 NodeExporterDown 变为 Firing(红色):

3.3(选做)Alertmanager
部署 Alertmanager 后,在 prometheus.yml 加:
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
Alertmanager 配置路由到企业微信/钉钉/邮件,按实训需要选一种。
第四层级:运维工具
任务4:部署 Jenkins
VM3 用 Docker 跑,端口用 8090(避开 Apache 的 8080):
mkdir -p /data/jenkins
chown -R 1000:1000 /data/jenkins
docker run -d \
--name jenkins \
--restart=always \
-p 8090:8080 \
-v /data/jenkins:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:lts
初始化:
# 看初始管理员密码
docker logs jenkins 2>&1 | grep -A1 "initialAdminPassword"
# 或直接读文件
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
查看初始管理员密码(解锁用):

浏览器开 http://10.4.0.20:8090,粘贴密码 → 选 Install suggested plugins(安装推荐插件,含 Git / Pipeline)→ 创建管理员账号 → 进入主界面:


初始化完成后,在 Manage Jenkins → Plugins → Available plugins 搜索并安装以下必要插件(装完无需重启):
- Git(git-plugin,推荐插件阶段通常已装好)
- Pipeline(workflow-aggregator,流水线)
- Docker(docker-plugin,节点/云配置用)
- Kubernetes(kubernetes-plugin,后续 K8s 部署用)
- 建议加 Docker Pipeline(docker-workflow),在 Jenkinsfile 里用
docker指令
安装时勾选 Docker / Kubernetes / Pipeline 并点击安装:

任务5:部署 Harbor
5.1 准备
Harbor 依赖 Docker + docker-compose。先确认:
docker --version
docker compose version
下载离线包(VM3 无外网就笔记本下好传上去):
cd /tmp
wget https://github.com/goharbor/harbor/releases/download/v2.10.2/harbor-offline-installer-v2.10.2.tgz
tar xzf harbor-offline-installer-v2.10.2.tgz
cd harbor
cp harbor.yml.tmpl harbor.yml
5.2 改配置 harbor.yml
hostname: harbor.mxdx.local
http:
port: 80
# https 段先注释掉,用 http 方便内网
harbor_admin_password: Harbor@123456
data_volume: /data/harbor
如果用 http,所有 docker 客户端要在
/etc/docker/daemon.json加"insecure-registries": ["harbor.mxdx.local"]然后systemctl restart docker。
5.3 安装
cd /tmp/harbor
./prepare
./install.sh
docker compose ps
浏览器开 http://harbor.mxdx.local(域名访问),用 admin / Harbor@123456 登录。 新建项目 unitalk(公开)。
Web 验证截图:
登录页(admin / Harbor@123456):

登录后主界面:

新建公开项目 unitalk:

5.4 推送测试
在 VM3 上:
# 让内网能解析 harbor.mxdx.local(临时写 hosts,或配 VM1 的 DNS)
echo "10.4.0.20 harbor.mxdx.local" >> /etc/hosts
docker login harbor.mxdx.local -u admin -p Harbor@123456
docker pull busybox
docker tag busybox harbor.mxdx.local/unitalk/busybox:v1
docker push harbor.mxdx.local/unitalk/busybox:v1
推送成功后在 Harbor 仓库页可见 `unitalk/busybox:v1`:

> 验证 pull:删除本地镜像后 `docker pull harbor.mxdx.local/unitalk/busybox:v1` 能重新拉回,说明 Harbor 存储与分发正常。
第五层级:综合验收
| # | 验收项 | 操作 | 预期 |
|---|---|---|---|
| 1 | Prometheus Targets | 开 9090 Targets 页 | 三个 target 全 UP |
| 2 | 指标查询 | 查 node_cpu_seconds_total |
有数据 |
| 3 | Grafana 面板 | 开 3000 导入面板 | 有数据 |
| 4 | 三台服务器监控 | Grafana 切换 instance | 每台都有指标 |
| 5 | 告警规则 | 开 Alerts 页 | 4 条规则已加载 |
| 6 | 告警触发 | 停一台 Node Exporter | 状态变 Firing |
| 7 | Jenkins 访问 | 开 8090 | 主界面正常 |
| 8 | Harbor 访问 | 开 80 | 能登录 |
| 9 | Docker 推送 | push 到 Harbor | 成功 |
| 10 | 内网域名访问 | Grafana / Jenkins / Harbor 全部用域名访问 | ✅ 已验证 |
项 10:内网域名访问(三服务)
在 Windows 一体机(或教室客户端)hosts 文件中添加解析:
10.4.0.20 grafana.mxdx.local jenkins.mxdx.local harbor.mxdx.local
浏览器分别打开三个域名地址,均能正常访问:
| 服务 | 域名地址 | 账号 |
|---|---|---|
| Grafana | http://grafana.mxdx.local:3000 |
admin / 123456 |
| Jenkins | http://jenkins.mxdx.local:8090 |
管理员账号 |
| Harbor | http://harbor.mxdx.local |
admin / Harbor@123456 |
三项服务全部用域名访问成功:

验收结论:Grafana / Jenkins / Harbor 三服务全部域名访问 ✅
注意事项
- 端口冲突:Jenkins 用 8090 不是 8080(Apache 占了 8080);如果后面 Apache 也反代这些服务,再统一规划。
- Node Exporter 三台都要装:只装 VM3 的话 Targets 页面只有 1 个 UP。
- 下载源:GitHub release 有时慢,VM3 没外网就笔记本下载 + scp。
- Harbor 域名:
harbor.mxdx.local要能解析,一体机测试时在 hosts 或 VM1 DNS 加一条。 - 告警测试完记得恢复:停掉 Node Exporter 验证完马上 start,别一直 Firing。
综合验收记录(完整版)
测试时间:2026-07-22 网络环境:教室拓扑 10.4.0.x/24(VM1 网关 10.4.0.1 / VM2 Web 10.4.0.10 / VM3 监控运维 10.4.0.20) 服务规划:VM3 上 Prometheus(9090) + Grafana(3000) + Jenkins(8090) + Harbor(80);Node Exporter(9100) 装在三台 VM
汇总:10/10 通过 ✅(项 1–10 全部完成)
| # | 验收项 | 结果 |
|---|---|---|
| 1 | Prometheus Targets 三个目标全部 UP | ✅ |
| 2 | 指标查询 node_cpu_seconds_total 有数据 |
✅ |
| 3 | Grafana 面板导入有数据 | ✅ |
| 4 | 三台服务器监控切换各有指标 | ✅ |
| 5 | 告警规则 4 条已加载 | ✅ |
| 6 | 告警触发 停一台变 Firing | ✅ |
| 7 | Jenkins 访问主界面 | ✅ |
| 8 | Harbor 访问能登录 | ✅ |
| 9 | Docker 推送到 Harbor | ✅ |
| 10 | 内网域名访问(三服务) | ✅ |
第 1 项:Prometheus Targets 三个目标全部 UP
浏览器打开 http://10.4.0.20:9090 → Status → Targets,三个 target(10.4.0.1:9100 / 10.4.0.10:9100 / 10.4.0.20:9100)全部 UP,状态 node (3/3 up)。
期间 10.4.0.10 曾因共享教室二层网络 ARP/IP 冲突导致 DOWN,已通过静态钉 ARP 修复(见 docs/问题记录-ARP冲突导致Prometheus_target_DOWN.md)。

第 2 项:指标查询 node_cpu_seconds_total 有数据
Prometheus Graph 页查询 node_cpu_seconds_total,返回 64 条 series(三台机器 × CPU 多模式 idle/system/user/iowait/…),指标正常采集。

第 3 项:Grafana 面板导入有数据
浏览器打开 http://10.4.0.20:3000(admin / 123456),已配 Prometheus 数据源(localhost:9090,health=OK),导入 Dashboard 1860(Node Exporter Full)。面板显示三台机器的 CPU / 内存 / 磁盘 / 网络 / 负载曲线。

第 4 项:三台服务器监控切换各有指标
Grafana 自建面板(CPU / 内存使用率时间序列 + 磁盘使用率 Gauge),按 {{instance}} 区分 10.4.0.1 / 10.4.0.10 / 10.4.0.20,三台服务器各有曲线与指标。

第 5 项:告警规则 4 条已加载
在 VM3 上写入 /etc/prometheus/alert.rules.yml(4 条规则:HighCpuUsage / HighMemoryUsage / HighDiskUsage / NodeExporterDown),挂到 prometheus.yml 的 rule_files,promtool check config 校验 SUCCESS(4 rules found),systemctl restart prometheus 后生效。
浏览器打开 http://10.4.0.20:9090/alerts,显示 4 条规则全部 Inactive(绿色):

第 6 项:告警触发 停一台变 Firing
在 VM1 上停止 Node Exporter 模拟故障:systemctl stop node_exporter。等待约 78 秒后(NodeExporterDown 规则 for: 1m),Prometheus Alerts 页面显示 NodeExporterDown (1 active) 变为 Firing(红色),其余 3 条仍 Inactive。
验证后立即恢复:systemctl start node_exporter,VM1 node_exporter 回到 active,告警自动回 Inactive。

第 7 项:Jenkins 访问主界面
在 VM3 用 Docker 部署 Jenkins(镜像 jenkins/jenkins:lts,因实验室网络拉取大层超时,改由本机/VM3 直接 pull 完成),容器参数:
- 容器名
jenkins,--restart=always - 端口映射
8090:8080(避开 8080 被占用) - 数据卷
/data/jenkins:/var/jenkins_home(目录属主uid:gid=1000,与 Jenkins 容器内运行用户一致) - 挂载
/var/run/docker.sock供 Jenkins 流水线调用宿主 Docker
启动后 docker ps 显示 Up、0.0.0.0:8090->8080/tcp;浏览器打开 http://10.4.0.20:8090/login 返回 HTTP 200,页面标题 Sign in - Jenkins,解锁页出现 Administrator password 输入框,证明主界面可访问。
初始管理员密码(解锁用):fb38aaf712964f0b9333b81677bdcbed (读取自 /var/jenkins_home/secrets/initialAdminPassword,首次登录后建议修改)
解锁界面(粘贴初始管理员密码):

初始化与管理员账号
解锁后选 Install suggested plugins(推荐插件含 Git / Pipeline)→ 创建管理员账号 → 进入主界面,初始化完成:

必要插件安装
Manage Jenkins → Plugins → Available plugins,安装 Git / Pipeline / Docker / Kubernetes(Docker Pipeline 一并装上):

验收结论:Web 可访问 ✅、管理员账号已创建 ✅、4 个必要插件已装 ✅。
验收项 8–9:Harbor 部署与镜像推送
项 8:Harbor Web 访问与登录
VM3 上 docker compose ps 全部容器 Up,浏览器开 http://harbor.mxdx.local(域名访问)用 admin / Harbor@123456 登录成功,并新建公开项目 unitalk。
登录页:

登录后主界面:

公开项目 unitalk:

项 9:Docker 登录与推送/拉取
VM3 上 docker 配置 insecure-registries: ["harbor.mxdx.local"] 并 hosts 解析后:
docker login harbor.mxdx.local -u admin -p Harbor@123456 # Login Succeeded
docker pull busybox
docker tag busybox harbor.mxdx.local/unitalk/busybox:v1
docker push harbor.mxdx.local/unitalk/busybox:v1 # Pushed
docker rmi harbor.mxdx.local/unitalk/busybox:v1 busybox:latest
docker pull harbor.mxdx.local/unitalk/busybox:v1 # 从 Harbor 拉回成功
仓库页可见 unitalk/busybox:v1:

验收结论:Harbor Web 能访问登录 ✅、能创建公开项目 ✅、docker login 成功 ✅、push/pull 正常 ✅。
项 10:内网域名访问(三服务)
题目要求一体机用域名访问 Grafana / Jenkins / Harbor 三套服务。在 Windows 客户端 hosts 文件添加解析:
10.4.0.20 grafana.mxdx.local jenkins.mxdx.local harbor.mxdx.local
浏览器分别打开三个域名地址,均正常访问:
| 服务 | 域名地址 | 状态 |
|---|---|---|
| Grafana | http://grafana.mxdx.local:3000 |
✅ Welcome to Grafana 首页 |
| Jenkins | http://jenkins.mxdx.local:8090 |
✅ 欢迎来到 Jenkins 主界面 |
| Harbor | http://harbor.mxdx.local |
✅ 项目列表(unitalk 公开仓库可见) |
三项服务全部用域名访问成功(地址栏均显示对应域名):

验收结论:Grafana / Jenkins / Harbor 三服务全部域名访问 ✅
遇到的问题及解决
问题 1:Prometheus 的 VM2 target 因 ARP 冲突 DOWN
共享教室二层网络里,隔壁同学的克隆 VM 也使用了 10.4.0.10 / 10.4.0.20,导致 VM3 的 ARP 表被毒化——发往 10.4.0.10:9100 的采集请求被送到邻居机(邻居没开 9100)→ connection refused,Targets 显示 node (2/3 up)。
详细排查证据与解决见 docs/问题记录-ARP冲突导致Prometheus_target_DOWN.md。解决:在 VM2 / VM3 钉静态 ARP 到正确 MAC:
VM1 网关 10.4.0.1 = 00:0c:29:eb:81:5f
VM2 10.4.0.10 = 00:0c:29:0e:8c:a5
VM3 10.4.0.20 = 00:0c:29:1e:12:16
钉完后 Prometheus Targets 恢复 node (3/3 up),截图见第 1 项。
问题 2:systemctl reload prometheus 报错 “Job type reload is not applicable”
执行 systemctl reload prometheus.service 时报错:
Failed to reload prometheus.service: Job type reload is not applicable for unit prometheus.service
原因:prometheus.service 的 unit 文件没有定义 ExecReload= 指令,且启动参数缺少 --web.enable-lifecycle(所以 POST /-/reload 端点也返回 403)。这不是配置写错了,而是 unit 本身不支持 reload 操作。
解决:改用 systemctl restart prometheus.service 替代 reload(几秒闪断可接受)。如需后续支持平滑 reload,可在 ExecStart 加 --web.enable-lifecycle 并补一行 ExecReload=/bin/kill -HUP $MAINPID。
Comments NOTHING