Elasticsearch 8.7.1 Ubuntu 22.04 部署实战:从安全配置到系统调优
2026/9/13 16:25:22 网站建设 项目流程

1. 部署前的关键认知:8.x 和 7.x 的安装逻辑已经不一样了

先交代一下背景。我自己在 Ubuntu 服务器上部署过好几轮 Elasticsearch,从 6.x 一路用到 8.x,每次升级都会被几个不大不小的坑绊一下。如果你之前接触过 7.x,那你一定要先纠正一个惯性思维:8.x 的安装和初始化流程,从默认配置到安全机制,完全不是“升个版本号”那么简单。

Elasticsearch 8.7.1 属于 8.x 中期版本,这个版本最大的变化在于三点:

第一,整包自带 JDK。官方从 7.0 开始就内置了 OpenJDK,8.7.1 更是明确要求在启动时使用内置 JDK 或自行指定兼容版本。很多人习惯性的先去系统里装 Java,其实这一步不是必须的。除非你想用系统自带的 JDK 17,否则完全可以跳过装 Java 这个环节。我实测过,用内置 JDK 跑起来最省心,不用处理 JAVA_HOME 路径冲突。

第二,安全默认开启。8.x 安装完成后会自动生成 elastic 超级用户的密码,同时启用 HTTPS 和 TLS 加密通信。这跟 7.x 默认裸奔的风格截然不同。很多教程还停留在“装完直接 curl localhost:9200”的阶段,你照做的话会直接看到 unrecognized command error 或者证书报错。

第三,系统参数要求更严格。ES 8.x 启动时会强制检查内核参数 vm.max_map_count、文件描述符限制、线程数限制,任何一个不满足都会直接拒绝启动。这一点在 Ubuntu 22.04 上尤其容易踩:22.04 默认的 vm.max_map_count 是 65530,而 ES 要求至少 262144,不修改就会报错。

所以这篇文章不是简单地把官网下载命令搬一遍,而是把从零开始到“能跑业务”的全链路操作串起来,包含我实测时踩过的坑和验证过的配置。适合刚接触 Elasticsearch 的运维新手,也适合从 7.x 迁移到 8.x、急需补安全机制课的朋友。

2. 初始环境准备与下载源选择

2.1 查看系统基本信息,确认运行环境

我把这次部署放在一台刚装好 Ubuntu 22.04 LTS 的虚拟机上,4 核 CPU、8GB 内存、50GB 硬盘。在开始之前,先养好一个习惯:确认系统架构、内核版本、可用内存。因为 ES 虽然对系统没太多硬性要求,但架构选错会导致安装包直接装不上,内存不够会让 JVM 启动即崩溃。

# 查看系统版本 lsb_release -a # 查看内核版本 uname -a # 查看 CPU 架构 uname -m # 查看内存情况 free -h

在 Ubuntu 22.04 上,lsb_release -a 输出的 Description 一般是 Ubuntu 22.04.2 LTS 之类。注意这里有个小细节:如果你用 uname -m 看到的是 x86_64,那下载包就选 x86_64 架构的 tar.gz;如果看到的是 aarch64,就需要下载 ARM 版本。ES 8.7.1 官网包列表里明确区分了这两个架构,下错了会直接报 “cannot execute binary file” 之类的错误。

内存方面,建议至少 4GB 可用内存。ES 默认 JVM 堆占用是机器物理内存的一半,在一台 8GB 内存的机器上,默认会给 JVM 分配约 4GB。如果内存低于 4GB,启动时大概率会出现 “memory locking requested for elasticsearch process but memory is not locked” 之类的错误,原因请往后面看第三节的 JVM 配置。

2.2 对比三种安装方式:apt、tar.gz、deb

安装 ES 8.7.1 常见的有三种方式,我在不同环境里都试过,先把结论放出来:

安装方式优点缺点适合场景
apt 官方仓库升级方便,systemd 服务自动配置仓库连接国内网络较慢,ES 版本更新滞后生产环境、长期维护
tar.gz 手动解压自由度最高,目录位置随意需要自己写 systemd 或手动启动多实例部署、自定义目录结构
deb 包安装安装快捷,自动注册 systemd 服务目录结构固定,想改 path 很麻烦快速部署单实例

