Devops项目阶段 10:Prometheus 监控与 Alertmanager 邮件告警

Prometheus 外部节点监控与 Alertmanager 邮件告警配置笔记

0. 本阶段目标

这一阶段是在已经存在的 Kubernetes + kube-prometheus-stack 环境上继续完善监控系统,主要完成以下工作:

  1. 使用 Ansible 给 Kubernetes 集群之外的 Linux 节点部署 node_exporter
  2. 将外部节点加入 Prometheus Targets
  3. 验证 Prometheus 是否能够正常采集外部服务器 CPU、内存、磁盘、网络等指标
  4. 排查 Prometheus Pod 的 kubectl exec 异常
  5. 开启并验证 Alertmanager
  6. 配置 QQ 邮箱 SMTP
  7. 使用 Kubernetes Secret 保存 SMTP 授权码
  8. 使用 AlertmanagerConfig 配置邮件 Receiver
  9. 使用 PrometheusRule 创建测试告警
  10. 验证:
text 复制代码
node_exporter
      ↓
Prometheus
      ↓
PrometheusRule
      ↓
Alertmanager
      ↓
SMTP
      ↓
QQ邮箱

最终以实际收到 FIRING 告警邮件作为本阶段完成标志。


一、环境与节点

1. Kubernetes 节点

本阶段 Kubernetes 集群包括:

text 复制代码
k8s-master
k8s-node1
k8s-node2

其中 kube-prometheus-stack 已经部署:

text 复制代码
Prometheus
Grafana
Alertmanager
kube-state-metrics
prometheus-node-exporter

Kubernetes 节点自己的 node_exporter 由 kube-prometheus-stack DaemonSet 提供,因此不需要使用外部节点的 Ansible Playbook 再安装一次。


2. Kubernetes 外部节点

需要额外监控:

text 复制代码
devops    192.168.205.144
elk       192.168.205.145
infra     192.168.205.146

这些机器不属于 Kubernetes 集群,因此不能依赖 Kubernetes DaemonSet 部署 node_exporter

采用:

text 复制代码
Ansible
   ↓
monitor_external
   ↓
systemd node_exporter

二、使用 Ansible 部署外部 node_exporter

1. 操作位置

在 Ansible 控制节点:

bash 复制代码
cd ~/devops-lab/ansible

相关文件:

text 复制代码
inventory/hosts.ini
node-exporter.yml

2. Ansible inventory

外部监控服务器统一放入:

text 复制代码
monitor_external

组。

这样以后增加新的普通 Linux 服务器时,只需要:

  1. 加入 inventory
  2. 加入 monitor_external
  3. 重新运行 node-exporter.yml

即可完成 node_exporter 部署。


3. node_exporter Playbook

使用文件:

text 复制代码
node-exporter.yml

该 Playbook 负责:

text 复制代码
创建 node_exporter 用户
        ↓
下载 node_exporter
        ↓
解压
        ↓
复制到 /usr/local/bin/
        ↓
创建 systemd service
        ↓
启动并设置开机启动

执行:

bash 复制代码
ansible-playbook node-exporter.yml -K

三、验证外部节点 node_exporter

部署完成不能直接认为 Prometheus 已经监控成功。

首先只能说明:

node_exporter 已经部署。

必须分两层验证:

text 复制代码
第一层:Exporter 本身是否正常
第二层:Prometheus 是否成功 Scrape

1. 检查 9100 端口

在 Ansible 控制节点执行:

bash 复制代码
ansible monitor_external \
-m shell \
-a "ss -lntp | grep 9100" \
-K

实际得到:

text 复制代码
infra | CHANGED | rc=0 >>
LISTEN ... *:9100

devops | CHANGED | rc=0 >>
LISTEN ... *:9100

elk | CHANGED | rc=0 >>
LISTEN ... *:9100

说明三台服务器的 node_exporter 都监听:

text 复制代码
TCP/9100

2. 直接访问 /metrics

分别测试:

bash 复制代码
curl http://192.168.205.144:9100/metrics | head
bash 复制代码
curl http://192.168.205.145:9100/metrics | head
bash 复制代码
curl http://192.168.205.146:9100/metrics | head

