使用 Docker 安装 Elasticsearch

编辑

Elasticsearch 的 Docker 镜像可从 Elastic Docker 注册表获得。所有已发布的 Docker 镜像和标签的列表可在 www.docker.elastic.co 上找到。源代码位于 GitHub 上。

此软件包包含免费和订阅功能。 开始 30 天试用 以试用所有功能。

如果您只是想在本地开发中测试 Elasticsearch,请参阅 在本地运行 Elasticsearch。请注意,此设置不适合生产环境。

在 Docker 中运行 Elasticsearch

编辑

使用 Docker 命令启动用于开发或测试的单节点 Elasticsearch 集群。然后,您可以运行其他 Docker 命令以向测试集群添加节点或运行 Kibana。

此设置默认情况下不运行多个 Elasticsearch 节点或 Kibana。要创建带有 Kibana 的多节点集群,请改用 Docker Compose。请参阅 使用 Docker Compose 启动多节点集群

启动单节点集群

编辑
  1. 安装 Docker。访问 获取 Docker 以安装适合您环境的 Docker。

    如果使用 Docker Desktop,请确保至少分配 4GB 的内存。您可以通过转到 设置 > 资源 来调整 Docker Desktop 中的内存使用情况。

  2. 创建一个新的 docker 网络。

    docker network create elastic
  3. 拉取 Elasticsearch Docker 镜像。

    docker pull docker.elastic.co/elasticsearch/elasticsearch:8.17.0
  4. 可选:为您的环境安装 Cosign。然后使用 Cosign 验证 Elasticsearch 镜像的签名。

    wget https://artifacts.elastic.co/cosign.pub
    cosign verify --key cosign.pub docker.elastic.co/elasticsearch/elasticsearch:8.17.0

    cosign 命令以 JSON 格式打印检查结果和签名有效负载

    Verification for docker.elastic.co/elasticsearch/elasticsearch:8.17.0 --
    The following checks were performed on each of these signatures:
      - The cosign claims were validated
      - Existence of the claims in the transparency log was verified offline
      - The signatures were verified against the specified public key
  5. 启动 Elasticsearch 容器。

    docker run --name es01 --net elastic -p 9200:9200 -it -m 1GB docker.elastic.co/elasticsearch/elasticsearch:8.17.0

    使用 -m 标志为容器设置内存限制。这样就不需要手动设置 JVM 大小

    诸如使用 ELSER 进行语义搜索之类的机器学习功能需要一个更大的容器,其中具有超过 1GB 的内存。如果您打算使用机器学习功能,则使用此命令启动容器

    docker run --name es01 --net elastic -p 9200:9200 -it -m 6GB -e "xpack.ml.use_auto_machine_memory_percent=true" docker.elastic.co/elasticsearch/elasticsearch:8.17.0

    该命令会打印 elastic 用户密码和 Kibana 的注册令牌。

  6. 复制生成的 elastic 密码和注册令牌。这些凭据仅在您首次启动 Elasticsearch 时显示。您可以使用以下命令重新生成凭据。

    docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
    docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana

    我们建议将 elastic 密码作为环境变量存储在您的 shell 中。示例

    export ELASTIC_PASSWORD="your_password"
  7. http_ca.crt SSL 证书从容器复制到您的本地计算机。

    docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .
  8. 向 Elasticsearch 发出 REST API 调用,以确保 Elasticsearch 容器正在运行。

    curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD https://127.0.0.1:9200

添加更多节点

编辑
  1. 使用现有节点为新节点生成注册令牌。

    docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node

    注册令牌有效期为 30 分钟。

  2. 启动一个新的 Elasticsearch 容器。将注册令牌作为环境变量包含在内。

    docker run -e ENROLLMENT_TOKEN="<token>" --name es02 --net elastic -it -m 1GB docker.elastic.co/elasticsearch/elasticsearch:8.17.0
  3. 调用 cat nodes API 以验证节点是否已添加到集群。

    curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD https://127.0.0.1:9200/_cat/nodes

运行 Kibana

编辑
  1. 拉取 Kibana Docker 镜像。

    docker pull docker.elastic.co/kibana/kibana:8.17.0
  2. 可选:验证 Kibana 镜像的签名。

    wget https://artifacts.elastic.co/cosign.pub
    cosign verify --key cosign.pub docker.elastic.co/kibana/kibana:8.17.0
  3. 启动 Kibana 容器。

    docker run --name kib01 --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:8.17.0
  4. Kibana 启动时,它会向终端输出一个唯一的生成链接。要访问 Kibana,请在 Web 浏览器中打开此链接。
  5. 在您的浏览器中,输入您在启动 Elasticsearch 时生成的注册令牌。

    要重新生成令牌,请运行

    docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
  6. 使用您在启动 Elasticsearch 时生成的密码以 elastic 用户身份登录 Kibana。

    要重新生成密码,请运行

    docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