我自己这次选择的是tar.gz方式,原因有三:第一,ES 8.x 的目录结构比较清晰,解压即用,想换目录随时挪;第二,便于同时做数据目录、日志目录的分区隔离;第三,tar.gz 包在官方 tar 下载页面上更新最及时,apt 仓库有时还停留在 8.6.x。

不过如果追求省事,生产环境直接上 apt 也可以,只是你在执行 apt update 之前需要先把 Elastic 官方签名密钥导入,否则仓库连接会报错。这个细节后面会补一句,但我在正文中主要按 tar.gz 的路线走。

2.3 下载 Elasticsearch 8.7.1 安装包与校验

确定方案后就是下载。官方下载地址是https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.7.1-linux-x86_64.tar.gz。我建议用 wget 直接拉包,不要用什么图形化浏览器,也别在 Windows 上下载再上传,效率太低。

# 安装 wget(如果还没有) sudo apt update && sudo apt install -y wget # 下载 ES 8.7.1 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.7.1-linux-x86_64.tar.gz # 下载校验文件 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.7.1-linux-x86_64.tar.gz.sha512 # 校验文件完整性 shasum -a 512 -c elasticsearch-8.7.1-linux-x86_64.tar.gz.sha512

校验这一步很多人会跳过去,我劝你别省。网络传输过程中文件损坏的概率虽然低,但一旦出现,解压报错你能排查到怀疑人生。校验结果会输出类似elasticsearch-8.7.1-linux-x86_64.tar.gz: OK的信息,看到 OK 再继续。

如果你在服务器上下载速度很慢,可以自己换镜像源,但注意不要因为图快下载到了第三方重新打包的版本,安全性风险太高。官方包已经够用了。

3. 创建运行用户和调整系统参数

3.1 为什么不能直接用 root 运行 Elasticsearch

这是 ES 的一个硬性约束。ES 出于安全考虑,禁止 root 用户直接启动,因为在 Java 层面它需要限制自身的系统权限,防止因漏洞被利用时扩大影响范围。官方文档里写得很清楚:can not run elasticsearch as root。

所以我通常会新建一个专用用户,比如 es 用户,然后把 ES 整个目录 owner 改成这个用户。这一步看似多余,但在生产环境里非常必要,因为 ES 进程只需要对自己目录下有写权限,不需要其他系统权限,这也符合最小权限原则。

# 创建 es 用户 sudo useradd -m -s /bin/bash es # 将解压目录移动到 /opt 下 sudo mkdir -p /opt/elasticsearch sudo tar -xzf elasticsearch-8.7.1-linux-x86_64.tar.gz -C /opt/elasticsearch # 修改目录归属 sudo chown -R es:es /opt/elasticsearch/elasticsearch-8.7.1

把 ES 放在 /opt 下是我个人的习惯,因为 /opt 在 Linux 文件系统标准里就是放第三方软件的目录,日志也容易配合 logrotate 做轮转。你们可以按公司规范调整目录位置,但一定要保证这个目录所在的磁盘有足够的空间,索引文件体积增长速度远超预期。

3.2 修改 vm.max_map_count 与文件描述符限制

这一步是新人最容易翻车的地方。ES 启动时会检查三个系统级别的参数,不满足就直接 exit。

第一个是 vm.max_map_count,这个参数控制进程能拥有的最大内存映射区域数量。ES 底层使用 Lucene,它内部有大量的文件映射操作,如果映射数太少会报max virtual memory areas vm.max_map_count [65530] is too low。Ubuntu 22.04 默认值是 65530,ES 要求至少 262144,所以必须改。

# 永久修改 vm.max_map_count sudo sysctl -w vm.max_map_count=262144 echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf # 生效 sudo sysctl -p

第二个是文件描述符限制。ES 需要打开大量的文件句柄,默认的 1024 肯定不够,至少要 65535。如果用 tar.gz 方式启动,需要通过修改 /etc/security/limits.conf 来提升权限。

echo 'es soft nofile 65535' | sudo tee -a /etc/security/limits.conf echo 'es hard nofile 65535' | sudo tee -a /etc/security/limits.conf echo 'es soft nproc 4096' | sudo tee -a /etc/security/limits.conf echo 'es hard nproc 4096' | sudo tee -a /etc/security/limits.conf