正常可以看到:

text 复制代码
# HELP ...
# TYPE ...
go_gc_duration_seconds...
go_goroutines...

这说明:

text 复制代码
Linux
 ↓
node_exporter
 ↓
:9100/metrics

链路正常。


3. curl: (23) 不是 node_exporter 故障

测试过程中出现:

text 复制代码
curl: (23) Failed writing body

这是因为执行了:

bash 复制代码
curl ... | head

head 读取前几行后主动退出。

curl 还在继续向管道写数据,于是发现下游已经关闭,最终产生 (23)

因此这里不能看到 (23) 就认为 node_exporter 有问题。

关键判断是前面是否已经正常输出 metrics。


四、让 Prometheus 抓取外部节点

1. 为什么安装 node_exporter 还不够

node_exporter 只是:

text 复制代码
提供指标

Prometheus 必须知道:

text 复制代码
去哪里抓

因此:

text 复制代码
安装 node_exporter ≠ Prometheus 已监控

完整关系:

text 复制代码
192.168.205.144:9100
192.168.205.145:9100
192.168.205.146:9100
          ↓
Prometheus Scrape Config
          ↓
Prometheus Targets

2. Prometheus 配置文件

本项目相关文件:

text 复制代码
files/monitoring/prometheus-values.yaml

该文件最终需要应用到 Kubernetes Master 上的 Helm Release。

需要注意:

devops 节点本身没有 Kubernetes。

所以不能因为文件最初位于:

text 复制代码
~/devops-lab/ansible/files/monitoring/

就直接在那里运行 Kubernetes Helm 操作。

本项目采用:

text 复制代码
devops
  ↓ scp
k8s-master
  ↓ helm upgrade
Kubernetes

五、更新 kube-prometheus-stack

把修改后的:

text 复制代码
prometheus-values.yaml

传到 Kubernetes Master。

然后在:

text 复制代码
k8s-master

执行 Helm 更新。

基本流程:

bash 复制代码
helm upgrade monitoring \
prometheus-community/kube-prometheus-stack \
-n monitoring \
-f prometheus-values.yaml

这里的实际文件路径根据 SCP 到 Master 后的位置填写。


六、验证 Prometheus 外部 Targets

这是判断"外部服务器真正被监控"的关键步骤。

不能只看:

text 复制代码
9100 LISTEN

必须看 Prometheus Target。


1. Prometheus Targets

进入 Prometheus:

text 复制代码
Status
  ↓
Targets

查看:

text 复制代码
job="external-node-exporter"

实际看到:

text 复制代码
http://192.168.205.144:9100/metrics
hostname="devops"
job="external-node-exporter"
UP

以及:

text 复制代码
http://192.168.205.146:9100/metrics
hostname="infra"
job="external-node-exporter"
UP

说明:

text 复制代码
Prometheus
   ↓
192.168.205.144:9100
192.168.205.146:9100

采集成功。


2. ELK 节点出现 DOWN

曾经看到:

text 复制代码
http://192.168.205.145:9100/metrics

DOWN

Error scraping target:
dial tcp 192.168.205.145:9100:
connect: no route to host

这个错误需要区分:

text 复制代码
Exporter故障

和:

text 复制代码
机器本身不可达

当时 ELK 虚拟机已经关闭,所以:

text 复制代码
no route to host

属于预期结果。

这反而证明 Prometheus 的监控是有效的:

节点关机以后,Target 会自动变成 DOWN。

因此不需要修改 Prometheus 配置。


七、node_exporter 当前能监控到什么

完成以上步骤后,外部服务器已经可以采集主机资源:

text 复制代码
CPU
Memory
Load
Disk
Filesystem
Network
系统运行状态

例如 ELK 服务器:

text 复制代码
192.168.205.145

开机以后可以监控:

text 复制代码
CPU使用率
内存使用率
磁盘使用率
网络流量
Load
服务器是否可达

但要特别注意:

node_exporter 监控的是 ELK 服务器本身,不等于监控 Elasticsearch 应用内部状态。

例如:

