日志收集 #
一、日志概述 #
日志是排查问题和监控系统的重要数据来源,Kubernetes提供了多种日志收集方案。
1.1 日志类型 #
text
日志类型
│
├── 容器日志
│ ├── stdout/stderr
│ └── 应用日志文件
│
├── 系统日志
│ ├── kubelet日志
│ └── 系统服务日志
│
└── 审计日志
└── API Server审计日志
1.2 日志架构 #
text
日志架构
│
├── 节点级日志
│ └── 容器运行时管理
│
├── 集群级日志
│ ├── 日志采集Agent
│ └── 日志存储后端
│
└── 日志分析
├── 搜索查询
└── 可视化展示
二、EFK架构 #
2.1 EFK组件 #
| 组件 | 说明 |
|---|---|
| Elasticsearch | 日志存储和搜索 |
| Fluentd/Fluent Bit | 日志采集 |
| Kibana | 日志可视化 |
2.2 部署Elasticsearch #
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: elasticsearch
namespace: logging
spec:
serviceName: elasticsearch
replicas: 1
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
spec:
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:8.8.0
env:
- name: discovery.type
value: single-node
- name: ES_JAVA_OPTS
value: "-Xms1g -Xmx1g"
- name: xpack.security.enabled
value: "false"
ports:
- containerPort: 9200
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
volumes:
- name: data
persistentVolumeClaim:
claimName: elasticsearch-pvc
---
apiVersion: v1
kind: Service
metadata:
name: elasticsearch
namespace: logging
spec:
ports:
- port: 9200
selector:
app: elasticsearch
2.3 部署Fluentd #
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentd
rules:
- apiGroups: [""]
resources: ["pods", "namespaces"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fluentd
subjects:
- kind: ServiceAccount
name: fluentd
namespace: logging
roleRef:
kind: ClusterRole
name: fluentd
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: logging
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch.logging.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
2.4 部署Kibana #
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kibana
namespace: logging
spec:
replicas: 1
selector:
matchLabels:
app: kibana
template:
metadata:
labels:
app: kibana
spec:
containers:
- name: kibana
image: docker.elastic.co/kibana/kibana:8.8.0
env:
- name: ELASTICSEARCH_HOSTS
value: "http://elasticsearch:9200"
ports:
- containerPort: 5601
---
apiVersion: v1
kind: Service
metadata:
name: kibana
namespace: logging
spec:
ports:
- port: 80
targetPort: 5601
selector:
app: kibana
type: LoadBalancer
三、Fluent Bit部署 #
3.1 Fluent Bit配置 #
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: logging
data:
fluent-bit.conf: |
[SERVICE]
Flush 1
Log_Level info
Daemon off
Parsers_File parsers.conf
[INPUT]
Name tail
Tag kube.*
Path /var/log/containers/*.log
Parser docker
DB /var/log/flb_kube.db
Mem_Buf_Limit 5MB
Skip_Long_Lines On
Refresh_Interval 10
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
Merge_Log On
K8S-Logging.Parser On
K8S-Logging.Exclude On
[OUTPUT]
Name es
Match *
Host elasticsearch
Port 9200
Logstash_Format On
Retry_Limit False
parsers.conf: |
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On
3.2 Fluent Bit DaemonSet #
yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluent-bit
namespace: logging
spec:
selector:
matchLabels:
app: fluent-bit
template:
metadata:
labels:
app: fluent-bit
spec:
containers:
- name: fluent-bit
image: fluent/fluent-bit:2.1.0
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
- name: config
mountPath: /fluent-bit/etc/
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: config
configMap:
name: fluent-bit-config
四、日志格式 #
4.1 标准输出日志 #
yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: nginx
command: ["sh", "-c", "echo 'Hello World' && sleep 3600"]
4.2 JSON格式日志 #
yaml
apiVersion: v1
kind: Pod
metadata:
name: json-log-pod
annotations:
fluentbit.io/parser: json
spec:
containers:
- name: app
image: myapp
command: ["sh", "-c", "echo '{\"level\":\"info\",\"message\":\"Hello World\",\"timestamp\":\"2024-01-01T00:00:00Z\"}' && sleep 3600"]
4.3 多行日志 #
yaml
# Java堆栈日志
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-parsers
data:
parsers.conf: |
[PARSER]
Name multiline
Format regex
Regex /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (?<level>\w+) (?<message>.*)/
Time_Key time
Time_Format %Y-%m-%d %H:%M:%S
五、日志查询 #
5.1 kubectl logs #
bash
# 查看Pod日志
kubectl logs <pod-name>
# 实时查看日志
kubectl logs -f <pod-name>
# 查看最近N行日志
kubectl logs --tail=100 <pod-name>
# 查看指定时间日志
kubectl logs --since=1h <pod-name>
# 查看之前容器日志
kubectl logs --previous <pod-name>
# 多容器Pod指定容器
kubectl logs <pod-name> -c <container-name>
5.2 Elasticsearch查询 #
json
# 查询特定Pod日志
{
"query": {
"match": {
"kubernetes.pod_name": "my-pod"
}
}
}
# 查询错误日志
{
"query": {
"match": {
"log": "ERROR"
}
}
}
# 时间范围查询
{
"query": {
"range": {
"@timestamp": {
"gte": "now-1h",
"lte": "now"
}
}
}
}
六、日志最佳实践 #
6.1 日志规范 #
text
日志规范建议
│
├── 使用标准输出
│ └── stdout/stderr
│
├── JSON格式
│ ├── level
│ ├── message
│ └── timestamp
│
├── 避免敏感信息
│ └── 脱敏处理
│
└── 合理日志级别
├── DEBUG
├── INFO
├── WARN
└── ERROR
6.2 日志级别配置 #
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
spec:
containers:
- name: app
image: myapp
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
6.3 日志轮转 #
yaml
# 容器日志轮转配置
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
七、故障排查 #
7.1 常见问题 #
bash
# 查看Fluentd日志
kubectl logs -n logging -l app=fluentd
# 查看Elasticsearch状态
kubectl exec -n logging -it elasticsearch-0 -- curl localhost:9200/_cluster/health
# 检查日志采集
kubectl exec -n logging -it fluentd-xxx -- ls /var/log/containers/
# 测试Elasticsearch连接
kubectl run test --image=curlimages/curl --rm -it -- curl http://elasticsearch:9200
7.2 问题诊断 #
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 日志未采集 | Agent异常 | 检查Fluentd状态 |
| ES写入失败 | 存储满 | 清理或扩容存储 |
| 日志格式错误 | Parser错误 | 检查Parser配置 |
八、总结 #
8.1 核心要点 #
| 组件 | 说明 |
|---|---|
| Elasticsearch | 日志存储搜索 |
| Fluentd/Fluent Bit | 日志采集 |
| Kibana | 日志可视化 |
8.2 下一步 #
掌握了日志收集后,让我们学习 健康检查,了解容器健康监控的方法。
最后更新:2026-03-28