部署三节点Elasticsearch集群:详细步骤与文件解析

21 阅读11分钟

部署三节点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-2node-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-2es-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 部署中的关键文件和目录及其作用:

  1. /data/elasticsearch/data

    • 作用:存储索引数据和分片。
    • 内容:Elasticsearch 的数据文件,包括索引、文档和元数据。
    • 注意:需要足够的磁盘空间,建议使用 SSD。
  2. /data/elasticsearch/config/elasticsearch.yml

    • 作用:Elasticsearch 的主配置文件,定义集群和节点行为。
    • 内容:集群名称、节点名称、网络设置、安全配置等。
  3. /data/elasticsearch/config/certs/

    • 作用:存储 SSL 证书,用于节点间通信和客户端连接。
    • 内容
      • elastic-stack-ca.p12:CA 证书。
      • elastic-certificates.p12:节点证书。
    • 注意:证书需在所有节点间共享,权限为 1000:1000
  4. /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。排查步骤:

  1. 查看容器日志:docker logs es-node-1,查找证书相关的错误。
  2. 进入容器:docker exec -it es-node-1 bash,检查文件是否存在:ls -l /usr/share/elasticsearch/config/certs/
  3. 验证宿主机路径:ls -l /data/elasticsearch/config/certs/,确保证书文件存在且权限为 1000:1000
  4. 检查配置文件:cat /data/elasticsearch/config/elasticsearch.yml,确认路径拼写正确。
  5. 如果证书缺失,重新生成并分发证书。

面试官:你设置了 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 中定义的主节点仍在运行,集群仍可提供服务。恢复步骤:

  1. 检查集群状态:curl -u elastic:<password> http://192.168.1.101:9200/_cluster/health
  2. 重启节点 2 的容器:docker start es-node-2
  3. 验证节点加入:curl -u elastic:<password> http://192.168.1.101:9200/_cat/nodes
  4. 如果节点无法恢复,需替换节点:
    • 在新服务器上配置环境(Docker、系统参数、证书等)。
    • 更新 elasticsearch.yml,设置新节点名称。
    • 启动新容器,集群会自动重新分配分片。

面试官:你没有提到防火墙配置,如果端口 9200 被防火墙阻止,会怎样?如何处理?

回答:如果防火墙阻止了 9200 端口,客户端无法访问 Elasticsearch 的 HTTP 接口,报错类似 Connection refused。节点间的 9300 端口(传输层)如果被阻止,会导致节点无法加入集群,日志可能显示 Failed to connect to [192.168.1.102:9300]。处理步骤:

  1. 检查防火墙规则:sudo ufw status
  2. 开放端口:
    sudo ufw allow 9200/tcp
    sudo ufw allow 9300/tcp
    
  3. 验证端口:netstat -tuln | grep 9200
  4. 测试连接:curl http://192.168.1.101:9200。 生产环境中,建议使用安全组或 iptables 限制访问来源。

面试官:你的部署没有配置日志轮转,长期运行可能导致磁盘满,如何优化?

回答:Elasticsearch 的日志默认存储在 /data/elasticsearch/logs/,长期运行可能导致磁盘空间耗尽。优化方法:

  1. 配置日志轮转,在 elasticsearch.yml 中添加:
    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
    
    这将限制单个日志文件大小为 100MB,最多保留 5 个文件。
  2. 使用外部工具如 logrotate
    sudo nano /etc/logrotate.d/elasticsearch
    
    添加:
    /data/elasticsearch/logs/*.log {
        daily
        rotate 7
        compress
        missingok
        notifempty
        create 640 elasticsearch elasticsearch
    }
    
  3. 定期监控磁盘:df -h /data/elasticsearch

面试官:如果我想扩展到 5 个节点,需要做什么?

回答:扩展到 5 个节点需要以下步骤:

  1. 准备两台新服务器(例如 192.168.1.104192.168.1.105),安装 Docker,配置系统参数(vm.max_map_count 等)。
  2. 复制证书和配置文件到新节点。
  3. 在新节点上创建 elasticsearch.yml,设置 node.namenode-4node-5,其他配置与现有节点一致。
  4. 启动新节点的容器:
    docker run -d --name es-node-4 ...
    
  5. 更新现有节点的 discovery.seed_hostscluster.initial_master_nodes(可选,视主节点策略而定)。
  6. 验证新节点加入:curl -u elastic:<password> http://192.168.1.101:9200/_cat/nodes
  7. 检查分片重新分配:curl -u elastic:<password> http://192.168.1.101:9200/_cat/shards