text 复制代码
ELK服务器内存使用率        → node_exporter 可以
ELK服务器CPU使用率         → node_exporter 可以
ELK服务器磁盘使用率        → node_exporter 可以

Elasticsearch Cluster Health → 需要对应 Exporter/API
Kafka Consumer Lag            → 需要对应 Exporter
MySQL Connections             → 需要 mysqld_exporter

因此原则是:

text 复制代码
Linux主机资源
   ↓
node_exporter

具体中间件
   ↓
对应Exporter

八、Prometheus Pod 检查时发现 kubectl exec 异常

在后续验证 Prometheus 配置时,需要进入 Prometheus Pod。

执行:

bash 复制代码
kubectl exec \
-n monitoring \
-it prometheus-monitoring-kube-prometheus-prometheus-0 \
-c prometheus \
-- sh

失败:

text 复制代码
Internal error occurred:
error sending request:

Post "//[::]:38989/cri/exec/..."

http:
server gave HTTP response to HTTPS client

即:

text 复制代码
kubectl exec
      ↓
kube-apiserver
      ↓
kubelet
      ↓
CRI streaming
      ↓
失败

九、排查 kubectl exec:确认 Container Runtime

1. 查看 Kubernetes Runtime

执行:

bash 复制代码
kubectl describe node k8s-master | grep -i runtime

得到:

text 复制代码
Container Runtime Version:
docker://28.1.1

说明集群使用:

text 复制代码
Docker
+
cri-dockerd

2. 查看 cri-dockerd

bash 复制代码
systemctl status cri-docker

结果:

text 复制代码
Active: active (running)

版本:

bash 复制代码
cri-dockerd --version

结果:

text 复制代码
cri-dockerd 0.4.4

3. 检查 cri-dockerd systemd 配置

执行:

bash 复制代码
systemctl cat cri-docker

确认服务:

text 复制代码
/etc/systemd/system/cri-docker.service

然后:

bash 复制代码
systemctl cat cri-docker.socket

确认:

text 复制代码
/etc/systemd/system/cri-docker.socket

Socket 使用:

text 复制代码
/run/cri-dockerd.sock

十、检查 kubelet CRI Endpoint

执行:

bash 复制代码
sudo cat /var/lib/kubelet/config.yaml

发现:

text 复制代码
containerRuntimeEndpoint:
unix:///run/cri-dockerd.sock

再检查:

bash 复制代码
ls -l /var/run/cri*

存在:

text 复制代码
/var/run/cri-dockerd.sock

说明:

text 复制代码
kubelet
  ↓
cri-dockerd.sock

基础连接配置没有明显错误。


十一、确认 kubelet 实际加载配置

仅仅查看文件不够,因为:

文件内容 ≠ kubelet 当前实际运行配置。

因此使用:

bash 复制代码
kubectl get --raw "/api/v1/nodes/k8s-master/proxy/configz"

实际配置中确认:

text 复制代码
address="0.0.0.0"
port=10250
enableDebuggingHandlers=true
containerRuntimeEndpoint="unix:///run/cri-dockerd.sock"

这一步非常重要。

说明 kubelet 当前确实:

text 复制代码
监听10250
启用了Debug Handler
使用cri-dockerd

十二、验证 kubelet 10250

查看:

bash 复制代码
sudo ss -lntp | grep kubelet

得到:

text 复制代码
127.0.0.1:10248
*:10250

然后:

bash 复制代码
curl -k https://127.0.0.1:10250/healthz

返回:

text 复制代码
Unauthorized

这里:

text 复制代码
Unauthorized

不是 kubelet 挂了。

恰恰说明:

text 复制代码
TCP连接成功
TLS成功
HTTP请求成功
认证被拒绝

也就是说 10250 HTTPS 服务是工作的。

进一步:

bash 复制代码
curl -k https://192.168.205.141:10250/

返回:

text 复制代码
404 page not found

同样说明 kubelet HTTPS Endpoint 可访问。


十三、验证 kubelet 普通 API

继续测试:

bash 复制代码
kubectl get --raw \
"/api/v1/nodes/k8s-master/proxy/stats/summary"

成功返回 Node Stats。

测试:

bash 复制代码
kubectl get --raw \
"/api/v1/nodes/k8s-master/proxy/runningpods/"

成功返回 PodList。

说明:

text 复制代码
API Server
    ↓
kubelet 10250

普通 HTTP API 是正常的。

因此故障范围进一步缩小到:

text 复制代码
exec / port-forward 等 Streaming 功能

而不是整个 kubelet。


十四、cri-dockerd 日志中的 No such container

排查时查看 cri-dockerd 日志,出现:

text 复制代码
error getting RW layer size for container ID ...

Error response from daemon:
No such container

以及:

text 复制代码
Set backoffDuration to : 1m0s

这些日志说明 cri-dockerd 曾经保留了一些已经不存在的 Container ID 状态。

但与此同时:

text 复制代码
RuntimeReady = true
NetworkReady = true

而且 Pod 能:

text 复制代码
创建
启动
运行
拉取镜像

因此不能单凭这些旧 Container ID 日志认定 Runtime 整体故障。


十五、Prometheus 镜像与 Pod 本身没有问题

检查 Prometheus:

text 复制代码
quay.io/prometheus/prometheus:v3.14.0-distroless

镜像成功:

text 复制代码
Pulled
Created
Started

并且日志中:

text 复制代码
Starting Prometheus Server
Start listening for connections
address=0.0.0.0:9090

因此 Prometheus 程序本身可以正常启动。


十六、曾出现 Prometheus Liveness / Readiness 失败

事件中曾看到:

text 复制代码
Liveness probe failed:

Get "http://10.244.2.19:9090/-/healthy":
context deadline exceeded

以及:

text 复制代码
Readiness probe failed

后来 Prometheus Pod 已重新调度:

text 复制代码
10.244.1.54

执行:

bash 复制代码
curl http://10.244.1.54:9090/-/ready

得到:

text 复制代码
Prometheus Server is Ready.

说明:

text 复制代码
10.244.2.19

是旧 Pod IP。

不能拿旧 Pod IP 判断当前 Prometheus 是否故障。

以后应该先:

bash 复制代码
kubectl get pods -n monitoring -o wide

确认当前 Pod IP,再测试。


十七、kubectl exec 问题的处理结论

经过以上排查,可以确认:

text 复制代码
Pod运行正常
Docker运行正常
cri-dockerd运行正常
kubelet运行正常
10250正常
普通kubelet API正常
Prometheus正常

但:

text 复制代码
kubectl exec
kubectl port-forward

这类 Streaming 操作存在异常。

因此本阶段没有让这个问题阻塞 Prometheus 配置。

后续验证改用:

text 复制代码
kubectl logs
kubectl get
kubectl describe
kubectl get --raw
直接访问 Pod IP
读取 Kubernetes Secret

而不是依赖:

text 复制代码
kubectl exec

十八、开启 Alertmanager

Prometheus 监控完成以后,下一阶段目标是:

text 复制代码
发现问题
 ↓
产生告警
 ↓
发送邮件

相关 Helm 配置文件:

text 复制代码
files/monitoring/prometheus-values.yaml

开启 Alertmanager 后重新:

bash 复制代码
helm upgrade

因为 prometheus-values.yaml 属于 Helm values:

修改 values 文件本身不会自动改变已经部署的 Release。

必须执行 Helm Upgrade。


十九、确认 Alertmanager Pod

执行:

bash 复制代码
kubectl get pods -n monitoring | grep alertmanager

正常看到:

text 复制代码
alertmanager-monitoring-kube-prometheus-alertmanager-0

2/2 Running

说明 Alertmanager 已部署。


二十、查看 Alertmanager 初始配置

执行:

bash 复制代码
kubectl get secret \
-n monitoring \
alertmanager-monitoring-kube-prometheus-alertmanager \
-o yaml

发现 Secret 中存在:

text 复制代码
alertmanager.yaml

初始配置的 Receiver:

text 复制代码
null

即:

text 复制代码
Prometheus产生告警
       ↓
Alertmanager
       ↓
null receiver
       ↓
不发送任何通知

所以:

Alertmanager Running 并不等于邮件通知已经配置。


二十一、QQ邮箱 SMTP 测试