注意,如果你在/etc/security/limits.conf里设置了 nofile 的上限,登录用户是否生效取决于你启动 ES 的方式。手动 su 过去启动是可以生效的,但如果通过 systemd 启动则需要单独配置 LimitNOFILE,这一点第三节会再提。

第三是线程数限制,一般通过 nproc 配置即可,ES 默认最大线程数是 4096,限制太小会报max number of threads [1024] for user is too low

3.3 设置 JVM 堆内存

ES 8.7.1 在启动时默认堆内存是 1GB(-Xms1g -Xmx1g),如果你数据量不大、内存也有限,这个值够用。但如果你想让 ES 承载更多数据或高并发查询,最好手动调整堆内存。

这里要强调一个原则:ES 的 JVM 堆不要超过物理内存的一半。因为 ES 除了 JVM 堆之外,还要用大量堆外内存来缓存 Lucene 的段数据、文件系统缓存、网络缓冲区等。你把 JVM 堆设得太大,反而会因为堆外内存不足导致性能剧烈下降甚至 OOM。

JVM 配置位于config/jvm.options。我这台机器内存 8GB,给它分配 4GB 堆比较合理:

-Xms4g -Xmx4g

注意 -Xms 和 -Xmx 最好设成一样的值,避免堆动态伸缩时产生不必要的 GC 压力。另外在实际生产环境里,我见过不少把 -Xmx 值设成里物理内存 90% 的做法,结果查询量一上来系统直接卡死。老老实实保守一点。

4. 安装并配置 elasticsearch.yml

4.1 修改关键配置:节点名、路径、网络

在启动之前,需要编辑 ES 主配置文件config/elasticsearch.yml。这个文件里默认全是注释,我们逐项放开关键参数。我的配置参考如下:

# ======================== Elasticsearch Configuration ========================= cluster.name: my-es-cluster node.name: node-1 path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch network.host: 0.0.0.0 http.port: 9200 discovery.seed_hosts: ["node-1"] cluster.initial_master_nodes: ["node-1"]

这里每项的用途我解释一下:

  • cluster.name:给集群起个名字,单节点也要设置,避免以后加入其他节点时集群混乱。
  • node.name:当前节点的名称,默认会取主机名。我一般显式指定,因为日志里排查节点更方便。
  • path.datapath.logs:数据目录和日志目录。我习惯把数据目录放到独立挂载盘,避免系统盘写满拖垮主机。
  • network.host:默认是 localhost,只允许本机访问。如果需要其他机器远程访问,就改成0.0.0.0监听所有网卡。这只是解决“远程无法访问”的第一步,后续还有安全认证要处理。
  • discovery.seed_hostscluster.initial_master_nodes:集群发现的种子主机和初始 master 节点。单节点部署时把两者都指向自己即可,不然会陷入master not discovered yet的循环日志。

如果你只是本机测试,network.host 可以保持默认,不用暴露到公网。但如果你要接入业务,那就得配上 0.0.0.0,并且要在防火墙里放行 9200 端口。

4.2 8.x 安全配置:初始密码与证书机制

这是 8.x 区别于 7.x 的重点。

在 tar.gz 方式下,ES 在首次启动时如果检测到安全配置没有关闭,会自动生成以下内容:

  • 一个名为elastic的超级用户的随机密码
  • 一个为节点间通信签发的 TLS 证书和密钥
  • 一个 CA 证书,位于config/certs目录

更具体地说,首次启动后,终端会输出一段类似下面的信息:

The generated password for the elastic built-in superuser is : xxxxxxxx

这一大串随机密码是唯一的,忘记就只能重置。因此我建议你启动前先在配置里加上这几行,方便后面管理:

xpack.security.enabled: true xpack.security.enrollment.enabled: true

然后按顺序执行:

# 生成证书 bin/elasticsearch-certutil cert -s -p=password -out config/certs/elastic-certificates.p12 # 在 elasticsearch.yml 中配置证书路径 echo 'xpack.security.transport.ssl.enabled: true' >> config/elasticsearch.yml echo 'xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12' >> config/elasticsearch.yml echo 'xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12' >> config/elasticsearch.yml

如果你的集群只是单节点,最简单的做法其实是用默认自动生成的证书,不需要手动执行 certutil。我自己首次部署时习惯手动生成一遍,因为后面如果扩展多节点,这些证书可以直接复制到新节点,省得再整套生成。

