在之前的文章中 “如何在一个机器上同时模拟多个 node”,我们介绍了如何在同一个机器中运行同一个 Elasticsearch 的安装,并创建一个多 node 的 Elasticsearch 集群。我们也在 “Elastic:用 Docker 部署 Elastic 栈” 文章中介绍了如何使用 docker 技术来创建多个 node 的 Elasticsearch 集群。在实际的应用中,我们可能需要在不同的机器中部署 Elasticsearch,并让它们一起连起来组成集群。Elasticsearch 其中一个重要的特点就是它的可拓展性。在今天的文章中,我们来讲述一下:

  • 部署多个节点的集群
  • 为集群之前提供安全的通信

前提条件

在今天的实验中,我使用了两个不同的机器来做我们的练习:

es 几个 节点 es集群节点_elasticsearch

如上图所示,我有两台机器,其中的一个是 MacOS,其IP地址是 192.168.0.100。另外一台机器安装的是 Ubuntu OS 20.04 版本。它的IP地址是 192.168.0.102。

安装

如果你还不知道如何安装 Elasticsearch 和 Kibana 的话,请参阅我之前的文章 “Elastic:开发者上手指南”。我们分别在上面的两个机器上安装 Elasticsearch 及 Kibana。在运行我们的 Elasticsearch 之前,我们先要做配置。特别是 Ubuntu 的这个 Node。如果没有配置就直接运行,那么就会造成一个错误的信息:

Error while clustering nodes from different host/machines

也就是说之前它自己运行起来了,并创建了自己的 cluster。然后我们让它去加入另外一个 node 去组成一个集群的话,就会出现上面的错误。

另外一个我在运行 Ubuntu OS 上的 Elasticsearch 时,我发现有这样的一个错误信息:

max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

上面的错误信息应该很明显,我们需要使用如下的命令来进行修正:

sudo sysctl -w vm.max_map_count=262144

为了能够正确地运行,我们针对这个两个机器分别做配置。

配置 host 名称

我们分别到 MacOS 及 Ubuntu 电脑的 /etc/hosts 文件里加入如下的两句:

192.168.0.100	mac
192.168.0.102	ubuntu

我们必须保证我们的这两个电脑在同一个局域网中。一旦配置成功,我们可以在 MacOS 的电脑中,输入如下的命令:

$ ping ubuntu
PING ubuntu (192.168.0.102): 56 data bytes
64 bytes from 192.168.0.102: icmp_seq=0 ttl=64 time=0.593 ms
64 bytes from 192.168.0.102: icmp_seq=1 ttl=64 time=0.930 ms
64 bytes from 192.168.0.102: icmp_seq=2 ttl=64 time=0.832 ms

很显然,我们在 MacOS 的电脑中可以看到 Ubuntu 电脑。同样的我们也可以在 Ubuntu 电脑中 ping 到 MacOS 的电脑。

Elasticsearch 配置

根据文章中的介绍,在我们平时的开发中,我们很多时候是使用开发模式,也就是我们把 Elasticsearch 绑定于自己机器的 localhost。显然在 production 模式下这个是不适用的。要加入集群,Elasticsearch 节点必须可以通过 transport 通信到达。 要通过non-loopback 地址加入群集,节点必须将传输绑定到 non-loopback 地址,并且不能使用 single-node discovery。 因此,如果Elasticsearch 节点无法通过 non-loopback 地址与另一台机器形成集群,则认为该节点处于开发模式,如果它可以通过 non loopback 地址加入集群,则该节点处于生产模式。

请注意,可以通过 http.host 和 transport.host 独立配置 HTTP 和传输。 这对于将单个节点配置为可通过 HTTP 进行访问以进行测试(而不触发生产模式)很有用。

Elasticsearch 配置 - MacOS

我们使用自己喜欢的编辑器打开在 Elasticsearch 安装目录下的 config/elasticsearch.yml 文件

cluster.name: elasticsearch
node.name: node2
network.host: _site_
discovery.seed_hosts: ["mac"]
cluster.initial_master_nodes: ["node2"]

在这里,我们取一个叫做 elasticsearch 的集群。该 node 的名称为 node2。我们把 network.host 设置为 _site_ 则表明 elasticsearch 将绑定于电脑所在的本地地址上。针对我们的情况就是 192.168.0.100。在上面我们也配置了d iscover.seed_hosts 为 "mac"。请参照上一节 “配置 host 名称” 中的介绍。它会解析出来 192.168.0.100。我们设置 cluster.initial_master_nodes 为和 node.name 一样的配置。请参阅 Elastic 的官方文档

Elasticsearch 配置 - Ubuntu OS

按照同样的方法,我们对 Ubuntu OS 中 Elasticsearch 的 config/elasticsearch.yml 文件进行如下的配置:

cluster.name: elasticsearch
node.name: node1
network.host: _site_
discovery.seed_hosts: ["mac"]
cluster.initial_master_nodes: ["node1"]

特别指出的是,我们在这里设置 discovery.seed_hosts 为 “mac”。

Kibana 配置

由于我们使用了私用地址,我们需要对 Kibana 中的一些配置做一些修改,否认它访问不到我们的 Elasticsearch。我们打开 config/kibana.yml 文件:

server.host: "192.168.0.100"
elasticsearch.hosts: ["http://192.168.0.100:9200"]

启动集群

我们按照如下的顺来启动集群:

  1. 在 MacOS 上的 Elasticsearch
  2. 在 Ubuntu OS 上的 Elasticsearch
  3. 在 MacOS 上的 Kibana

