You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Elasticsearch无法识别快照文件求助

问题:Docker部署的Elasticsearch无法识别复制到快照仓库的文件

我用Docker部署了Elasticsearch,运行正常,现在想从另一台电脑的Elasticsearch恢复数据。已经创建了快照仓库,环境变量里配置了repo.path,仓库文件夹也生成了。把从API获取的快照文件复制到仓库文件夹后,Elasticsearch API识别不到这些文件。

Docker Compose配置

volumes:
 certs:
   driver: local
 esdata01:
   driver: local
 kibanadata:
   driver: local
 metricbeatdata01:
   driver: local
 filebeatdata01:
   driver: local
 logstashdata01:
   driver: local

networks:
 default:
   name: elastic
   external: false

services:
 setup:
   image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
   volumes:
     - certs:/usr/share/elasticsearch/config/certs
   user: "0"
   command: >
     bash -c '
       if [ x${ELASTIC_PASSWORD} == x ]; then
         echo "Set the ELASTIC_PASSWORD environment variable in the .env file";
         exit 1;
       elif [ x${KIBANA_PASSWORD} == x ]; then
         echo "Set the KIBANA_PASSWORD environment variable in the .env file";
         exit 1;
       fi;
       if [ ! -f config/certs/ca.zip ]; then
         echo "Creating CA";
         bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip;
         unzip config/certs/ca.zip -d config/certs;
       fi;
       if [ ! -f config/certs/certs.zip ]; then
         echo "Creating certs";
         echo -ne \
         "instances:\n"\
         "  - name: es01\n"\
         "    dns:\n"\
         "      - es01\n"\
         "      - localhost\n"\
         "    ip:\n"\
         "      - 127.0.0.1\n"\
         "  - name: kibana\n"\
         "    dns:\n"\
         "      - kibana\n"\
         "      - localhost\n"\
         "    ip:\n"\
         "      - 127.0.0.1\n"\
         > config/certs/instances.yml;
         bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key;
         unzip config/certs/certs.zip -d config/certs;
       fi;
       echo "Setting file permissions"
       chown -R root:root config/certs;
       find . -type d -exec chmod 750 {} \;;
       find . -type f -exec chmod 640 {} \;;
       echo "Waiting for Elasticsearch availability";
       until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done;
       echo "Setting kibana_system password";
       until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done;
       echo "All done!";
     '
   healthcheck:
     test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"]
     interval: 1s
     timeout: 5s
     retries: 120
 es01:
   depends_on:
     setup:
       condition: service_healthy
   image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
   labels:
     co.elastic.logs/module: elasticsearch
   volumes:
     - certs:/usr/share/elasticsearch/config/certs
     - esdata01:/usr/share/elasticsearch/data
     - ./snapshots:/usr/share/elasticsearch/snapshots
   ports:
     - ${ES_PORT}:9200
   environment:
     - node.name=es01
     - cluster.name=${CLUSTER_NAME}
     - discovery.type=single-node
     - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
     - bootstrap.memory_lock=true
     - xpack.security.enabled=true
     - xpack.security.http.ssl.enabled=true
     - xpack.security.http.ssl.key=certs/es01/es01.key
     - xpack.security.http.ssl.certificate=certs/es01/es01.crt
     - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
     - xpack.security.transport.ssl.enabled=true
     - xpack.security.transport.ssl.key=certs/es01/es01.key
     - xpack.security.transport.ssl.certificate=certs/es01/es01.crt
     - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
     - xpack.security.transport.ssl.verification_mode=certificate
     - xpack.license.self_generated.type=${LICENSE}
     - path.repo=/usr/share/elasticsearch/snapshots
     - xpack.graph.enabled=true
   mem_limit: ${ES_MEM_LIMIT}
   ulimits:
     memlock:
       soft: -1
       hard: -1
   healthcheck:
     test:
       [
         "CMD-SHELL",
         "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
       ]
     interval: 10s
     timeout: 10s
     retries: 120

创建快照仓库的API请求

通过Postman发送PUT请求到 https://localhost:9200/_snapshot/snap,请求体:

{
  "type": "fs",
  "settings": {
    "location": "/usr/share/elasticsearch/snapshots/snap"
  }
}

快照文件结构

复制到snap文件夹后的内容:

19/02/2025  21:07    <DIR>          .
19/02/2025  19:58    <DIR>          ..
19/02/2025  20:39            13.133 index-0
19/02/2025  20:39                 8 index.latest
19/02/2025  20:39    <DIR>          indices
19/02/2025  20:39             1.208 meta-4rweKduLS3e1knI8y8Z7Pw.dat
19/02/2025  20:39             1.267 snap-4rweKduLS3e1knI8y8Z7Pw.dat

查询快照结果

发送GET请求到 https://localhost:9200/_snapshot/snap/_all,返回:

{
    "snapshots": [],
    "total": 0,
    "remaining": 0
}

已执行的操作

  • 执行chmod -R 777 /usr/share/elasticsearch/snapshots设置全权限
  • 主机系统为Windows,通过docker exec能看到snapshots文件夹中的文件

解决方案

1. 修正容器内文件所有者

Elasticsearch容器默认以elasticsearch用户(UID=1000)运行,Windows挂载的文件可能存在权限映射异常。进入容器执行以下命令:

# 查看文件所有者
docker exec -it es01 ls -l /usr/share/elasticsearch/snapshots/snap

# 修正所有者
docker exec -it es01 chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/snapshots

2. 重新注册快照仓库

删除现有仓库后重新注册,触发Elasticsearch重新扫描目录:

# 删除仓库
curl -X DELETE -u elastic:${ELASTIC_PASSWORD} --cacert config/certs/ca/ca.crt https://localhost:9200/_snapshot/snap

# 重新注册仓库
curl -X PUT -u elastic:${ELASTIC_PASSWORD} --cacert config/certs/ca/ca.crt https://localhost:9200/_snapshot/snap -H "Content-Type: application/json" -d '{
  "type": "fs",
  "settings": {
    "location": "/usr/share/elasticsearch/snapshots/snap"
  }
}'

3. 验证版本兼容性

确保源Elasticsearch和目标Elasticsearch大版本一致(如均为7.x或8.x),跨大版本的快照无法被识别。查看目标容器版本:

docker exec -it es01 bin/elasticsearch --version

4. 规避Windows挂载文件系统问题

Windows NTFS挂载到Linux容器可能丢失文件元数据,可通过打包复制的方式解决:

# 主机上打包快照文件夹
zip -r snap.zip ./snapshots/snap

# 复制到容器内
docker cp snap.zip es01:/usr/share/elasticsearch/snapshots/

# 进入容器解压并修正权限
docker exec -it es01 unzip /usr/share/elasticsearch/snapshots/snap.zip -d /usr/share/elasticsearch/snapshots/
docker exec -it es01 chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/snapshots

5. 强制扫描快照仓库

执行以下命令触发Elasticsearch强制扫描仓库内容:

curl -X POST -u elastic:${ELASTIC_PASSWORD} --cacert config/certs/ca/ca.crt https://localhost:9200/_snapshot/snap/_verify

内容的提问来源于stack exchange,提问作者Ignacio O. Muñoz Nicolás

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:55:53