0%

Effective Elasticsearch Plugin Management with Docker

原文地址:https://www.elastic.co/cn/blog/elasticsearch-docker-plugin-management

如果你正在用容器来运行elasticsearch,那么有一些事项需要注意。在管理有状态服务和守护进程时尤其如此——当将数据持久化在临时容器之外变得很重要时。

在容器中使用Elasticsearch插件就是一个例子,无论是以可重复、可跟踪的方式安装它们,还是管理插件配置和数据。

在这篇文章中,我们将探讨一些在Docker和Elasticsearch中实现合理插件管理的选项。

Docker 持久性入门

与版本控制系统中更改文档一样,更改正在运行的容器中的文档系统会在正在运行的镜像中引入差异。如果数据和更改需要在临时容器的范围之外永久保留,则需要采取措施。

尽管可以利用一些更复杂的存储方案来实现容器持久化,但绑定挂载的基本Docker机制最能说明问题。例如,通过将-v /data:/usr/share/elasticsearch/data之类的选项传递给docker run命令,将 Elasticsearch 索引长期保存在/data中来实现的,该命令有效地将Elasticsearch数据存储在主机的(不是容器的)/data 目录。

如果更改是永久性的,也就是说,预计它们不会随着时间的推移而改变,那么将更改编入Dockerfile中可能更有意义。这两种方法在不同情况下都有用。

管理基础插件

在以下示例中,我将“基础”插件称为不需要许可证或任何其他特殊组件的插件。 像cloud-aws这样简单的插件只需要在系统上放置一些文件就可以工作。

在这种情况下,管理插件的存在最简单,只需使用Dockerfile扩展镜像即可。 例如:

1
2
3
FROM elasticsearch:2

RUN /usr/share/elasticsearch/bin/plugin install --batch cloud-aws

这个Dockerfile从Docker Hub的维护者提供的Elasticsearch镜像开始,并运行一个简单的插件安装命令。然后可以通过标签构建和引用此镜像:

1
$ docker build -t elasticsearch-aws .

更复杂的插件

某些插件可能需要额外的文件(例如使用Shield时的证书)才能实现某些功能。上述构建自定义镜像的技术可以处理这些插件的安装,但管理配置是用其它方法处理更好。这有助于保持镜像的通用性以供部署重用,并保持对密钥的控制更严格。

注意:一些商业插件需要license。在以下示例中,我们仅依赖默认存在的临时试用license。在生产环境中部署时,license是通过Elasticsearch REST API执行的,它将license信息存储在Elasticsearch的数据路径中。只要您的数据通过卷装载或其他方式适当地持久化,您的license信息就会保存在您的集群中。

Example: Shield

正如Shield安装文档中所述,安装license和shield插件是先决条件,我们可以使用之前的构建派生镜像的策略来实现:

1
2
3
4
FROM elasticsearch:2

RUN /usr/share/elasticsearch/bin/plugin install --batch license
RUN /usr/share/elasticsearch/bin/plugin install --batch shield

构建镜像

1
$ docker build -t elasticsearch-shield .

此时,如果我们将配置目录卷挂载到容器中,Shield 将获取我们的设置。 作为示例配置,请考虑以下目录结构:

1
2
3
4
5
6
7
8
9
10
11
$ tree config
config
├── elasticsearch.yml
├── logging.yml
├── scripts
└── shield
├── roles.yml
├── users
└── users_roles

2 directories, 4 files

logging.yml包含默认日志记录配置。 在elasticsearch.yml中,绑定到通配符 0.0.0.0 确保我们可以访问到容器:

1
2
$ cat elasticsearch.yml
network.host: 0.0.0.0

对于 Shield 配置,我们定义了一个单独的角色admin,以及一个名为“example”且密码为“password”的用户,并将其添加到 admin 角色(您显然需要比这更安全的配置!) :

1
2
3
4
5
6
7
8
9
10
$ cat shield/roles.yml
admin:
cluster: all
indices:
'*':
privileges: all
$ cat shield/users
example:$2a$10$ppZqjFEXgVE3yT/yQPsp4etGMdF4.RFCS9OOGwZGAp0l3lPh4/ALC
$ cat shield/users_roles
admin:example

