部署三节点Elasticsearch集群:详细步骤与文件解析
Elasticsearch 是一个强大的分布式搜索和分析引擎,广泛用于日志分析、搜索服务等场景。本文将详细讲解如何在三个 Linux 节点上部署一个 Elasticsearch 集群,使用 Docker 容器化部署,确保高可用性和分布式特性。每个步骤都将包含具体的 Linux 命令、操作结果、文件说明,以及命令的详细含义。我们假设使用 Ubuntu 20.04 作为操作系统,Elasticsearch 版本为 8.15.0,Docker 作为容器化工具。
环境准备
1. 准备三台服务器
我们假设有三台服务器,IP 地址分别为:
- 节点 1:
192.168.1.101
- 节点 2:
192.168.1.102
- 节点 3:
192.168.1.103
每台服务器配置:
- 操作系统:Ubuntu 20.04
- CPU:4 核
- 内存:8GB(ES 推荐至少 4GB 堆内存)
- 磁盘:50GB 可用空间
- 网络:节点间可通过内网通信
操作: 检查服务器网络连通性。
ping -c 3 192.168.1.101
命令含义:
ping
:测试网络连通性。-c 3
:发送 3 次 ping 请求。192.168.1.101
:目标节点 IP。
操作结果(以节点 1 为例):
PING 192.168.1.101 (192.168.1.101) 56(84) bytes of data.
64 bytes from 192.168.1.101: icmp_seq=1 ttl=64 time=0.025 ms
64 bytes from 192.168.1.101: icmp_seq=2 ttl=64 time=0.030 ms
64 bytes from 192.168.1.101: icmp_seq=3 ttl=64 time=0.028 ms
--- 192.168.1.101 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
在每个节点上重复上述命令,确保节点间网络通畅。
2. 安装 Docker
在每个节点上安装 Docker 以运行 Elasticsearch 容器。
操作: 更新包索引并安装 Docker。
sudo apt update && sudo apt install -y docker.io
命令含义:
sudo apt update
:更新 Ubuntu 的软件包索引。sudo apt install -y docker.io
:安装 Docker,-y
表示自动确认。
操作结果:
Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease
...
Reading package lists... Done
Building dependency tree
...
Setting up docker.io (20.10.7-0ubuntu5~20.04.2) ...
启动 Docker 并设置开机自启:
sudo systemctl start docker
sudo systemctl enable docker
命令含义:
sudo systemctl start docker
:启动 Docker 服务。sudo systemctl enable docker
:设置 Docker 开机自启。
操作结果:
Synchronizing state of docker.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable docker
验证 Docker 安装:
docker --version
操作结果:
Docker version 20.10.7, build f0df350
3. 配置系统参数
Elasticsearch 对系统参数有特定要求,例如文件句柄数和虚拟内存设置。
操作: 修改最大文件句柄数。
sudo sysctl -w fs.file-max=65536
命令含义:
sysctl -w
:临时修改内核参数。fs.file-max=65536
:设置最大文件句柄数为 65536,ES 推荐此值以支持高并发。
操作结果:
fs.file-max = 65536
持久化配置:
echo "fs.file-max=65536" | sudo tee -a /etc/sysctl.conf
命令含义:
tee -a
:追加内容到文件。/etc/sysctl.conf
:系统内核参数配置文件。
增加虚拟内存映射范围:
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
命令含义:
vm.max_map_count=262144
:设置最大内存映射区域,ES 推荐此值以支持内存密集型操作。
操作结果:
vm.max_map_count = 262144
验证配置:
sysctl vm.max_map_count
操作结果:
vm.max_map_count = 262144
4. 创建 Elasticsearch 数据目录
为每个节点创建数据存储目录,并设置权限。
操作:
sudo mkdir -p /data/elasticsearch/data
sudo chown -R 1000:1000 /data/elasticsearch
命令含义:
mkdir -p
:递归创建目录。chown -R 1000:1000
:将目录所有者设置为 UID 和 GID 为 1000(Elasticsearch 容器默认用户)。
操作结果:
目录 /data/elasticsearch/data
创建成功,权限为 1000:1000
。
5. 拉取 Elasticsearch Docker 镜像
在每个节点上拉取 Elasticsearch 8.15.0 镜像。
操作:
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.15.0
命令含义:
docker pull
:从 Docker 仓库拉取镜像。docker.elastic.co/elasticsearch/elasticsearch:8.15.0
:官方 Elasticsearch 8.15.0 镜像。
操作结果:
8.15.0: Pulling from elasticsearch/elasticsearch
Digest: sha256:...
Status: Downloaded newer image for docker.elastic.co/elasticsearch/elasticsearch:8.15.0
配置 Elasticsearch 集群
6. 创建 Elasticsearch 配置文件
在每个节点上创建 Elasticsearch 配置文件 elasticsearch.yml
。
操作: 在节点 1 创建配置文件:
sudo mkdir -p /data/elasticsearch/config
sudo nano /data/elasticsearch/config/elasticsearch.yml
输入以下内容:
cluster.name: my-es-cluster
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["192.168.1.101", "192.168.1.102", "192.168.1.103"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
文件说明:
cluster.name
:集群名称,三个节点必须一致。node.name
:节点名称,节点 1 为node-1
,节点 2 为node-2
,节点 3 为node-3
。network.host
:绑定所有网络接口。http.port
:HTTP 服务端口。discovery.seed_hosts
:集群发现的种子节点列表。cluster.initial_master_nodes
:初始主节点列表,用于集群初始化。xpack.security.enabled
:启用 X-Pack 安全功能。xpack.security.transport.ssl.*
:配置节点间通信的 SSL 证书。
在节点 2 和 3 重复创建配置文件,修改 node.name
分别为 node-2
和 node-3
。
操作结果:
文件 /data/elasticsearch/config/elasticsearch.yml
创建成功。
7. 生成 SSL 证书
Elasticsearch 8.x 默认启用安全功能,需要 SSL 证书。
操作: 在节点 1 上生成证书:
docker run --rm -v /data/elasticsearch/config/certs:/certs docker.elastic.co/elasticsearch/elasticsearch:8.15.0 bin/elasticsearch-certutil ca --out /certs/elastic-stack-ca.p12 --pass ""
docker run --rm -v /data/elasticsearch/config/certs:/certs docker.elastic.co/elasticsearch/elasticsearch:8.15.0 bin/elasticsearch-certutil cert --ca /certs/elastic-stack-ca.p12 --out /certs/elastic-certificates.p12 --pass "" --name elasticsearch
sudo chown -R 1000:1000 /data/elasticsearch/config/certs
命令含义:
docker run --rm
:运行容器并在完成后删除。-v /data/elasticsearch/config/certs:/certs
:挂载本地目录到容器。bin/elasticsearch-certutil ca
:生成 CA 证书。bin/elasticsearch-certutil cert
:生成节点证书。--pass ""
:设置空密码(生产环境应设置强密码)。chown -R 1000:1000
:确保证书文件权限正确。
操作结果: 生成文件:
/data/elasticsearch/config/certs/elastic-stack-ca.p12
/data/elasticsearch/config/certs/elastic-certificates.p12
将证书复制到节点 2 和 3:
scp -r /data/elasticsearch/config/certs/* user@192.168.1.102:/data/elasticsearch/config/certs/
scp -r /data/elasticsearch/config/certs/* user@192.168.1.103:/data/elasticsearch/config/certs/
命令含义:
scp -r
:递归复制目录。user@192.168.1.102
:目标节点的用户和 IP。
8. 启动 Elasticsearch 容器
在每个节点上启动 Elasticsearch 容器。
操作(以节点 1 为例):
docker run -d --name es-node-1 \
-v /data/elasticsearch/data:/usr/share/elasticsearch/data \
-v /data/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /data/elasticsearch/config/certs:/usr/share/elasticsearch/config/certs \
-p 9200:9200 \
-e "ES_JAVA_OPTS=-Xms4g -Xmx4g" \
docker.elastic.co/elasticsearch/elasticsearch:8.15.0
命令含义:
-d
:后台运行容器。--name es-node-1
:容器名称。-v
:挂载数据目录、配置文件和证书目录。-p 9200:9200
:映射端口。-e "ES_JAVA_OPTS=-Xms4g -Xmx4g"
:设置 JVM 堆内存为 4GB。
操作结果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
abc123def456 docker.elastic.co/elasticsearch/elasticsearch:8.15.0 "/usr/local/bin/dock…" 2 seconds ago Up 1 second 0.0.0.0:9200->9200/tcp es-node-1
在节点 2 和 3 重复上述命令,修改容器名称为 es-node-2
和 es-node-3
。
9. 设置 Elasticsearch 密码
在节点 1 上设置用户密码。
操作: 进入节点 1 容器:
docker exec -it es-node-1 bash
命令含义:
docker exec -it
:交互式进入容器。bash
:启动 Bash shell。
在容器内运行:
bin/elasticsearch-setup-passwords auto
命令含义:
bin/elasticsearch-setup-passwords auto
:自动生成用户密码,包括elastic
用户。
操作结果(示例):
Changed password for user elastic
PASSWORD elastic = xYz123Abc
...
记录 elastic
用户密码,退出容器:
exit
10. 验证集群状态
在任意节点上验证集群健康状态。
操作:
curl -u elastic:xYz123Abc http://192.168.1.101:9200/_cluster/health
命令含义:
curl
:发送 HTTP 请求。-u elastic:xYz123Abc
:使用elastic
用户和密码认证。http://192.168.1.101:9200/_cluster/health
:查询集群健康状态。
操作结果:
{
"cluster_name": "my-es-cluster",
"status": "green",
"number_of_nodes": 3,
"number_of_data_nodes": 3,
...
}
status: green
表示集群健康。
Elasticsearch 关键文件和目录
以下是 Elasticsearch 部署中的关键文件和目录及其作用:
-
/data/elasticsearch/data:
- 作用:存储索引数据和分片。
- 内容:Elasticsearch 的数据文件,包括索引、文档和元数据。
- 注意:需要足够的磁盘空间,建议使用 SSD。
-
/data/elasticsearch/config/elasticsearch.yml:
- 作用:Elasticsearch 的主配置文件,定义集群和节点行为。
- 内容:集群名称、节点名称、网络设置、安全配置等。
-
/data/elasticsearch/config/certs/:
- 作用:存储 SSL 证书,用于节点间通信和客户端连接。
- 内容:
elastic-stack-ca.p12
:CA 证书。elastic-certificates.p12
:节点证书。
- 注意:证书需在所有节点间共享,权限为
1000:1000
。
-
/data/elasticsearch/logs/(自动生成):
- 作用:存储 Elasticsearch 日志。
- 内容:
my-es-cluster.log
(主日志文件)、GC 日志等。 - 注意:定期清理以避免磁盘满。
模拟面试官拷问环节
以下是模拟面试官针对上述部署流程的严格提问,重点考察细节理解和潜在问题处理能力。
面试官:你提到在每个节点上设置 vm.max_map_count=262144
,为什么需要这个设置?如果不设置会发生什么?
回答:vm.max_map_count
定义了系统允许的最大内存映射区域数。Elasticsearch 使用内存映射来高效访问索引文件(通过 Lucene),需要较高的内存映射区域。如果不设置或值过低(默认可能是 65530),Elasticsearch 可能因为无法创建足够的内存映射而启动失败,报错类似 max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
。设置 262144 是 Elasticsearch 官方推荐的最小值,以确保性能和稳定性。
面试官:你在 elasticsearch.yml
中启用了 xpack.security.transport.ssl
,但如果证书文件路径错误,会发生什么?如何排查?
回答:如果证书路径错误(例如 /usr/share/elasticsearch/config/certs/elastic-certificates.p12
不存在),Elasticsearch 容器启动时会失败,日志中会报错类似 java.io.FileNotFoundException: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
。排查步骤:
- 查看容器日志:
docker logs es-node-1
,查找证书相关的错误。 - 进入容器:
docker exec -it es-node-1 bash
,检查文件是否存在:ls -l /usr/share/elasticsearch/config/certs/
。 - 验证宿主机路径:
ls -l /data/elasticsearch/config/certs/
,确保证书文件存在且权限为1000:1000
。 - 检查配置文件:
cat /data/elasticsearch/config/elasticsearch.yml
,确认路径拼写正确。 - 如果证书缺失,重新生成并分发证书。
面试官:你设置了 JVM 堆内存为 4GB (-Xms4g -Xmx4g
),为什么选择这个值?如果服务器内存不足会怎样?
回答:Elasticsearch 推荐将 JVM 堆内存设置为服务器总内存的 50% 或最大 31GB,以避免直接内存访问的性能开销。这里选择 4GB 是因为每台服务器有 8GB 内存,分配一半给 ES,留给操作系统和其他进程。堆内存过大会导致垃圾回收(GC)时间过长,过小则可能导致 OutOfMemoryError
。如果服务器内存不足,可能导致:
- ES 进程被 OOM Killer 杀死。
- 系统交换内存(swap)增加,性能下降。
解决方法:监控内存使用(
free -m
),必要时调整ES_JAVA_OPTS
或升级硬件。
面试官:如果节点 2 宕机,集群会发生什么?如何恢复?
回答:如果节点 2 宕机,集群状态可能从 green
变为 yellow
,因为某些分片(主分片或副本分片)可能暂时不可用,但只要 cluster.initial_master_nodes
中定义的主节点仍在运行,集群仍可提供服务。恢复步骤:
- 检查集群状态:
curl -u elastic:<password> http://192.168.1.101:9200/_cluster/health
。 - 重启节点 2 的容器:
docker start es-node-2
。 - 验证节点加入:
curl -u elastic:<password> http://192.168.1.101:9200/_cat/nodes
。 - 如果节点无法恢复,需替换节点:
- 在新服务器上配置环境(Docker、系统参数、证书等)。
- 更新
elasticsearch.yml
,设置新节点名称。 - 启动新容器,集群会自动重新分配分片。
面试官:你没有提到防火墙配置,如果端口 9200 被防火墙阻止,会怎样?如何处理?
回答:如果防火墙阻止了 9200 端口,客户端无法访问 Elasticsearch 的 HTTP 接口,报错类似 Connection refused
。节点间的 9300 端口(传输层)如果被阻止,会导致节点无法加入集群,日志可能显示 Failed to connect to [192.168.1.102:9300]
。处理步骤:
- 检查防火墙规则:
sudo ufw status
。 - 开放端口:
sudo ufw allow 9200/tcp sudo ufw allow 9300/tcp
- 验证端口:
netstat -tuln | grep 9200
。 - 测试连接:
curl http://192.168.1.101:9200
。 生产环境中,建议使用安全组或 iptables 限制访问来源。
面试官:你的部署没有配置日志轮转,长期运行可能导致磁盘满,如何优化?
回答:Elasticsearch 的日志默认存储在 /data/elasticsearch/logs/
,长期运行可能导致磁盘空间耗尽。优化方法:
- 配置日志轮转,在
elasticsearch.yml
中添加:
这将限制单个日志文件大小为 100MB,最多保留 5 个文件。logger.level: info appender.rolling.type: RollingFile appender.rolling.fileName: /usr/share/elasticsearch/logs/my-es-cluster.log appender.rolling.policies.size.type: SizeBasedTriggeringPolicy appender.rolling.policies.size.size: 100MB appender.rolling.strategy.max: 5
- 使用外部工具如
logrotate
:
添加:sudo nano /etc/logrotate.d/elasticsearch
/data/elasticsearch/logs/*.log { daily rotate 7 compress missingok notifempty create 640 elasticsearch elasticsearch }
- 定期监控磁盘:
df -h /data/elasticsearch
。
面试官:如果我想扩展到 5 个节点,需要做什么?
回答:扩展到 5 个节点需要以下步骤:
- 准备两台新服务器(例如
192.168.1.104
和192.168.1.105
),安装 Docker,配置系统参数(vm.max_map_count
等)。 - 复制证书和配置文件到新节点。
- 在新节点上创建
elasticsearch.yml
,设置node.name
为node-4
和node-5
,其他配置与现有节点一致。 - 启动新节点的容器:
docker run -d --name es-node-4 ...
- 更新现有节点的
discovery.seed_hosts
和cluster.initial_master_nodes
(可选,视主节点策略而定)。 - 验证新节点加入:
curl -u elastic:<password> http://192.168.1.101:9200/_cat/nodes
。 - 检查分片重新分配:
curl -u elastic:<password> http://192.168.1.101:9200/_cat/shards
。