Docker容器化高可用架构部署方案(十六)

15-EFK日志收集配置详解

本文档详细介绍EFK(Elasticsearch + Fluentd + Kibana)日志收集系统的部署和配置。

概述

EFK是一套成熟的日志收集、存储和可视化解决方案:

  • Elasticsearch:分布式搜索引擎,用于存储和检索日志

  • Fluentd:日志收集器,运行在每个节点收集容器日志

  • Kibana:可视化界面,用于查询和分析日志

架构设计

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                     manage-net (172.20.5.0/24)                  │
│                                                                   │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐     │
│  │ Fluentd-N1   │    │ Fluentd-N2   │    │ Fluentd-N3   │     │
│  │172.20.5.11   │    │172.20.5.12   │    │172.20.5.22   │     │
│  └──────┬───────┘    └──────┬───────┘    └──────┬───────┘     │
│         │                    │                    │              │
│         └────────────────────┼────────────────────┘              │
│                              │                                    │
│                              ▼                                    │
│                    ┌─────────────────┐                           │
│                    │  Elasticsearch   │                           │
│                    │  172.20.5.21     │                           │
│                    └────────┬────────┘                           │
│                             │                                     │
│                             ▼                                     │
│                    ┌─────────────────┐                           │
│                    │     Kibana       │                           │
│                    │  172.20.5.23     │                           │
│                    └─────────────────┘                           │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘

IP规划

组件 IP地址 节点 端口
Fluentd 172.20.5.11 Node1 24224
Fluentd 172.20.5.12 Node2 24224
Fluentd 172.20.5.22 Node3 24224
Elasticsearch 172.20.5.21 Node3 9200, 9300
Kibana 172.20.5.23 Node3 5601

部署步骤

步骤1:创建配置目录

在所有节点执行:

复制代码
mkdir -p /opt/cluster-deploy/config/{elasticsearch,fluentd,kibana}
mkdir -p /opt/cluster-deploy/logs/elasticsearch
chmod -R 777 /opt/cluster-deploy/logs

步骤2:创建Elasticsearch配置

在Node3执行,创建Elasticsearch配置文件:

复制代码
cat > /opt/cluster-deploy/config/elasticsearch/elasticsearch.yml << 'EOF'
cluster.name: docker-cluster
node.name: elasticsearch-node1
node.attr.box_type: normal
path.data: /usr/share/elasticsearch/data
path.logs: /usr/share/elasticsearch/logs
​
bootstrap.memory_lock: true
bootstrap.system_call_filter: false
​
discovery.type: single-node
​
network.host: 0.0.0.0
http.port: 9200
​
transport.publish_host: 172.20.5.21
http.publish_host: 172.20.5.21
​
xpack.security.enabled: false
xpack.security.enrollment.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
​
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-methods: OPTIONS,HEAD,GET,POST,PUT,DELETE
http.cors.allow-headers: "X-Requested-With,Content-Type,Content-Length"
​
indices.memory.index_buffer_size: 20%
indices.queries.cache.size: 15%
​
action.auto_create_index: true
EOF

创建JVM配置:

复制代码
cat > /opt/cluster-deploy/config/elasticsearch/jvm.options << 'EOF'
-Xms512m
-Xmx512m
-XX:+UseG1GC
-XX:+DisableExplicitGC
-XX:+ExitOnOutOfMemoryError
EOF

步骤3:创建Fluentd配置

在所有节点执行,创建Fluentd配置文件(以Node1为例):

