这条路径解决“出事时只能靠猜”的问题:把指标、日志、链路和剖析四种信号接到同一条排障流程里,最后用 SLO 和值班制度把告警变成可执行的动作。适合已经会 Linux 基础、能读 YAML、手上有 Docker 或 kind 集群的后端与运维工程师。
前置知识:看得懂 HTTP 状态码,用过 systemctl 和 docker,知道 CPU、内存、磁盘的基本含义。四个阶段按依赖排序,每阶段建议 3–4 小时;没有监控环境的,先用 Docker 或 kind 起一套单机栈。
所有实验只在本地或测试环境做。给生产加采集器、改告警规则、调采样率都属于变更,需要评审、灰度和回滚方案。
目标:能从一条 PromQL 查询追到采集目标,判断问题在应用、exporter 还是采集链路。
阅读顺序:
kubectl top,不能替代 Prometheus。rate、histogram_quantile 和聚合的常用写法。动手任务:在本地 Docker 起 Prometheus、node-exporter 和一条告警规则,确认 up 指标与规则校验通过。环境是本机 Docker,端口只绑定回环地址;Linux 上把 host.docker.internal 换成宿主机地址或改用 --network host。风险是端口暴露和容器残留,实验后删除容器。
mkdir -p /tmp/obs-lab
cat > /tmp/obs-lab/prometheus.yml <<'EOF'
scrape_configs: [{job_name: node, static_configs: [{targets: ['host.docker.internal:9100']}]}]
EOF
cat > /tmp/obs-lab/alerts.yml <<'EOF'
groups: [{name: lab, rules: [{alert: InstanceDown, expr: 'up == 0', for: 5m}]}]
EOF
docker run -d --name node-exporter -p 127.0.0.1:9100:9100 prom/node-exporter:v1.8.2
docker run -d --name prometheus -p 127.0.0.1:9090:9090 -v /tmp/obs-lab/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus:v2.54.1
docker run --rm -v /tmp/obs-lab:/lab --entrypoint promtool prom/prometheus:v2.54.1 check rules /lab/alerts.yml
curl -s 'http://127.0.0.1:9090/api/v1/query?query=up' | head -c 300
过关标准:
up == 0 能定位到具体 job 和 instance,而不是只说“监控挂了”。rate 而不是原始计数。for 和 labels 在告警里的作用。目标:让一条错误日志能从容器、节点到 Loki 全链路查到,并能按标签和 trace_id 收敛范围。
阅读顺序:
动手任务:在本机 Docker 起 Loki 和 promtail,采集 /var/log 下的系统日志,用 logcli 查询标签并过滤关键字。环境是本机 Docker;只读挂载 /var/log,不要把采集范围扩到用户目录。风险是日志可能含敏感信息、磁盘被占满,实验后删除容器并限制保留时间。
docker run -d --name loki -p 127.0.0.1:3100:3100 grafana/loki:3.1.1
cat > /tmp/obs-lab/promtail.yml <<'EOF'
server: {http_listen_port: 9080, grpc_listen_port: 0}
positions: {filename: /tmp/positions.yaml}
clients: [{url: http://host.docker.internal:3100/loki/api/v1/push}]
scrape_configs:
- job_name: varlogs
static_configs: [{targets: [localhost], labels: {job: varlogs, __path__: /var/log/*.log}}]
EOF
docker run -d --name promtail -v /tmp/obs-lab/promtail.yml:/etc/promtail/config.yml -v /var/log:/var/log:ro grafana/promtail:3.1.1 -config.file=/etc/promtail/config.yml
curl -s http://127.0.0.1:3100/loki/api/v1/labels
过关标准:
{job="varlogs"} |= "error" 这类查询,并说明标签选择器为什么比全文过滤便宜。目标:用一个 trace_id 串起服务调用,并能从最慢 span 定位到下游依赖或代码热点。
阅读顺序:
动手任务:起本地 Jaeger,用 otel-cli 发送一个 span,再通过 Jaeger API 确认服务已注册。环境是本机 Docker,OTLP 端口只给本地使用。风险是 trace 会携带请求元数据,不要写入密码、令牌或个人数据;实验结束删除容器。
docker run -d --name jaeger -p 127.0.0.1:16686:16686 -p 127.0.0.1:4317:4317 -p 127.0.0.1:4318:4318 jaegertracing/all-in-one:1.60
sleep 5
otel-cli span --endpoint http://127.0.0.1:4317 --service demo --name checkout
curl -s http://127.0.0.1:16686/api/services
过关标准:
目标:把“系统慢”变成有错误预算、有告警路由、有值班动作的闭环。
阅读顺序:
动手任务:在本地起 Alertmanager,用 amtool 校验配置、注入一条告警并创建静默,确认 API 能看到状态变化。环境是本机 Docker,配置和接收端都是假的。风险是静默会掩盖真实告警,生产环境创建静默必须写原因和过期时间。
cat > /tmp/obs-lab/alertmanager.yml <<'EOF'
route: {receiver: default}
receivers: [{name: default}]
EOF
docker run -d --name alertmanager -p 127.0.0.1:9093:9093 -v /tmp/obs-lab/alertmanager.yml:/etc/alertmanager/alertmanager.yml prom/alertmanager:v0.27.0
docker exec alertmanager amtool check-config /etc/alertmanager/alertmanager.yml
docker exec alertmanager amtool alert add alertname=ServiceLatency service=api severity=warning --alertmanager.url=http://127.0.0.1:9093
curl -s http://127.0.0.1:9093/api/v2/alerts
过关标准:
合上页面,先回答,再展开对照。
up 为 1,但用户请求全部超时,你会先看哪三类信号?