06. 通过 Docker 安装 Elasticsearch

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

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

在Docker中运行Elasticsearch

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

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

启动单节点集群

安装Docker。访问Get Docker以安装适用于您环境的Docker。

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

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

bash 复制代码
docker network create elastic
  1. 拉取Elasticsearch Docker镜像。
bash 复制代码
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.11.1
  1. 可选:为您的环境安装Cosign。然后使用Cosign验证Elasticsearch镜像的签名。
bash 复制代码
wget https://artifacts.elastic.co/cosign.pub
cosign verify --key cosign.pub docker.elastic.co/elasticsearch/elasticsearch:8.11.1

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

vbnet 复制代码
Verification for docker.elastic.co/elasticsearch/elasticsearch:8.11.1 --
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
  1. 启动Elasticsearch容器。
bash 复制代码
docker run --name es01 --net elastic -p 9200:9200 -it -m 1GB docker.elastic.co/elasticsearch/elasticsearch:8.11.1

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

该命令打印出elastic用户密码和Kibana的enrollment令牌。

  1. 复制生成的elastic密码和enrollment令牌。这些凭据仅在首次启动Elasticsearch时显示。您可以使用以下命令重新生成凭据。
bash 复制代码
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环境变量。例如:

bash 复制代码
export ELASTIC_PASSWORD="your_password"
  1. 从容器复制http_ca.crt SSL证书到本地机器。
bash 复制代码
docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .
  1. 通过REST API调用Elasticsearch来确保Elasticsearch容器正在运行。
bash 复制代码
curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD https://localhost:9200
添加更多节点
  1. 使用现有节点生成新节点的enrollment令牌。
bash 复制代码
docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node

enrollment令牌有效期为30分钟。

  1. 启动新的Elasticsearch容器。将enrollment令牌作为环境变量包含在内。
bash 复制代码
docker run -e ENROLLMENT_TOKEN="<token>" --name es02 --net elastic -it -m 1GB docker.elastic.co/elasticsearch/elasticsearch:8.11.1
  1. 调用cat nodes API来验证节点是否已添加到集群。
bash 复制代码
curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD https://localhost:9200/_cat/nodes
运行Kibana
  1. 拉取Kibana Docker镜像。
bash 复制代码
docker pull docker.elastic.co/kibana/kibana:8.11.1
  1. 可选:验证Kibana镜像的签名。
bash 复制代码
wget https://artifacts.elastic.co/cosign.pub
cosign verify --key cosign.pub docker.elastic.co/kibana/kibana:8.11.1
  1. 启动Kibana容器。
bash 复制代码
docker run --name kib01 --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:8.11.1
  1. 当Kibana启动时,它会在终端输出一个唯一生成的链接。要访问Kibana,请在Web浏览器中打开此链接。

  2. 在浏览器中,输入启动Elasticsearch时生成的enrollment令牌。

  3. 要重新生成令牌,请运行:

bash 复制代码
docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
  1. 使用在启动Elasticsearch时生成的密码登录Kibana。

要重新生成密码,请运行:

bash 复制代码
docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
删除容器

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

bash 复制代码
# 删除Elastic网络
docker network rm elastic

# 删除Elasticsearch容器
docker rm es01
docker rm es02

# 删除Kibana容器
docker rm kib01
下一步

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

使用Docker Compose启动一个包含三个节点的Elasticsearch集群以及Kibana。

Docker Compose可以使用单个命令启动多个容器。

配置并启动集群:
  1. 安装Docker Compose。请访问Docker Compose文档以在您的环境中安装Docker Compose。 如果您使用的是Docker Desktop,Docker Compose将自动安装。确保为Docker Desktop分配至少4GB的内存。您可以通过转到Settings > Resources来调整Docker Desktop的内存使用。
  2. 创建或导航到项目的空目录。
  3. 在项目目录中下载并保存以下文件:
  • .env
  • docker-compose.yml
  1. 在.env文件中,为ELASTIC_PASSWORD和KIBANA_PASSWORD变量指定密码。 密码必须是字母数字组合,不能包含特殊字符,例如!或@。docker-compose.yml文件中包含的bash脚本仅支持字母数字字符。示例:
ini 复制代码
# 'elastic'用户的密码(至少6个字符)
ELASTIC_PASSWORD=changeme

# 'kibana_system'用户的密码(至少6个字符)
KIBANA_PASSWORD=changeme
...
  1. 在.env文件中,将STACK_VERSION设置为当前Elastic Stack版本。
ini 复制代码
...
# Elastic产品的版本
STACK_VERSION=8.11.1
...
  1. 默认情况下,Docker Compose配置将端口9200暴露给所有网络接口。 为了避免将端口9200暴露给外部主机,请在.env文件中将ES_PORT设置为127.0.0.1:9200。这将确保Elasticsearch仅从主机机器访问。
ini 复制代码
...
# 将Elasticsearch HTTP API暴露给主机的端口
# ES_PORT=9200
ES_PORT=127.0.0.1:9200
...
  1. 要启动集群,请从项目目录运行以下命令。
bash 复制代码
docker-compose up -d
  1. 集群启动后,在Web浏览器中打开http://localhost:5601以访问Kibana。
  2. 使用您之前设置的ELASTIC_PASSWORD登录到Kibana。
停止和删除集群:

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

bash 复制代码
docker-compose down

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

bash 复制代码
docker-compose down -v
下一步:

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

在生产环境中运行Elasticsearch的Docker镜像

需要遵循以下要求和建议。

设置vm.max_map_count至少为262144

在生产环境中,vm.max_map_count内核设置必须设置为至少262144。

设置vm.max_map_count的方式取决于您的平台。

Linux

查看当前vm.max_map_count设置的值:

bash 复制代码
grep vm.max_map_count /etc/sysctl.conf

将该设置应用于运行中的系统:

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

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

macOS with Docker for Mac

必须在xhyve虚拟机中设置vm.max_map_count设置: 从命令行运行:

bash 复制代码
screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty

按回车键并使用sysctl配置vm.max_map_count

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

退出screen会话,输入Ctrl a d。

Windows and macOS with Docker Desktop

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

bash 复制代码
docker-machine ssh
sudo sysctl -w vm.max_map_count=262144
Windows with Docker Desktop WSL 2 backend

在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窗口中运行以下命令:

bash 复制代码
wsl -d docker-desktop -u root
sysctl -w vm.max_map_count=262144

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

ini 复制代码
[wsl2]
kernelCommandLine = "sysctl.vm.max_map_count=262144"

这将导致启动时为所有WSL2 VM分配该设置。 如果您使用的是Windows 11或Windows 10版本22H2,并且已安装了WSL的Microsoft Store版本,可以在"docker-desktop"WSL分发中修改/etc/sysctl.conf,例如使用以下命令:

bash 复制代码
wsl -d docker-desktop -u root
vi /etc/sysctl.conf

并追加一行:

ini 复制代码
vm.max_map_count = 262144
配置文件必须对elasticsearch用户可读

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

一个例外是Openshift,它使用任意分配的用户ID运行容器。Openshift将具有gid设置为0的持久卷呈现给容器,这样就无需进行任何调整。

如果正在进行本地目录或文件的bind-mount,它必须可读取elasticsearch用户。此外,此用户必须对config、data和log目录(Elasticsearch需要对config目录具有写入访问权限,以便它可以生成keystore)具有写访问权限。一种良好的策略是为本地目录授予gid 0的组访问权限。

例如,为通过bind-mount存储数据准备本地目录:

bash 复制代码
mkdir esdatadir
chmod g+rwx esdatadir
chgrp 0 esdatadir

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

  • Bind-mount config、data和logs目录。如果打算安装插件并且不想创建自定义Docker镜像,则还必须bind-mount插件目录。
  • docker run命令中传递--group-add 0选项。这确保Elasticsearch正在运行的用户也是容器内的root(GID 0)组的成员。
