在 Kubernetes 中使用 EFK 栈(Elasticsearch + Fluentd/Fluent Bit + Kibana) 实现日志统一管理,是业界标准的集中式日志解决方案。它通过高效收集、存储、分析和可视化容器日志,满足企业级需求。以下是详细实现步骤和关键配置:
核心架构与组件作用
graph LRA[Kubernetes Pods] -->|stdout/stderr| B((Node))B -->|Log Files| C[Fluent Bit DaemonSet]C -->|聚合/过滤日志| D[Kafka/缓冲队列 可选]D --> E[Fluentd Aggregator 可选]C --> F[Elasticsearch]E --> FF --> G[Kibana]G --> H[DevOps/SRE]
- 
Fluent Bit (轻量级日志收集器 - 推荐) - 部署方式: DaemonSet(每个节点运行一个 Pod)
- 作用:
- 读取节点上所有容器的 stdout/stderr日志(默认路径/var/log/containers/*.log)
- 采集节点系统日志(如 /var/log/syslog)
- 通过 Tail Input Plugin 跟踪日志文件变化
- 解析、过滤、丰富日志(如添加 Kubernetes 元数据:Pod 名称、Namespace、标签等)
- 将处理后的日志 高效转发 到 Elasticsearch 或 Fluentd 聚合层
 
- 读取节点上所有容器的 
 
- 部署方式: 
- 
Elasticsearch (分布式搜索与存储引擎) - 部署方式: StatefulSet(有状态应用,需持久化存储)
- 作用:
- 接收并索引来自 Fluent Bit/Fluentd 的日志数据
- 提供分布式、高可用的日志存储
- 支持 PB 级数据检索与分析
 
 
- 部署方式: 
- 
Kibana (日志分析与可视化平台) - 部署方式: Deployment
- 作用:
- 通过 Web UI 查询、分析 Elasticsearch 中的日志
- 创建仪表盘(如错误日志统计、请求延迟分析)
- 设置告警规则(如 ERROR 日志突增)
 
 
- 部署方式: 
详细部署步骤
步骤 1: 部署 Elasticsearch
# elasticsearch-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: elasticsearchnamespace: logging  # 建议使用独立命名空间
spec:serviceName: elasticsearchreplicas: 3  # 至少3节点保证高可用selector:matchLabels:app: elasticsearchtemplate:metadata:labels:app: elasticsearchspec:containers:- name: elasticsearchimage: docker.elastic.co/elasticsearch/elasticsearch:8.9.0env:- name: node.namevalueFrom:fieldRef:fieldPath: metadata.name- name: cluster.namevalue: k8s-logs- name: discovery.seed_hostsvalue: "elasticsearch-0.elasticsearch,elasticsearch-1.elasticsearch,elasticsearch-2.elasticsearch"- name: ES_JAVA_OPTSvalue: "-Xms2g -Xmx2g"  # 根据节点内存调整- name: ELASTIC_PASSWORD  # 设置密码(生产环境必须)value: "your-strong-password"ports:- containerPort: 9200name: http- containerPort: 9300name: transportvolumeMounts:- name: datamountPath: /usr/share/elasticsearch/datavolumes:- name: datapersistentVolumeClaim:claimName: es-data  # 需要提前创建 PVC
---
# Service(Headless 用于节点发现)
apiVersion: v1
kind: Service
metadata:name: elasticsearchnamespace: logging
spec:clusterIP: None  # Headless Serviceports:- port: 9200name: http- port: 9300name: transportselector:app: elasticsearch
步骤 2: 部署 Fluent Bit (DaemonSet)
# fluent-bit-config.yaml (ConfigMap)
apiVersion: v1
kind: ConfigMap
metadata:name: fluent-bit-confignamespace: logging
data:fluent-bit.conf: |[SERVICE]Flush         5Log_Level     infoDaemon        offParsers_File  parsers.conf[INPUT]Name              tailPath              /var/log/containers/*.logParser            dockerTag               kube.*Refresh_Interval  5Mem_Buf_Limit     50MB  # 内存缓冲区限制[FILTER]Name                kubernetesMatch               kube.*Kube_URL            https://kubernetes.default.svc:443Kube_CA_File        /var/run/secrets/kubernetes.io/serviceaccount/ca.crtKube_Token_File     /var/run/secrets/kubernetes.io/serviceaccount/tokenKube_Tag_Prefix     kube.var.log.containers.Merge_Log           OnKeep_Log           Off[OUTPUT]Name            esMatch           *Host            elasticsearch.logging.svc  # ES 服务地址Port            9200Logstash_Format OnLogstash_Prefix fluent-bitHTTP_User       elastic  # ES 用户名HTTP_Passwd     your-strong-passwordtls             Ontls.verify      Off  # 测试环境可关闭验证,生产需配置 CA
---
# fluent-bit-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:name: fluent-bitnamespace: logging
spec:selector:matchLabels:app: fluent-bittemplate:metadata:labels:app: fluent-bitspec:serviceAccountName: fluent-bit  # 需创建有权限的 SAcontainers:- name: fluent-bitimage: fluent/fluent-bit:2.1.8volumeMounts:- name: configmountPath: /fluent-bit/etc/- name: varlogmountPath: /var/log- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: truevolumes:- name: configconfigMap:name: fluent-bit-config- name: varloghostPath:path: /var/log- name: varlibdockercontainershostPath:path: /var/lib/docker/containers
关键配置说明:
- Kubernetes Filter: 自动添加 Pod 元数据(名称、命名空间、标签等)。
- Logstash Format: 自动按日生成索引(如
fluent-bit-2023.10.01)。- RBAC: 需创建 ServiceAccount 并绑定
get/list/watchPod 和 Namespace 的权限。
步骤 3: 部署 Kibana
# kibana-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: kibananamespace: logging
spec:replicas: 1selector:matchLabels:app: kibanatemplate:metadata:labels:app: kibanaspec:containers:- name: kibanaimage: docker.elastic.co/kibana/kibana:8.9.0env:- name: ELASTICSEARCH_HOSTSvalue: "http://elasticsearch:9200"- name: ELASTICSEARCH_USERNAMEvalue: "elastic"- name: ELASTICSEARCH_PASSWORDvalue: "your-strong-password"ports:- containerPort: 5601
---
# kibana-service.yaml
apiVersion: v1
kind: Service
metadata:name: kibananamespace: logging
spec:type: NodePort  # 或 LoadBalancer/Ingress 暴露ports:- port: 5601targetPort: 5601selector:app: kibana
高级优化与生产实践
- 
日志缓冲与可靠性 - 问题: ES 故障时日志丢失风险
- 方案: 引入 Kafka 作为缓冲队列graph LRA[Fluent Bit] --> B[Kafka]B --> C[Fluentd]C --> D[Elasticsearch]
- Fluent Bit 配置输出到 Kafka,由 Fluentd 消费后写入 ES。
 
- 
日志过滤与裁剪 - 使用 Fluent Bit 过滤器:[FILTER]Name grepMatch *Exclude log /healthcheck|ping/
- 丢弃无关日志(如健康检查),减少 ES 负载。
 
- 使用 Fluent Bit 过滤器:
- 
多租户与索引策略 - 按命名空间分离索引:[OUTPUT]Name esMatch *Index fluent-bit-${kubernetes['namespace_name']}
- 便于按团队管理日志和设置权限。
 
- 按命名空间分离索引:
- 
Elasticsearch 优化 - 冷热架构:
- 热节点(SSD):存放近期日志(高性能)
- 温节点(HDD):存放历史日志(低成本)
 
- 索引生命周期管理 (ILM):PUT _ilm/policy/logs-policy {"policy": {"phases": {"hot": {"min_age": "0ms","actions": {"rollover": {"max_size": "50gb"}}},"delete": {"min_age": "30d","actions": {"delete": {}}}}} }
- 自动滚动删除旧索引,控制存储成本。
 
- 冷热架构:
- 
安全性增强 - TLS 加密: Fluent Bit 到 ES 的 HTTPS 通信。
- RBAC: Kibana 中按角色限制日志访问权限。
- 网络策略: 限制 Fluent Bit 仅可访问 ES 的 9200 端口。
 
- 
性能调优参数 [SERVICE]Flush 5 # 刷新间隔(秒)HTTP_Server On # 开启监控端点storage.path /var/log/flb-storage/ # 磁盘缓冲storage.sync normalstorage.checksum offstorage.backlog.mem_limit 50M
验证与使用
- 
检查日志采集: kubectl logs -n logging fluent-bit-xxxxx # 查看 Fluent Bit 是否正常发送日志到 ES
- 
访问 Kibana: - 通过 kubectl port-forward svc/kibana -n logging 5601:5601临时访问
- 或配置 Ingress 暴露服务
- 在 Kibana 中创建 Index Pattern(如 fluent-bit-*)
 
- 通过 
- 
查询示例: // 查找 nginx 命名空间的 ERROR 日志 {"query": {"bool": {"must": [{"match": {"kubernetes.namespace_name": "nginx"}},{"match": {"log": "ERROR"}}]}} }
常见问题排查
- 日志未采集: 检查 Fluent Bit 的 Path配置是否匹配容器日志路径(如 Docker/Containerd 差异)。
- ES 连接失败: 检查网络策略、ES 认证信息和证书。
- 元数据缺失: 确认 Fluent Bit 的 Kubernetes Filter 配置正确且 RBAC 权限足够。
- 性能瓶颈: 监控 Fluent Bit 内存/CPU 使用率,调整 Mem_Buf_Limit和 Flush 间隔。
通过以上步骤,EFK 栈可为 Kubernetes 提供高可靠、可扩展的日志管理能力,满足从开发测试到大规模生产环境的需求。