复制代码
cat > /opt/cluster-deploy/config/fluentd/fluentd-node1.conf << 'EOF'
<source>
  @type tail
  @id input_tail_docker_containers
  path /var/lib/docker/containers/*/*-json.log
  pos_file /var/log/fluentd-containers.log.pos
  tag docker.*
  read_from_head true
  <parse>
    @type json
    time_type float
    time_format %Y-%m-%dT%H:%M:%S.%NZ
  </parse>
</source>
​
<source>
  @type tail
  @id input_tail_nginx_access
  path /var/log/nginx/access.log
  pos_file /var/log/fluentd-nginx-access.log.pos
  tag nginx.access
  <parse>
    @type nginx
  </parse>
</source>
​
<source>
  @type tail
  @id input_tail_nginx_error
  path /var/log/nginx/error.log
  pos_file /var/log/fluentd-nginx-error.log.pos
  tag nginx.error
  <parse>
    @type nginx
  </parse>
</source>
​
<filter docker.**>
  @type record_transformer
  <record>
    hostname "#{Socket.gethostname}"
    node_name Node1
  </record>
</filter>
​
<filter nginx.**>
  @type record_transformer
  <record>
    hostname "#{Socket.gethostname}"
    node_name Node1
  </record>
</filter>
​
<match docker.**>
  @type elasticsearch
  host 172.20.5.21
  port 9200
  logstash_format true
  logstash_prefix docker
  logstash_dateformat %Y.%m.%d
  include_tag_key true
  tag_key docker_tag
  type_name docker-container
  flush_interval 10s
  buffer_type file
  buffer_path /var/log/fluentd-buffers/elasticsearch.buffer
  buffer_queue_full_action block
  buffer_chunk_limit 2M
  buffer_queue_limit 256
  flush_interval 10s
  max_retry_wait 30
  disable_retry_limit
</match>
​
<match nginx.**>
  @type elasticsearch
  host 172.20.5.21
  port 9200
  logstash_format true
  logstash_prefix nginx
  logstash_dateformat %Y.%m.%d
  include_tag_key true
  tag_key nginx_tag
  type_name nginx-log
  flush_interval 10s
  buffer_type file
  buffer_path /var/log/fluentd-buffers/elasticsearch.buffer
  buffer_queue_full_action block
  buffer_chunk_limit 2M
  buffer_queue_limit 256
  max_retry_wait 30
  disable_retry_limit
</match>
​
<system>
  process_name fluentd
</system>
EOF

注意 :Node2和Node3的Fluentd配置只需将node_name改为对应的节点名称。

步骤4:创建Docker Compose文件

Node1 EFK部署文件
复制代码
cat > /opt/cluster-deploy/docker-compose-efk-node1.yml << 'EOF'
services:
  fluentd:
    image: fluent/fluentd:v1.16-1
    container_name: fluentd
    networks:
      manage-net:
        ipv4_address: 172.20.5.11
    volumes:
      - ./config/fluentd/fluentd-node1.conf:/fluentd/etc/fluent.conf:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/log:/var/log:ro
      - fluentd-buffer:/var/log/fluentd-buffers
    environment:
      - FLUENTD_CONF=fluent.conf
    restart: unless-stopped
    logging:
      driver: none
​
networks:
  manage-net:
    external: true
​
volumes:
  fluentd-buffer:
EOF
Node2 EFK部署文件
复制代码
cat > /opt/cluster-deploy/docker-compose-efk-node2.yml << 'EOF'
services:
  fluentd:
    image: fluent/fluentd:v1.16-1
    container_name: fluentd
    networks:
      manage-net:
        ipv4_address: 172.20.5.12
    volumes:
      - ./config/fluentd/fluentd-node2.conf:/fluentd/etc/fluent.conf:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/log:/var/log:ro
      - fluentd-buffer:/var/log/fluentd-buffers
    environment:
      - FLUENTD_CONF=fluent.conf
    restart: unless-stopped
    logging:
      driver: none
​
networks:
  manage-net:
    external: true
​
volumes:
  fluentd-buffer:
EOF
Node3 EFK部署文件
复制代码
cat > /opt/cluster-deploy/docker-compose-efk-node3.yml << 'EOF'
services:
  fluentd:
    image: fluent/fluentd:v1.16-1
    container_name: fluentd
    networks:
      manage-net:
        ipv4_address: 172.20.5.22
    volumes:
      - ./config/fluentd/fluentd-node3.conf:/fluentd/etc/fluent.conf:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/log:/var/log:ro
      - fluentd-buffer:/var/log/fluentd-buffers
    environment:
      - FLUENTD_CONF=fluent.conf
    restart: unless-stopped
    logging:
      driver: none
​
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
    container_name: elasticsearch
    hostname: elasticsearch
    networks:
      manage-net:
        ipv4_address: 172.20.5.21
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
      - xpack.security.enabled=false
      - xpack.security.http.ssl.enabled=false
    volumes:
      - elasticsearch-data:/usr/share/elasticsearch/data
      - ./config/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro
    ulimits:
      memlock:
        soft: -1
        hard: -1
    restart: unless-stopped
​
  kibana:
    image: docker.elastic.co/kibana/kibana:8.11.0
    container_name: kibana
    networks:
      manage-net:
        ipv4_address: 172.20.5.23
    environment:
      - ELASTICSEARCH_HOSTS=http://172.20.5.21:9200
      - SERVER_NAME=kibana
      - SERVER_HOST=0.0.0.0
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
    restart: unless-stopped
​
networks:
  manage-net:
    external: true
​
volumes:
  elasticsearch-data:
    driver: local
  fluentd-buffer:
EOF

步骤5:启动EFK服务

在所有节点执行:

复制代码
# Node1
cd /opt/cluster-deploy
docker compose -f docker-compose-efk-node1.yml up -d

# Node2
cd /opt/cluster-deploy
docker compose -f docker-compose-efk-node2.yml up -d

# Node3
cd /opt/cluster-deploy
docker compose -f docker-compose-efk-node3.yml up -d

验证部署

检查容器状态

复制代码
docker ps | grep -E "fluentd|elasticsearch|kibana"

验证Elasticsearch

复制代码
curl http://172.20.5.21:9200

预期输出:

复制代码
{
  "name" : "elasticsearch-node1",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "...",
  "version" : {
    "number" : "8.11.0",
    ...
  },
  "tagline" : "You Know, for Search"
}

验证Kibana

访问 http://192.168.64.130:5601 ,应该能看到Kibana界面。

查看日志索引

在Kibana中执行以下操作创建索引模式:

  1. 进入 ManagementStack ManagementIndex Patterns

  2. 点击 Create index pattern

  3. 输入索引名称 docker-*nginx-*

  4. 选择时间字段 @timestamp

  5. 点击 Create index pattern

Kibana使用指南

查看容器日志

  1. 在左侧菜单点击 Discover

  2. 选择索引模式 docker-*

  3. 可以按以下字段筛选:

    • node_name:按节点筛选

    • docker_tag:按容器标签筛选

    • log:日志内容全文搜索

创建可视化

  1. 点击左侧菜单 Visualize

  2. 选择可视化类型(如 LensData Table

  3. 选择索引模式

  4. 配置聚合和筛选条件

  5. 保存可视化

创建仪表板

  1. 点击左侧菜单 Dashboard

  2. 点击 Create dashboard

  3. 点击 Add 添加已有可视化

  4. 保存仪表板

故障排除

Elasticsearch启动失败

检查内存锁定设置:

复制代码
# 检查系统限制
grep MemLock /etc/security/limits.conf

# 临时禁用内存锁定(测试用)
ulimit -l unlimited

Fluentd无法连接Elasticsearch

复制代码
# 查看Fluentd日志
docker logs fluentd

# 检查网络连通性
docker exec fluentd nc -zv elasticsearch 9200

Kibana无法连接到Elasticsearch

复制代码
# 检查Elasticsearch是否正常运行
curl http://172.20.5.21:9200/_cluster/health

# 检查Kibana日志
docker logs kibana

性能优化

Elasticsearch优化

  1. 设置分片数量:默认1个主分片足够单节点使用

  2. 调整刷新间隔:默认1秒,可适当增加

  3. 配置索引生命周期管理(ILM):自动清理旧日志

Fluentd优化

  1. 调整缓冲区大小 :根据日志量调整 buffer_chunk_limit

  2. 使用多worker:高负载时可启用多worker

  3. 过滤不必要的日志:减少传输数据量

定时清理旧日志

创建定时任务清理Elasticsearch中的旧索引:

复制代码
# 每天凌晨2点删除30天前的索引
0 2 * * * curl -XDELETE "http://172.20.5.21:9200/docker-$(date -d '30 days ago' +%Y.%m.%d)*" && \
curl -XDELETE "http://172.20.5.21:9200/nginx-$(date -d '30 days ago' +%Y.%m.%d)*"
相关推荐
这个DBA有点耶4 小时前
数据库迁移怎么做到“零翻车“:金仓 KDMS/KDTS/KFS 工具链实测
数据库·架构·dba
lucky_syq5 小时前
第5篇 · S1·下:前沿架构:MoE、Reasoning 模型、长上下文、多模态、SSM/Mamba 与模型谱系
人工智能·学习·架构
lucky_syq6 小时前
第3篇 · S1·上:什么是大语言模型 + Transformer 架构深讲
人工智能·语言模型·架构·transformer
这个DBA有点耶7 小时前
迁移中的数据一致性挑战:如何确保百万行数据“搬得对”
mysql·架构·dba
holidaypenguin7 小时前
Docker 前端本地开发指南(实操版)
docker
zlinear数据采集卡8 小时前
数据采集卡从入门到精通(10):采样率与分辨率的核心关系——反比律、架构分布与过采样
arm开发·嵌入式硬件·算法·fpga开发·架构·开源
fatcoder8 小时前
玩转Docker 08 — 实战:容器化真实后端并编排
后端·docker·容器
Hy行者勇哥9 小时前
软硬件一体化公司 企业标准体系架构
架构
她的男孩10 小时前
我用 LLM 把后台 CRUD 效率提升 10 倍:AI 代码生成器的架构与落地实践
java·后端·架构
全栈技术负责人10 小时前
解密 MCP(Model Context Protocol):大模型时代的“Type-C”总线与三驾马车架构深度解析
开发语言·ai·架构