增加nofilenproc的ulimits

Elasticsearch容器需要nofilenproc的增加的ulimits。验证Docker守护程序的init系统是否将其设置为可接受的值。

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

bash 复制代码
docker run --rm docker.elastic.co/elasticsearch/elasticsearch:8.11.1 /bin/bash -c 'ulimit -Hn && ulimit -Sn && ulimit -Hu && ulimit -Su'

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

bash 复制代码
--ulimit nofile=65535:65535
禁用交换

出于性能和节点稳定性的考虑,交换需要被禁用。有关如何执行此操作的信息,请参见禁用交换。 如果选择bootstrap.memory_lock: true 的方法,还需要在Docker Daemon中定义memlock: true ulimit,或者像示例compose文件中显示的那样为容器显式设置。在使用docker run时,可以指定:

bash 复制代码
bashCopy code
-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,请使用以下命令:

ini 复制代码
bashCopy code
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.11.1

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

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

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

始终绑定数据卷

应该使用绑定到**/usr/share/elasticsearch/data**的卷,原因如下:

  • 如果容器被终止,Elasticsearch节点的数据不会丢失。
  • Elasticsearch对I/O敏感,Docker存储驱动程序不适用于快速I/O。
  • 它允许使用高级Docker卷插件。
避免使用loop-lvm模式

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

集中化日志

考虑使用不同的日志驱动程序将日志集中起来。还请注意,默认的json-file日志驱动程序不太适合生产使用。

配置Elasticsearch

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

要使用自定义配置文件,您可以通过bind-mount方式将文件挂载到镜像中的配置文件上。

您可以使用Docker环境变量设置单个Elasticsearch配置参数。示例compose文件和单节点示例使用了此方法。您可以直接使用设置名称作为环境变量名称。如果不能这样做,例如因为编排平台禁止环境变量名称中的句点,则可以使用另一种样式,方法是按照以下方式转换设置名称。

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

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

您可以使用文件的内容来设置ELASTIC_PASSWORDKEYSTORE_PASSWORD环境变量的值,方法是在环境变量名称后缀添加_FILE。这对于在不直接指定密码的情况下将密码等机密信息传递给Elasticsearch非常有用。

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

bash 复制代码
-e ELASTIC_PASSWORD_FILE=/run/secrets/bootstrapPassword.txt

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

bash 复制代码
docker run <various parameters> bin/elasticsearch -Ecluster.name=mynewclustername

尽管在生产中通常是通过bind-mount配置文件的方式,但您还可以创建一个包含您的配置的自定义Docker镜像。

挂载Elasticsearch配置文件

创建自定义配置文件并通过bind-mount方式将它们挂载到Docker镜像中的相应文件上。例如,使用docker run时,要bind-mount custom_elasticsearch.yml,请指定:

bash 复制代码
-v full_path_to/custom_elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

如果绑定-mount了自定义elasticsearch.yml文件,请确保它包含network.host: 0.0.0.0设置。此设置确保节点可以通过HTTP和传输流量访问,前提是其端口已暴露。Docker镜像的内置elasticsearch.yml文件默认包含此设置。

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

创建加密的Elasticsearch keystore

默认情况下,Elasticsearch将使用密码自动生成一个keystore文件,该文件是混淆的但未加密的。

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

  • bind-mount配置目录。该命令将在此目录中创建一个elasticsearch.keystore文件。为避免错误,请不要直接bind-mount elasticsearch.keystore 文件。
  • 使用带有create -p选项的elasticsearch-keystore工具。您将被提示输入keystore的密码。

例如:

bash 复制代码
docker run -it --rm \
-v full_path_to/config:/usr/share/elasticsearch/config \
docker.elastic.co/elasticsearch/elasticsearch:8.11.1 \
bin/elasticsearch-keystore create -p

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

bash 复制代码
docker run -it --rm \
-v full_path

_to/config:/usr/share/elasticsearch/config \
docker.elastic.co/elasticsearch/elasticsearch:8.11.1 \
bin/elasticsearch-keystore \
add my.secure.setting \
my.other.secure.setting

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