删除容器

编辑

要删除容器及其网络,请运行

# Remove the Elastic network
docker network rm elastic

# Remove Elasticsearch containers
docker rm es01
docker rm es02

# Remove the Kibana container
docker rm kib01

后续步骤

编辑

您现在已经设置好了一个测试 Elasticsearch 环境。在您开始使用 Elasticsearch 进行认真的开发或投入生产之前,请查看在生产环境中在 Docker 中运行 Elasticsearch 时要应用的要求和建议

使用 Docker Compose 启动多节点集群

编辑

使用 Docker Compose 启动一个带有 Kibana 的三节点 Elasticsearch 集群。Docker Compose 允许您使用单个命令启动多个容器。

配置并启动集群

编辑
  1. 安装 Docker Compose。访问 Docker Compose 文档以安装适合您环境的 Docker Compose。

    如果您使用的是 Docker Desktop,则会自动安装 Docker Compose。请确保为 Docker Desktop 分配至少 4GB 的内存。您可以通过转到 设置 > 资源 来调整 Docker Desktop 中的内存使用情况。

  2. 创建或导航到项目的空目录。
  3. 在项目目录中下载并保存以下文件

  4. .env 文件中,为 ELASTIC_PASSWORDKIBANA_PASSWORD 变量指定密码。

    密码必须是字母数字,并且不能包含特殊字符,例如 !@docker-compose.yml 文件中包含的 bash 脚本仅适用于字母数字字符。示例

    # Password for the 'elastic' user (at least 6 characters)
    ELASTIC_PASSWORD=changeme
    
    # Password for the 'kibana_system' user (at least 6 characters)
    KIBANA_PASSWORD=changeme
    ...
  5. .env 文件中,将 STACK_VERSION 设置为当前的 Elastic Stack 版本。

    ...
    # Version of Elastic products
    STACK_VERSION=8.17.0
    ...
  6. 默认情况下,Docker Compose 配置在所有网络接口上公开端口 9200

    要避免将端口 9200 公开给外部主机,请在 .env 文件中将 ES_PORT 设置为 127.0.0.1:9200。这可确保只能从主机访问 Elasticsearch。

    ...
    # Port to expose Elasticsearch HTTP API to the host
    #ES_PORT=9200
    ES_PORT=127.0.0.1:9200
    ...
  7. 要启动集群,请从项目目录运行以下命令。

    docker-compose up -d
  8. 集群启动后,在 Web 浏览器中打开 https://127.0.0.1:5601 以访问 Kibana。
  9. 使用您之前设置的 ELASTIC_PASSWORDelastic 用户身份登录 Kibana。

停止并删除集群

编辑

要停止集群,请运行 docker-compose down。Docker 卷中的数据将被保留,并在您使用 docker-compose up 重新启动集群时加载。

docker-compose down

要在您停止集群时删除网络、容器和卷,请指定 -v 选项

docker-compose down -v

后续步骤

编辑

您现在已经设置好了一个测试 Elasticsearch 环境。在您开始使用 Elasticsearch 进行认真的开发或投入生产之前,请查看在生产环境中在 Docker 中运行 Elasticsearch 时要应用的要求和建议

在生产中使用 Docker 镜像

编辑

以下要求和建议适用于在生产环境中在 Docker 中运行 Elasticsearch。

vm.max_map_count 设置为至少 262144

编辑

对于生产用途,vm.max_map_count 内核设置必须设置为至少 262144

如何设置 vm.max_map_count 取决于您的平台。

Linux
编辑

要查看 vm.max_map_count 设置的当前值,请运行

grep vm.max_map_count /etc/sysctl.conf
vm.max_map_count=262144

要在实时系统上应用设置,请运行

sysctl -w vm.max_map_count=262144

要永久更改 vm.max_map_count 设置的值,请更新 /etc/sysctl.conf 中的值。

带有 Docker for Mac 的 macOS
编辑

必须在 xhyve 虚拟机内设置 vm.max_map_count 设置

  1. 从命令行,运行

    screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
  2. 按 Enter 键,并使用 sysctl 配置 vm.max_map_count

    sysctl -w vm.max_map_count=262144
  3. 要退出 screen 会话,请键入 Ctrl a d