注意:在此示例中,我们使用的是使用esusers Shield实用程序生成的密码哈希。

然后我们启动容器,为我们的配置指定挂载卷并公开REST端口:

1
$ docker run -d -p 9200:9200 -v "$PWD/config":/usr/share/elasticsearch/config elasticsearch-shield

Elasticsearch 应拒绝未经身份验证的请求:

1
2
3
4
5
6
7
8
9
$ curl -I -XGET -k https://localhost:9200/_cluster/health
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="shield"
Content-Type: application/json; charset=UTF-8
Content-Length: 389
$ curl -I -XGET -k -u example:password https://localhost:9200/_cluster/health
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 389

Adding SSL/TLS

与挂载Shield配置文件一样,可以类似地管理SSL和TLS证书。可以遵循Shield SSL/TLS 指南中概述的大部分步骤请记住CONFIG_DIR目录是我们将在运行时安装到容器中的路径。 CA和证书管理的全部内容不在本教程的讨论范围内,因此我们在此假设您使用的是正确配置的Javakeystore文件,此处称为 node01.jks

公开keystore文件只是将其包含在安装到容器中的配置目录中的问题。

1
2
3
4
5
6
7
8
9
10
11
12
$ tree config
config
├── elasticsearch.yml
├── logging.yml
├── node01.jks
├── scripts
└── shield
├── roles.yml
├── users
└── users_roles
$ file config/node01.jks
config/node01.jks: Java KeyStore

按照Shield用户指南,我们启用传输加密:

1
2
3
4
5
6
$ cat config/elasticsearch.yml
network.host: 0.0.0.0
shield.ssl.keystore.path: /usr/share/elasticsearch/config/node01.jks
shield.ssl.keystore.password: password
shield.transport.ssl: true
shield.http.ssl: true

注意:在生产中,您可能希望更严格地控制您的keystore - 在本例中,我们只使用通用密码锁定keystore。

有了keystore文件并启用了SSL,我们可以启动节点并通过HTTPS发出请求(在这种情况下,将 -k 传递给 curl 以绕过自签名证书):

1
2
3
4
5
6
$ docker run -d -p 9200:9200 -v "$PWD/config":/usr/share/elasticsearch/config elasticsearch-shield
87e51d000cc11d63fbedb8a61d58ab1723f4a598b13614272a3b9d7f36a7b223
$ curl -I -XGET -k -u example:password https://localhost:9200/_cluster/health
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 0

当需要在集群中分发keystore文件时,它们可能会由配置管理模块或类似方法进行管理。

注意:在生成将在Docker内运行的节点的证书时,请密切注意将适当的选项传递到-ext选项。DNS名称和IP地址应正确反映节点将用于相互通信的主机名或IP地址。

总结

尽管我们在这篇博文中给出了几个具体示例,但每个部署都是不同的,您应该根据提高环境可靠性、可重复性和安全性的因素来定制您的设置。 一般来说,遵循这些准则应该有助于一个好的插件管理方案:

  • 在Docker镜像中定义最通用的步骤。通过尽早管理插件然后从这些镜像运行容器,您可以避免一遍又一遍地重新运行相同的安装命令。
  • 在挂载卷中维护持久数据。将您的索引数据和插件配置与容器镜像分开存储可确保您的数据受到控制并且容器保持短暂。
  • 测试!在部署任何生产基础设施之前,确保Elasticsearch在Docker中的行为符合预期,尤其是在网络通信(包括单播和IP地址绑定行为)、JVM资源分配和插件功能方面。

新版本示例

1
2
3
4
5
FROM elasticsearch:7.13.4

# RUN ./bin/elasticsearch-plugin install --batch https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.13.4/elasticsearch-analysis-ik-7.13.4.zip
ADD elasticsearch-analysis-ik-7.13.4.zip /usr/share/elasticsearch
RUN ./bin/elasticsearch-plugin install --batch file:///usr/share/elasticsearch/elasticsearch-analysis-ik-7.13.4.zip

欢迎关注我的其它发布渠道