Docker 安装 Elasticsearch 、Kibana

105 阅读6分钟

以下是一个简单的 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

配置说明:

  1. 版本匹配:Elasticsearch 和 Kibana 必须使用相同版本号(本例使用 8.13.4)
  2. Elasticsearch 配置
    • 单节点模式 (discovery.type=single-node)
    • 禁用安全功能 (xpack.security.enabled=false) - 仅限开发环境
    • JVM 内存分配 1GB
    • 数据持久化到名为 elasticsearch_data 的卷
  3. Kibana 配置
    • 通过环境变量连接到 Elasticsearch 容器
    • 自动等待 Elasticsearch 就绪 (depends_on)
  4. 网络配置:创建专用网络 elastic 确保容器间通信
  5. 端口映射
    • Elasticsearch: 9200 (HTTP API) / 9300 (集群通信)
    • Kibana: 5601 (Web 界面)

使用说明:

  1. 保存为 docker-compose.yml
  2. 启动服务:
docker-compose up -d
  1. 验证服务:
    • Elasticsearch: http://localhost:9200
    • Kibana: http://localhost:5601

生产环境建议:

  1. 启用安全认证
  2. 配置集群多节点
  3. 增加资源限制 (CPU/MEM)
  4. 使用专用 Docker volume 驱动
  5. 配置日志和监控

如果需要旧版本(如 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 访问。