带有 Docker Desktop 的 Windows 和 macOS
编辑

必须通过 docker-machine 设置 vm.max_map_count 设置

docker-machine ssh
sudo sysctl -w vm.max_map_count=262144

在 Elasticsearch 容器正常启动之前,必须在 "docker-desktop" WSL 实例中设置 vm.max_map_count 设置。根据您的 Windows 版本和 WSL 版本,有几种方法可以执行此操作。

如果您使用的是 Windows 10 版本 22H2 之前的版本,或者如果您使用的是 Windows 10 版本 22H2 并且使用 WSL 的内置版本,则必须在每次重新启动 Docker 并在启动 Elasticsearch 容器之前手动设置它,或者(如果您不希望在每次重新启动时都这样做)必须全局设置每个 WSL2 实例,以更改 vm.max_map_count。这是因为这些版本的 WSL 不能正确处理 /etc/sysctl.conf 文件。

要每次重新启动时手动设置它,您必须在每次重新启动 Docker 时在命令提示符或 PowerShell 窗口中运行以下命令

wsl -d docker-desktop -u root
sysctl -w vm.max_map_count=262144

如果您使用的是这些版本的 WSL,并且不希望每次重新启动 Docker 时都必须运行这些命令,则可以通过如下修改 %USERPROFILE%\.wslconfig 来全局更改具有此设置的每个 WSL 分发

[wsl2]
kernelCommandLine = "sysctl.vm.max_map_count=262144"

这将导致所有 WSL2 VM 在启动时分配该设置。

如果您使用的是 Windows 11,或者 Windows 10 版本 22H2,并且已安装 Microsoft Store 版本的 WSL,则可以修改 "docker-desktop" WSL 分发中的 /etc/sysctl.conf,或许可以使用如下命令

wsl -d docker-desktop -u root
vi /etc/sysctl.conf

并附加一行,其中读取

vm.max_map_count = 262144

配置文件必须可由 elasticsearch 用户读取

编辑

默认情况下,Elasticsearch 在容器内以用户 elasticsearch 的身份运行,使用 uid:gid 1000:0

一个例外是Openshift,它使用任意分配的用户 ID 运行容器。Openshift 会显示 gid 设置为 0 的持久卷,这无需任何调整即可正常工作。

如果您要绑定挂载本地目录或文件,则它必须可由 elasticsearch 用户读取。此外,此用户必须具有对配置、数据和日志目录的写入权限(Elasticsearch 需要对 config 目录的写入权限,以便它可以生成密钥库)。一个好的策略是为本地目录授予对 gid 0 的组访问权限。

例如,要准备一个本地目录以通过绑定挂载来存储数据

mkdir esdatadir
chmod g+rwx esdatadir
chgrp 0 esdatadir

您还可以使用自定义的 UID 和 GID 运行 Elasticsearch 容器。您必须确保文件权限不会阻止 Elasticsearch 执行。您可以使用以下两种选项之一:

  • 绑定挂载 configdatalogs 目录。如果您打算安装插件并且不希望创建自定义 Docker 镜像,则还必须绑定挂载 plugins 目录。
  • --group-add 0 命令行选项传递给 docker run。 这可确保运行 Elasticsearch 的用户也是容器内 root (GID 0) 组的成员。

增加 nofile 和 nproc 的 ulimit

编辑

Elasticsearch 容器必须具有增加的 nofilenproc 的 ulimit。请验证 Docker 守护程序的 初始化系统是否将其设置为可接受的值。

要检查 Docker 守护程序 ulimit 的默认值,请运行:

docker run --rm docker.elastic.co/elasticsearch/elasticsearch:8.17.0 /bin/bash -c 'ulimit -Hn && ulimit -Sn && ulimit -Hu && ulimit -Su'

如果需要,可以在守护程序中调整它们,或者为每个容器覆盖它们。例如,当使用 docker run 时,设置:

--ulimit nofile=65535:65535

禁用交换

编辑

出于性能和节点稳定性的考虑,需要禁用交换。有关禁用交换的方法的信息,请参阅禁用交换

如果您选择 bootstrap.memory_lock: true 方法,则还需要在 Docker 守护程序中定义 memlock: true ulimit,或者如示例 compose 文件所示,为容器显式设置。 当使用 docker run 时,您可以指定:

-e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1

随机化发布的端口

编辑

该镜像公开了 TCP 端口 9200 和 9300。对于生产集群,建议使用 --publish-all 随机化发布的端口,除非您为每个主机固定一个容器。