先不急着改 Kubernetes。

先验证:

text 复制代码
QQ邮箱账号
SMTP服务器
授权码

本身是否可用。

使用:

text 复制代码
smtp.qq.com:587

进行了 SMTP 测试。

最终测试邮件成功收到。

这一步证明:

text 复制代码
邮箱
SMTP
授权码
网络

都正常。

因此后面如果 Alertmanager 不发邮件,排查重点应该放在:

text 复制代码
Alertmanager配置
Receiver
Route
Operator生成配置

而不是先怀疑 QQ SMTP。


二十二、SMTP Secret

为了避免直接把 SMTP 授权码写入 AlertmanagerConfig,创建 Kubernetes Secret。

文件:

text 复制代码
files/monitoring/smtp-auth.yaml

应用:

bash 复制代码
kubectl apply -f smtp-auth.yaml

验证:

bash 复制代码
kubectl get secret -n monitoring

应该看到:

text 复制代码
smtp-auth

二十三、创建 AlertmanagerConfig

文件:

text 复制代码
files/monitoring/alertmanager-email-config.yaml

对应的 Ansible Playbook:

text 复制代码
alertmanager-config.yml

设计目标:

text 复制代码
Ansible控制节点
       ↓
复制 YAML 到 k8s-master
       ↓
kubectl apply
       ↓
AlertmanagerConfig

这样以后可以通过 Ansible 重复部署 Alertmanager 邮件配置。


二十四、第一个 AlertmanagerConfig 错误:authUsername

第一次执行:

bash 复制代码
ansible-playbook alertmanager-config.yml -K

失败:

text 复制代码
strict decoding error:

unknown field
spec.receivers[0].emailConfigs[0].authUsername.key

unknown field
spec.receivers[0].emailConfigs[0].authUsername.name

这里说明:

当前安装的 AlertmanagerConfig CRD 与最初写的 YAML 字段结构不一致。

不能继续猜字段。


二十五、正确处理 CRD 字段问题

使用 Kubernetes 自带:

bash 复制代码
kubectl explain

查询实际 CRD。

例如:

bash 复制代码
kubectl explain \
alertmanagerconfig.spec.receivers.emailConfigs.authPassword

结果明确显示:

text 复制代码
FIELD: authPassword <Object>

并包含:

text 复制代码
key
name
optional

因此这里得到一个重要经验:

使用 CRD 时,不要完全依赖网上不同版本示例,应该以当前集群安装的 CRD Schema 为准。


二十六、第二个 AlertmanagerConfig 错误:authPassword

修改后再次 Apply:

text 复制代码
authPassword: "string"

又报:

text 复制代码
authPassword in body must be of type object

这次原因已经非常明确:

text 复制代码
authPassword

不是:

text 复制代码
字符串

而是:

text 复制代码
SecretKeySelector Object

因此应该引用前面创建的:

text 复制代码
smtp-auth

Secret。

修正:

text 复制代码
files/monitoring/alertmanager-email-config.yaml

然后重新执行:

bash 复制代码
ansible-playbook alertmanager-config.yml -K

二十七、确认 AlertmanagerConfig 创建成功

执行:

bash 复制代码
kubectl get alertmanagerconfig -n monitoring

得到:

text 复制代码
NAME           AGE
email-config   ...

说明:

text 复制代码
AlertmanagerConfig CR

已经被 Kubernetes API Server 接受。

但是这里又有一个重要点:

kubectl get alertmanagerconfig 能看到对象,不等于 Alertmanager 已经真正使用它。

还必须继续检查 Operator 生成的最终配置。


二十八、检查 Alertmanager CR 状态

执行:

bash 复制代码
kubectl get alertmanager \
-n monitoring \
monitoring-kube-prometheus-alertmanager \
-o yaml

当时发现:

text 复制代码
type: Reconciled
status: "False"
reason: ReconciliationFailed

错误:

text 复制代码
provision alertmanager configuration:
failed to initialize from secret:

undefined receiver "null" used in route

二十九、为什么出现 undefined receiver "null"

默认 Alertmanager Route 使用:

text 复制代码
receiver: "null"

