Skip to content
ES
安装与配置

安装与配置

Elasticsearch 的 Docker 部署与插件配置速查,涵盖 ES + Kibana + 分词插件 + 安全认证 + SSH 隧道远程访问。


环境准备

查看系统架构

uname -m
# x86_64 → amd64 镜像
# aarch64 → arm64 镜像

根据架构去 Docker 官方镜像站 选择对应镜像。

系统级调优(生产必备)

# 增加虚拟内存映射数(ES 使用 mmap 存储索引)
sudo sysctl -w vm.max_map_count=262144

# 永久生效
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf

🚨 陷阱:Linux 下 ES 默认使用 mmapfs 存储索引,需要大量虚拟内存映射。如果不调高 vm.max_map_count,ES 启动时会报 max virtual memory areas vm.max_map_count [65530] is too low 而退出。

# 增加文件描述符上限
ulimit -n 65536

Docker 安装 Elasticsearch

拉取镜像

docker pull docker.elastic.co/elasticsearch/elasticsearch:9.3.4-amd64

⚠️ 版本兼容性提醒:ES、Kibana 和所有插件(IK、拼音)必须版本号严格一致(如全是 9.3.4),否则会出现不兼容错误。

创建数据目录

mkdir -p /home/developer/es-data

授予权限

sudo chown -R 1000:1000 /home/developer/es-data
sudo chmod -R 775 /home/developer/es-data

🔬 深入原理:ES 容器内部以 uid=1000elasticsearch 用户)运行,而非 root。宿主机挂载的目录所有权必须与此用户匹配,否则 ES 无法写入数据。

启动容器

简单启动(开发/测试环境):

docker run -d \
    --name es \
    -p 9200:9200 \
    -p 9300:9300 \
    -e "discovery.type=single-node" \
    -e "xpack.security.enabled=false" \
    -v /home/developer/es-data:/usr/share/elasticsearch/data \
    docker.elastic.co/elasticsearch/elasticsearch:9.3.4-amd64

限定资源启动(低配服务器):

docker run -d \
    --name es \
    -p 9200:9200 \
    -p 9300:9300 \
    -e "discovery.type=single-node" \
    -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
    -e "xpack.security.enabled=false" \
    -v /home/developer/es-data:/usr/share/elasticsearch/data \
    docker.elastic.co/elasticsearch/elasticsearch:9.3.4-amd64
参数 说明
-p 9200:9200 HTTP API 端口(客户端 REST 调用)
-p 9300:9300 集群内部传输端口(节点间通信)
discovery.type=single-node 单节点模式,跳过集群发现
ES_JAVA_OPTS JVM 参数,-Xms-Xmx 应设为相同值,避免堆 resize
xpack.security.enabled ES 8.x+ 默认开启安全认证;测试环境可关闭

💡 最佳实践:

  • JVM 堆内存设为物理内存的 50%,且不超过 32GB(超过后指针压缩失效,反而浪费内存)
  • -Xms-Xmx 必须相等,防止 JVM 动态调整堆大小带来的停顿
  • 剩余 50% 物理内存留给 OS 做文件系统缓存(Lucene 严重依赖页缓存)

验证启动

curl http://localhost:9200
# 返回 JSON,包含 "tagline": "You Know, for Search" 表示成功

Docker Compose 一键部署(推荐)

# docker-compose.yml
version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.3.4-amd64
    container_name: es
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
      - xpack.security.enabled=false
    ports:
      - "9200:9200"
      - "9300:9300"
    volumes:
      - es-data:/usr/share/elasticsearch/data
    ulimits:
      memlock:
        soft: -1
        hard: -1
    networks:
      - es-net

  kibana:
    image: kibana:9.3.4
    container_name: kibana
    environment:
      - ELASTICSEARCH_HOSTS=http://es:9200
      - I18N_LOCALE=zh-CN
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
    networks:
      - es-net

volumes:
  es-data:

networks:
  es-net:
docker-compose up -d

核心配置文件(elasticsearch.yml)

生产环境通常挂载自定义配置:

# elasticsearch.yml 关键配置
cluster.name: my-cluster
node.name: node-1

# 数据与日志路径
path.data: /usr/share/elasticsearch/data
path.logs: /usr/share/elasticsearch/logs

# 网络
network.host: 0.0.0.0
http.port: 9200

# 集群发现(ES 7.0+)
discovery.seed_hosts: ["es-node1", "es-node2", "es-node3"]
cluster.initial_master_nodes: ["es-node1", "es-node2", "es-node3"]

# 安全(ES 8.x+ 默认开启)
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

安全认证(X-Pack)

ES 8.x+ 默认启用安全认证。首次启动会自动生成 elastic 用户密码。

手动设置密码

# 进入容器
docker exec -it es /bin/bash

# 交互式设置内置用户密码
./bin/elasticsearch-reset-password -u elastic -i

# 或自动生成
./bin/elasticsearch-reset-password -u elastic

# 或通过 API 修改
curl -X PUT "localhost:9200/_security/user/elastic/_password?pretty" \
  -H "Content-Type: application/json" \
  -u elastic:旧密码 \
  -d '{"password": "新密码"}'

