ELK + Redis Docker 企业级部署落地方案
📋 方案概述
架构设计

🚀 一、准备工作
1.1 环境要求
# 最低硬件配置
– 内存: 16GB RAM (推荐32GB+)
– 存储: 200GB SSD (推荐NVMe)
– CPU: 8核 (推荐16核+)
– 网络: 千兆网卡
# 软件要求
– Docker 20.10+
– Docker Compose 2.0+
– 操作系统: Ubuntu 20.04/22.04, CentOS 8+
# 端口规划
┌─────────────┬─────────┬───────────────┐
│ 服务 │ 端口 │ 用途 │
├─────────────┼─────────┼───────────────┤
│ Elasticsearch│ 9200 │ HTTP API │
│ Elasticsearch│ 9300 │ 节点通信 │
│ Kibana │ 5601 │ Web界面 │
│ Logstash │ 5044 │ Beats输入 │
│ Logstash │ 5000 │ TCP输入 │
│ Redis │ 6379 │ 缓存队列 │
│ Cerebro │ 9000 │ ES集群管理 │
│ Prometheus │ 9090 │ 监控 │
│ Grafana │ 3000 │ 可视化 │
└─────────────┴─────────┴───────────────┘
1.2 目录结构
elk-docker-enterprise/
├── .env # 环境变量配置
├── docker-compose.yml # 主编排文件
├── README.md # 部署文档
├── LICENSE
├── scripts/ # 维护脚本
│ ├── init.sh
│ ├── backup.sh
│ ├── restore.sh
│ └── health-check.sh
├── configs/ # 配置文件
│ ├── elasticsearch/
│ │ ├── elasticsearch.yml
│ │ ├── jvm.options
│ │ └── log4j2.properties
│ ├── kibana/
│ │ └── kibana.yml
│ ├── logstash/
│ │ ├── logstash.yml
│ │ ├── pipelines.yml
│ │ ├── patterns/ # Grok模式
│ │ └── conf.d/ # 管道配置
│ ├── filebeat/
│ │ └── filebeat.yml
│ └── redis/
│ └── redis.conf
├── data/ # 持久化数据
│ ├── elasticsearch/
│ ├── redis/
│ ├── logstash/
│ └── prometheus/
├── logs/ # 容器日志
├── certificates/ # TLS证书
│ ├── ca.crt
│ ├── elasticsearch.crt
│ └── elasticsearch.key
└── grafana/
├── dashboards/
└── provisioning/
1.3 创建部署目录
# 创建项目目录结构
mkdir -p elk-docker-enterprise/{configs,data,logs,scripts,certificates,grafana}
cd elk-docker-enterprise
# 创建子目录
mkdir -p configs/{elasticsearch,kibana,logstash/{patterns,conf.d},filebeat,redis}
mkdir -p data/{elasticsearch,redis,logstash,prometheus}
mkdir -p grafana/{dashboards,provisioning}
mkdir -p certificates
mkdir -p logs/{elasticsearch,kibana,logstash,filebeat,redis}
🐳 二、Docker Compose 编排文件
2.1 环境变量文件 (.env)
# ELK 版本配置
ELK_VERSION=8.11.0
REDIS_VERSION=7.2
# 网络配置
NETWORK_NAME=elk-network
SUBNET=172.20.0.0/16
# Elasticsearch 配置
ES_CLUSTER_NAME=elk-enterprise-cluster
ES_NODE_NAME=node-1
ES_DISCOVERY_TYPE=single-node
ES_HEAP_SIZE=4g
ES_JAVA_OPTS=-Xms4g -Xmx4g
# 安全配置
ELASTIC_PASSWORD=YourSecurePassword123!
KIBANA_PASSWORD=KibanaSecurePass456!
LOGSTASH_SYSTEM_PASSWORD=LogstashSystem789!
BEATS_SYSTEM_PASSWORD=BeatsSystemPass321!
# Redis 配置
REDIS_PASSWORD=RedisSecurePass654!
REDIS_MAXMEMORY=2gb
# 存储路径
ELK_DATA_PATH=/data/elk
ELK_LOGS_PATH=/var/log/elk
# 资源限制
ES_CPU_LIMIT=4
ES_MEMORY_LIMIT=8g
LOGSTASH_CPU_LIMIT=2
LOGSTASH_MEMORY_LIMIT=4g
KIBANA_CPU_LIMIT=1
KIBANA_MEMORY_LIMIT=2g
# 节点数量
ES_NODES_COUNT=3
LOGSTASH_NODES_COUNT=2
KIBANA_NODES_COUNT=2
2.2 Docker Compose 主文件 (docker-compose.yml)
version: \’3.8\’
networks:
elk-network:
driver: bridge
ipam:
config:
– subnet: ${SUBNET:-172.20.0.0/16}
attachable: true
volumes:
elasticsearch-data:
driver: local
driver_opts:
type: none
o: bind
device: ${ELK_DATA_PATH:-./data}/elasticsearch
redis-data:
driver: local
driver_opts:
type: none
o: bind
device: ${ELK_DATA_PATH:-./data}/redis
prometheus-data:
driver: local
services:
# ============== Redis 集群(缓冲队列)==============
redis-master:
image: redis:${REDIS_VERSION:-7.2}-alpine
container_name: redis-master
hostname: redis-master
restart: unless-stopped
command: redis-server /usr/local/etc/redis/redis.conf –requirepass ${REDIS_PASSWORD}
environment:
– REDIS_REPLICATION_MODE=master
volumes:
– ./configs/redis/redis.conf:/usr/local/etc/redis/redis.conf
– redis-data:/data
– ./logs/redis:/var/log/redis
ports:
– \”6379:6379\”
networks:
elk-network:
ipv4_address: 172.20.0.10
healthcheck:
test: [\”CMD\”, \”redis-cli\”, \”-a\”, \”${REDIS_PASSWORD}\”, \”ping\”]
interval: 10s
timeout: 5s
retries: 3
deploy:
resources:
limits:
cpus: \’1\’
memory: 2G
reservations:
cpus: \’0.5\’
memory: 1G
redis-replica:
image: redis:${REDIS_VERSION:-7.2}-alpine
container_name: redis-replica
hostname: redis-replica
restart: unless-stopped
command: redis-server /usr/local/etc/redis/redis.conf –requirepass ${REDIS_PASSWORD} –slaveof redis-master 6379
environment:
– REDIS_REPLICATION_MODE=slave
– REDIS_MASTER_HOST=redis-master
– REDIS_MASTER_PORT_NUMBER=6379
– REDIS_MASTER_PASSWORD=${REDIS_PASSWORD}
volumes:
– ./configs/redis/redis.conf:/usr/local/etc/redis/redis.conf
depends_on:
– redis-master
networks:
elk-network:
ipv4_address: 172.20.0.11
healthcheck:
test: [\”CMD\”, \”redis-cli\”, \”-a\”, \”${REDIS_PASSWORD}\”, \”ping\”]
interval: 10s
timeout: 5s
retries: 3
# ============== Elasticsearch 集群 ==============
elasticsearch-node1:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
container_name: elasticsearch-node1
hostname: elasticsearch-node1
restart: unless-stopped
environment:
– node.name=elasticsearch-node1
– cluster.name=${ES_CLUSTER_NAME:-elk-enterprise-cluster}
– cluster.initial_master_nodes=elasticsearch-node1,elasticsearch-node2,elasticsearch-node3
– discovery.seed_hosts=elasticsearch-node2,elasticsearch-node3
– bootstrap.memory_lock=true
– \”ES_JAVA_OPTS=${ES_JAVA_OPTS:–Xms4g -Xmx4g}\”
– xpack.security.enabled=true
– xpack.security.http.ssl.enabled=false
– xpack.security.transport.ssl.enabled=false
– xpack.license.self_generated.type=basic
– ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
– LOGSTASH_SYSTEM_PASSWORD=${LOGSTASH_SYSTEM_PASSWORD}
– KIBANA_SYSTEM_PASSWORD=${KIBANA_PASSWORD}
– BEATS_SYSTEM_PASSWORD=${BEATS_SYSTEM_PASSWORD}
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
– elasticsearch-data:/usr/share/elasticsearch/data
– ./configs/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
– ./configs/elasticsearch/jvm.options:/usr/share/elasticsearch/config/jvm.options
– ./logs/elasticsearch:/usr/share/elasticsearch/logs
ports:
– \”9200:9200\”
– \”9300:9300\”
networks:
elk-network:
ipv4_address: 172.20.0.20
healthcheck:
test: [\”CMD-SHELL\”, \”curl -s -u elastic:${ELASTIC_PASSWORD} http://localhost:9200/_cluster/health | grep -q \’\\\”status\\\”:\\\”green\\\”\’\”]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy:
resources:
limits:
cpus: \’${ES_CPU_LIMIT:-4}\’
memory: ${ES_MEMORY_LIMIT:-8g}
reservations:
cpus: \’${ES_CPU_LIMIT:-2}\’
memory: ${ES_MEMORY_LIMIT:-4g}
elasticsearch-node2:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
container_name: elasticsearch-node2
hostname: elasticsearch-node2
restart: unless-stopped
environment:
– node.name=elasticsearch-node2
– cluster.name=${ES_CLUSTER_NAME:-elk-enterprise-cluster}
– cluster.initial_master_nodes=elasticsearch-node1,elasticsearch-node2,elasticsearch-node3
– discovery.seed_hosts=elasticsearch-node1,elasticsearch-node3
– bootstrap.memory_lock=true
– \”ES_JAVA_OPTS=${ES_JAVA_OPTS:–Xms4g -Xmx4g}\”
– xpack.security.enabled=true
– xpack.security.http.ssl.enabled=false
– xpack.security.transport.ssl.enabled=false
– ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
ulimits:
memlock:
soft: -1
hard: -1
volumes:
– elasticsearch-data-node2:/usr/share/elasticsearch/data
– ./configs/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
– ./logs/elasticsearch-node2:/usr/share/elasticsearch/logs
networks:
elk-network:
ipv4_address: 172.20.0.21
depends_on:
– elasticsearch-node1
healthcheck:
test: [\”CMD-SHELL\”, \”curl -s http://localhost:9200/_cluster/health | grep -q \’\\\”status\\\”:\\\”green\\\”\’\”]
interval: 30s
timeout: 10s
retries: 3
elasticsearch-node3:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
container_name: elasticsearch-node3
hostname: elasticsearch-node3
restart: unless-stopped
environment:
– node.name=elasticsearch-node3
– cluster.name=${ES_CLUSTER_NAME:-elk-enterprise-cluster}
– cluster.initial_master_nodes=elasticsearch-node1,elasticsearch-node2,elasticsearch-node3
– discovery.seed_hosts=elasticsearch-node1,elasticsearch-node2
– bootstrap.memory_lock=true
– \”ES_JAVA_OPTS=${ES_JAVA_OPTS:–Xms4g -Xmx4g}\”
– xpack.security.enabled=true
– xpack.security.http.ssl.enabled=false
– xpack.security.transport.ssl.enabled=false
– ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
ulimits:
memlock:
soft: -1
hard: -1
volumes:
– elasticsearch-data-node3:/usr/share/elasticsearch/data
– ./configs/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
– ./logs/elasticsearch-node3:/usr/share/elasticsearch/logs
networks:
elk-network:
ipv4_address: 172.20.0.22
depends_on:
– elasticsearch-node1
healthcheck:
test: [\”CMD-SHELL\”, \”curl -s http://localhost:9200/_cluster/health | grep -q \’\\\”status\\\”:\\\”green\\\”\’\”]
interval: 30s
timeout: 10s
retries: 3
# ============== Logstash 集群 ==============
logstash-node1:
image: docker.elastic.co/logstash/logstash:${ELK_VERSION}
container_name: logstash-node1
hostname: logstash-node1
restart: unless-stopped
environment:
– LS_JAVA_OPTS=-Xmx2g -Xms2g
– XPACK_MONITORING_ENABLED=true
– XPACK_MONITORING_ELASTICSEARCH_URL=http://elasticsearch-node1:9200
– XPACK_MONITORING_ELASTICSEARCH_USERNAME=logstash_system
– XPACK_MONITORING_ELASTICSEARCH_PASSWORD=${LOGSTASH_SYSTEM_PASSWORD}
– ELASTICSEARCH_HOSTS=http://elasticsearch-node1:9200
volumes:
– ./configs/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml
– ./configs/logstash/pipelines.yml:/usr/share/logstash/config/pipelines.yml
– ./configs/logstash/conf.d:/usr/share/logstash/pipeline
– ./configs/logstash/patterns:/usr/share/logstash/patterns
– ./logs/logstash:/usr/share/logstash/logs
ports:
– \”5044:5044\” # Beats input
– \”5000:5000\” # TCP input
– \”5001:5001\” # UDP input
– \”9600:9600\” # Logstash monitoring API
networks:
elk-network:
ipv4_address: 172.20.0.30
depends_on:
– elasticsearch-node1
– redis-master
healthcheck:
test: [\”CMD\”, \”curl\”, \”-f\”, \”http://localhost:9600\”]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy:
resources:
limits:
cpus: \’${LOGSTASH_CPU_LIMIT:-2}\’
memory: ${LOGSTASH_MEMORY_LIMIT:-4g}
reservations:
cpus: \’1\’
memory: 2g
logstash-node2:
image: docker.elastic.co/logstash/logstash:${ELK_VERSION}
container_name: logstash-node2
hostname: logstash-node2
restart: unless-stopped
environment:
– LS_JAVA_OPTS=-Xmx2g -Xms2g
– XPACK_MONITORING_ENABLED=true
– XPACK_MONITORING_ELASTICSEARCH_URL=http://