但有一点必须提醒:elasticsearch-certutil cert这条命令执行后,会生成一个加密的 PKCS#12 文件,后续启动时如果不输入密码会报错。所以在执行命令时,可以直接用--password参数指定密码,不建议留空,除非你能确保你的目录权限安全。

4.3 启动方式:前台启动与后台启动

启动命令很简单,但有两种方式:

# 切换用户 sudo -u es -H bash # 方式1:前台启动(便于查看日志) cd /opt/elasticsearch/elasticsearch-8.7.1 ./bin/elasticsearch # 方式2:后台启动 ./bin/elasticsearch -d -p pid

前台启动适合第一轮调试:肉眼看到启动日志、发现报错、改配置再重启。等确认无误后,再改成后台启动或者做成 systemd 服务。千万不要一上来就-d后台跑,否则报错信息被吞掉,排查起来效率极低。

我第一次启动时看到日志停在"publish_address {127.0.0.1:9300}"之后就没反应了,当时以为是卡住了,其实是 ES 正在做安全初始化,需要等 10 到 30 秒。用前台启动能看到完整流程,心里踏实。

4.4 验证启动状态和密码重置步骤

启动成功后,浏览器或 curl 访问需要带上用户密码。比如:

curl -k -u elastic:这里填密码 https://localhost:9200

注意两点:第一,因为启用了 HTTPS,-k参数是忽略 SSL 证书校验,本地测试可以加,正式环境应把证书加到信任链里;第二,密码是刚才自动生成的,如果你还没复制到或丢失了,可以用下面命令重置:

bin/elasticsearch-reset-password -u elastic

它会重新生成一个新密码并打印出来。不过这个命令要求认证用户有权限操作,如果你连 elastic 的密码都忘了,那就用:

bin/elasticsearch-setup-passwords auto

这一条会自动重置所有内置账号的密码,并且会统一输出。我建议密码生成后第一时间存到密码管理工具里。

5. 调优与常见问题排查实录

5.1 启动时报错的 5 个高频问题

我把自己在 Ubuntu 22.04 上部署 ES 8.7.1 过程中遇到过的错误列成一张速查表,方便你遇到时对照解决:

报错信息原因解决方案
max virtual memory areas vm.max_map_count [65530] is too low内核参数不满足按上文修改 vm.max_map_count 为 262144
memory locking requested for elasticsearch process but memory is not locked内存锁配置不对修改/etc/security/limits.conf或者config/jvm.options中加-XX:+UseLargePages;更简单的方法是关闭bootstrap.memory_lock: false
failed to obtain node locks数据目录被占用或权限不足停掉其他 ES 进程,chown 数据目录给 es 用户
unrecognized main optionunable to load JNA library使用的 JDK 版本不对检查 JAVA_HOME,推荐用内置 JDK 17,或安装 OpenJDK 17
initial master nodes [...] may be discovered via IPv4/IPv6警告,节点无法成为 masternetwork.host 配置为空或主机名无法解析在 elasticsearch.yml 中显式配置network.hostcluster.initial_master_nodes

其中 “node locks” 问题最容易踩。用 root 启动过 ES 之后,再切到 es 用户启动就会报这个错,因为数据目录的属主还是 root。改完 chown 即可。

5.2 内存锁与 systemd 服务配置的细节坑

如果你按照官方文档开启了 bootstrap.memory_lock,也就是启用了bootstrap.memory_lock: true,那么内核会尝试锁定 ES 进程的地址空间,防止内存被 swap 到磁盘。这在生产环境能显著提升性能。

但如果你用 systemd 管理 ES,这个设置通常会导致启动失败,因为 systemd 默认不会给服务分配锁定内存的权限。你需要编辑 systemd 服务文件,加入:

LimitMEMLOCK=infinity

如果你是用/etc/init.d/elasticsearch这类脚本来管理,还需要确认 es 用户在/etc/security/limits.conf里的 memlock 配置:

echo 'es soft memlock unlimited' | sudo tee -a /etc/security/limits.conf echo 'es hard memlock unlimited' | sudo tee -a /etc/security/limits.conf

