以下是一个简单的 docker-compose.yml
配置文件,用于部署 Elasticsearch 和 Kibana:
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4
container_name: elasticsearch
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms1g -Xmx1g
- xpack.security.enabled=false
volumes:
- /app/elasticsearch/data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
- "9300:9300"
networks:
- elastic
kibana:
image: docker.elastic.co/kibana/kibana:8.13.4
container_name: kibana
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- I18N_LOCALE=zh-CN # 新增中文语言环境变量
ports:
- "5601:5601"
networks:
- elastic
networks:
elastic:
driver: bridge
配置说明:
- 版本匹配:Elasticsearch 和 Kibana 必须使用相同版本号(本例使用 8.13.4)
- Elasticsearch 配置:
- 单节点模式 (
discovery.type=single-node
) - 禁用安全功能 (
xpack.security.enabled=false
) - 仅限开发环境 - JVM 内存分配 1GB
- 数据持久化到名为
elasticsearch_data
的卷
- 单节点模式 (
- Kibana 配置:
- 通过环境变量连接到 Elasticsearch 容器
- 自动等待 Elasticsearch 就绪 (
depends_on
)
- 网络配置:创建专用网络
elastic
确保容器间通信 - 端口映射:
- Elasticsearch: 9200 (HTTP API) / 9300 (集群通信)
- Kibana: 5601 (Web 界面)
使用说明:
- 保存为
docker-compose.yml
- 启动服务:
docker-compose up -d
- 验证服务:
- Elasticsearch:
http://localhost:9200
- Kibana:
http://localhost:5601
- Elasticsearch:
生产环境建议:
- 启用安全认证
- 配置集群多节点
- 增加资源限制 (CPU/MEM)
- 使用专用 Docker volume 驱动
- 配置日志和监控
如果需要旧版本(如 7.x),请修改镜像标签为 7.17.13
并注意 7.x 与 8.x 的配置差异。
报错解决
2025-02-18 20:45:58 {"@timestamp":"2025-02-18T12:45:58.544Z", "log.level":"ERROR", "message":"fatal exception while booting Elasticsearch", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"main","log.logger":"org.elasticsearch.bootstrap.Elasticsearch","elasticsearch.node.name":"e95dcacd0c29","elasticsearch.cluster.name":"docker-cluster","error.type":"java.lang.IllegalStateException","error.message":"failed to obtain node locks, tried [/usr/share/elasticsearch/data]; maybe these locations are not writable or multiple nodes were started on the same data path?","error.stack_trace":"java.lang.IllegalStateException: failed to obtain node locks, tried [/usr/share/elasticsearch/data]; maybe these locations are not writable or multiple nodes were started on the same data path?\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.env.NodeEnvironment.<init>(NodeEnvironment.java:293)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.node.NodeConstruction.validateSettings(NodeConstruction.java:500)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.node.NodeConstruction.prepareConstruction(NodeConstruction.java:255)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.node.Node.<init>(Node.java:192)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.bootstrap.Elasticsearch$2.<init>(Elasticsearch.java:237)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.bootstrap.Elasticsearch.initPhase3(Elasticsearch.java:237)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:74)\nCaused by: java.io.IOException: failed to obtain lock on /usr/share/elasticsearch/data\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.env.NodeEnvironment$NodeLock.<init>(NodeEnvironment.java:238)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.env.NodeEnvironment$NodeLock.<init>(NodeEnvironment.java:206)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.env.NodeEnvironment.<init>(NodeEnvironment.java:285)\n\t... 6 more\nCaused by: java.nio.file.NoSuchFileException: /usr/share/elasticsearch/data/node.lock\n\tat java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)\n\tat java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)\n\tat java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)\n\tat java.base/sun.nio.fs.UnixPath.toRealPath(UnixPath.java:834)\n\tat org.apache.lucene.core@9.10.0/org.apache.lucene.store.NativeFSLockFactory.obtainFSLock(NativeFSLockFactory.java:94)\n\tat org.apache.lucene.core@9.10.0/org.apache.lucene.store.FSLockFactory.obtainLock(FSLockFactory.java:43)\n\tat org.apache.lucene.core@9.10.0/org.apache.lucene.store.BaseDirectory.obtainLock(BaseDirectory.java:44)\n\tat org.elasticsearch.server@8.13.4/org.elasticsearch.env.NodeEnvironment$NodeLock.<init>(NodeEnvironment.java:231)\n\t... 8 more\n\tSuppressed: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/node.lock\n\t\tat java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90)\n\t\tat java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)\n\t\tat java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)\n\t\tat java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:261)\n\t\tat java.base/java.nio.file.Files.newByteChannel(Files.java:379)\n\t\tat java.base/java.nio.file.Files.createFile(Files.java:657)\n\t\tat org.apache.lucene.core@9.10.0/org.apache.lucene.store.NativeFSLockFactory.obtainFSLock(NativeFSLockFactory.java:84)\n\t\t... 11 more\n"}
2025-02-18 20:45:58 ERROR: Elasticsearch did not exit normally - check the logs at /usr/share/elasticsearch/logs/docker-cluster.log
2025-02-18 20:45:58
2025-02-18 20:45:59 ERROR: Elasticsearch died while starting up, with exit code 1
Elasticsearch 启动失败是由于 数据目录权限问题 或 残留的锁文件(node.lock) 导致的。以下是具体解决方案:
1. 停止并清理旧容器和数据
# 停止并删除容器
docker-compose down
# 删除残留的挂载目录(确保数据备份后操作)
sudo rm -rf /app/elasticsearch/data/*
2. 修复宿主机目录权限
Elasticsearch 容器默认以用户 elasticsearch
(UID 1000)运行,需确保宿主机目录 /app/elasticsearch/data
对该用户可写:
# 创建目录(如果不存在)
sudo mkdir -p /app/elasticsearch/data
# 修改目录权限
sudo chmod 777 -R /app/elasticsearch/data # 临时解决方案(开发环境)
# 或更安全的权限(推荐)
sudo chown 1000:0 -R /app/elasticsearch/data # 将目录所有者设为 UID 1000(elasticsearch用户)
3. 确保数据目录为空
Elasticsearch 首次启动时,如果数据目录非空且包含旧集群数据,会导致锁冲突。清空目录:
sudo rm -rf /app/elasticsearch/data/*
4. 检查是否有其他 Elasticsearch 实例占用锁文件
确保没有其他容器或进程在使用相同的数据目录:
# 检查正在运行的容器
docker ps
# 停止所有 Elasticsearch 相关容器
docker stop $(docker ps -q --filter name=elasticsearch)
5. 调整 Elasticsearch 的挂载配置(可选)
如果仍存在问题,可以尝试在 docker-compose.yml
中显式设置用户:
services:
elasticsearch:
user: "1000:0" # 强制以 UID 1000 运行
volumes:
- /app/elasticsearch/data:/usr/share/elasticsearch/data
6. 重新启动服务
docker-compose up -d
错误原因解析
- 权限问题:Elasticsearch 容器用户(UID 1000)无法写入宿主机目录
/app/elasticsearch/data
。 - 锁文件冲突:数据目录中残留了
node.lock
文件,导致新节点误认为已有其他实例在运行。 - 旧数据残留:非空数据目录包含旧集群信息,与新节点不兼容。
验证是否成功
检查 Elasticsearch 日志:
docker logs elasticsearch
如果看到 "message":"started"
或 "status":"green"
,则表示启动成功。
补充说明
- 生产环境建议:使用 Docker 卷(volume)替代直接挂载宿主机目录,避免权限问题。
- 安全警告:
chmod 777
会开放目录的完全权限,仅建议在开发环境使用。生产环境应严格限制权限。
Q 为啥我的kibana登录没有账号密码,直接进去了?
你的 Kibana 无需账号密码直接登录,是因为 Elasticsearch 的安全功能(Security)已被明确关闭,导致 Kibana 跳过了身份验证步骤。以下是具体原因和解释:
1. 安全功能被关闭
在你的 **docker-compose.yml**
中,Elasticsearch 的配置明确禁用了安全模块:
environment:
- xpack.security.enabled=false
此配置会直接关闭 Elasticsearch 的登录认证功能,连带影响 Kibana 的行为(无需登录)。
2. Kibana 的安全模式与 Elasticsearch 同步
Kibana 默认会继承 Elasticsearch 的安全配置。当 Elasticsearch 禁用安全功能时:
- Kibana 不会显示登录界面。
- 所有用户可以直接访问 Kibana 的所有功能(等同于拥有超级管理员权限)。
3. 验证安全状态
通过以下命令检查 Elasticsearch 的安全状态:
curl http://localhost:9200/_xpack/usage?filter_path=security.enabled
如果返回 **{ "security": { "enabled": false } }**
,说明安全功能已关闭。
4. 这是否安全?
- 开发环境**:禁用安全功能是合理的,便于快速调试。**
- 生产环境**:极度危险! 必须通过以下方式启用安全防护:**
# 启用 Elasticsearch 安全功能
environment:
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=true
- xpack.security.transport.ssl.enabled=true
# 设置默认用户密码(自动生成或自定义)
- ELASTIC_PASSWORD=your_strong_password
5. 如何恢复登录界面?
如果你希望 Kibana 要求账号密码,需重新启用 Elasticsearch 的安全功能:
# 修改 docker-compose.yml 中 Elasticsearch 的配置
services:
elasticsearch:
environment:
- xpack.security.enabled=true
- ELASTIC_PASSWORD=your_password # 设置 Elastic 用户密码
- xpack.security.http.ssl.enabled=false # 开发环境可临时关闭 SSL
随后执行以下操作:
# 清理旧数据并重启
docker-compose down -v
sudo rm -rf /app/elasticsearch/data/*
docker-compose up -d
# 访问 Kibana 时,使用以下账号登录:
用户名:elastic
密码:your_password
6. 为何不推荐长期禁用安全功能?
- 数据暴露风险**:任何能访问 Kibana 或 Elasticsearch 端口的人都可以随意读写数据。**
- 合规性问题**:违反数据隐私保护法规(如 GDPR)。**
- 审计困难**:无法追踪用户操作记录。**
总结
- 直接登录的原因**:
**xpack.security.enabled=false**
导致安全功能被禁用。** - 临时开发环境**:可以接受此行为,但需确保服务不暴露在公网。**
- 生产环境:必须启用安全功能,配置 HTTPS 和强密码,并限制 IP 访问。