使用 Docker 安装 Elasticsearch编辑

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

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

如果您只想在本地开发中测试 Elasticsearch,请参考 本地开发设置(Docker)。请注意,此设置不适用于生产环境。

在 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.14.2
  4. 可选:为您的环境安装 Cosign。然后使用 Cosign 验证 Elasticsearch 镜像的签名。

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

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

    Verification for docker.elastic.co/elasticsearch/elasticsearch:8.14.2 --
    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.14.2

    使用 -m 标志为容器设置内存限制。这消除了 手动设置 JVM 大小 的需要。

    该命令打印 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.14.2
  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.14.2
  2. 可选:验证 Kibana 镜像的签名。

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

    docker run --name kib01 --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:8.14.2
  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.14.2
    ...
  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. 按回车键并使用 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

必须在 "docker-desktop" WSL 实例中设置 vm.max_map_count 设置,然后 Elasticsearch 容器才能正常启动。有几种方法可以做到这一点,具体取决于您的 Windows 版本和 WSL 版本。

如果您使用的是 Windows 10 版本 22H2 之前的版本,或者如果您使用的是 Windows 10 版本 22H2 并使用内置版本的 WSL,则您必须在每次重启 Docker 之前手动设置它,或者(如果您不想在每次重启时都这样做)您必须全局设置每个 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 用户读取edit

默认情况下,Elasticsearch 在容器内以用户 elasticsearch 身份运⾏,⽤户 ID 和组 ID 分别为 1000:0

唯⼀的例外是 Openshift,它使⽤随机分配的⽤户 ID 执⾏容器。Openshift 使⽤组 ID 为 0 的持久卷,这无需任何调整即可运⾏。

如果您要绑定挂载本地⽬录或⽂件,则该⽬录或⽂件必须可被 elasticsearch 用户读取。此外,该⽤户必须对 配置、数据和⽇志⽬录 具有写⼊权限(Elasticsearch 需要对 config ⽬录具有写⼊权限,以便它可以⽣成密钥库)。⼀个好的策略是授予本地⽬录的组 ID 为 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 的 ulimitedit

必须为 Elasticsearch 容器提供增加的 nofilenproc 的 ulimit。验证 Docker 守护进程的 init 系统 是否将其设置为可接受的值。

要检查 Docker 守护进程的 ulimit 默认值,请运⾏

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

如果需要,请在守护进程中调整它们,或为每个容器覆盖它们。例如,当使⽤ docker run 时,请设置

--ulimit nofile=65535:65535

禁用交换edit

为了性能和节点稳定性,需要禁用交换。有关如何禁用的信息,请参阅 禁用交换

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

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

随机化发布的端口edit

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

⼿动设置堆⼤⼩edit

默认情况下,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.14.2

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

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

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

始终绑定数据卷edit

您应该使⽤绑定到 /usr/share/elasticsearch/data 的卷,原因如下

  1. 如果容器被杀死,您的 Elasticsearch 节点的數據将不会丢失
  2. Elasticsearch 对 I/O 敏感,Docker 存储驱动程序不适合快速 I/O
  3. 它允许使⽤⾼级 Docker 卷插件

避免使⽤ loop-lvm 模式edit

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

集中您的日志edit

考虑使⽤不同的 日志驱动程序 集中您的日志。另请注意,默认的 json-file 日志驱动程序不适合⽣产使⽤。

使⽤ Docker 配置 Elasticsearchedit

在 Docker 中运⾏时,Elasticsearch 配置⽂件/usr/share/elasticsearch/config/ 加载。

要使⽤自定义配置⽂件,您需要 绑定挂载⽂件 到镜像中的配置⽂件上。

您可以使⽤ Docker 环境变量设置单个 Elasticsearch 配置参数。 示例组合⽂件单节点示例 使⽤了这种⽅法。您可以直接使⽤设置名称作为环境变量名称。如果您无法这样做(例如,因为您的编排平台禁止环境变量名称中出现句点),那么您可以使⽤备⽤样式,⽅法如下。

  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 配置⽂件edit

创建自定义配置⽂件,并将它们绑定挂载到 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 ⽂件默认包含此设置。

该容器 以用户 elasticsearch 身份运⾏ Elasticsearch,⽤户 ID 和组 ID 分别为 1000:0。绑定挂载的主机⽬录和⽂件必须可被该⽤户访问,并且数据和⽇志⽬录必须可被该⽤户写⼊。

创建加密的 Elasticsearch 密钥库edit

默认情况下,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.14.2 \
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.14.2 \
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.14.2
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. 重试命令。