217 lines
6.7 KiB
Markdown
217 lines
6.7 KiB
Markdown
# 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` 维度查询。
|