Files
juwan-backend/docs/loki-log-troubleshooting.md

217 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Loki 无日志排查与修复手册
## 背景
现象:Grafana Explore 使用 Loki 数据源查询 `{job="kubernetes-pods"}` 时无结果,页面提示 `No logs found`
影响:日志链路不可用,无法按服务排查线上问题。
链路目标:
- Promtail 采集 Kubernetes Pod 日志
- Loki 存储与检索日志
- Grafana 查询展示日志
---
## 一、排查思路
本次按“组件健康 -> 采集发现 -> 文件可读 -> 入库验证 -> 查询验证”的顺序排查。
### 1) 确认监控组件健康
先确认 Promtail/Loki/Grafana 是否都在 Running,避免在异常状态下排查配置。
### 2) 判断是“没采到”还是“没查到”
通过 Promtail `/targets``/service-discovery` 页面确认是否存在 active target。
-`0/0``0/1 unready`,说明采集端有问题
- 若 target 正常但 Loki 无数据,再看推送或查询标签
### 3) 检查 Promtail 能否访问节点日志文件
重点确认:
- `/var/log/pods` 是否可见
- 采集路径是否匹配
- 是否存在大量 `stat ... no such file or directory`
### 4) 直连 Loki API 验证是否入库
绕过 Grafana,直接访问 Loki API。
- 若 API 无数据,问题在 Promtail 采集/推送链路
- 若 API 有数据,问题在 Grafana 查询条件、时间范围或标签
---
## 二、根因分析
本次属于“Promtail 侧采集链路不完整”,主要问题如下:
1. Kubernetes SD 目标未生效(Promtail targets 显示 `kubernetes-pods (0/0)`)。
2. 即使加入静态采集,目标一度 `0/1 unready`
3. `/var/log/pods` 下日志多为符号链接,真实目标在 `/var/lib/docker/containers`
4. Promtail 容器未挂载 `/var/lib/docker/containers`,导致大量 `stat ... no such file or directory`
5. 标签维度不足,不便于按业务服务名筛选日志。
---
## 三、修复思路
### 1) 强化 Promtail 权限与发现能力
`deploy/k8s/monitoring/promtail.yaml` 中:
- 补充 RBAC 资源权限:
- `nodes`
- `pods`
- `pods/log`
- `services`
- `endpoints`
- `namespaces`
### 2) 增加静态采集兜底
`scrape_configs` 中新增 `kubernetes-pods-static`,路径:
- `/var/log/pods/*/*/*.log`
用于在 Kubernetes SD 临时失效时仍能采集日志。
### 3) 修复宿主机日志访问链路
Promtail DaemonSet 增加:
- `securityContext.runAsUser: 0`
- `securityContext.runAsGroup: 0`
- 挂载 `hostPath: /var/lib/docker/containers`
并挂载到容器内同路径只读。
### 4) 完善标签体系,支持按服务筛选
新增/保留标签:
- `namespace`
- `pod`
- `container`
- `app`
静态采集通过 `pipeline_stages``filename` 解析标签,并从 `pod` 生成 `app`(去除滚动后缀)。
---
## 四、关键变更文件
- `deploy/k8s/monitoring/promtail.yaml`
本次 Loki 主配置与 Grafana 数据源无需改动,核心修复集中在 Promtail 采集侧。
---
## 五、排查与修复命令清单
> 以下命令均在项目根目录执行。
### 1) 组件状态检查
```powershell
kubectl get pods -n monitoring -o wide
kubectl get svc -n monitoring
kubectl logs -n monitoring -l app=promtail --tail=120
kubectl logs -n monitoring -l app=loki --tail=80
```
### 2) Promtail 文件系统与配置检查
```powershell
$pod=(kubectl get pod -n monitoring -l app=promtail -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n monitoring $pod -- sh -c "ls -ld /var/log /var/log/pods /var/log/containers"
kubectl exec -n monitoring $pod -- sh -c "find /var/log/pods -name '*.log' | head -n 20"
kubectl exec -n monitoring $pod -- sh -c "cat /etc/promtail/promtail.yaml"
kubectl exec -n monitoring $pod -- sh -c "cat /run/promtail/positions.yaml | head -n 120"
```
### 3) Promtail Web 诊断页(targets / service-discovery
```powershell
$pod=(kubectl get pod -n monitoring -l app=promtail -o jsonpath='{.items[0].metadata.name}')
$job=Start-Job -ScriptBlock { param($p) kubectl port-forward -n monitoring pod/$p 19080:9080 } -ArgumentList $pod
Start-Sleep -Seconds 3
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:19080/targets | Select-Object -ExpandProperty Content
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:19080/service-discovery | Select-Object -ExpandProperty Content
Stop-Job $job -ErrorAction SilentlyContinue
Remove-Job $job -Force -ErrorAction SilentlyContinue
```
### 4) RBAC 实测
```powershell
kubectl auth can-i list pods --as=system:serviceaccount:monitoring:promtail --all-namespaces
kubectl auth can-i watch pods --as=system:serviceaccount:monitoring:promtail --all-namespaces
kubectl auth can-i list namespaces --as=system:serviceaccount:monitoring:promtail
kubectl auth can-i get nodes --as=system:serviceaccount:monitoring:promtail
```
### 5) 应用修复并滚动重启 Promtail
```powershell
kubectl apply -f deploy/k8s/monitoring/promtail.yaml
kubectl rollout restart ds/promtail -n monitoring
kubectl rollout status ds/promtail -n monitoring --timeout=120s
kubectl logs -n monitoring -l app=promtail --tail=120
```
### 6) Loki API 直连验证
```powershell
$job=Start-Job -ScriptBlock { kubectl port-forward -n monitoring svc/loki 13100:3100 }
Start-Sleep -Seconds 3
Invoke-WebRequest -UseBasicParsing "http://127.0.0.1:13100/loki/api/v1/query_range?query=%7Bjob%3D%22kubernetes-pods%22%7D&limit=10" | Select-Object -ExpandProperty Content
Stop-Job $job -ErrorAction SilentlyContinue
Remove-Job $job -Force -ErrorAction SilentlyContinue
```
### 7) 按 app 标签验证
```powershell
$job=Start-Job -ScriptBlock { kubectl port-forward -n monitoring svc/loki 13100:3100 }
Start-Sleep -Seconds 3
Invoke-WebRequest -UseBasicParsing "http://127.0.0.1:13100/loki/api/v1/query_range?query=%7Bjob%3D%22kubernetes-pods%22%2Capp%3D~%22.+%22%7D&limit=5" | Select-Object -ExpandProperty Content
Stop-Job $job -ErrorAction SilentlyContinue
Remove-Job $job -Force -ErrorAction SilentlyContinue
```
---
## 六、Grafana 查询建议
建议先放大时间范围(Last 6 hours / Last 24 hours),再逐步收敛:
```logql
{job="kubernetes-pods"}
{job="kubernetes-pods", namespace="juwan"}
{job="kubernetes-pods", app="user-rpc"}
{job="kubernetes-pods", app=~"user-rpc|snowflake|email-mq"} |= "error"
```
---
## 七、后续优化建议
1. 当前 Loki 使用 `emptyDir`,重建后数据会丢失;生产建议改 PVC 持久化。
2. 可以补充 Promtail 的 `drop` 规则,减少噪音日志(如健康检查日志)。
3. 建议在 Grafana 中预置业务 Dashboard 与告警规则(按 app + error rate)。
---
## 八、结论
本次无日志的核心问题不在 Loki 或 Grafana,而在 Promtail 采集链路:
- 发现目标不稳定 + 日志文件符号链接目标未挂载
完成上述修复后,已可通过 Loki API 查到日志,并支持按 `app` 维度查询。