但在配置合并过程中:

text 复制代码
route仍引用null

而最终 Receiver 中没有正确对应:

text 复制代码
null

于是 Operator 无法生成有效 Alertmanager 配置。

所以:

text 复制代码
AlertmanagerConfig存在

但:

text 复制代码
Alertmanager Reconciled=False

这就是为什么仅检查 CR 对象是不够的。


三十、修复 Alertmanager Receiver

修正相关配置文件:

text 复制代码
files/monitoring/prometheus-values.yaml
files/monitoring/alertmanager-email-config.yaml

目标是让:

text 复制代码
默认 null receiver
+
email-config receiver

能够同时存在,并让邮件 Route 正确引用邮件 Receiver。

更新 Helm / AlertmanagerConfig 后,再次检查:

bash 复制代码
kubectl get alertmanager \
-n monitoring \
monitoring-kube-prometheus-alertmanager \
-o yaml

确认不再出现:

text 复制代码
undefined receiver "null"

三十一、不要只看原始 Alertmanager Secret

最开始查看:

bash 复制代码
kubectl get secret \
-n monitoring \
alertmanager-monitoring-kube-prometheus-alertmanager \
-o jsonpath='{.data.alertmanager\.yaml}' \
| base64 -d

这个 Secret 可以看到基础配置。

但使用 Prometheus Operator + AlertmanagerConfig 后:

真正需要检查的是 Operator 生成的 generated Secret。


三十二、第一次读取 generated Secret 为什么是空的

最初执行:

bash 复制代码
kubectl get secret \
-n monitoring \
alertmanager-monitoring-kube-prometheus-alertmanager-generated \
-o jsonpath='{.data.alertmanager\.yaml}' \
| base64 -d

没有任何输出。

原因不是 Secret 没内容。

而是实际 Key:

text 复制代码
alertmanager.yaml.gz

不是:

text 复制代码
alertmanager.yaml

三十三、查看 generated Secret 正确方法

先:

bash 复制代码
kubectl get secret \
-n monitoring \
alertmanager-monitoring-kube-prometheus-alertmanager-generated \
-o yaml

发现:

text 复制代码
data:
  alertmanager.yaml.gz:

因此正确命令:

bash 复制代码
kubectl get secret \
-n monitoring \
alertmanager-monitoring-kube-prometheus-alertmanager-generated \
-o jsonpath='{.data.alertmanager\.yaml\.gz}' \
| base64 -d \
| gunzip -c

这是本阶段非常重要的一条排查命令。

因为 kubectl exec 不能使用,所以可以通过这个方法直接确认:

Alertmanager 最终到底加载了什么配置。


三十四、第一次 generated 配置仍然只有 null

第一次解压看到:

text 复制代码
route:
  receiver: "null"

receivers:
- name: "null"

没有:

text 复制代码
email

这说明:

text 复制代码
AlertmanagerConfig虽然创建成功

但是:

text 复制代码
Operator没有把邮件配置合并进最终配置

所以当时没有收到邮件是合理的。


三十五、检查 AlertmanagerConfig Selector

继续查看:

bash 复制代码
kubectl get alertmanager \
-n monitoring \
monitoring-kube-prometheus-alertmanager \
-o yaml

发现:

text 复制代码
alertmanagerConfigNamespaceSelector: {}
alertmanagerConfigSelector: {}

说明 Alertmanager CR 已允许选择 AlertmanagerConfig。

随后修复 Receiver / Route 问题,使 Operator 能成功 Reconcile。


三十六、最终 generated 配置验证

再次执行:

bash 复制代码
kubectl get secret \
-n monitoring \
alertmanager-monitoring-kube-prometheus-alertmanager-generated \
-o jsonpath='{.data.alertmanager\.yaml\.gz}' \
| base64 -d \
| gunzip -c

最终出现:

text 复制代码
receiver:
monitoring/email-config/email

同时 Receiver 中出现:

text 复制代码
monitoring/email-config/email

以及:

text 复制代码
email_configs
smtp.qq.com:587

说明:

text 复制代码
AlertmanagerConfig
       ↓
Prometheus Operator
       ↓
