监控日志 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 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。
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
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'
看 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
查 Promtail:
kubectl get pods -n monitoring -l app=promtail -o wide
kubectl logs -n monitoring -l app=promtail --tail=100
常见问题:
| 现象 | 查什么 | 原因 |
|---|---|---|
| Grafana 查不到日志 | Loki labels API | Promtail 没采到或 datasource 错 |
| promtail readiness fail | promtail logs | 连不上 Loki 或节点日志路径异常 |
| Loki Pending | PVC / 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