- Published on
Elasticsearch Docker
- Authors
- Name
- Shelton Ma
0. 最佳实践
1. 生产环境建议
- 至少 3 个 Master(不能是 2 个)
- node.roles 明确区分 Master / Data / Coordinator
- 启用 xpack.security 避免未授权访问
1. docker搭建
拉取并运行 Elasticsearch
# 参数解释: # -d:后台运行容器 # --name elasticsearch:给容器命名 # -p 9200:9200:映射 REST API 端口 # -p 9300:9300:映射集群通信端口 # -e "discovery.type=single-node":单节点模式(适用于开发) # -e "ES_JAVA_OPTS=-Xms512m -Xmx512m":限制内存,防止占用过多资源 docker run -d --name elasticsearch \ -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \ docker.elastic.co/elasticsearch/elasticsearch:6.8.13
拉取并运行 Kibana
docker run -d --name kibana \ -p 5601:5601 --link elasticsearch:elasticsearch \ docker.elastic.co/kibana/kibana:6.12.0
2. docker compose 开发环境搭建, es单节点
1. 创建网络
docker network create es_network
2. 启动时使用es_network网络
docker_compose.yml
version: "3.8" services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0 container_name: elasticsearch environment: - discovery.type=single-node # 单节点模式 - xpack.security.enabled=false # 关闭认证(测试环境) - ES_JAVA_OPTS=-Xms512m -Xmx512m # 限制内存 ports: - "9200:9200" - "9300:9300" volumes: - es_data:/usr/share/elasticsearch/data kibana: image: docker.elastic.co/kibana/kibana:8.12.0 container_name: kibana environment: - ELASTICSEARCH_HOSTS=http://elasticsearch:9200 ports: - "5601:5601" depends_on: - elasticsearch volumes: es_data: driver: local networks: default: name: es_network external: true
启动命令
docker-compose -f docker-compose.dev.yml up -d
访问地址:
- Elasticsearch: http://localhost:9200
- Kibana: http://localhost:5601
3. 生产环境, 高可用集群
适用于 Kubernetes(EKS)或 Docker Swarm
- es master节点设置为奇数, 避免
split-brain
问题 - 持久化存储(Volumes)
- 使用统一网络
- 开启 Heap Dump 以排查 OOM
- es master节点设置为奇数, 避免
docker-compose.pod.yml
version: "3.8" services: es-master: image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0 container_name: es-master environment: - node.name=es-master - cluster.name=es-cluster - node.roles=master - discovery.seed_hosts=es-node1,es-node2 - cluster.initial_master_nodes=es-master - ELASTIC_PASSWORD=changeme # 生产环境建议更改 - xpack.security.enabled=true # 启用认证 - bootstrap.memory_lock=true # 避免内存交换影响性能 - ES_JAVA_OPTS=-Xms1g -Xmx1g ulimits: memlock: soft: -1 hard: -1 ports: - "9200:9200" volumes: - es_master_data:/usr/share/elasticsearch/data es-node1: image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0 container_name: es-node1 environment: - node.name=es-node1 - cluster.name=es-cluster - node.roles=data - discovery.seed_hosts=es-master,es-node2 - cluster.initial_master_nodes=es-master - ELASTIC_PASSWORD=changeme - xpack.security.enabled=true - bootstrap.memory_lock=true - ES_JAVA_OPTS=-Xms1g -Xmx1g volumes: - es_node1_data:/usr/share/elasticsearch/data es-node2: image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0 container_name: es-node2 environment: - node.name=es-node2 - cluster.name=es-cluster - node.roles=data - discovery.seed_hosts=es-master,es-node1 - cluster.initial_master_nodes=es-master - ELASTIC_PASSWORD=changeme - xpack.security.enabled=true - bootstrap.memory_lock=true - ES_JAVA_OPTS=-Xms1g -Xmx1g volumes: - es_node2_data:/usr/share/elasticsearch/data kibana: image: docker.elastic.co/kibana/kibana:8.12.0 container_name: kibana environment: - ELASTICSEARCH_HOSTS=<https://es-master:9200> - ELASTICSEARCH_USERNAME=elastic - ELASTICSEARCH_PASSWORD=changeme - SERVER_SSL_ENABLED=false ports: - "5601:5601" depends_on: - es-master volumes: es_master_data: driver: local es_node1_data: driver: local es_node2_data: driver: local networks: default: name: es_network external: true # 开启 Heap Dump 以排查 OOM environment: - ES_JAVA_OPTS=-Xms2g -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/share/elasticsearch/logs
启动
docker-compose -f docker-compose.prod.yml up -d
4. 背景
1. 什么是脑裂(split brain)问题
在 Elasticsearch(ES)集群 中,Split-Brain(脑裂) 发生在 主节点(Master)竞争 过程中, 网络分区(Network Partition)导致集群分裂为两个或多个独立部分.
后果:
- 多个主节点同时存在 → 数据更新冲突,导致数据不一致.
- 部分节点无法访问其他节点 → 影响查询或写入,部分数据丢失.
- 举个例子: 假设有 3 个节点的集群:node1(Master)、node2、node3, node1 和 node2 突然失去与 node3 的网络连接, node3 认为 node1 挂了,于是自己选举为 Master, 现在 node1 和 node3 都是 Master(脑裂!), 这两个 Master 可能会分别接受写入数据,导致数据不一致
2. 如何解决脑裂问题
Elasticsearch 采用 Zen Discovery(7.x 及以下)和 Cluster Coordination(8.x 及以上)来防止脑裂问题,主要有以下方案:
确保 Master 节点数量为奇数
原理:奇数个 Master 通过 "过半数投票" 来避免多个 Master, 3、5、7 个 Master 节点(推荐)
environment: - discovery.seed_hosts=es-master1,es-master2,es-master3 - cluster.initial_master_nodes=es-master1,es-master2,es-master3
只允许特定节点选举 Master 原理:限制选举 Master 的范围 设置 node.roles=master 只让 Master 角色的节点被选举.
- node.roles=master
配置 minimum_master_nodes(7.x 及以下) 原理:需要至少 N 个 Master 参与选举, 计算公式:minimum_master_nodes = (N / 2) + 1
- discovery.zen.minimum_master_nodes=2