kube-prometheus-stack 安装配置文档
kube-prometheus-stack 安装配置文档
本文档介绍了在 Kubernetes 集群中安装和配置 kube-prometheus-stack 监控组件的两种方式(在线安装和离线/网络不佳情况下的安装)、如何访问 Grafana 仪表盘,以及如何配置邮件、钉钉和飞书等报警通知。
0. 安装前准备(重要):修改 127.0.0.1 监听地址,避免 Prometheus 抓取失败
在部分 kubeadm 集群中,控制平面组件(controller-manager / scheduler / etcd)以及 kube-proxy 的 metrics 端口可能默认只监听 127.0.0.1,会导致 Prometheus 通过 PodIP/NodeIP 抓取时出现 connect: connection refused。
请在安装 kube-prometheus-stack 之前,按以下步骤修改 metrics 监听地址。
说明:
- 第 1/2/3 项需要在每一台 master 节点上执行(静态 Pod 清单在各节点本地:
/etc/kubernetes/manifests/*.yaml)。 - 避坑警告:备份文件时,绝对不要将备份文件(如
.bak)留在/etc/kubernetes/manifests/目录下!Kubelet 会读取该目录下的所有文件,导致读取到旧配置产生冲突而不生效。请将备份文件存放到其他目录(如/root/或/tmp/)。本指南已将备份路径修改为/root/。 - 第 4 项为 kube-proxy(DaemonSet),修改 ConfigMap 后需滚动重启 kube-proxy。
0.1 清理历史遗留的备份文件(极度重要)
如果您之前在 /etc/kubernetes/manifests/ 目录下生成了 .bak 结尾的备份文件,必须先将它们移出,否则 Kubelet 会因为加载了备份文件导致后续修改无法生效。
# 检查是否存在遗留的备份文件
ls -l /etc/kubernetes/manifests/*.bak* || true
# 将它们统一移动到 /root/ 目录下
sudo mv /etc/kubernetes/manifests/*.bak* /root/ 2>/dev/null || true
0.2 controller-manager(10257)
sudo grep -n -- '--bind-address=' /etc/kubernetes/manifests/kube-controller-manager.yaml
sudo cp -a /etc/kubernetes/manifests/kube-controller-manager.yaml \
/root/kube-controller-manager.yaml.bak.$(date +%F_%H%M%S)
sudo sed -i -E 's#(--bind-address=).*#\10.0.0.0#' /etc/kubernetes/manifests/kube-controller-manager.yaml
kubectl -n kube-system get pod -o wide | grep kube-controller-manager
sudo ss -lntp | grep 10257
0.3 etcd(2381)
sudo grep -n -- '--listen-metrics-urls' /etc/kubernetes/manifests/etcd.yaml || true
sudo cp -a /etc/kubernetes/manifests/etcd.yaml \
/root/etcd.yaml.bak.$(date +%F_%H%M%S)
sudo sed -i -E 's#(--listen-metrics-urls=http://)127\.0\.0\.1:2381#\10.0.0.0:2381#' /etc/kubernetes/manifests/etcd.yaml
sudo sed -i -E 's#(--listen-metrics-urls=http://)\[::1\]:2381#\10.0.0.0:2381#' /etc/kubernetes/manifests/etcd.yaml
sudo ss -lntp | grep 2381
0.4 kube-scheduler(10259)
sudo grep -n -- '--bind-address=' /etc/kubernetes/manifests/kube-scheduler.yaml || true
sudo cp -a /etc/kubernetes/manifests/kube-scheduler.yaml \
/root/kube-scheduler.yaml.bak.$(date +%F_%H%M%S)
sudo sed -i -E 's#(--bind-address=).*#\10.0.0.0#' /etc/kubernetes/manifests/kube-scheduler.yaml
kubectl -n kube-system get pod -o wide | grep kube-scheduler
sudo ss -lntp | grep 10259
0.5 kube-proxy(10249)
kubectl -n kube-system get cm | grep -i proxy
kubectl -n kube-system get cm kube-proxy -o yaml > /root/kube-proxy-cm.bak.$(date +%F_%H%M%S).yaml
NEW_CONF="$(kubectl -n kube-system get cm kube-proxy -o jsonpath='{.data.config\.conf}' \
| sed -E 's#(^[[:space:]]*metricsBindAddress:[[:space:]]*).*$#\10.0.0.0:10249#m')"
kubectl -n kube-system patch cm kube-proxy --type merge \
-p "{\"data\":{\"config.conf\":$(printf '%s' "$NEW_CONF" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')}}"
kubectl -n kube-system rollout restart ds/kube-proxy
kubectl -n kube-system rollout status ds/kube-proxy
1. 方式一:在线安装(网络良好)
如果您的集群网络可以直接拉取官方镜像,可以直接使用 Helm 在线安装:
# 添加 prometheus-community 仓库
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# 搜索仓库确认
helm search repo prometheus-community | grep kube-prometheus-stack
# 方式A:执行安装/更新 (默认配置,仅集群内访问)
helm upgrade --install prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false # 允许 Prometheus 自动发现并抓取所有未指定特定 Label 的 ServiceMonitor
# 方式B:执行安装/更新 (支持直接开启 Grafana、Prometheus 和 Alertmanager 的 NodePort 供外部访问)
helm upgrade --install prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set "grafana.grafana\.ini.server.domain=<您的节点IP>" \
--set "grafana.grafana\.ini.server.root_url=http://<您的节点IP>:32000" \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \# 允许抓取所有 ServiceMonitor
--set grafana.service.type=NodePort \
--set grafana.service.nodePort=32000 \
--set prometheus.service.type=NodePort \
--set prometheus.service.nodePort=32090 \
--set alertmanager.service.type=NodePort \
--set alertmanager.service.nodePort=32093
# 方式C:执行安装/更新 (支持直接开启 Grafana、Prometheus 和 Alertmanager 的 Ingress 供外部域名访问)
helm upgrade --install prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set "grafana.grafana\.ini.server.domain=grafana.aioil.top" \
--set "grafana.grafana\.ini.server.root_url=http://grafana.aioil.top" \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \
--set grafana.ingress.enabled=true \
--set grafana.ingress.ingressClassName=nginx \
--set grafana.ingress.hosts="{grafana.aioil.top}" \
--set prometheus.ingress.enabled=true \
--set prometheus.ingress.ingressClassName=nginx \
--set prometheus.ingress.hosts="{prometheus.aioil.top}" \
--set alertmanager.ingress.enabled=true \
--set alertmanager.ingress.ingressClassName=nginx \
--set alertmanager.ingress.hosts="{alertmanager.aioil.top}"
# 方式D:执行安装/更新 (支持直接开启 Ingress 供外部域名访问,使用 Higress 网关并自动配置 TLS 证书)
helm upgrade --install prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set "grafana.grafana\.ini.server.domain=grafana.aioil.top" \
--set "grafana.grafana\.ini.server.root_url=https://grafana.aioil.top" \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \
--set grafana.ingress.enabled=true \
--set grafana.ingress.ingressClassName=higress \
--set grafana.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string grafana.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set grafana.ingress.hosts="{grafana.aioil.top}" \
--set grafana.ingress.tls[0].secretName=grafana-tls \
--set grafana.ingress.tls[0].hosts[0]=grafana.aioil.top \
--set prometheus.ingress.enabled=true \
--set prometheus.ingress.ingressClassName=higress \
--set prometheus.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string prometheus.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set prometheus.ingress.hosts="{prometheus.aioil.top}" \
--set prometheus.ingress.tls[0].secretName=prometheus-tls \
--set prometheus.ingress.tls[0].hosts[0]=prometheus.aioil.top \
--set alertmanager.ingress.enabled=true \
--set alertmanager.ingress.ingressClassName=higress \
--set alertmanager.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string alertmanager.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set alertmanager.ingress.hosts="{alertmanager.aioil.top}" \
--set alertmanager.ingress.tls[0].secretName=alertmanager-tls \
--set alertmanager.ingress.tls[0].hosts[0]=alertmanager.aioil.top
# 方式E:执行安装/更新 (在方式D的基础上,增加 StorageClass 持久化存储,保证监控数据和面板配置重启不丢失)
# 注意:以下使用集群默认 StorageClass `rook-ceph-block` (RBD)。您也可根据需求替换为 `rook-ceph-block-retain` (Retain回收策略更安全)、
# 或 `rook-cephfs` (CephFS, 支持 ReadWriteMany)。可通过 `kubectl get sc` 查看集群中所有可用 StorageClass。
helm upgrade --install prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set "grafana.grafana\.ini.server.domain=grafana.aioil.top" \
--set "grafana.grafana\.ini.server.root_url=https://grafana.aioil.top" \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \
--set grafana.ingress.enabled=true \
--set grafana.ingress.ingressClassName=higress \
--set grafana.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string grafana.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set grafana.ingress.hosts="{grafana.aioil.top}" \
--set grafana.ingress.tls[0].secretName=grafana-tls \
--set grafana.ingress.tls[0].hosts[0]=grafana.aioil.top \
--set prometheus.ingress.enabled=true \
--set prometheus.ingress.ingressClassName=higress \
--set prometheus.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string prometheus.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set prometheus.ingress.hosts="{prometheus.aioil.top}" \
--set prometheus.ingress.tls[0].secretName=prometheus-tls \
--set prometheus.ingress.tls[0].hosts[0]=prometheus.aioil.top \
--set alertmanager.ingress.enabled=true \
--set alertmanager.ingress.ingressClassName=higress \
--set alertmanager.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string alertmanager.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set alertmanager.ingress.hosts="{alertmanager.aioil.top}" \
--set alertmanager.ingress.tls[0].secretName=alertmanager-tls \
--set alertmanager.ingress.tls[0].hosts[0]=alertmanager.aioil.top \
--set grafana.persistence.enabled=true \
--set grafana.persistence.storageClassName="rook-ceph-block" \
--set grafana.persistence.size=20Gi \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName="rook-ceph-block" \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.accessModes[0]="ReadWriteOnce" \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage="50Gi" \
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.storageClassName="rook-ceph-block" \
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.accessModes[0]="ReadWriteOnce" \
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.resources.requests.storage="20Gi"
📦 持久化存储扩容说明:
rook-ceph-blockStorageClass 已启用ALLOWVOLUMEEXPANSION: true,后期如果 Grafana/Prometheus/Alertmanager 的存储空间不足,可以直接在线扩容 PVC,无需重新部署。扩容步骤(以 Grafana 10Gi → 20Gi 为例):
# 1. 编辑 PVC,将 spec.resources.requests.storage 改为 20Gi kubectl edit pvc prometheus-stack-grafana -n monitoring # 2. 重启对应 Pod 使其重新挂载扩容后的卷 kubectl rollout restart deployment prometheus-stack-grafana -n monitoringPrometheus 和 Alertmanager 扩容方式同理,只需替换 PVC 名称:
- Prometheus PVC:
prometheus-prometheus-stack-kube-prom-prometheus-db-prometheus-prometheus-stack-kube-prom-prometheus-0
(实际名称可用kubectl get pvc -n monitoring | grep prometheus确认)- Alertmanager PVC:
alertmanager-prometheus-stack-kube-prom-alertmanager-db-alertmanager-prometheus-stack-kube-prom-alertmanager-0
2. 方式二:离线包安装及国内镜像源替换(网络不佳)
如果拉取官方镜像速度较慢或超时,可以下载 Chart 压缩包,替换其中的镜像地址为国内加速源后再进行本地安装。
2.1 下载并解压 Chart 包
# 下载指定版本的压缩包 (例如 85.1.3)
wget https://github.com/prometheus-community/helm-charts/releases/download/kube-prometheus-stack-85.1.3/kube-prometheus-stack-85.1.3.tgz
# 解压压缩包
tar xvf kube-prometheus-stack-85.1.3.tgz
# 进入解压后的目录
cd kube-prometheus-stack
(注:如果需要通过源码包下载,可以使用 wget https://github.com/prometheus-community/helm-charts/archive/refs/tags/kube-prometheus-stack-85.1.3.tar.gz)
2.2 替换镜像为国内加速源
在解压后的 kube-prometheus-stack 目录下执行以下命令,将官方镜像替换为 DaoCloud 的国内加速镜像:
# 替换主 values.yaml
sed -i 's#registry.k8s.io#k8s.m.daocloud.io#g' values.yaml
sed -i 's#quay.io#quay.m.daocloud.io#g' values.yaml
sed -i 's#docker.io#docker.m.daocloud.io#g' values.yaml
# 替换 kube-state-metrics 子 chart
sed -i 's#registry.k8s.io#k8s.m.daocloud.io#g' charts/kube-state-metrics/values.yaml
# 替换 grafana 子 chart
sed -i 's#registry.k8s.io#k8s.m.daocloud.io#g' charts/grafana/values.yaml
sed -i 's#quay.io#quay.m.daocloud.io#g' charts/grafana/values.yaml
sed -i 's#docker.io#docker.m.daocloud.io#g' charts/grafana/values.yaml
2.3 执行本地安装
使用当前目录 (.) 作为 chart 源进行安装:
# 方式A:执行本地安装/更新 (默认配置,仅集群内访问)
helm upgrade --install prometheus-stack . \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false # 允许 Prometheus 自动发现并抓取所有未指定特定 Label 的 ServiceMonitor
# 方式B:执行本地安装/更新 (支持直接开启 Grafana、Prometheus 和 Alertmanager 的 NodePort 供外部访问)
helm upgrade --install prometheus-stack . \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set "grafana.grafana\.ini.server.domain=<您的节点IP>" \
--set "grafana.grafana\.ini.server.root_url=http://<您的节点IP>:32000" \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \ # 允许抓取所有 ServiceMonitor
--set grafana.service.type=NodePort \
--set grafana.service.nodePort=32000 \
--set prometheus.service.type=NodePort \
--set prometheus.service.nodePort=32090 \
--set alertmanager.service.type=NodePort \
--set alertmanager.service.nodePort=32093
# 方式C:执行本地安装/更新 (支持直接开启 Grafana、Prometheus 和 Alertmanager 的 Ingress 供外部域名访问)
helm upgrade --install prometheus-stack . \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set "grafana.grafana\.ini.server.domain=grafana.aioil.top" \
--set "grafana.grafana\.ini.server.root_url=http://grafana.aioil.top" \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \
--set grafana.ingress.enabled=true \
--set grafana.ingress.ingressClassName=nginx \
--set grafana.ingress.hosts="{grafana.aioil.top}" \
--set prometheus.ingress.enabled=true \
--set prometheus.ingress.ingressClassName=nginx \
--set prometheus.ingress.hosts="{prometheus.aioil.top}" \
--set alertmanager.ingress.enabled=true \
--set alertmanager.ingress.ingressClassName=nginx \
--set alertmanager.ingress.hosts="{alertmanager.aioil.top}"
# 方式D:执行本地安装/更新 (支持直接开启 Ingress 供外部域名访问,使用 Higress 网关并自动配置 TLS 证书)
helm upgrade --install prometheus-stack . \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set "grafana.grafana\.ini.server.domain=grafana.aioil.top" \
--set "grafana.grafana\.ini.server.root_url=https://grafana.aioil.top" \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \
--set grafana.ingress.enabled=true \
--set grafana.ingress.ingressClassName=higress \
--set grafana.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string grafana.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set grafana.ingress.hosts="{grafana.aioil.top}" \
--set grafana.ingress.tls[0].secretName=grafana-tls \
--set grafana.ingress.tls[0].hosts[0]=grafana.aioil.top \
--set prometheus.ingress.enabled=true \
--set prometheus.ingress.ingressClassName=higress \
--set prometheus.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string prometheus.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set prometheus.ingress.hosts="{prometheus.aioil.top}" \
--set prometheus.ingress.tls[0].secretName=prometheus-tls \
--set prometheus.ingress.tls[0].hosts[0]=prometheus.aioil.top \
--set alertmanager.ingress.enabled=true \
--set alertmanager.ingress.ingressClassName=higress \
--set alertmanager.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string alertmanager.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set alertmanager.ingress.hosts="{alertmanager.aioil.top}" \
--set alertmanager.ingress.tls[0].secretName=alertmanager-tls \
--set alertmanager.ingress.tls[0].hosts[0]=alertmanager.aioil.top
# 方式E:执行本地安装/更新 (在方式D的基础上,增加 StorageClass 持久化存储,保证监控数据和面板配置重启不丢失)
# 注意:以下使用集群默认 StorageClass `rook-ceph-block` (RBD)。您也可根据需求替换为 `rook-ceph-block-retain` (Retain回收策略更安全)、
# 或 `rook-cephfs` (CephFS, 支持 ReadWriteMany)。可通过 `kubectl get sc` 查看集群中所有可用 StorageClass。
helm upgrade --install prometheus-stack . \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set grafana.deploymentStrategy.type=Recreate \
--set "grafana.grafana\.ini.server.domain=grafana.aioil.top" \
--set "grafana.grafana\.ini.server.root_url=https://grafana.aioil.top" \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \
--set grafana.ingress.enabled=true \
--set grafana.ingress.ingressClassName=higress \
--set grafana.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string grafana.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set grafana.ingress.hosts="{grafana.aioil.top}" \
--set grafana.ingress.tls[0].secretName=grafana-tls \
--set grafana.ingress.tls[0].hosts[0]=grafana.aioil.top \
--set prometheus.ingress.enabled=true \
--set prometheus.ingress.ingressClassName=higress \
--set prometheus.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string prometheus.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set prometheus.ingress.hosts="{prometheus.aioil.top}" \
--set prometheus.ingress.tls[0].secretName=prometheus-tls \
--set prometheus.ingress.tls[0].hosts[0]=prometheus.aioil.top \
--set alertmanager.ingress.enabled=true \
--set alertmanager.ingress.ingressClassName=higress \
--set alertmanager.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod-dns \
--set-string alertmanager.ingress.annotations."nginx\.ingress\.kubernetes\.io/ssl-redirect"="true" \
--set alertmanager.ingress.hosts="{alertmanager.aioil.top}" \
--set alertmanager.ingress.tls[0].secretName=alertmanager-tls \
--set alertmanager.ingress.tls[0].hosts[0]=alertmanager.aioil.top \
--set grafana.persistence.enabled=true \
--set grafana.persistence.storageClassName="rook-ceph-block" \
--set grafana.persistence.size=10Gi \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName="rook-ceph-block" \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.accessModes[0]="ReadWriteOnce" \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage="50Gi" \
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.storageClassName="rook-ceph-block" \
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.accessModes[0]="ReadWriteOnce" \
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.resources.requests.storage="20Gi"
3. 验证安装状态
安装完成后,可以通过以下命令查看监控组件的 Pod、Service 和 Ingress 状态:
kubectl get po -n monitoring
kubectl get svc -n monitoring
kubectl get ingress -n monitoring
4. 访问监控组件仪表盘
默认情况下,kube-prometheus-stack 中的各个组件(如 Grafana、Prometheus、Alertmanager 等)会以 ClusterIP 方式暴露,只能在集群内部访问。你可以使用 kubectl port-forward 命令将这些服务映射到本地,从而在浏览器中直接访问。
注意:加入 --address 0.0.0.0 参数可以允许不仅是本机(localhost),还允许局域网内的其他机器通过当前机器的 IP 来访问这些映射的端口。这在您通过 SSH 连接到服务器进行操作时非常有用。
4.1 访问 Grafana 仪表盘
方式一:临时端口转发 (Port-Forward)
执行以下命令将 Grafana 服务暴露出来:
kubectl port-forward --address 0.0.0.0 svc/prometheus-stack-grafana 3000:80 -n monitoring
- 命令解释:将
monitoring命名空间下名为prometheus-stack-grafana服务的80端口,映射到当前机器的所有网卡(0.0.0.0)的3000端口上。 - 访问方式:在浏览器中访问
http://<您的机器IP>:3000
方式二:永久修改为 NodePort (推荐外部访问使用)
如果您希望长期通过节点的 IP 地址访问,可以将其 Service 类型修改为 NodePort,并指定一个固定端口(例如 32000):
kubectl patch svc prometheus-stack-grafana -n monitoring -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 3000, "nodePort": 32000}]}}'
-
访问方式:在浏览器中访问
http://<任意K8s-Node-IP>:32000 -
默认登录凭据:
- 用户名:
admin - 密码:可以通过以下命令获取并解密:
kubectl get secret -n monitoring prometheus-stack-grafana -o jsonpath="{.data.admin-password}" | base64 --decode
- 用户名:
方式三:通过 YAML 文件独立创建 Ingress
如果您不想修改 Helm 配置,也可以直接编写 Ingress 资源清单并应用:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-stack-grafana-ingress
namespace: monitoring
spec:
ingressClassName: nginx
rules:
- host: grafana.aioil.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheus-stack-grafana
port:
number: 80
保存为 grafana-ingress.yaml,然后执行 kubectl apply -f grafana-ingress.yaml 即可。
4.2 访问 Prometheus 原生 UI
方式一:临时端口转发 (Port-Forward)
执行以下命令将 Prometheus 服务暴露出来:
kubectl port-forward --address 0.0.0.0 svc/prometheus-stack-kube-prom-prometheus 9090:9090 -n monitoring
- 命令解释:将
monitoring命名空间下名为prometheus-stack-kube-prom-prometheus服务的9090端口,映射到当前机器的所有网卡(0.0.0.0)的9090端口上。 - 访问方式:在浏览器中访问
http://<您的机器IP>:9090,可以直接使用 PromQL 查询指标数据。
方式二:永久修改为 NodePort
修改 Service 为 NodePort 并指定固定端口(例如 32090):
kubectl patch svc prometheus-stack-kube-prom-prometheus -n monitoring -p '{"spec": {"type": "NodePort", "ports": [{"port": 9090, "targetPort": 9090, "nodePort": 32090}]}}'
- 访问方式:在浏览器中访问
http://<任意K8s-Node-IP>:32090
方式三:通过 YAML 文件独立创建 Ingress
如果您希望通过域名访问 Prometheus,可以编写如下 Ingress 资源清单:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-stack-prometheus-ingress
namespace: monitoring
spec:
ingressClassName: nginx
rules:
- host: prometheus.aioil.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheus-stack-kube-prom-prometheus
port:
number: 9090
保存为 prometheus-ingress.yaml,然后执行 kubectl apply -f prometheus-ingress.yaml 即可。
- 访问方式:配置本地 hosts 或 DNS 解析后,在浏览器中访问
http://prometheus.aioil.top
4.3 访问 Alertmanager 报警面板
方式一:临时端口转发 (Port-Forward)
执行以下命令将 Alertmanager 服务暴露出来:
kubectl port-forward --address 0.0.0.0 svc/prometheus-stack-kube-prom-alertmanager 9093:9093 -n monitoring
- 命令解释:将
monitoring命名空间下名为prometheus-stack-kube-prom-alertmanager服务的9093端口,映射到当前机器的所有网卡(0.0.0.0)的9093端口上。 - 访问方式:在浏览器中访问
http://<您的机器IP>:9093,可以查看当前触发的报警规则和告警信息。
方式二:永久修改为 NodePort
修改 Service 为 NodePort 并指定固定端口(例如 32093):
kubectl patch svc prometheus-stack-kube-prom-alertmanager -n monitoring -p '{"spec": {"type": "NodePort", "ports": [{"port": 9093, "targetPort": 9093, "nodePort": 32093}]}}'
- 访问方式:在浏览器中访问
http://<任意K8s-Node-IP>:32093
方式三:通过 YAML 文件独立创建 Ingress
如果您希望通过域名访问 Alertmanager,可以编写如下 Ingress 资源清单:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-stack-alertmanager-ingress
namespace: monitoring
spec:
ingressClassName: nginx
rules:
- host: alertmanager.aioil.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheus-stack-kube-prom-alertmanager
port:
number: 9093
保存为 alertmanager-ingress.yaml,然后执行 kubectl apply -f alertmanager-ingress.yaml 即可。
- 访问方式:配置本地 hosts 或 DNS 解析后,在浏览器中访问
http://alertmanager.aioil.top
4.4 访问 Node Exporter 指标暴露端口
方式一:临时端口转发 (Port-Forward)
执行以下命令将 Node Exporter 服务暴露出来:
kubectl port-forward --address 0.0.0.0 svc/prometheus-stack-prometheus-node-exporter 9110:9100 -n monitoring
- 命令解释:将
monitoring命名空间下名为prometheus-stack-prometheus-node-exporter服务的9100端口,映射到当前机器的所有网卡(0.0.0.0)的9110端口上。(注意:这里本地映射端口改为了 9110,避免与本地可能运行的其他服务冲突)。 - 访问方式:在浏览器中访问
http://<您的机器IP>:9110/metrics,可以看到该节点采集到的基础物理指标(CPU、内存、磁盘等)的原始数据。
方式二:永久修改为 NodePort
修改 Service 为 NodePort 并指定固定端口(例如 32110):
kubectl patch svc prometheus-stack-prometheus-node-exporter -n monitoring -p '{"spec": {"type": "NodePort", "ports": [{"port": 9100, "targetPort": 9100, "nodePort": 32110}]}}'
- 访问方式:在浏览器中访问
http://<任意K8s-Node-IP>:32110/metrics
方式三:通过 YAML 文件独立创建 Ingress
如果您希望通过域名访问 Node Exporter 指标,可以编写如下 Ingress 资源清单:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-stack-node-exporter-ingress
namespace: monitoring
spec:
ingressClassName: nginx
rules:
- host: node-exporter.aioil.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheus-stack-prometheus-node-exporter
port:
number: 9100
保存为 node-exporter-ingress.yaml,然后执行 kubectl apply -f node-exporter-ingress.yaml 即可。
- 访问方式:配置本地 hosts 或 DNS 解析后,在浏览器中访问
http://node-exporter.aioil.top/metrics
5. 配置报警通知 (邮件、钉钉、飞书)
Alertmanager 默认支持邮件(Email)、企业微信(WeChat)、Slack 等原生报警配置,但对于钉钉(DingTalk)和飞书(Feishu),需要通过 Webhook 配合中间件转发来实现。
5.1 配置邮件报警 (原生支持)
可以在部署时通过覆盖 values.yaml 中的 alertmanager.config 来配置邮件报警。以下是以 QQ 邮箱为例的配置。
注意: 对于 QQ 邮箱等第三方邮箱,smtp_auth_password 通常不能使用网页登录密码,而是需要使用邮箱设置中生成的授权码。
获取 QQ 邮箱授权码的步骤:
- 电脑端登录你的 QQ 邮箱 / Foxmail 邮箱。
- 点击顶部的 设置 -> 账号与安全 -> 安全设置。
- 向下滚动找到 POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 区域。
- 确保 POP3/SMTP服务 已开启,然后点击下方的 生成授权码。
- 根据提示完成密保验证(通常是发送短信),然后将获取到的一串英文字母填入下方配置的
smtp_auth_password中。
alertmanager:
config:
global:
# 当告警状态从 firing 变为 resolved 时,Alertmanager 等待多长时间才发送恢复通知
resolve_timeout: 5m
# SMTP 服务器地址和端口 (这里以 QQ 邮箱为例,465 端口通常用于 SSL 加密传输)
smtp_smarthost: 'smtp.qq.com:465'
# 发件人的邮箱地址
smtp_from: 'your-email@foxmail.com'
# SMTP 认证用户名 (通常与发件人邮箱相同)
smtp_auth_username: 'your-email@foxmail.com'
# SMTP 认证密码或授权码 (QQ/网易等第三方邮箱通常需要使用授权码而不是网页登录密码)
smtp_auth_password: 'your-auth-password'
# 是否强制要求 TLS 连接。由于 QQ 邮箱 465 端口已经是隐式 SSL 协议,因此这里设为 false
smtp_require_tls: false
route:
# 告警分组策略:将具有相同 namespace 和 alertname 标签的告警合并成一条通知发送,避免告警风暴
group_by: ['namespace', 'alertname']
# 分组等待时间:产生新告警后,等待 30s 收集同组的其他告警,然后合并后一起发送
group_wait: 30s
# 分组间隔时间:当一组告警已经发送过通知后,如果该组内有新的告警产生,需等待 5m 后才再次发送通知
group_interval: 5m
# 重复发送间隔:如果告警一直处于未解决 (firing) 状态,每隔 12h 会重新发送一次通知提醒
repeat_interval: 12h
# 默认接收者:如果没有匹配到任何子路由规则,告警将默认发送给这个接收者
receiver: 'email-receiver'
routes:
# 子路由规则配置
- receiver: 'email-receiver'
# 匹配器配置:只有告警标签 severity 为 warning 或 critical 时,才会进入此路由发送通知
matchers:
- severity=~"warning|critical"
receivers:
# 接收者配置列表
- name: 'email-receiver'
# 邮件发送配置
email_configs:
# 收件人的邮箱地址
- to: 'your-email@foxmail.com'
# 告警恢复时,是否发送已恢复 (resolved) 的通知邮件
send_resolved: true
将上述内容保存到 values-alert.yaml,然后使用 Helm 更新(在线安装或离线安装根据实际情况调整命令):
# 如果是离线安装方式,请将 prometheus-community/kube-prometheus-stack 替换为本地的 chart 目录(例如:.)
helm upgrade prometheus-stack prometheus-community/kube-prometheus-stack -n monitoring \
--reuse-values \
-f values-alert.yaml
注意: 如果你之前使用 --set 参数(例如开启了 Ingress 或 NodePort)安装了 Helm release,在执行 helm upgrade 时一定要加上 --reuse-values 参数,否则之前配置的那些 --set 参数(包括 Ingress 配置)都会被覆盖丢失!
5.1.1 检查配置是否生效
执行完更新命令后,可以通过以下几种方式验证 Alertmanager 是否成功加载了最新的邮件配置:
方式一:通过 Alertmanager Web UI 查看 (推荐)
- 确保已经通过端口转发或 NodePort 暴露了 Alertmanager 服务(参考 4.3 章节)。
- 在浏览器中访问 Alertmanager 面板(如
http://<机器IP>:9093)。 - 点击顶部导航栏的 Status。
- 在 Config 区块中,你可以直接看到当前 Alertmanager 正在运行的配置文件内容,检查是否包含你刚刚添加的邮箱配置。
方式二:通过 kubectl 查看集群中的 Secret
Alertmanager 的配置最终会被 Helm 渲染并存储为一个 Secret,你可以直接解密查看该 Secret 的内容:
kubectl get secret alertmanager-prometheus-stack-kube-prom-alertmanager -n monitoring -o jsonpath="{.data.alertmanager\.yaml}" | base64 --decode
方式三:查看 Alertmanager Pod 日志
检查 Alertmanager 的日志,确认其成功启动或加载了配置,且没有报错信息:
kubectl logs -l app.kubernetes.io/name=alertmanager -n monitoring -c alertmanager
(注:新版本的 Prometheus Operator 会通过独立的 config-reloader sidecar 容器来处理配置更新,主容器 alertmanager 的日志中可能不会出现 reload 关键字,只要没有 Error 即代表正常运行)
5.1.2 验证邮件发送功能 (发送测试告警)
配置更新并生效后,可以通过向 Alertmanager 的 API 发送一条模拟告警来验证邮件是否能成功接收。
打开终端,使用 curl 命令发送一条级别为 warning 的模拟告警(由于配置中已将报警级别门槛设置为 warning 及以上,带有 warning 或 critical 标签均可触发)。
注意: 请根据你在 4.3 章节中选择的 Alertmanager 暴露方式,将下面命令末尾的 URL 替换为实际地址:
- 如果配置了 Ingress:使用
http://alertmanager.aioil.top/api/v2/alerts - 如果配置了 NodePort:使用
http://<任意Node-IP>:32093/api/v2/alerts - 如果使用 Port-Forward:使用
http://localhost:9093/api/v2/alerts
curl -H "Content-Type: application/json" -d '[
{
"labels": {
"alertname": "TestEmailAlert",
"severity": "warning"
},
"annotations": {
"summary": "这是一条测试邮件告警",
"description": "用于验证 Alertmanager 的邮件发送功能是否配置成功。"
}
}
]' <请替换为你的 Alertmanager 实际地址>/api/v2/alerts
(注:执行成功后通常没有任何文本输出,这是正常的)
稍等片刻,登录你的接收邮箱,检查是否成功收到了标题包含 TestEmailAlert 的告警邮件。
关于重复发送告警的限制:
repeat_interval: 12h:如果同一个告警(比如上面你刚刚发的那条TestEmailAlert)一直处于未恢复(firing)状态,Alertmanager 会等待 12 小时后才重新发送一次邮件,以防止邮件轰炸。如果你想多次测试同一条告警,可以临时修改curl命令中alertname的值(例如改为TestEmailAlert2),或者在发送info级别测试邮件后,再发一条包含"endsAt": "2023-10-25T12:00:00Z"的解除告警,之后就能再次发送了。
5.1.3 如何通过日志排查邮件发送失败问题
如果你在邮箱中一直没有收到邮件,可以通过查看 Alertmanager 的日志来定位问题。
- 查看 Alertmanager 实时日志:
kubectl logs -f -l app.kubernetes.io/name=alertmanager -n monitoring -c alertmanager
(注:默认情况下,Alertmanager 日志级别为 info。因为生产环境中告警较多,“没有消息就是好消息”,邮件发送成功时控制台通常没有任何日志输出,只有发送失败或重载配置时才会打印。如果你想查看详细的发送成功日志,可以在 helm upgrade 时增加 --set alertmanager.alertmanagerSpec.logLevel=debug 参数来开启 Debug 模式)
- 常见错误及排查思路:
- 如果日志中出现
AuthError、535 Login Fail或authorization failed:说明smtp_auth_password(授权码) 填写错误,或者邮箱的 SMTP/POP3 服务未开启。 - 如果日志中出现
connection refused或timeout:说明 Kubernetes 集群网络无法连接到smtp.qq.com:465,请检查服务器网络或防火墙策略。 - 如果日志中出现
certificate signed by unknown authority等 TLS 报错:可以检查配置中smtp_require_tls: false是否生效,或者尝试将端口改为465(SSL) 或587(TLS)。
5.1.4 Alertmanager 面板 Silence (静默) 功能说明
在 Alertmanager 的 Web UI 告警列表中,每条告警旁边都有一个 Silence(静默)按钮。
- 作用:当集群出现已知故障或正在进行停机维护时,你可以点击
Silence按钮,通过标签匹配(如指定alertname="Watchdog")并设置一个时间段(例如 2 小时)。 - 常见报错 (
Silence is not yet valid):如果你在提交 Silence 时遇到Could not submit the form, Silence is not yet valid,这不是代表没报警了,而是因为你设置的 Start 时间 (生效时间) 晚于当前服务器的真实时间。由于浏览器时间和服务器时间可能存在几十秒到几分钟的误差,或者时区不一致,导致你提交的时间被判定为“未来的时间”。- 解决办法:在创建 Silence 表单时,将
Start(开始时间) 手动往前调 1-2 分钟,然后再点击提交即可。
- 解决办法:在创建 Silence 表单时,将
- 效果:在这个时间段内,即使 Prometheus 不断触发这条告警发送给 Alertmanager,Alertmanager 也不会将它转发给接收者(不会发邮件/钉钉/飞书等)。
- 使用场景:非常适合在日常系统维护发布、或者处理已知长时间故障时,防止持续收到骚扰邮件。静默期结束后,如果告警仍然存在,则会恢复发送。
5.2 配置钉钉和飞书报警 (需借助 Webhook 转发)
由于 Alertmanager 原生不支持钉钉和飞书,我们通常需要部署一个 Webhook 转换器(例如开源的 PrometheusAlert),将 Alertmanager 的 Webhook 请求转换为钉钉或飞书支持的 API 请求格式。
步骤 1:部署 PrometheusAlert(支持钉钉、飞书、企业微信等)
创建一个简单的 PrometheusAlert 部署文件 prometheusalert.yaml,并附带 Ingress 以便外部访问:
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheusalert
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: prometheusalert
template:
metadata:
labels:
app: prometheusalert
spec:
containers:
- name: prometheusalert
image: feiyu563/prometheus-alert:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: prometheusalert
namespace: monitoring
spec:
selector:
app: prometheusalert
ports:
- port: 8080
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheusalert-ingress
namespace: monitoring
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: higress
tls:
- hosts:
- prometheusalert.aioil.top
secretName: prometheusalert-tls
rules:
- host: prometheusalert.aioil.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheusalert
port:
number: 8080
执行部署:
kubectl apply -f prometheusalert.yaml
部署完成后,你可以通过配置的域名访问其管理后台进行测试和模板配置:
- 访问地址:
https://prometheusalert.aioil.top - 默认用户名:
prometheusalert - 默认密码:
prometheusalert
验证 TLS 证书是否正常签发
由于 Ingress 配置了 cert-manager.io/cluster-issuer 注解,部署后 cert-manager 会自动为 prometheusalert.aioil.top 申请证书。可通过以下命令确认证书状态:
# 1. 查看 Ingress 是否正确关联了 Higress
kubectl describe ingress prometheusalert-ingress -n monitoring
# 确认:Ingress Class 为 higress,且 TLS 证书 secretName 为 prometheusalert-tls
# 2. 查看 Certificate 资源状态(cert-manager 会自动创建 Certificate 资源)
kubectl get certificate -n monitoring | grep prometheusalert
# 正常情况下 STATE 应显示 Ready=True。如果卡在 Pending,往下逐级排查:
# Certificate → CertificateRequest → Order → Challenge
# 3. 查看证书详情(含到期时间和续期计划)
kubectl describe certificate prometheusalert-tls -n monitoring
# 关键字段:
# - Not After: 证书过期时间
# - Not Before: 证书生效时间
# - Renewal Time: 计划续期时间(通常在过期前 30 天)
# - Status.Conditions 中 Ready=True 代表签发成功
# 4. 查看证书 Secret 是否包含 tls.crt 和 tls.key
kubectl get secret prometheusalert-tls -n monitoring
# 正常应显示 TYPE 为 kubernetes.io/tls,DATA 为 2(tls.crt + tls.key)
# 5. 如果证书一直未 Ready,逐级排查签发流程
kubectl get certificaterequest -n monitoring | grep prometheusalert
kubectl get order -n monitoring | grep prometheusalert
kubectl get challenge -n monitoring | grep prometheusalert
# 通过 kubectl describe 对应资源可查看具体失败原因(如 DNS 记录未生效、Webhook 凭证错误等)
# 6. 验证 HTTPS 访问
curl -v https://prometheusalert.aioil.top
# 确认输出中 TLS 握手成功,且证书 CN/SAN 匹配 prometheusalert.aioil.top
故障排查提示:
- 如果 Certificate 一直处于 Pending 状态,通常是因为 DNS-01 挑战未完成。可查看 alidns-webhook 日志:
kubectl logs -f -n cert-manager deploy/alidns-webhook --tail=100- 如果 cert-manager Controller 未能识别 Ingress annotation,检查 ClusterIssuer
letsencrypt-prod-dns是否已创建且状态为 Ready:kubectl get clusterissuer letsencrypt-prod-dns
步骤 2:配置 Alertmanager 发送 Webhook
修改 values-alert.yaml 中的 Alertmanager 配置,将告警发送给 PrometheusAlert 的 Service 地址:
alertmanager:
config:
global:
resolve_timeout: 5m
route:
# 将告警按照 alertname 进行分组
group_by: ['alertname']
# 当产生一个新分组的告警时,等待 10s 以收集同组的其他告警,然后一起发送(避免告警轰炸)
group_wait: 10s
# 当第一个告警发送后,如果该组又产生了新的告警,需等待 10s 后再将新告警合并发送
group_interval: 10s
# 注意:Alertmanager 原生不支持“阶梯式/递增式频率重发”(如前3次每60秒发一次,之后每1小时发一次)。
# 它的重发频率是固定的,由 repeat_interval 决定(如 1h 代表永远是每隔 1 小时发一次)。
# 如果有递增报警频率的复杂需求,必须借助外部的告警中心系统(如 夜莺 Nightingale、PrometheusAlert 深度定制开发、或自建 Webhook 服务)来实现。
repeat_interval: 1h
# 默认的接收者。如果没有匹配到下面 routes 里的规则,告警就会发给这个接收者。
# 这里的名字必须和最下方 receivers 列表中的 name 保持一致。
receiver: 'prometheusalert-webhook'
routes:
- receiver: 'prometheusalert-webhook'
matchers:
- severity=~"warning|critical"
receivers:
- name: 'prometheusalert-webhook'
webhook_configs:
# 钉钉报警配置示例 (注意替换 ddurl 为你的钉钉群机器人 Webhook 地址)
- url: 'http://prometheusalert.monitoring.svc.cluster.local:8080/prometheusalert?type=dd&tpl=prometheus-dd&ddurl=https://oapi.dingtalk.com/robot/send?access_token=9de0877c213ac09b09f562951b1860070f2a6b5af87f585b3d86b8a2f61e3dbf'
send_resolved: true
# 飞书报警配置示例 (注意替换 fsurl 为你的飞书群机器人 Webhook 地址)
# - url: 'http://prometheusalert.monitoring.svc.cluster.local:8080/prometheusalert?type=fs&tpl=prometheus-fs&fsurl=https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_FEISHU_TOKEN'
# send_resolved: true
说明:
url参数中的type=dd代表钉钉,type=fs代表飞书。tpl为在 PrometheusAlert 中内置的报警内容格式模板。ddurl和fsurl分别为钉钉和飞书机器人的 Webhook 地址。
保存后再次更新 Helm Release:
# 如果是离线安装方式,请将 prometheus-community/kube-prometheus-stack 替换为本地的 chart 目录(例如:.)
helm upgrade prometheus-stack prometheus-community/kube-prometheus-stack -n monitoring \
--reuse-values \
-f values-alert.yaml
步骤 3:验证钉钉/飞书发送功能 (发送测试告警)
和前面测试邮件类似,我们可以向 Alertmanager 发送一条告警来验证 Webhook 是否能成功把消息推送到你的钉钉/飞书群。
打开终端,执行以下 curl 命令(发送 warning 级别告警触发我们刚配置的路由)。同样地,请根据你的 Alertmanager 部署方式替换 URL 地址:
curl -H "Content-Type: application/json" -d '[
{
"labels": {
"alertname": "TestWebhookAlert",
"severity": "warning"
},
"annotations": {
"summary": "这是一条测试 Webhook 告警",
"description": "用于验证 Alertmanager 通过 PrometheusAlert 转发给钉钉/飞书的功能是否配置成功。"
}
}
]' <请替换为你的 Alertmanager 实际地址>/api/v2/alerts
验证方法:
- 查看群消息:稍等片刻(大约 10 秒的
group_wait时间),看看你的钉钉/飞书群是否收到了对应的机器人消息卡片。 - 排查错误:如果没有收到,可以通过查看
PrometheusAlert的日志来排查原因:
注:如果日志中提示kubectl logs -f -l app=prometheusalert -n monitoringtoken is invalid或类似报错,请检查你在values-alert.yaml中配置的 Webhook URL 是否准确,以及钉钉机器人的安全设置(如加签、关键字等)是否匹配。
6. 常见告警规则说明与修改
Prometheus 的告警状态分为三种:
- Inactive (未激活):正常状态,未触发报警。
- Pending (待触发):监控数据已满足报警条件,但尚未达到规则中配置的持续时间阈值(例如
for: 15m)。这是一种缓冲机制,用于防止短暂的网络抖动或服务重启引发误报。 - Firing (已触发):满足报警条件且持续时间超过了阈值,此时 Alertmanager 会向外发送报警通知(如邮件、钉钉等)。
如何查看和修改告警的 Pending 持续时间阈值?
告警的触发阈值是由 PrometheusRule 资源定义的。如果你觉得某个告警(比如 KubeDaemonSetRolloutStuck)反应太慢(默认需要等 15 分钟才报警),或者反应太快(稍微抖动就报警),你可以通过以下方式修改它:
-
查找对应的 PrometheusRule 资源
使用命令搜索包含特定告警规则名称的资源:kubectl get prometheusrules -n monitoring -
编辑告警规则
找到对应的规则名称后(例如prometheus-stack-kube-prom-kubernetes-apps),执行编辑命令:kubectl edit prometheusrules prometheus-stack-kube-prom-kubernetes-apps -n monitoring -
修改
for字段的值
在打开的 YAML 文件中,找到你需要修改的告警规则(例如alert: KubeDaemonSetRolloutStuck),修改其下方的for字段。
例如,将 15 分钟(15m)改为 5 分钟(5m):- alert: KubeDaemonSetRolloutStuck annotations: description: DaemonSet {{ $labels.namespace }}/{{ $labels.daemonset }} has not finished or progressed for at least 15m on cluster {{ $labels.cluster }}. runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedaemonsetrolloutstuck summary: DaemonSet rollout is stuck. expr: |- # ... (此处省略复杂的 PromQL 表达式) ... for: 5m # <--- 将这里的 15m 修改为你期望的 Pending 时间阈值 labels: severity: warning -
保存并退出
保存文件后,Prometheus Operator 会自动检测到规则变化,并热重载 Prometheus 配置,新的时间阈值将立即生效。
7. 自定义告警配置指南 (以 Pod 异常为例)
在 kube-prometheus-stack 体系中,配置告警主要有两种方式:
- 基于 Kubernetes CRD (
PrometheusRule) 配置 (官方推荐) - 在 Grafana UI 中配置 (Grafana Managed Alerts)
💡 架构建议:强烈推荐通过 Alertmanager 统一发送告警
无论你是通过 YAML 还是在 Grafana 中配置告警规则,我们都强烈建议将告警路由给底层的 Alertmanager 处理(即前面配置的 PrometheusAlert + 钉钉),而不是让 Grafana 自身直接去发钉钉。
原因如下:
- 统一的告警收口:集群内置的告警(如节点宕机、API Server 异常等)都是由 Alertmanager 发送的。如果自定义告警用 Grafana 发,会导致告警渠道割裂,难以统一管理(比如统一静默、统一修改接收人)。
- 强大的去重与分组 (Grouping):Alertmanager 拥有强大的路由和分组能力,能把瞬间产生的几百个同类告警合并成一条发送,避免“告警风暴”把钉钉群淹没。而 Grafana 自身的通知机制在这方面较弱。
- 配置解耦:Grafana 专注负责“可视化”和“数据评估”,Alertmanager 专注负责“消息分发”,职责清晰。
7.1 方式一:使用 PrometheusRule CRD 配置 (推荐)
这是最符合云原生(GitOps)理念的做法,规则作为代码持久化在 Kubernetes 中,Pod 重启不会丢失。
1. 编写规则文件 custom-pod-alert.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: custom-pod-alerts
namespace: monitoring
labels:
# 关键:此 Label 必须与 helm 部署时的 release name 一致,Operator 才会热加载
release: prometheus-stack
spec:
groups:
- name: custom.pod.rules
rules:
- alert: CustomPodAbnormal
# PromQL: 筛选出非 Running/Succeeded 状态的异常 Pod
expr: kube_pod_status_phase{phase=~"Failed|Unknown|Pending"} == 1
# Pending 缓冲期:持续 3 分钟才触发,防止网络抖动导致的误报
for: 3m
labels:
severity: warning
annotations:
summary: "发现异常 Pod: {{ $labels.namespace }}/{{ $labels.pod }}"
description: "Pod {{ $labels.pod }} 处于 {{ $labels.phase }} 状态已超过 3 分钟,请及时排查。"
2. 应用到集群
kubectl apply -f custom-pod-alert.yaml
应用后无需重启,Prometheus Operator 会自动热加载。只要包含了 severity: warning 等标签,触发后 Alertmanager 就会根据我们之前配置的路由规则自动发送到钉钉。
7.2 方式二:在 Grafana UI 中配置
如果你更习惯图形化操作,可以通过 Grafana 的统一告警界面进行配置。
(注意:请确保 Helm values.yaml 中已开启 grafana.persistence.enabled=true,否则重启后规则会丢失)
操作步骤:
- 新建规则: 登录 Grafana -> 左侧菜单
Alerting->Alert rules-> 点击+ New alert rule。- Rule name (步骤 1): 在最上方填入告警名称,如
Pod状态异常报警。
- Rule name (步骤 1): 在最上方填入告警名称,如
- 定义查询 (Define query and condition):
- 切换到 Code 模式,选择数据源为 Prometheus。
- 输入查询语句:
kube_pod_status_phase{phase=~"Failed|Unknown|Pending"} == 1 - Alert condition (告警条件) 保持默认:
WHEN QUERY IS ABOVE 0。
- 添加文件夹和标签 (Add folder and labels):
- Folder: 点击
+ New folder新建一个文件夹(如K8s-Alerts)用于归类保存该规则。 - Labels (极其重要): 点击
+ Add labels。这里必须添加一个与你 Alertmanager 路由匹配的标签,否则告警发不出去!例如添加severity=warning。
- Folder: 点击
- 设置评估行为 (Set evaluation behavior):
- Evaluation group (评估组): 点击
+ New evaluation group新建一个评估组。- 名字建议:建议以“时间间隔+业务类别”命名,例如
1m-k8s-core或1m-eval-group。 - 作用:它决定了 Grafana 多久去查一次数据。放在同一个组里的规则,会按照相同的频率(如
1m每分钟一次)依次执行,这样可以避免瞬间并发查询压垮数据库。
- 名字建议:建议以“时间间隔+业务类别”命名,例如
- Pending period (挂起时间): 设为
3m。表示发现异常后,观察 3 分钟,如果依然异常才真正触发告警,可有效防止短暂的网络抖动或 Pod 正常重启导致的误报。 - Keep firing for (保持触发状态时长): 保持默认的
None (0s)。如果遇到频繁的“恢复-告警”抖动,可将其调大(如5m),表示恢复后依然保持告警状态 5 分钟,确认彻底稳定后再发恢复通知。 - Configure no data and error handling (配置无数据和错误处理):
- Alert state if no data or all values are null: 【非常关键】必须将默认的
No Data修改为OK(或 Normal)。因为当所有 Pod 都正常时,PromQL 是查不到异常数据的,如果保持 No Data 会导致误报! - Alert state if execution error or timeout: 保持默认的
Error即可。 - Missing series evaluations to resolve (序列丢失自动恢复): 保持默认的
2即可。意思是如果某个异常的 Pod 被直接删除了(数据彻底消失),Grafana 在连续 2 次查询不到该 Pod 的数据后,会自动将该告警标记为已恢复 (Resolved)。
- Alert state if no data or all values are null: 【非常关键】必须将默认的
- Evaluation group (评估组): 点击
- 配置通知 (Configure notifications):
- Contact point (联系点): 决定将告警发送到哪里。
- 推荐方式一:留空/转交 Alertmanager(统一收口)
- 强烈建议留空或选择指向 Alertmanager 的通道,让 Grafana 将触发的告警转交给外置的 Alertmanager 处理。
- 注意:较新版本的 Grafana 可能不会显示名为 “Alertmanager” 的默认 Contact Point,而是显示一个名为
empty(或者由 Helm 注入的grafana-default-email等)的联系点,并提示 “No integrations configured”。 - 如何手动添加 Alertmanager 通道(排障方案)? 如果你在 Alertmanager 界面中始终收不到告警,说明默认的通道可能未生效。此时你需要手动添加它:
- 在 Grafana 左侧菜单进入 Alerting -> Contact points。
- 点击 + Add contact point。
- Name: 填入
My-Alertmanager。 - Integration: 下拉选择
Alertmanager。 - URL: 填入你集群中 Alertmanager 内部 Service 地址,例如
http://alertmanager-operated.monitoring.svc:9093。 - 保存后,回到告警规则编辑页,将 Contact point 明确选择为
My-Alertmanager。
- 方式二:直接在 Grafana 中配置钉钉 (ActionCard 格式)
- 如果你不想经过 Alertmanager,可以直接让 Grafana 发送钉钉:
- 在 Contact points 中新建,Name 填入
DingDing-Alerts。 - Integration 选择
DingDing。 - URL 填入钉钉机器人的 Webhook 地址。
- 展开 Optional DingDing settings,将 Message Type 改为
ActionCard(支持 Markdown 渲染)。 - Title 建议填入:
{{ if eq .Status "firing" }}🔥 发生告警{{ else }}✅ 告警恢复{{ end }}: {{ .CommonLabels.alertname }} - Message 建议填入:
**告警状态**: {{ .Status }} **告警摘要**: {{ .CommonAnnotations.summary }} **详细描述**: {{ .CommonAnnotations.description }} **告警详情**: {{ range .Alerts -}} * 实例: {{ .Labels.instance }} * 命名空间: {{ .Labels.namespace }} * 触发时间: {{ .StartsAt.Local.Format "2006-01-02 15:04:05" }} {{ end }} - (重要)如果在钉钉配置了“加签”,需在下方找到并填入 Secret。保存并在规则中选用该通道。
- 在 Contact points 中新建,Name 填入
- 如果你不想经过 Alertmanager,可以直接让 Grafana 发送钉钉:
- 方式三:同时发送给钉钉和 Alertmanager (多重路由)
- 如果你希望告警既发送给 Alertmanager (走邮件流程) 又直接通过 Grafana 发给钉钉,你需要创建一个复合通道:
- 在 Contact points 页面点击
+ New contact point。 - Name: 填入
DingDing-AND-Alertmanager。 - Integration: 第一项选择
Alertmanager并填好内部 Service URL。 - 向下滚动,点击
+ Add contact point integration添加第二个集成。 - 在新出现的配置块中,选择
DingDing,并按照“方式二”中的说明填好 Webhook、Title 和 Message。 - 保存该 Contact point,并在你的告警规则的步骤 5 中选择它。这样 Grafana 触发告警时就会并行发送给这两处。
- 在 Contact points 页面点击
- 如果你希望告警既发送给 Alertmanager (走邮件流程) 又直接通过 Grafana 发给钉钉,你需要创建一个复合通道:
- 推荐方式一:留空/转交 Alertmanager(统一收口)
- Muting, grouping and timings (静默、分组和时间控制 - 进阶选项): 展开后可以对告警发送频率进行精细控制(通常保持默认即可,若有特殊需求可参考下方说明):
- Mute / Active timings (静默/活跃时间): 用于设置在哪些特定时间段“绝对不发”或“只在此时段发”报警。适用于固定维护窗口或仅需在工作时间监控的边缘业务。
- 注:这里只能下拉选择预先定义好的时间范围。如果你需要新建一个时间范围,请前往 Grafana 左侧菜单的 Alerting -> Notification configuration -> Time intervals 中进行创建。
- Override grouping (覆盖分组): 决定发生大面积故障时,告警如何合并打包发送。保持关闭(默认按文件夹和告警名分组)已足够合理。
- Override timings (覆盖时间控制): 决定告警的发送频率。开启后可修改三个核心参数:
Group wait (组等待): 发现第一个告警后,等多久才发(默认 30s,用于收集同期其他告警)。Group interval (组间隔): 上波告警发完,如果有新告警,等多久再发(默认 5m)。Repeat interval (重发间隔): 【最常用】如果故障一直没修好,多久重新提醒你一次?默认是 4h,如果觉得太久,可以开启此项并修改为1h或30m。
- Mute / Active timings (静默/活跃时间): 用于设置在哪些特定时间段“绝对不发”或“只在此时段发”报警。适用于固定维护窗口或仅需在工作时间监控的边缘业务。
- Contact point (联系点): 决定将告警发送到哪里。
- 配置告警消息 (Configure notification message):
- Summary:
发现异常 Pod: {{ $labels.namespace }}/{{ $labels.pod }} - Description:
Pod {{ $labels.pod }} 处于 {{ $labels.phase }} 状态已超过 3 分钟,请及时排查。 - Runbook URL (可选): 填入你们内部的故障处理文档链接。
- Link dashboard and panel (可选): 绑定一个相关的监控大屏,报警时可直接点击跳转查看图表。
- Summary:
最后,点击右上角的 Save rule and exit 即可完成配置。
8. 在 Alertmanager 中查看与管理告警
无论告警是通过 PrometheusRule (YAML) 还是 Grafana UI 配置产生的,只要它最终被路由到了 Alertmanager,你就可以在 Alertmanager 的原生界面中集中查看和管理它们。
8.1 访问 Alertmanager 界面
请参考文档 4.3 访问 Alertmanager 报警面板 章节。通常你可以通过以下方式访问:
- 如果配置了 Ingress:访问
http://alertmanager.aioil.top - 如果配置了 NodePort:访问
http://<NodeIP>:32093 - 如果临时使用端口转发:访问
http://localhost:9093
8.2 查看正在触发的告警 (Alerts)
登录 Alertmanager 界面后,默认首页即为 Alerts 页面:
- 查看告警列表:这里会展示当前集群中所有处于
Firing(触发中) 状态的告警。 - 按标签筛选:你可以在顶部的搜索框中输入
severity="warning"或alertname="Pod状态异常报警"来过滤特定的告警。 - 查看告警详情:点击任意一条告警前面的
+号展开,你可以看到这条告警携带的所有 Labels(如 namespace、pod 名称)和 Annotations(如 summary 描述信息)。 - 查看告警来源:点击告警详情底部的
Source链接,可以直接跳转回 Prometheus 或 Grafana 中触发该告警的原始图表或规则页面。
8.3 告警静默管理 (Silences)
如果你在 Alerts 页面发现了一些“已知故障”(比如某个节点正在进行计划内重启,导致疯狂报警),你可以直接在 Alertmanager 中对它们进行“静默”处理。
操作步骤:
- 在正在触发的告警卡片右上角,点击
Silence按钮。 - 界面会自动跳转到新建静默规则页面,并且已经帮你填好了匹配这条告警的 Labels。
- Start / End:选择静默开始和结束的时间。
(⚠️ 注意:如果你发现无法提交,提示Silence is not yet valid,请手动把 Start 时间往前调 1-2 分钟,这是由于浏览器和服务器时间差导致的常见问题) - Creator:填入你的名字。
- Comment:填入静默原因,例如
“正在对 node-01 进行升级维护,预计 2 小时后恢复”。 - 点击
Create。
在静默期间,Alertmanager 虽然仍然会收到这条告警,但不会再通过钉钉/邮件发送通知。静默期结束后,如果故障依然存在,通知会自动恢复发送。
9. 彻底卸载清理
更多推荐


所有评论(0)