Docker 部署 Elasticsearch 单节点如何持久化数据避免丢失

文章导读
最稳妥的方式是通过挂载卷(Volume)将容器内的数据目录映射到宿主机,并配置单节点发现模式。
📋 目录
  1. 命令速用版
  2. Docker Compose 部署方案
  3. 数据备份与恢复实操
  4. 为什么会这样
  5. 分步处理
  6. 怎么验证是否生效
  7. 常见坑
  8. 参考来源
A A

最稳妥的方式是通过挂载卷(Volume)将容器内的数据目录映射到宿主机,并配置单节点发现模式。

先说结论:数据持久化依赖宿主机目录挂载,权限配置错误是启动失败的主因。

  • 适合:本地开发、测试环境或非关键业务单节点场景
  • 先准备:宿主机创建数据目录并修正所有者权限
  • 验收:重启容器后确认索引数据依然存在
  • 注意:生产环境建议配合快照备份,单节点无高可用冗余

命令速用版

docker run -d `--name` es01 \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "ELASTIC_PASSWORD=你的密码" \
-v /path/to/es/data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:8.11.0

注意:上述命令仅为示意,版本号请根据实际需求调整,密码必须满足复杂度要求(至少 8 位,含字母数字符号)。

Docker Compose 部署方案

对于需要管理配置的场景,推荐使用 Docker Compose。创建 docker-compose.yml 文件:

version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
    container_name: es01
    environment:
      - discovery.type=single-node
      - ELASTIC_PASSWORD=你的密码
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - ./data:/usr/share/elasticsearch/data
      - ./backup:/usr/share/elasticsearch/backup
    ports:
      - "9200:9200"
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health || exit 1"]
      interval: 10s
      timeout: 10s
      retries: 120

启动命令:

docker-compose up -d

数据备份与恢复实操

单节点持久化只能防容器丢失,无法防磁盘损坏。建议配置快照仓库定期备份。

1. 配置快照路径(前置条件)

需在 elasticsearch.yml 中设置 path.repo。若使用 Docker,需挂载配置文件或启动参数。示例配置内容:

Docker 部署 Elasticsearch 单节点如何持久化数据避免丢失
path.repo: ["/usr/share/elasticsearch/backup"]

2. 注册快照仓库

假设已挂载备份目录且配置生效,调用 API 注册:

curl -X PUT "localhost:9200/_snapshot/my_backup" -H "Content-Type: application/json" `--user` elastic:你的密码 -d '{
  "type": "fs",
  "settings": {
    "location": "/usr/share/elasticsearch/backup"
  }
}'

3. 创建快照

curl -X PUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true" `--user` elastic:你的密码

4. 恢复数据

curl -X POST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore" `--user` elastic:你的密码

为什么会这样

Docker 容器本质是 ephemeral(临时)的,容器删除后,内部文件系统随之消失。Elasticsearch 默认将数据写在容器内的 /usr/share/elasticsearch/data 目录。如果不挂载卷,重启容器即丢失数据。此外,Elasticsearch 进程在容器内以 uid 1000 运行,若宿主机目录权限不匹配,容器将因无权写入而启动失败。

分步处理

1. 准备宿主机目录

Docker 部署 Elasticsearch 单节点如何持久化数据避免丢失

在宿主机创建一个目录用于存放数据,例如:

mkdir -p /opt/es/data

2. 修正权限

将目录所有者改为 uid 1000,这是官方镜像内 elasticsearch 用户的 ID:

chown -R 1000:1000 /opt/es/data

3. 启动容器

使用 docker run 或 docker-compose 启动,务必设置 discovery.type 和密码。8.x 版本默认开启安全认证,必须设置 ELASTIC_PASSWORD。

4. 内存设置(可选但推荐)

Linux 宿主机通常需要调整 vm.max_map_count,否则可能启动报错:

Docker 部署 Elasticsearch 单节点如何持久化数据避免丢失
sysctl -w vm.max_map_count=262144

怎么验证是否生效

1. 检查容器状态

docker ps | grep es01

状态应为 Up。

2. 写入测试数据

curl -X POST "localhost:9200/test/_doc/1" -H "Content-Type: application/json" -d "{\"title\": \"hello\"}" `--user` elastic:你的密码

3. 重启验证

停止并删除容器(不要删除宿主机目录),重新运行启动命令。再次查询数据:

curl "localhost:9200/test/_doc/1" `--user` elastic:你的密码

若能返回之前写入的内容,说明持久化生效。

常见坑

  • 权限拒绝:最常见错误是容器日志显示 Permission denied,原因是宿主机目录未 chown 1000:1000。
  • 内存不足:ES 默认占用较多内存,确保 Docker 分配了足够资源,否则容器会不断重启。
  • 安全认证:8.x 版本默认开启 Security,若未设置密码或未配置证书,客户端无法连接。
  • 路径混淆:挂载的是 data 目录,不要误挂载 config 目录导致配置文件冲突,除非你明确知道自己在做什么。
  • 单点风险:单节点部署无冗余,磁盘故障会导致服务不可用,生产环境请评估备份策略或集群方案。

参考来源

  • Elastic Official Documentation, "Run Elasticsearch with Docker", URL: https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html