手动设置堆大小

编辑

默认情况下,Elasticsearch 会根据节点的角色和节点容器可用的总内存自动调整 JVM 堆的大小。 我们建议大多数生产环境使用此默认大小。 如果需要,您可以通过手动设置 JVM 堆大小来覆盖默认大小。

要在生产环境中手动设置堆大小,请在 /usr/share/elasticsearch/config/jvm.options.d 下绑定挂载一个 JVM 选项文件,其中包括您所需的堆大小设置。

对于测试,您还可以使用 ES_JAVA_OPTS 环境变量手动设置堆大小。例如,要使用 1GB,请使用以下命令。

docker run -e ES_JAVA_OPTS="-Xms1g -Xmx1g" -e ENROLLMENT_TOKEN="<token>" --name es01 -p 9200:9200 --net elastic -it docker.elastic.co/elasticsearch/elasticsearch:8.17.0

ES_JAVA_OPTS 变量会覆盖所有其他 JVM 选项。我们不建议在生产环境中使用 ES_JAVA_OPTS

将部署固定到特定的镜像版本

编辑

将您的部署固定到特定版本的 Elasticsearch Docker 镜像。例如 docker.elastic.co/elasticsearch/elasticsearch:8.17.0

始终绑定数据卷

编辑

您应该将卷绑定到 /usr/share/elasticsearch/data,原因如下:

  1. 如果容器被杀死,您的 Elasticsearch 节点的数据不会丢失
  2. Elasticsearch 对 I/O 很敏感,而 Docker 存储驱动程序对于快速 I/O 来说并不理想
  3. 它允许使用高级的 Docker 卷插件

避免使用 loop-lvm 模式

编辑

如果您使用的是 devicemapper 存储驱动程序,请勿使用默认的 loop-lvm 模式。配置 docker-engine 以使用direct-lvm

集中管理您的日志

编辑

请考虑使用不同的 日志记录驱动程序来集中管理您的日志。另请注意,默认的 json-file 日志记录驱动程序并不适合在生产环境中使用。

使用 Docker 配置 Elasticsearch

编辑

当您在 Docker 中运行时,Elasticsearch 配置文件/usr/share/elasticsearch/config/ 加载。

要使用自定义配置文件,您需要绑定挂载文件,覆盖镜像中的配置文件。

您可以使用 Docker 环境变量设置单个 Elasticsearch 配置参数。 示例 compose 文件单节点示例使用此方法。您可以直接使用设置名称作为环境变量名称。如果您无法这样做,例如因为您的编排平台禁止环境变量名称中包含句点,则您可以通过以下方式转换设置名称来使用替代样式。

  1. 将设置名称更改为大写
  2. ES_SETTING_ 为前缀
  3. 通过重复来转义任何下划线 (_)
  4. 将所有句点 (.) 转换为下划线 (_)

例如,-e bootstrap.memory_lock=true 变为 -e ES_SETTING_BOOTSTRAP_MEMORY__LOCK=true

您可以使用文件的内容来设置 ELASTIC_PASSWORDKEYSTORE_PASSWORD 环境变量的值,方法是在环境变量名称后附加 _FILE。 这对于将密码等机密传递给 Elasticsearch 而无需直接指定它们非常有用。

例如,要从文件设置 Elasticsearch 引导密码,您可以绑定挂载该文件并将 ELASTIC_PASSWORD_FILE 环境变量设置为挂载位置。 如果您将密码文件挂载到 /run/secrets/bootstrapPassword.txt,请指定:

-e ELASTIC_PASSWORD_FILE=/run/secrets/bootstrapPassword.txt

您可以覆盖镜像的默认命令,以将 Elasticsearch 配置参数作为命令行选项传递。例如:

docker run <various parameters> bin/elasticsearch -Ecluster.name=mynewclustername

虽然绑定挂载您的配置文件通常是生产环境中的首选方法,但您也可以创建包含您的配置的自定义 Docker 镜像

挂载 Elasticsearch 配置文件

编辑

创建自定义配置文件,并将其绑定挂载到 Docker 镜像中对应的文件上。例如,要使用 docker run 绑定挂载 custom_elasticsearch.yml,请指定:

-v full_path_to/custom_elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

如果您绑定挂载自定义的 elasticsearch.yml 文件,请确保其中包含 network.host: 0.0.0.0 设置。此设置可确保节点可用于 HTTP 和传输流量,前提是其端口已公开。Docker 镜像的内置 elasticsearch.yml 文件默认包含此设置。