我们可以在 MacOS master node 里看到如下的信息:

es 几个 节点 es集群节点_elasticsearch_02

我们打开 Kibana,然后,查看我们的集群:

GET _cat/nodes?v

es 几个 节点 es集群节点_es 几个 节点_03

上面显示我们有两个 node 的集群。其中 master 是 node2。Hooray! 我们终于有了第一个分布于不同机器的集群。

我们接下来来查看我们集群的健康状况:

GET _cluster/health

es 几个 节点 es集群节点_Ubuntu_04

上面显示我们有两个 data node。器状态是 green的。

我们可以通过如下的命令来查看 master node:

curl -XGET 'http://mac:9200/_cluster/state/master_node?pretty'

我们可以在命令行中使用如下的命令来查看所有的节点:

curl -XGET 'http://mac:9200/_cluster/state/nodes?pretty'

为 node 之间的通信加密

我们知道 node 之间的通信是通过 Transport 模块来进行的。它们之间的通信可以通过加密而得到更加安全的保护。为此,Elastic 为这个 transport 配置了安全的设置。

Elasticsearch 配置 - MacOS 

我们在 Elasticsearch 的安装目录中打入如下的命令来生产根证书:

./bin/elasticsearch-certutil cert

es 几个 节点 es集群节点_es 几个 节点_05

我们把生产的证书保存于 config 子目录中:

$ pwd
/Users/liuxg/elastic/elasticsearch-7.6.2
liuxg:elasticsearch-7.6.2 liuxg$ ls config/
elastic-certificates.p12 jvm.options              roles.yml
elasticsearch.keystore   log4j2.properties        users
elasticsearch.yml        role_mapping.yml         users_roles

从上面可以看出来,我们已经在 config 子目录下生成了一个可以使用的叫做 elastic-certificates.p12 的证书。接下来我们需要运用这个证书来配置我们的 Elasticsearch。我们可以参阅官方文档。打开 config/elasticsearch.yml 文件,并把如下的配置加入到文件的后面:

xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12

我们重新启动 Elasticsearch。由于我们已经启动了安全的设置,我们必须为 Elasticsearch 设置密码。我们可以参考我之前的文章 “Elasticsearch:设置Elastic账户安全”。我们在另外一个 terminal 中输入如下的命令:

./bin/elasticsearch-setup-passwords interactive

你可以选择你自己喜欢的密码。针对我的情况,为了方便,我都设置为 123456。

Elasticsearch 配置 - Ubuntu OS

 我们必须把在 MacOS 上生产的证书拷入到 Ubuntu OS 中的 Elasticsearch 中。证书 elastic-certificates.p12 将被放入同样的位置 config 子目录中。我们可以按照如下的命令来进行拷贝:

scp ./config/elastic-certificates.p12 liuxg@ubuntu:/home/liuxg/elastic/elasticsearch-7.6.2/config

请注意上面的在 Ubuntu 机器中的路径和你的安装路径应该不同。你需要做相应的修改。这样在 Ubuntu 机器上的文件显示为:

es 几个 节点 es集群节点_es 几个 节点_06

我们同样启动 Elasticsearch。

在我们的 MacOS 机器上,我们可以看到:

es 几个 节点 es集群节点_es 几个 节点_07

node1 已经成功地加入到集群里。

这时候,如果我们在 Ubuntu OS 的机器里尝试使用如下的命令来设置密码的话:

./bin/elasticsearch-setup-passwords interactive

它将会告诉我们如下的错误信息:

$ ./bin/elasticsearch-setup-passwords interactive
future versions of Elasticsearch will require Java 11; your Java version from [/usr/lib/jvm/java-8-openjdk-amd64/jre] does not meet this requirement

Failed to authenticate user 'elastic' against http://192.168.0.102:9200/_security/_authenticate?pretty
Possible causes include:
 * The password for the 'elastic' user has already been changed on this cluster
 * Your elasticsearch node is running against a different keystore
   This tool used the keystore at /home/liuxg/elastic/elasticsearch-7.6.2/config/elasticsearch.keystore

ERROR: Failed to verify bootstrap password

上面标明 Ubuntu OS 上的 Elasticsearh 的安全配置已经跟随 MacOS 上的 Elasticsearch 设置的密码。我们尝试使用如下的命令来访问这个 Elasticsearch:

$ curl -u "elastic:123456" http://ubuntu:9200
{
  "name" : "node1",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "fylS-jtjRRSeJlTCW1UN8Q",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

显然我们的用户名及密码是成功的。

配置 Kibana

由于我们已经加入了安全,我们需要对 Kibana 的配置 config/kibana.yml 重新进行修改:

elasticsearch.username: "kibana"
elasticsearch.password: "123456"

打开 Kibana,我们重新查看一下我们的 Elasticsearch 集群的健康状况:

es 几个 节点 es集群节点_Elastic_08

好了。经过这样的设置后,我们集群里的 node 之前的通信就变得更加安全了。

在上面的实验中,我们配置了两个节点的 Elasticsearch 集群。在实际的使用中,我们通常会部署多于两个节点的集群以满足大数据的需求。我们设置需要为这些节点指定特定的角色。为了配置一个高可用的 Elasticsearch 集群,你需要:

  • 至少三个 master 节点
  • 每个角色至少两个节点
  • 每个 shard 至少两个拷贝
  • 超过一个节点可以接收客户端发送的请求

更多阅读,请参考:Elasticsearch Cluster Tutorial - Grafana Tutorials