AI Infra 训练营
总览
  • 总览
  • 完整安装
  • 核心 K8s
  • Cilium 网络
  • Longhorn 存储
  • 监控日志
  • CI / GitOps
  • 安全准入
  • CI/CD 实战(MySQL+Go+Vue)
  • HPA/Ingress/Hubble 实战
  • 面试速查 + 真实踩坑
  • Day 0 · 新手接管 Runbook
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
命令手册
HiHuo 主站
GitHub
总览
  • 总览
  • 完整安装
  • 核心 K8s
  • Cilium 网络
  • Longhorn 存储
  • 监控日志
  • CI / GitOps
  • 安全准入
  • CI/CD 实战(MySQL+Go+Vue)
  • HPA/Ingress/Hubble 实战
  • 面试速查 + 真实踩坑
  • Day 0 · 新手接管 Runbook
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
命令手册
HiHuo 主站
GitHub
  • 实操 Runbook

    • Runbook 总览:从零部署、查看、调试
    • 完整安装总 Runbook:5 台 Ubuntu 到可用平台
    • 核心 K8s Runbook:apiserver / etcd / kubelet / containerd / HAProxy
    • Cilium 网络 Runbook:安装、查看、调试
    • Longhorn 存储 Runbook:安装、查看、调试
    • 监控日志 Runbook:Prometheus / Grafana / Loki / Alertmanager
    • CI / GitOps Runbook:Harbor / Gitea / Jenkins / Kaniko / ArgoCD
    • 安全准入 Runbook:RBAC / PSA / Kyverno / ResourceQuota
    • 实战 Runbook:MySQL + Go + Vue 全链路 CI/CD 真实发布
    • 实战 Runbook:给应用加 HPA 自动扩缩 + Ingress 域名 + Hubble 流量观测
    • 面试速查:这套平台 + 高频问答 + 真实踩坑

监控日志 Runbook:Prometheus / Grafana / Loki / Alertmanager

这篇讲监控和日志怎么装、怎么看、怎么排障。


1. 组件作用

组件作用
Prometheus拉取和存储指标,比如 CPU、内存、Pod 状态
Grafana展示指标和日志,看 dashboard
Alertmanager接收 Prometheus 告警,做分组、静默、通知
kube-state-metrics把 K8s 对象状态转成指标
node-exporter采集节点 CPU、内存、磁盘、网络
Loki存日志
Promtail每个节点采集 Pod 日志发给 Loki

为什么用 kube-prometheus-stack:它一次性安装 Prometheus Operator、Prometheus、Grafana、Alertmanager、ServiceMonitor CRD 和默认 dashboard,学习和生产都常见。


2. 安装 kube-prometheus-stack

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install kps prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace \
  --version 85.3.3 \
  --set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName=longhorn \
  --set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=10Gi \
  --set prometheus.service.type=NodePort \
  --set prometheus.service.nodePort=30090 \
  --set grafana.service.type=NodePort \
  --set grafana.service.nodePort=32380 \
  --set grafana.persistence.enabled=true \
  --set grafana.persistence.storageClassName=longhorn \
  --set grafana.persistence.size=2Gi \
  --set grafana.deploymentStrategy.type=Recreate \
  --set grafana.adminPassword=bootcamp \
  --set 'prometheus.prometheusSpec.tolerations[0].operator=Exists' \
  --set 'grafana.tolerations[0].operator=Exists'

为什么 grafana.deploymentStrategy.type=Recreate:Grafana 单副本挂 Longhorn RWO PVC,默认 RollingUpdate 会让新旧 Pod 抢同一个卷,出现 Multi-Attach。

前置依赖:这一步重度依赖前两步。①Longhorn 要能制备 PVC(Prometheus 10Gi + Grafana 2Gi);②Cilium MTU 必须已修对(见 Cilium 2.5 节),否则 Prometheus 跨节点抓取大量指标、写 TSDB 时会零星超时——又是"小请求通、大请求挂"的 MTU 症状。

chart 版本 85.3.3 对应 app(Prometheus Operator)v0.90.1。装前可 helm search repo prometheus-community/kube-prometheus-stack --versions | head 确认版本仍在。

真实输出(装好后):

$ kubectl get pvc -n monitoring
NAME              STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS
kps-grafana       Bound    pvc-4646..   2Gi        RWO            longhorn      ← 存储真的制备了
prometheus-...-0  Bound    pvc-d817..   10Gi       RWO            longhorn