服务账号(Service Account)

# 创建 API Key(推荐用于程序访问,而非直接用 elastic 账号)
curl -X POST "localhost:9200/_security/api_key" \
  -H "Content-Type: application/json" \
  -u elastic:密码 \
  -d '{
    "name": "my-app-key",
    "role_descriptors": {
      "my-role": {
        "cluster": ["monitor"],
        "index": [
          { "names": ["my-index*"], "privileges": ["read", "write"] }
        ]
      }
    }
  }'

💡 最佳实践:

  • 永远不要用 elastic 超级用户跑应用程序
  • 为每个应用创建最小权限的 API Key
  • 生产环境启用 HTTPS(xpack.security.http.ssl.enabled: true

安装中文分词插件(IK)

# 版本对应:https://release.infinilabs.com/analysis-ik/stable/
docker exec -it es /bin/bash

# ES 9.x 安装路径
cd /usr/share/elasticsearch/bin/
./elasticsearch-plugin install https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-9.3.4.zip

exit
docker restart es

IK 分词器模式

模式 说明 示例:“中华人民共和国”
ik_max_word 最细粒度切分,召回率高 中华人民共和国 / 中华人民 / 中华 / 华人 / 人民共和国 / 人民 / 共和国 / 共和 /
ik_smart 粗粒度切分,索引体积小 中华人民共和国

💡 最佳实践:索引时用 ik_max_word(扩大召回),搜索时用 ik_smart(提高精度),这是 ES 中 IK 分词的最佳搭配。


安装拼音分词插件

用于搜索框智能补全,详见 06-搜索补全

docker exec -it es /bin/bash
cd /usr/share/elasticsearch/bin/
./elasticsearch-plugin install https://github.com/infinilabs/analysis-pinyin/releases/download/v9.3.4/elasticsearch-analysis-pinyin-9.3.4.zip
exit
docker restart es

查看已安装插件

curl http://localhost:9200/_cat/plugins
# 或用
docker exec -it es ./bin/elasticsearch-plugin list

🚨 陷阱:安装插件后必须重启 ES。插件与 ES 版本必须严格一致,否则节点启动失败。


安装 Kibana

启动

docker run -d \
  --name kibana \
  -p 5601:5601 \
  --link es:es \
  -e "ELASTICSEARCH_HOSTS=http://es:9200" \
  -e "I18N_LOCALE=zh-CN" \
  -e "NODE_OPTIONS=--max-old-space-size=512" \
  kibana:9.3.4
参数 说明
--link es:es Docker 网络连接到 ES 容器(Compose 中不需要)
ELASTICSEARCH_HOSTS ES 地址,多个用逗号分隔
I18N_LOCALE=zh-CN 界面中文化
NODE_OPTIONS=--max-old-space-size=512 限制 Node.js 堆内存,Kibana 默认 1.4GB

Dev Tools 控制台

Kibana 的 Dev Tools(原 Console)是执行 ES DSL 的主要入口,路径:Management → Dev Tools。本文档所有 PUT/GET/POST/DELETE 示例均可直接粘贴执行。

远程访问隧道

# 将服务器 Kibana 端口映射到本地(不暴露公网)
ssh -L 5601:localhost:5601 developer@your-server-ip

💡 最佳实践:生产环境禁止将 Kibana 直接暴露到公网。使用 SSH 隧道或 VPN 访问,并在 ES 侧启用安全认证。


导入测试数据

# 下载官方 accounts 测试数据集
wget https://raw.githubusercontent.com/elastic/elasticsearch/v6.8.18/docs/src/test/resources/accounts.json
# 使用 Bulk API 导入
curl -H "Content-Type: application/x-ndjson" \
     -XPOST "localhost:9200/bank/_bulk?pretty&refresh" \
     --data-binary "@accounts.json"

🔬 深入原理:application/x-ndjson(Newline Delimited JSON)格式要求每行一个 JSON 对象,以换行符分隔。--data-binary 防止 curl 对内容做任何转换。?refresh 参数确保数据导入后立即可搜索(默认每 1s 自动刷新)。

验证数据

# 查看所有索引
curl "localhost:9200/_cat/indices?v"

# 查看 bank 索引文档数
curl "localhost:9200/bank/_count?pretty"

常见陷阱

陷阱 说明 解决
🚨 vm.max_map_count 过低 mmap 映射不足导致启动失败 sysctl -w vm.max_map_count=262144
🚨 目录权限拒绝 宿主机数据目录 uid 不匹配 chown -R 1000:1000 授权
🚨 插件安装后未重启 插件不生效,创建索引报错 docker restart es
🚨 插件版本不一致 插件与 ES 版本不匹配导致启动失败 对齐所有组件版本号
🚨 Kibana OOM Node.js 默认堆内存过大 设置 NODE_OPTIONS=--max-old-space-size=512
🚨 ES OOM JVM 堆内存设置超过物理内存 50% -Xms -Xmx 设为一致且不超过 32GB
🚨 -Xms != -Xmx JVM 动态调整堆大小产生 GC 停顿 -Xms-Xmx 必须相等