bash 复制代码
-v full_path_to/config/elasticsearch.keystore:/usr/share/elasticsearch/config/elasticsearch.keystore
-e KEYSTORE_PASSWORD=mypassword
使用自定义Docker镜像

在某些环境中,准备一个包含您的配置的自定义镜像可能更有意义。实现这一点的Dockerfile可能如下所示:

dockerfile 复制代码
FROM docker.elastic.co/elasticsearch/elasticsearch:8.11.1
COPY --chown=elasticsearch:elasticsearch elasticsearch.yml /usr/share/elasticsearch/config/

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

bash 复制代码
docker build --tag=elasticsearch-custom .
docker run -ti -v /usr/share/elasticsearch/data elasticsearch-custom

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

  • 在运行Docker镜像时附加一个tty,并在提示时允许权限。
  • 通过在plugin install命令中添加--batch标志,检查安全权限并接受它们(如果适用)。

有关更多信息,请参见Plugin management

解决Elasticsearch运行Docker错误
elasticsearch.keystore是一个目录
lua 复制代码
Exception in thread "main" org.elasticsearch.bootstrap.BootstrapException: java.io.IOException: Is a directory: SimpleFSIndexInput(path="/usr/share/elasticsearch/config/elasticsearch.keystore")

一个与keystore相关的docker run命令试图直接bind-mount不存在的elasticsearch.keystore文件。如果使用-v--volume标志挂载不存在的文件,Docker会创建具有相同名称的目录。

要解决此错误:

  • 删除config目录中的elasticsearch.keystore目录。
  • -v--volume标志更新为指向config目录路径,而不是keystore文件的路径。有关示例,请参见[创建加密的Elasticsearch keystore](#创建加密的Elasticsearch keystore "#%E5%88%9B%E5%BB%BA%E5%8A%A0%E5%AF%86%E7%9A%84Elasticsearch-keystore")。
  • 重试命令。
elasticsearch.keystore: Device or resource busy
ruby 复制代码
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命令试图在直接bind-mountelasticsearch.keystore文件的同时更新keystore。要更新keystore,容器需要访问config目录中的其他文件,例如keystore.tmp

要解决此错误:

  • -v--volume标志更新为指向config目录路径,而不是keystore文件的路径。有关示例,请参见[创建加密的Elasticsearch keystore](#创建加密的Elasticsearch keystore "#%E5%88%9B%E5%BB%BA%E5%8A%A0%E5%AF%86%E7%9A%84Elasticsearch-keystore")。
  • 重试命令。
相关推荐
Elastic 中国社区官方博客3 小时前
Elasticsearch 开放推理 API 增加了对 Google AI Studio 的支持
大数据·数据库·人工智能·elasticsearch·搜索引擎
alfiy5 小时前
Elasticsearch学习笔记(六)使用集群令牌将新加点加入集群
笔记·学习·elasticsearch
帅气的人1235 小时前
使用 docker-compose 启动 es 集群 + kibana
elasticsearch·docker
漫无目的行走的月亮6 小时前
比较Elasticsearch和Hadoop
hadoop·elasticsearch
hengzhepa14 小时前
ElasticSearch备考 -- Async search
大数据·学习·elasticsearch·搜索引擎·es
bubble小拾1 天前
ElasticSearch高级功能详解与读写性能调优
大数据·elasticsearch·搜索引擎
不能放弃治疗1 天前
重生之我们在ES顶端相遇第 18 章 - Script 使用(进阶)
elasticsearch
hengzhepa1 天前
ElasticSearch备考 -- Search across cluster
学习·elasticsearch·搜索引擎·全文检索·es
Elastic 中国社区官方博客1 天前
Elasticsearch:使用 LLM 实现传统搜索自动化
大数据·人工智能·elasticsearch·搜索引擎·ai·自动化·全文检索
慕雪华年1 天前
【WSL】wsl中ubuntu无法通过useradd添加用户
linux·ubuntu·elasticsearch