Docker容器日志采集与EFK体系搭建运维指南

容器日志管理的核心挑战

Docker容器日志管理是SRE日常运维的高频痛点。容器生命周期短暂,日志随容器销毁而丢失;默认json-file日志驱动无滚动机制,磁盘占满导致节点不可用是常见故障。EFK(Elasticsearch + Fluentd/Filebeat + Kibana)体系是容器日志领域最成熟的解决方案,本文从部署到排错覆盖完整实操路径。

Docker日志驱动选型与配置

Docker支持多种日志驱动,生产环境推荐json-file(配合滚动限制)或fluentd(直发模式):

# /etc/docker/daemon.json - 全局日志配置
{
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "50m",
        "max-file": "3"
    }
}

# 单容器覆盖日志驱动
# docker run --log-driver=fluentd #     --log-opt fluentd-address=localhost:24224 #     --log-opt tag="app.{{.Name}}" #     nginx:latest

max-size限制单文件最大50MB,max-file保留3个轮转文件。单容器日志上限150MB。未配置此参数时,json-file驱动会无限增长,曾导致多起磁盘100%占满事故。

Fluentd采集层部署与配置

Fluentd作为日志采集和路由层,负责从Docker容器收集日志并转发至Elasticsearch。使用fluent-plugin-docker_metadata_filter插件自动注入容器元数据:

# Fluentd配置文件 td-agent.conf
<source>
  @type tail
  path /var/lib/docker/containers/*/*-json.log
  pos_file /var/log/fluentd/docker-containers.log.pos
  tag docker.*
  read_from_head false
  <parse>
    @type json
    time_key time
    time_format %Y-%m-%dT%H:%M:%S.%NZ
  </parse>
</source>

<filter docker.**>
  @type docker_metadata
  @id container_metadata_filter
  <inject>
    hostname_key hostname
  </inject>
</filter>

<match docker.**>
  @type elasticsearch
  host elasticsearch.logging.svc
  port 9200
  logstash_format true
  logstash_prefix docker-logs
  include_tag_key true
  tag_key @log_name
  flush_interval 5s
  retry_max_interval 30s
  retry_forever true
</match>

关键配置说明:@type tail以尾部读取模式跟踪日志文件,pos_file记录读取位置保证重启后不丢数据。Docker元数据过滤器注入容器名、镜像名、标签等信息,方便后续在Kibana中按服务筛选。

Elasticsearch索引生命周期管理

日志场景下Elasticsearch索引无限增长会耗尽存储。ILM(Index Lifecycle Management)自动执行索引滚动、缩减副本和删除策略:

# 创建ILM策略
PUT _ilm/policy/docker-logs-policy
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_size": "50gb",
            "max_age": "7d"
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "shrink": { "number_of_shards": 1 },
          "forcemerge": { "max_num_segments": 1 }
        }
      },
      "delete": {
        "min_age": "30d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

# 关联到索引模板
PUT _template/docker-logs-template
{
  "index_patterns": ["docker-logs-*"],
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "lifecycle.name": "docker-logs-policy",
    "lifecycle.rollover_alias": "docker-logs"
  }
}

Hot阶段:索引超过50GB或7天触发滚动,生成新索引。Warm阶段:7天后合并分片和段文件,降低存储开销。Delete阶段:30天后自动删除,释放磁盘空间。这套策略在日均10GB日志量下运行稳定,Elasticsearch存储维持在150GB左右。

Kibana可视化与告警看板

Kibana提供日志搜索和可视化能力。推荐创建以下看板:

# 常用Kibana查询DSL

# 按容器名过滤
{"query": {"match": {"docker.container_name": "api-gateway"}}}

# 错误日志统计(5分钟粒度)
{"aggs": {
  "errors_over_time": {
    "date_histogram": {"field": "@timestamp", "fixed_interval": "5m"},
    "aggs": {"error_count": {
      "filter": {"match": {"log": "ERROR"}}
    }}
  }
}}

# 慢请求日志(响应时间>2s)
{"query": {"range": {"response_time": {"gt": 2000}}}}

告警方面,Elasticsearch Watcher或开源替代方案(如ElastAlert)可基于日志模式触发告警。典型场景:5分钟内ERROR日志超过阈值、特定容器连续Crash、磁盘使用率超85%。

常见故障排查清单

EFK体系运维中的高频问题及解法:

1. Fluentd采集延迟

查看Fluentd缓冲区:curl http://localhost:24220/api/plugins.json,关注buffer_queue_lengthbuffer_total_bytes。队列积压时增大flush_interval的并发度或扩容Fluentd实例。

2. Elasticsearch写入拒绝

日志中出现429 Too Many Requests时,索引写入速度超过Elasticsearch处理能力。解决方案:增大refresh_interval(默认1s改为30s)、增加索引分片数、启用批量请求缓冲。

3. 磁盘水位线告警

Elasticsearch默认在磁盘使用率超过85%时停止分配分片,超过95%时设索引为只读。提前配置cluster.routing.allocation.disk.watermark阈值,并确保ILM删除策略正常运行。

# Elasticsearch磁盘水位线配置
cluster.routing.allocation.disk.threshold_enabled: true
cluster.routing.allocation.disk.watermark.low: 85%
cluster.routing.allocation.disk.watermark.high: 90%
cluster.routing.allocation.disk.watermark.flood_stage: 95%

EFK体系搭建完成后,核心运维动作是监控Fluentd缓冲区积压、Elasticsearch集群健康状态和磁盘水位线。建议将这三个指标接入Prometheus告警体系,确保日志管道持续可靠运行。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/docker-rong-qi-ri-zhi-cai-ji-yu-efk-ti-xi-da-jian-yun-wei/

(0)
小编小编
上一篇 14小时前
下一篇 14小时前

相关推荐