$ kubectl get pods -n monitoring
alertmanager-...-0                    2/2   Running
kps-grafana-...                       3/3   Running    ← 见下方说明
kps-kube-prometheus-stack-operator-…  1/1   Running
kps-kube-state-metrics-…              1/1   Running
kps-prometheus-node-exporter-… ×5     1/1   Running    ← 每节点一个 (DaemonSet)
prometheus-...-0                      2/2   Running

⚠️ Grafana 启动时会短暂停在 2/3 Running(实测,正常)。3 个容器里 grafana 主容器首次启动要在 PVC 上初始化 SQLite、跑一大串 DB migration(日志全是 Migration successfully executed),几十秒后才 ready。grafana-sc-dashboard / grafana-sc-datasources 两个 sidecar 早就 ready。看到 2/3 别急,kubectl logs ... -c grafana 在刷 migration 就是在正常初始化。


3. 安装 Loki + Promtail

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

helm install loki grafana/loki-stack \
  --namespace monitoring \
  --set grafana.enabled=false \
  --set grafana.sidecar.datasources.enabled=false \
  --set prometheus.enabled=false \
  --set loki.enabled=true \
  --set loki.isDefault=false \
  --set loki.persistence.enabled=true \
  --set loki.persistence.storageClassName=longhorn \
  --set loki.persistence.size=5Gi \
  --set promtail.enabled=true \
  --set 'loki.tolerations[0].operator=Exists' \
  --set 'promtail.tolerations[0].operator=Exists'

自己创建 Grafana datasource:

cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: loki-datasource
  namespace: monitoring
  labels:
    grafana_datasource: "1"
data:
  loki-datasource.yaml: |
    apiVersion: 1
    datasources:
    - name: Loki
      type: loki
      access: proxy
      url: http://loki:3100
      isDefault: false
EOF

为什么关闭 loki-stack 自动 datasource:kube-prometheus-stack 已经把 Prometheus 设为默认 datasource。如果 Loki chart 也生成 isDefault: true,Grafana 会 CrashLoop。


4. 查看状态

helm list -n monitoring

kubectl get pods -n monitoring -o wide
kubectl get pvc -n monitoring
kubectl get svc -n monitoring

kubectl get prometheus,alertmanager,servicemonitor,prometheusrule -A

入口:

Grafana:    http://154.201.73.31:32380
Prometheus: http://154.201.73.31:30090

Grafana 默认账号:

kubectl get secret -n monitoring kps-grafana \
  -o jsonpath='{.data.admin-user}' | base64 -d; echo

kubectl get secret -n monitoring kps-grafana \
  -o jsonpath='{.data.admin-password}' | base64 -d; echo

(本集群装时用 --set grafana.adminPassword=bootcamp,所以账号 admin / 密码 bootcamp。)

确认数据源没冲突(Loki 装好后必查):

G=$(kubectl get pods -n monitoring -l app.kubernetes.io/name=grafana --no-headers | awk '{print $1}')
kubectl exec -n monitoring $G -c grafana -- \
  curl -sS -u admin:bootcamp http://localhost:3000/api/datasources | jq '.[]|{name,type,isDefault}'

真实输出(正确状态):

{ "name":"Prometheus",   "type":"prometheus",   "isDefault":true  }   ← 唯一默认
{ "name":"Loki",         "type":"loki",         "isDefault":false }
{ "name":"Alertmanager", "type":"alertmanager", "isDefault":false }

✅ 关键:只有 Prometheus 是 isDefault:true。这正是 3 节关掉 loki-stack 自动 datasource 的目的——两个默认源会让 Grafana CrashLoop(见 6.1)。


5. Prometheus 验收

PROM=$(kubectl get svc -n monitoring kps-kube-prometheus-stack-prometheus -o jsonpath='{.spec.clusterIP}')

curl -sS "http://$PROM:9090/-/ready"
curl -sS "http://$PROM:9090/api/v1/query?query=up" | jq '.status'
curl -sS "http://$PROM:9090/api/v1/query?query=count(up==1)" | jq '.data.result'

真实输出(本集群):

Prometheus Server is Ready.
count(up==1) = 32                      ← 32 个健康抓取目标

# 各 job 抓到几个 target(按 up 指标聚合):
  3 apiserver                3 kube-controller-manager
  2 coredns                  3 kube-scheduler
  5 kube-proxy               3 kube-etcd
 15 kubelet (5节点×3端点)     5 node-exporter
  1 kube-state-metrics       + grafana/alertmanager/operator/prometheus 自监控

