Elasticsearch:如何在 Docker 上运行 Elasticsearch 8.x 进行本地开发
对于 Elasticsearch 的新主要版本 (8.x.x),有关于在 Docker 上运行 Elasticsearch 和 Kibana 的重大更新。 过去适用于以前版本的 Docker 和 Docker Compose 的命令和语法需要更新才能适用于最新版本。 在这篇文章中,我们将介绍如何使用 Docker 和 Docker Compose 启动 Elasticsearch(8.6.0 版本)和 Kibana 进行本地开发。
我在之前的如下的文章中也对这个有所描述,但是在今天的文章中,我将从另外一个视角来进行展示。我将展示如何安装不带安全的 Elasticsearch。这个在很多的情况下也是适用的。
-
Elastic:使用 docker 来安装 Elastic Stack 8.0
-
Elasticsearch:使用 Docker compose 来一键部署 Elastic Stack 8.x
在我的展示中,我将使用最新的 Elastic Stack 8.6.0 来进行展示。
在禁用 xpack 安全性的情况下在 Docker 上运行 Elasticsearch 和 Kibana
默认情况下启用 xpack 安全性,这意味着你需要身份验证才能访问 Elasticsearch 服务器。 但是,对于本地开发,我们通常不需要很高的安全级别,因为一切都在本地。 我们将更多地关注业务逻辑和代码,而不是基础设施。 当代码准备好用于生产时。 我们可以使用托管的 Elasticsearch 解决方案,例如开发和维护 Elasticsearch 的公司 elastic.co。
直接用 Docker 启动 Elasticsearch 和 Kibana 非常简单。 首先,我们需要创建一个供 Elasticsearch 和 Kibana 使用的 network。这个 network 将被用于 Elasticsearch 和 Kibana 之间的通信。
docker network create elastic
1. $ docker network create elastic
2. 74c71b18b8f1a411e76ba9e99fea31d858301bc6b861d5fe795afac53b00fdce
然后我们可以为 Elasticsearch 创建一个 Docker 容器:
1. docker run \
2. --name elasticsearch \
3. --net elastic \
4. -p 9200:9200 \
5. -e discovery.type=single-node \
6. -e ES_JAVA_OPTS="-Xms1g -Xmx1g"\
7. -e xpack.security.enabled=false \
8. -it \
9. docker.elastic.co/elasticsearch/elasticsearch:8.6.0
这里的要点:
- 刚刚创建的网络用于 Elasticsearch,因此它可以被 Kibana 发现,Kibana 也将使用该网络。
- 创建单节点 Elasticsearch 集群。
- 环境变量 ES_JAVA_OPTS 用于指定最小和最大 JVM 堆大小(在本例中为 1GB)。 如果没有设置,很有可能你的 Elasticsearch 容器无法启动成功。
- 我们需要明确禁用 xpack 安全性,这样我们就不需要身份验证来访问 Elasticsearch 服务器。 本地开发没问题,但应该为生产启用。
我们可以使用 Dockerhub 上托管的 docker 镜像,也可以使用 Elasticsearch 直接提供的镜像。
运行完上面的命令后,我们可以使用如下的命令来查看正在运行的 docker 容器:
docker ps
1. $ docker ps
2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3. 5418c3eb7e96 docker.elastic.co/elasticsearch/elasticsearch:8.6.0 "/bin/tini -- /usr/l…" About a minute ago Up About a minute 0.0.0.0:9200->9200/tcp, 9300/tcp elasticsearch
我们在 macOS 上可以使用如下的命令来查看 9200 是否已经被使用:
sudo lsof -i -P | grep LISTEN | grep 9200
1. $ sudo lsof -i -P | grep LISTEN | grep 9200
2. Password:
3. com.docke 55204 liuxg 133u IPv6 0xec85ab355a7a51d 0t0 TCP *:9200 (LISTEN)
我们在 terminal 中可以打入如下的命令来进行查看:
curl localhost:9200
`
1. $ curl localhost:9200
2. {
3. "name" : "5418c3eb7e96",
4. "cluster_name" : "docker-cluster",
5. "cluster_uuid" : "8T2kPKBCQ_Ck03Xli0GHVw",
6. "version" : {
7. "number" : "8.6.0",
8. "build_flavor" : "default",
9. "build_type" : "docker",
10. "build_hash" : "f67ef2df40237445caa70e2fef79471cc608d70d",
11. "build_date" : "2023-01-04T09:35:21.782467981Z",
12. "build_snapshot" : false,
13. "lucene_version" : "9.4.2",
14. "minimum_wire_compatibility_version" : "7.17.0",
15. "minimum_index_compatibility_version" : "7.0.0"
16. },
17. "tagline" : "You Know, for Search"
18. }
`![](https://****img.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
上面表明我们的 Elasticsearch 已经成功地运行起来了。当你看到上面的输出时,表示 Elasticsearch Docker 容器已成功启动。
然后我们可以启动一个 Kibana 容器来管理带有漂亮用户界面的 Elasticsearch 服务器。要为 Kibana 启动 Docker 容器,请在另外一个 terminal 中运行:
1. docker run \
2. --name kibana \
3. --net elastic \
4. -p 5601:5601 \
5. docker.elastic.co/kibana/kibana:8.6.0
这里的重点是:
- 我们必须为 Kibana 指定与 Elasticsearch 相同的网络。
- 最好使用与 Elasticsearch 相同版本的 Kibana。
如果访问 http://localhost:5601,就可以直接打开 Kibana 的Web UI,不需要认证。
我们可以使用如下的命令来查看正在运行的容器:
docker ps
1. $ docker ps
2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3. 6a4a6b1f8fbf docker.elastic.co/kibana/kibana:8.6.0 "/bin/tini -- /usr/l…" 3 minutes ago Up 3 minutes 0.0.0.0:5601->5601/tcp kibana
4. 5418c3eb7e96 docker.elastic.co/elasticsearch/elasticsearch:8.6.0 "/bin/tini -- /usr/l…" 15 minutes ago Up 15 minutes 0.0.0.0:9200->9200/tcp, 9300/tcp elasticsearch
使用 Docker Compose 运行 Elasticsearch 和 Kibana
最好在 docker-compose.yaml 文件中指定我们需要运行的 Docker 容器,尤其是当你有多个容器时。 这样,你可以同时管理它们,而不需要一个一个地启动它们。 有了docker-compose.yaml,代码的版本控制和共享也更加方便。
上面演示的 Elasticsearch 和 Kibana 容器的 docker-compose.yaml 文件如下。 设置与直接启动 Docker 容器相同。我们先使用 CTRL+C 来停止上面运行的容器。我们创建如下的 docker-compose.yml 文件:
docker-compose.yml
`
1. version: "3.9"
2. services:
3. elasticsearch:
4. image: elasticsearch:8.6.0
5. environment:
6. - discovery.type=single-node
7. - ES_JAVA_OPTS=-Xms1g -Xmx1g
8. - xpack.security.enabled=false
9. volumes:
10. - es_data:/usr/share/elasticsearch/data
11. ports:
12. - target: 9200
13. published: 9200
14. networks:
15. - elastic
17. kibana:
18. image: kibana:8.6.0
19. ports:
20. - target: 5601
21. published: 5601
22. depends_on:
23. - elasticsearch
24. networks:
25. - elastic
27. volumes:
28. es_data:
29. driver: local
31. networks:
32. elastic:
33. name: elastic
34. driver: bridge
`![](https://****img.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
可以看到,我们可以在同一个文件中管理网络、volume 和容器,超级方便。 请记住在使用此 docker-compose.yaml 文件启动容器/服务之前关闭上面启动的 elasticsearch 和 kibana 容器,否则会发生端口冲突。 或者,你可以在此文件中指定不同的已发布端口。我们使用如下的命令来启动:
docker-compose up
等 Elasticsearch 及 Kibana 容器起来后,我们就可以访问它们了。当我们完成上面的运行并不再使用这些容器的话,请使用如下的命令来删除使用的资源:
docker-compose down
在启用 xpack 安全性的 Docker 上运行 Elasticsearch 和 Kibana
上面我们介绍了如何快速启动 Elasticsearch 和 Kibana 的 Docker 容器进行本地开发。 当不需要担心身份验证问题时,它们非常适合本地开发。
对于生产,我们当然应该启用 xpack 安全功能。 但是,如果可能的话,我们不应该自己托管 Elasticsearch 服务器,而应该通过专门的提供商来托管,例如开发和维护 Elasticsearch 的公司 elastic.co。 这样,我们就不用担心硬件、安全、升级等细节问题,可以专注于业务逻辑和数据。
然而,在某些情况下也需要本地身份验证。 我们可以删除上面演示的 xpack.security.enabled=false 环境变量,xpack 安全将自动启用。我们先创 elastic 这个网络:
docker network create elastic
如果网络已经存在,你可以不创建。
要启动启用了 xpack 安全性的 Elasticsearch 容器,请运行:
1. docker run \
2. --name elasticsearch \
3. --net elastic \
4. -p 9200:9200 \
5. -e discovery.type=single-node \
6. -e ES_JAVA_OPTS="-Xms1g -Xmx1g"\
7. -e ELASTIC_PASSWORD=elastic \
8. -it \
9. docker.elastic.co/elasticsearch/elasticsearch:8.6.0
如果你已经做了上面的练习,那么你可能会遇到如下的错误信息:
1. $ docker run \
2. > --name elasticsearch \
3. > --net elastic \
4. > -p 9200:9200 \
5. > -e discovery.type=single-node \
6. > -e ES_JAVA_OPTS="-Xms1g -Xmx1g"\
7. > -e ELASTIC_PASSWORD=elastic \
8. > -it \
9. > docker.elastic.co/elasticsearch/elasticsearch:8.6.0
10. docker: Error response from daemon: Conflict. The container name "/elasticsearch" is already in use by container "5418c3eb7e964993215c3162571e6cbe3dc969b68ced0cf5ff0529d9a93fb7ff". You have to remove (or rename) that container to be able to reuse that name.
11. See 'docker run --help'.
这是因为 elasticsearch 这个名字已经被使用。我们可以通过如下的方法来删除它:
1. $ docker ps -a
2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3. 6a4a6b1f8fbf docker.elastic.co/kibana/kibana:8.6.0 "/bin/tini -- /usr/l…" 15 minutes ago Exited (0) 7 minutes ago kibana
4. 5418c3eb7e96 docker.elastic.co/elasticsearch/elasticsearch:8.6.0 "/bin/tini -- /usr/l…" 27 minutes ago Exited (130) 7 minutes ago elasticsearch
5. $ docker container rm elasticsearch
6. elasticsearch
7. $ docker container rm kibana
8. kibana
这样,我们删除了上面的两个容器:elasticsearch 及 kibana。我们再次运行上面的命令:
请注意,我们为默认用户 elastic 指定了密码。 如果此处不指定,则在启动容器时会生成一个随机密码。 你还将看到为 Kibana 生成的注册 token:
我们向下滚动,我们可以看到:
打开一个新的控制台,我们先直接调用 Elasticsearch API。 奇怪的是,我们需要从 Docker 容器中复制安全证书并将其用于 curl 身份验证:
docker cp elasticsearch:/usr/share/elasticsearch/config/certs/http_ca.crt .
1. $ docker cp elasticsearch:/usr/share/elasticsearch/config/certs/http_ca.crt .
2. $ ls
3. docker-compose.yml http_ca.crt
我们在上面的目录中使用如下的命令:
curl --cacert http_ca.crt https://elastic:elastic@localhost:9200
`
1. $ curl --cacert http_ca.crt https://elastic:elastic@localhost:9200
2. {
3. "name" : "0d00368e6884",
4. "cluster_name" : "docker-cluster",
5. "cluster_uuid" : "_do0yq5LQt-puX4feF8cBQ",
6. "version" : {
7. "number" : "8.6.0",
8. "build_flavor" : "default",
9. "build_type" : "docker",
10. "build_hash" : "f67ef2df40237445caa70e2fef79471cc608d70d",
11. "build_date" : "2023-01-04T09:35:21.782467981Z",
12. "build_snapshot" : false,
13. "lucene_version" : "9.4.2",
14. "minimum_wire_compatibility_version" : "7.17.0",
15. "minimum_index_compatibility_version" : "7.0.0"
16. },
17. "tagline" : "You Know, for Search"
18. }
`![](https://****img.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
然后让我们创建一个 Kibana 容器来管理这个带有身份验证的 Elasticsearch 服务器。 该命令实际上与上面相同:
1. docker run \
2. --name kibana \
3. --net elastic \
4. -p 5601:5601 \
5. docker.elastic.co/kibana/kibana:8.6.0
在控制台中,我们看到类似这样的内容:
注意:我们需要在 URL 中指定验证码才能访问 Kibana。 0.0.0.0 表示本地计算机上的所有 IPv4 地址都可以访问此端口。 当你转到 http://0.0.0.0:5601/?code=828696 时,系统会提示你输入注册 token:
复制并粘贴启动 Elasticsearch 容器时屏幕上显示的注册 token。 如果屏幕上满是日志或令牌已过期,你可以使用 elasticsearch-create-enrollment-token 命令生成一个新 token。 我们可以直接在 Elasticsearch 容器内使用 elasticsearch-create-enrollment-token 命令:
1. $ docker exec -it elasticsearch \
2. /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token \
3. -s kibana
然后在你点击 “Configure Elastic” 之后,你需要输入你的用户名和密码,在这个例子中都 elastic。最后,你可以使用 Kibana 来管理你的 Elasticsearch 服务器。 嗯,启用 xpack 安全性确实非常安全。 我们需要验证码、注册 token 和用户名/密码,这将确保安全????️。
启用 xpack 安全性时使用 Docker Compose 运行 Elasticsearch 和 Kibana
令人惊讶的是,在启用 xpack 安全性的情况下,编写 docker-compose.yaml 文件来管理 Elasticsearch 和 Kibana 容器非常复杂。 我们需要自己明确管理证书,可以在 “Elasticsearch:使用 Docker compose 来一键部署 Elastic Stack 8.x” 中找到。 很奇怪,直接使用 Docker 如此简单,而使用 Docker Compose 对于 xpack 安全性却复杂得多。 我认为在他们有更好的版本之前,我们应该避免使用它。
总结
我们已经介绍了在 Docker 上运行 Elasticsearch 和 Kibana 的各种方法。 对于本地开发,在大多数情况下我们可以禁用 xpack 安全性,只关注数据和查询。 在禁用 xpack 安全性时使用 Docker 会更加直接。 对于生产,我们通常会将数据托管在专门的提供商(例如 elastic.co)上,这样可以省去管理服务器、证券和升级的工作,让我们专注于重要的业务逻辑。