Docker 容器 Elasticsearch 启动失败完整排查记录

背景

在服务器上运行 Docker 容器 es3,但 Elasticsearch 无法正常启动,运行 docker ps -a 发现 es3 处于 Exited (1) 状态,即进程异常退出。

本次排查从错误日志、容器挂载、权限问题、SELinux 影响、内核参数等多个方面入手,最终成功解决问题。

本文将详细记录整个排查过程,方便未来遇到类似问题时可以快速定位并解决。


问题描述

尝试进入 es3 容器时,报错:

sh 复制代码
docker exec -it es3 bash
Error response from daemon: Container 061588b201eb42a339add01209829ae7a3f09915160a6fd82a22ce5a2c05a6c8 is not running

这表明容器 es3 处于退出状态,无法直接进入。

运行 docker ps -a 发现:

sh 复制代码
CONTAINER ID   IMAGE                                                  COMMAND                  CREATED        STATUS                      PORTS                                           NAMES
061588b201eb   docker.elastic.co/elasticsearch/elasticsearch:7.15.0   "/bin/tini -- /usr/l..."   9 months ago   Exited (1) 8 minutes ago                                                    es3

查看 docker logs es3,发现错误:

ElasticsearchException[failed to bind service]; nested: AccessDeniedException[/usr/share/elasticsearch/data/nodes];
Caused by: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/nodes

这是典型的权限问题 ,Elasticsearch 无法访问 /usr/share/elasticsearch/data/nodes 目录,导致启动失败。


详细排查过程

步骤 1:检查 Elasticsearch 容器的挂载目录

运行以下命令查看 es3 容器的挂载信息:

sh 复制代码
docker inspect es3 | grep -i Mounts -A 10

输出:

json 复制代码
"Mounts": [
    {
        "Type": "bind",
        "Source": "/data/es",
        "Destination": "/usr/share/elasticsearch/data",
        "Mode": "rw",
        "RW": true
    }
]

分析:

  • Source 表示宿主机上的数据目录 /data/es 被绑定到了容器内部的 /usr/share/elasticsearch/data
  • RW: true 表示该挂载是读写权限,但仍可能存在宿主机目录权限不足导致容器内部访问失败。

步骤 2:检查宿主机目录权限

手动检查 /data/es 目录权限:

sh 复制代码
ls -ld /data/es

发现权限不正确:

sh 复制代码
drwx------ 2 root root 4096 Feb 7 12:00 /data/es

这个目录的所有者是 root,而 Elasticsearch 容器通常使用 uid=1000 运行,所以无法访问该目录。

解决方案:修改宿主机目录权限

执行以下命令,给 /data/es 目录赋予正确权限:

sh 复制代码
sudo chmod -R 777 /data/es
sudo chown -R 1000:1000 /data/es  # 确保 Elasticsearch 运行用户可以访问

然后重新启动容器:

sh 复制代码
docker restart es3

如果 docker logs es3 仍然报错,则继续排查。


步骤 3:检查 SELinux 是否影响容器挂载

在 RHEL/CentOS 服务器上,SELinux 可能会阻止 Docker 容器访问宿主机目录。

检查 SELinux 状态

sh 复制代码
sestatus

如果输出:

sh 复制代码
SELinux status: enabled

则说明 SELinux 可能影响了容器的数据目录挂载。

解决方案:

sh 复制代码
sudo setenforce 0  # 临时禁用 SELinux
docker restart es3

如果这样可以成功启动 Elasticsearch,则可以通过以下命令让 SELinux 允许容器访问:

sh 复制代码
sudo chcon -R -t container_file_t /data/es

步骤 4:调整 Elasticsearch 运行所需的内核参数

Elasticsearch 需要 vm.max_map_count 参数足够大,否则可能启动失败。

检查当前值

sh 复制代码
sysctl -n vm.max_map_count

如果值低于 262144,执行:

sh 复制代码
sudo sysctl -w vm.max_map_count=262144

并让其永久生效:

sh 复制代码
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

然后重新启动 es3

sh 复制代码
docker restart es3

步骤 5:进入容器手动检查目录权限

如果 es3 依然无法启动,可以手动进入容器内进行检查:

sh 复制代码
docker start es3
docker exec -it es3 bash
ls -lah /usr/share/elasticsearch/data

如果权限不正确:

sh 复制代码
chmod -R 777 /usr/share/elasticsearch/data
chown -R 1000:1000 /usr/share/elasticsearch/data

然后退出容器并重启:

sh 复制代码
exit
docker restart es3

步骤 6:查看 Elasticsearch 详细日志

如果仍然无法启动,查看完整日志:

sh 复制代码
docker logs es3 --tail 50

或者进入容器内部查看:

sh 复制代码
docker exec -it es3 bash
cat /usr/share/elasticsearch/logs/es-cluster1.log | tail -50

分析日志信息,找出可能的错误信息并针对性解决。


最终总结

本次排查经历了以下几个关键步骤:

  1. 检查容器挂载信息 ,确认 SourceDestination 绑定正确。
  2. 修复宿主机目录权限 ,确保 /data/es 可被 uid=1000 访问。
  3. 排查 SELinux 影响,临时禁用或永久授权容器访问数据目录。
  4. 调整 vm.max_map_count 参数,确保符合 Elasticsearch 运行要求。
  5. 进入容器检查目录权限 ,确保 /usr/share/elasticsearch/data 目录可读写。
  6. 查看完整日志,针对具体错误信息进行修复。

最终,成功让 es3 容器恢复正常运行 🎉🎉!


经验总结

  1. 遇到 Elasticsearch 容器无法启动时,不要直接删除容器,而是先排查原因!
  2. 容器挂载目录的权限问题是常见错误,chown -R 1000:1000 通常能解决。
  3. SELinux 可能影响 Docker 挂载,如果启用了 SELinux,需额外处理挂载目录的安全上下文。
  4. 调整 vm.max_map_count 以符合 Elasticsearch 运行要求。
  5. 详细日志是最终解决问题的关键,一定要查看 docker logses-cluster1.log

相关推荐
晓风残月( ̄ε(# ̄)~1 小时前
使用Docker + Ollama在Ubuntu中部署deepseek
人工智能·ubuntu·docker·chatgpt·容器·ollama·deepseek
菜萝卜子3 小时前
【AI】在Ubuntu中使用docker对DeepSeek的部署与使用
人工智能·ubuntu·docker
F_D_Z3 小时前
【清晰教程】通过Docker为本地DeepSeek-r1部署WebUI界面
运维·docker·容器·open webui·deepseek r1
�时过境迁,物是人非3 小时前
centos系统清理docker日志文件
linux·docker·centos
田猿笔记4 小时前
使用 Docker 和 PM2 构建高并发 Node.js API 网关
docker·容器·node.js
m0nesy_86808 小时前
Kubernetes云原生技术和docker的区别(deepseek R1)
docker·云原生·kubernetes
web150854159359 小时前
【rustdesk】客户端和服务端的安装和部署(自建服务器,docker,远程控制开源软件rustdesk)
运维·服务器·docker
Kasen's experience10 小时前
Debian安装Seafile
docker·debian·seafile
狮歌~资深攻城狮11 小时前
Elasticsearch 高级技巧
运维·jenkins