容器使用 uid:gid 1000:0 以用户 elasticsearch 身份运行 Elasticsearch。绑定挂载的主机目录和文件必须可由此用户访问,并且数据和日志目录必须可由此用户写入。

创建加密的 Elasticsearch 密钥库

编辑

默认情况下,Elasticsearch 将为安全设置自动生成密钥库文件。 此文件是混淆的,但未加密。

要使用密码加密您的安全设置并使其在容器外部持久保存,请使用 docker run 命令手动创建密钥库。 该命令必须:

  • 绑定挂载 config 目录。该命令将在此目录中创建一个 elasticsearch.keystore 文件。为避免错误,请勿直接绑定挂载 elasticsearch.keystore 文件。
  • 使用 elasticsearch-keystore 工具以及 create -p 选项。系统会提示您输入密钥库的密码。

例如:

docker run -it --rm \
-v full_path_to/config:/usr/share/elasticsearch/config \
docker.elastic.co/elasticsearch/elasticsearch:8.17.0 \
bin/elasticsearch-keystore create -p

您还可以使用 docker run 命令在密钥库中添加或更新安全设置。系统会提示您输入设置值。如果密钥库已加密,系统还会提示您输入密钥库密码。

docker run -it --rm \
-v full_path_to/config:/usr/share/elasticsearch/config \
docker.elastic.co/elasticsearch/elasticsearch:8.17.0 \
bin/elasticsearch-keystore \
add my.secure.setting \
my.other.secure.setting

如果您已创建密钥库并且不需要更新它,则可以直接绑定挂载 elasticsearch.keystore 文件。您可以使用 KEYSTORE_PASSWORD 环境变量在启动时向容器提供密钥库密码。例如,docker run 命令可能具有以下选项:

-v full_path_to/config/elasticsearch.keystore:/usr/share/elasticsearch/config/elasticsearch.keystore
-e KEYSTORE_PASSWORD=mypassword

使用自定义 Docker 镜像

编辑

在某些环境中,准备包含您的配置的自定义镜像可能更有意义。为此,Dockerfile 可能像这样简单:

FROM docker.elastic.co/elasticsearch/elasticsearch:8.17.0
COPY --chown=elasticsearch:elasticsearch elasticsearch.yml /usr/share/elasticsearch/config/

然后,您可以使用以下命令构建并运行该镜像:

docker build --tag=elasticsearch-custom .
docker run -ti -v /usr/share/elasticsearch/data elasticsearch-custom

某些插件需要额外的安全权限。您必须通过以下方式之一显式接受它们:

  • 在运行 Docker 镜像时附加 tty,并在提示时允许权限。
  • 检查安全权限并通过将 --batch 标志添加到插件安装命令来接受它们(如果合适)。

有关更多信息,请参阅插件管理

排除 Elasticsearch 的 Docker 错误

编辑

以下是如何解决使用 Docker 运行 Elasticsearch 时出现的常见错误的方法。

elasticsearch.keystore 是一个目录

编辑
Exception in thread "main" org.elasticsearch.bootstrap.BootstrapException: java.io.IOException: Is a directory: SimpleFSIndexInput(path="/usr/share/elasticsearch/config/elasticsearch.keystore") Likely root cause: java.io.IOException: Is a directory

密钥库相关docker run 命令尝试直接绑定挂载一个不存在的 elasticsearch.keystore 文件。如果您使用 -v--volume 标志来挂载一个不存在的文件,Docker 会创建一个同名的目录。

要解决此错误:

  1. 删除 config 目录中的 elasticsearch.keystore 目录。
  2. 更新 -v--volume 标志,以指向 config 目录路径,而不是密钥库文件的路径。有关示例,请参阅创建加密的 Elasticsearch 密钥库
  3. 重试该命令。

elasticsearch.keystore:设备或资源繁忙

编辑
Exception in thread "main" java.nio.file.FileSystemException: /usr/share/elasticsearch/config/elasticsearch.keystore.tmp -> /usr/share/elasticsearch/config/elasticsearch.keystore: Device or resource busy

一个 docker run 命令尝试在直接绑定挂载 elasticsearch.keystore 文件的情况下更新密钥库。要更新密钥库,容器需要访问 config 目录中的其他文件,例如 keystore.tmp

要解决此错误:

  1. 更新 -v--volume 标志,以指向 config 目录路径,而不是密钥库文件的路径。有关示例,请参阅创建加密的 Elasticsearch 密钥库
  2. 重试该命令。