我实测的经验是:对于单节点测试环境,bootstrap.memory_lock 设成 false 也没啥大问题;对于集群或生产环境,尽量开启。

5.3 7.x 升级到 8.x 时的 TLS 兼容问题

最后再聊一个特别容易被忽略的问题:如果你原来是 7.x 集群,往 8.7.1 迁移时,节点之间跨大版本通信需要开启兼容模式。

ES 官方给出的路径是:7.10 及以后版本可以直接滚转到 8.x,但需要设置xpack.security.transport.ssl.enabled: true。也就是说,8.x 强制要求运输层 TLS,而 7.x 默认是不加密的。如果你不提前在 7.x 侧把安全功能打开,直接混部会导致 8.x 节点无法与 7.x 节点握手。

这个坑我印象很深。当时迁移测试集群的时候,我一边在跑两个版本,一边查日志,最后发现 8.x 节点一直在handshake failed,根本原因就是 7.x 旧节点没有启用 TLS。所以如果要跨版本迁移,先把 7.x 安全功能升级并验证通过,再执行滚动升级,安全第一。

6. 用 Docker 安装 ES 8.7.1 的补充方案

如果你不想在物理机或者虚拟机上折腾系统目录权限,Docker 也是一个省心选择。Ubuntu 22.04 上安装 Docker 的流程很成熟,装完 Docker 之后,ES 8.7.1 容器可以直接拉镜像跑:

docker pull docker.elastic.co/elasticsearch/elasticsearch:8.7.1 # 创建数据目录 mkdir -p /opt/esdata && chmod 777 /opt/esdata # 启动容器 docker run -d \ --name es871 \ -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e "xpack.security.enabled=true" \ -e "ELASTIC_PASSWORD=你的密码" \ -v /opt/esdata:/usr/share/elasticsearch/data \ docker.elastic.co/elasticsearch/elasticsearch:8.7.1

有几个细节需要提醒:

  • 容器内运行用户是 uid 1000,目录权限如果不对,容器启动会报 permission denied。给 /opt/esdata 用 chmod 777 是最快的办法,生产环境建议用更精细的 uid 映射。
  • 容器启动后访问同样是 HTTPS 方式:curl -k -u elastic:你的密码 https://localhost:9200
  • 容器停止再启动时,数据不会丢,因为数据卷已经挂载到宿主机目录。
  • 用单节点模式跑,不需要配置 cluster.initial_master_nodes,这只是容器内部自动配置的单节点模式。
  • 如果需要在容器上开内存锁,需要加--ulimit memlock=-1:-1参数。

Docker 方式的好处是环境隔离,不会因为改系统内核参数影响其他服务。但坏处也是显而易见的:生产环境多节点编排时,容器内存、网络、存储的管理复杂度会高不少。如果只是自己测试学习,Docker 真的很快;如果要上生产,我更推荐传统 tar.gz + systemd 或直接上官方 Helm Chart(如果是 K8s 环境)。

7. 其他命令速记:启动、停止、查看状态

这部分是辅助内容,但实用性很高。很多新手第一次启动成功之后,不知道怎么优雅地停掉它,我把自己常用的命令列出来:

# 前台启动 ./bin/elasticsearch # 后台启动并记录 PID ./bin/elasticsearch -d -p /tmp/elasticsearch.pid # 停止后台进程 kill $(cat /tmp/elasticsearch.pid) # 查看进程 ps -ef | grep elasticsearch # 查看日志 tail -f /opt/elasticsearch/elasticsearch-8.7.1/logs/my-es-cluster.log

如果忘记 PID 文件在哪里,用jps命令也能看到 Elasticsearch 进程:

jps -l

进程输出里会有一个 Elasticsearch 主类,直接 kill 对应的 PID 就可以了。不要用pkill -9 -f elasticsearch这种暴力做法,容易造成数据目录锁没有释放,下次启动直接报 node locks 错误。

最后再分享一个我在实际操作中的体会:多花五分钟做验证,胜过启动失败后花半小时翻日志。每次改完配置文件,先用./bin/elasticsearch -V检查版本和 JVM 参数是否能正常加载,再用./bin/elasticsearch前台启动看一下日志,确认无 error 后再切后台。这套流程用熟了,后面无论是升级版本、加节点、换磁盘路径,都能稳稳当当。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询