generated Secret
       ↓
Alertmanager

这条配置链终于真正生效。


三十七、为什么 Receiver 名变成 monitoring/email-config/email

AlertmanagerConfig 中定义的 Receiver 名虽然是:

text 复制代码
email

Operator 最终会生成类似:

text 复制代码
monitoring/email-config/email

格式:

text 复制代码
namespace / AlertmanagerConfig名称 / Receiver名称

因此:

text 复制代码
monitoring/email-config/email

属于正常行为,不需要修改。


三十八、创建测试 PrometheusRule

为了验证邮件链路,不能等真实故障。

因此创建一个始终成立的测试告警。

相关文件:

text 复制代码
files/monitoring/alert-rules.yaml

Ansible Playbook:

text 复制代码
alert-rules.yml

目的:

text 复制代码
vector(1)
   ↓
测试规则成立
   ↓
Prometheus产生FIRING

这样可以验证:

text 复制代码
PrometheusRule
      ↓
Prometheus
      ↓
Alertmanager
      ↓
Email

三十九、使用 Ansible 部署测试告警

在:

text 复制代码
~/devops-lab/ansible

执行对应 Playbook:

bash 复制代码
ansible-playbook alert-rules.yml -K

然后在 Kubernetes Master 验证:

bash 复制代码
kubectl get prometheusrule -n monitoring

确认测试规则已经创建。


四十、验证 Alert 是否真正进入 Alertmanager

由于 kubectl exec 有问题,决定通过 Alertmanager API 检查。

最初尝试:

bash 复制代码
kubectl port-forward \
-n monitoring \
svc/monitoring-kube-prometheus-alertmanager \
9093:9093

终端显示:

text 复制代码
Forwarding from 127.0.0.1:9093 -> 9093

这里看起来像"卡住"。

实际上:

port-forward 是前台常驻进程,本来就不会自动退出。

正确使用方法:

text 复制代码
终端1:
kubectl port-forward ...

终端2:
curl ...

四十一、port-forward 又遇到 socat 问题

另一个终端执行:

bash 复制代码
curl http://127.0.0.1:9093/api/v2/alerts

失败。

port-forward 终端出现:

text 复制代码
unable to do port forwarding:
socat not found

说明这次问题又不是 Alertmanager。

而是:

text 复制代码
kubectl port-forward
       ↓
CRI streaming
       ↓
需要socat
       ↓
环境缺失/streaming异常

与之前 kubectl exec 问题属于同一类 Streaming 路径问题。

处理后重新测试 API。


四十二、Alertmanager API 验证成功

最终:

bash 复制代码
curl http://127.0.0.1:9093/api/v2/alerts

成功返回 Alert JSON。

其中包括:

text 复制代码
PrometheusOperatorSyncFailed
KubeProxyInstanceUnreachable
TargetDown
TestMailAlert
Watchdog

这一步证明:

text 复制代码
Prometheus
   ↓
Alertmanager

告警链路已经正常。


四十三、TestMailAlert 已经进入 Alertmanager

API 中明确出现:

text 复制代码
alertname:
TestMailAlert

并且状态:

text 复制代码
active

说明测试规则成功。

至此已经确认:

text 复制代码
PrometheusRule
      ↓
Prometheus
      ↓
Alertmanager

没有问题。

如果此时仍然没有邮件,就应该继续排查:

text 复制代码
Route
Receiver
SMTP

而不是再排查 PrometheusRule。


四十四、最终邮件成功

最终 QQ 邮箱收到:

text 复制代码
[FIRING:1]
PrometheusOperatorSyncFailed

这封邮件非常关键。

它证明的不是单独某个组件,而是整条链:

text 复制代码
Prometheus产生告警
        ↓
发送给Alertmanager
        ↓
Alertmanager匹配Route
        ↓
进入Email Receiver
        ↓
SMTP认证成功
        ↓
smtp.qq.com发送成功
        ↓
QQ邮箱成功接收

因此邮件告警链路正式完成。


四十五、为什么收到的是 PrometheusOperatorSyncFailed

收到的第一封邮件并不一定是:

text 复制代码
TestMailAlert

而是:

text 复制代码
PrometheusOperatorSyncFailed

这是因为前面 Alertmanager 配置过程中确实发生过:

text 复制代码
ReconciliationFailed

Prometheus Operator 的失败状态触发了内置告警。

而修复 Email Route 后,该告警正好进入邮件 Receiver。

这实际上比人工测试更有意义:

真实的 Kubernetes / Prometheus Operator 故障已经能够发送邮件。


四十六、当前 Route 的一个重要限制

最终 generated 配置中出现:

text 复制代码
matchers:
- namespace="monitoring"

因此当前 Email Route 主要匹配:

text 复制代码
namespace=monitoring

的告警。

这也是为什么:

text 复制代码
PrometheusOperatorSyncFailed

可以收到邮件。

但:

text 复制代码
kube-system
default

等 Namespace 的告警不一定走这个 Email Receiver。

这是后续如果要做"所有 Namespace 告警统一邮件通知"时需要继续调整的地方。

本阶段先完成邮件链路,不继续扩大配置范围。


四十七、最终文件关系

本阶段主要涉及:

text 复制代码
ansible/
│
├── node-exporter.yml
├── alertmanager-config.yml
├── alert-rules.yml
│
├── inventory/
│   └── hosts.ini
│
└── files/
    └── monitoring/
        ├── prometheus-values.yaml
        ├── alertmanager-email-config.yaml
        ├── smtp-auth.yaml
        └── alert-rules.yaml

作用:

text 复制代码
node-exporter.yml
        ↓
部署外部node_exporter


prometheus-values.yaml
        ↓
Prometheus / Alertmanager Helm配置


smtp-auth.yaml
        ↓
保存SMTP认证信息


alertmanager-email-config.yaml
        ↓
定义邮件Receiver和Route


alertmanager-config.yml
        ↓
Ansible部署AlertmanagerConfig


alert-rules.yaml
        ↓
定义测试/正式PrometheusRule


alert-rules.yml
        ↓
Ansible部署PrometheusRule

最终结果

本阶段最终实现:

text 复制代码
Kubernetes节点
      │
      ├── node_exporter
      │
外部Linux节点
      │
      └── node_exporter
              ↓
          Prometheus
              ↓
        PrometheusRule
              ↓
         Alertmanager
              ↓
          QQ SMTP
              ↓
             邮箱

外部节点:

text 复制代码
devops
elk
infra

已经纳入 Prometheus。

测试过程中 ELK 关机后 Prometheus 能正确显示:

text 复制代码
DOWN

Alertmanager 邮件 Receiver 最终成功被 Operator 合并进 generated 配置,并实际收到:

text 复制代码
[FIRING:1] PrometheusOperatorSyncFailed

因此本阶段的 Prometheus 基础监控与邮件告警链路验证完成。

相关推荐
.柒宇.2 天前
运维常见面试题_07_配置管理与监控(Ansible · Prometheus · Alertmanager)· 容器编排(Kubernetes)
运维·k8s·ansible·prometheus
玉&心4 天前
在grafana中引入prometheus的数据监控
grafana·prometheus
Dovis(誓平步青云)4 天前
从Redis指标采集到异常告警:redis_exporter + Prometheus 完整实战
服务器·数据库·人工智能·redis·架构·prometheus·vibe coding
吉甫作诵6 天前
Prometheus 安装配置:Consul 自动发现与 Thanos Sidecar 持久化
prometheus·consul
溜达的大象6 天前
Prometheus怎么监控没有公网IP的服务器?Node Exporter远程采集实战
服务器·tcp/ip·prometheus
Livia要学习11 天前
Prometheus架构解析
prometheus
云烟成雨TD12 天前
Micrometer 系列【63】统一观测:基于 Spring Boot 的生产级演示案例 | 基于 OTLP 集成 Prometheus + Jaeger
spring boot·云原生·prometheus
江南风月15 天前
如何使用WGCLOUD实现智能运维
运维·zabbix·运维开发·prometheus
凤山老林17 天前
可观测性落地:Spring Boot 3.x + Actuator + Prometheus + Grafana 监控体系搭建
spring boot·grafana·prometheus