一、k8s部署的promtail收集日志异常
K8s 部署 Promtail 无法收集 Pod 日志,通常原因集中在:
- 没有挂载宿主机
/var/log/pods - Promtail 配置中的
__path__错误 - RBAC 无法获取 Pod 元数据
- Loki 地址不可达
- containerd 日志格式没有解析(CRI)
- Pod 日志实际不在
/var/log/pods
按下面顺序排查
1. 查看 Promtail Pod 状态
kubectl get pods -n logging -o wide
确认:
promtail-xxxxx Running
如果不是:
kubectl describe pod -n logging promtail-xxxxx
2. 查看 Promtail 日志
重点:
kubectl logs -n logging -l app=promtail --tail=100
正常:
level=info msg="tail routine: started"
异常:
Loki连接失败
例如:
server returned HTTP status 500
或者:
connection refused
检查:
kubectl exec -n logging -it promtail-xxx -- \
curl http://loki.monitoring.svc.cluster.local:3100/ready
正常:
ready
3. 检查宿主机日志文件
登录 Promtail 所在节点:
kubectl get pod -n logging -o wide
例如:
promtail-xxxx worker01
登录:
ssh worker01
检查:
ls /var/log/pods/
应该有:
default_nginx_xxx_xxx
查看:
find /var/log/pods -name "*.log" | head
例如:
/var/log/pods/default_nginx_xxx/nginx/0.log
如果这里没有日志,Promtail 不可能采集
4. 检查 Promtail 是否挂载日志目录
执行:
kubectl describe pod -n logging -l app=promtail
看:
Mounts:
应该有:
/var/log/pods
/var/log/containers
例如:
volumeMounts:
- name: pods
mountPath: /var/log/pods
readOnly: true
- name: containers
mountPath: /var/log/containers
readOnly: true
5. 进入 Promtail 容器检查文件
进入:
kubectl exec -n logging -it \
$(kubectl get pod -n logging -l app=promtail -o name | head -1) \
-- sh
查看:
ls /var/log/pods
如果为空:
说明 volume 没挂载
6. 检查 Promtail 配置
查看:
kubectl get cm -n logging promtail-config -o yaml
重点:
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
以及:
relabel_configs:
- source_labels:
- __meta_kubernetes_pod_uid
target_label: __path__
7. 推荐使用 containerd 正确配置
你的环境是 containerd
Promtail 必须包含:
pipeline_stages:
- cri: {}
否则日志解析可能异常:
pipeline_stages:
- cri:
8. 检查 RBAC
查看:
kubectl auth can-i list pods \
--as=system:serviceaccount:logging:promtail
应该:
yes
否则补:
rules:
- apiGroups:
- ""
resources:
- pods
- nodes
- namespaces
verbs:
- get
- list
- watch
9. 查看 Promtail 是否发现目标
Promtail 有 debug 页面:
端口:
kubectl port-forward \
-n logging svc/promtail 3101:3101
访问:
http://127.0.0.1:3101/targets
查看:
Discovered labels
如果:
0 targets
说明 Kubernetes 服务发现失败
10. 检查 Loki 是否收到数据
进入 Grafana:
查询:
{namespace=~".+"}
或者:
{job="kubernetes-pods"}
11. containerd 环境对应关系
Kubernetes + containerd,日志链路:
应用 stdout
|
v
containerd
|
v
/var/log/pods
|
v
/var/log/containers
|
v
Promtail
|
v
Loki
查看软链接:
ls -l /var/log/containers/
例如:
nginx_default_nginx-abc.log ->
../pods/default_nginx-abc_UID/nginx/0.log
12. 常见修复(你的环境 containerd)
我建议 Promtail DaemonSet 使用:
volumeMounts:
- name: pods
mountPath: /var/log/pods
readOnly: true
- name: containers
mountPath: /var/log/containers
readOnly: true
volumes:
- name: pods
hostPath:
path: /var/log/pods
- name: containers
hostPath:
path: /var/log/containers
并配置:
pipeline_stages:
- cri: {}
二、docker-compose部署的promtail收集日志异常
如果是 docker-compose 部署 Promtail 无法收集日志,和 Kubernetes DaemonSet 不同,主要检查:
- Promtail 容器有没有挂载宿主机日志目录
__path__是否匹配真实日志路径- Docker 日志驱动是否是 json-file
- Promtail 权限是否足够
- Loki 地址是否正常
1. 先确认 Docker 日志位置
宿主机执行:
docker info | grep "Logging Driver"
正常:
Logging Driver: json-file
查看某个容器:
docker inspect <container_id> | grep LogPath
例如:
"LogPath": "/var/lib/docker/containers/8a12xxxx/8a12xxxx-json.log"
那么 Promtail 应采集:
/var/lib/docker/containers/*/*-json.log
2. docker-compose Promtail正确配置
示例:
version: "3"
services:
promtail:
image: grafana/promtail:3.0.0
container_name: promtail
restart: always
volumes:
# Docker日志
- /var/lib/docker/containers:/var/lib/docker/containers:ro
# Docker daemon日志
- /var/log:/var/log:ro
# promtail配置
- ./promtail.yaml:/etc/promtail/config.yaml:ro
# positions
- ./positions:/tmp
command:
- -config.file=/etc/promtail/config.yaml
3. promtail.yaml
Docker环境:
server:
http_listen_port: 9080
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: docker
pipeline_stages:
- docker: {}
static_configs:
- targets:
- localhost
labels:
job: docker
host: ${HOSTNAME}
__path__: /var/lib/docker/containers/*/*-json.log
4. 检查 Promtail 是否看到日志
进入容器:
docker exec -it promtail sh
查看:
ls /var/lib/docker/containers
应该看到:
8a12xxxx
bc33xxxx
继续:
ls /var/lib/docker/containers/*/
应该:
8a12xxxx-json.log
如果为空:
说明 volume 挂载错误
5. 常见错误1:使用了错误路径
很多人写:
__path__: /var/log/containers/*.log
这个是 Kubernetes 路径
Docker Compose 不存在:
/var/log/containers
应该:
/var/lib/docker/containers/*/*-json.log
6. 常见错误2:Docker使用journald
检查:
docker info | grep Logging
如果:
Logging Driver: journald
那么:
/var/lib/docker/containers
没有日志
需要改:
查看:
journalctl -u docker
或者:
修改:
/etc/docker/daemon.json
加入:
{
"log-driver": "json-file"
}
重启:
systemctl restart docker
7. 常见错误3:Promtail权限不足
查看:
docker logs promtail
如果:
permission denied
启动:
user: root
例如:
services:
promtail:
user: root
8. 测试日志采集
启动一个测试容器:
docker run -d \
--name log-test \
alpine \
sh -c 'while true;do echo hello-loki; sleep 5;done'
查看:
docker logs log-test
然后看 Promtail:
docker logs -f promtail
应该出现:
tailing new file
9. 如果同时采集 Kubernetes + Docker
你的环境前面提到:
containerd
docker
建议拆两个 job:
Kubernetes
__path__: /var/log/pods/*/*/*.log
pipeline:
- cri: {}
Docker Compose
__path__: /var/lib/docker/containers/*/*-json.log
pipeline:
- docker: {}
不要混用:
- docker: {}
去解析 containerd CRI 日志,否则 Loki 中会没有正常字段