逐项看什么(新手判断"监控是否真的全"):

job期望数含义
apiserver33 个控制面的 apiserver 都被抓
kube-etcd / kube-scheduler / kube-controller-manager各 3控制面核心组件指标都采到了(这几个最容易因 bind 地址漏采,能到 3 说明 kubeadm 暴露正常)
kubelet节点数×3每节点 3 个 metrics 端点(kubelet / cadvisor / probes)
node-exporter=节点数每节点一个,采机器级 CPU/内存/磁盘
kube-proxy=节点数5

如果 etcd / scheduler / controller-manager 的 up 是 0,多半是它们的 metrics 只 bind 在 127.0.0.1。kubeadm v1.30 默认 bind 0.0.0.0,本集群直接能抓到,无需额外改。

看 targets:

kubectl port-forward -n monitoring svc/kps-kube-prometheus-stack-prometheus 9090:9090

浏览器打开:

http://127.0.0.1:9090/targets

6. Grafana 常见故障

6.1 datasource 默认值冲突

日志:

kubectl logs -n monitoring -l app.kubernetes.io/name=grafana -c grafana --tail=100

如果看到:

Only one datasource per organization can be marked as default

检查:

kubectl get configmap -n monitoring -l grafana_datasource=1 -o yaml \
  | grep -n "name:\|isDefault"

处理原则:

  • Prometheus 保持 isDefault: true。
  • Loki 必须是 isDefault: false。
  • 不要让 loki-stack 自动生成第二个默认 datasource。

6.2 Grafana Multi-Attach

kubectl describe pod -n monitoring -l app.kubernetes.io/name=grafana
kubectl get volumeattachments.storage.k8s.io | grep grafana || true
kubectl get pvc -n monitoring kps-grafana

固定值:

helm upgrade kps prometheus-community/kube-prometheus-stack \
  --version 85.3.3 \
  -n monitoring \
  --reuse-values \
  --set grafana.deploymentStrategy.type=Recreate

7. Loki 验收和排障

LOKI=$(kubectl get svc -n monitoring loki -o jsonpath='{.spec.clusterIP}')

curl -sS "http://$LOKI:3100/ready"
curl -sS "http://$LOKI:3100/loki/api/v1/labels" | jq
curl -sS "http://$LOKI:3100/loki/api/v1/label/namespace/values" | jq

真实输出(装好后):

ready                                    ← Loki 就绪
namespace 标签值: ["kube-system","longhorn-system","monitoring"]
                  ↑ 能列出 namespace = promtail 真的采到日志并发给 Loki 了

loki-promtail 是 DaemonSet,应每节点一个:

$ kubectl get ds -n monitoring loki-promtail
NAME            DESIRED   CURRENT   READY   AVAILABLE
loki-promtail   5         5         5       5          ← 5 节点全覆盖

✅ 验证点:Loki ready + namespace 标签能列出值 + promtail DaemonSet 5/5。三者齐 = 日志链路通。

查 Promtail:

kubectl get pods -n monitoring -l app=promtail -o wide
kubectl logs -n monitoring -l app=promtail --tail=100

常见问题:

现象查什么原因
Grafana 查不到日志Loki labels APIPromtail 没采到或 datasource 错
promtail readiness failpromtail logs连不上 Loki 或节点日志路径异常
Loki PendingPVC / Longhorn卷挂载失败

8. Alertmanager 查看

kubectl get alertmanager -n monitoring
kubectl get pod -n monitoring | grep alertmanager
kubectl port-forward -n monitoring svc/kps-kube-prometheus-stack-alertmanager 9093:9093

浏览器:

http://127.0.0.1:9093

查看当前告警:

AM=$(kubectl get svc -n monitoring kps-kube-prometheus-stack-alertmanager -o jsonpath='{.spec.clusterIP}')
curl -sS "http://$AM:9093/api/v2/alerts" | jq 'length'

9. 一键健康检查

kubectl get pods -n monitoring -o wide
kubectl get pvc -n monitoring
kubectl get svc -n monitoring | grep NodePort
kubectl get configmap -n monitoring -l grafana_datasource=1 -o name
kubectl logs -n monitoring -l app.kubernetes.io/name=grafana -c grafana --tail=30
在 GitHub 上编辑此页
Prev
Longhorn 存储 Runbook:安装、查看、调试
Next
CI / GitOps Runbook:Harbor / Gitea / Jenkins / Kaniko / ArgoCD