在之前的文章中 “如何在一个机器上同时模拟多个 node”,我们介绍了如何在同一个机器中运行同一个 Elasticsearch 的安装,并创建一个多 node 的 Elasticsearch 集群。我们也在 “Elastic:用 Docker 部署 Elastic 栈” 文章中介绍了如何使用 docker 技术来创建多个 node 的 Elasticsearch 集群。在实际的应用中,我们可能需要在不同的机器中部署 Elasticsearch,并让它们一起连起来组成集群。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"]
启动集群
我们按照如下的顺来启动集群:
- 在 MacOS 上的 Elasticsearch
- 在 Ubuntu OS 上的 Elasticsearch
- 在 MacOS 上的 Kibana
我们可以在 MacOS master node 里看到如下的信息:
我们打开 Kibana,然后,查看我们的集群:
GET _cat/nodes?v
上面显示我们有两个 node 的集群。其中 master 是 node2。Hooray! 我们终于有了第一个分布于不同机器的集群。
我们接下来来查看我们集群的健康状况:
GET _cluster/health
上面显示我们有两个 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
我们把生产的证书保存于 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 机器上的文件显示为:
我们同样启动 Elasticsearch。
在我们的 MacOS 机器上,我们可以看到:
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 集群的健康状况:
好了。经过这样的设置后,我们集群里的 node 之前的通信就变得更加安全了。
在上面的实验中,我们配置了两个节点的 Elasticsearch 集群。在实际的使用中,我们通常会部署多于两个节点的集群以满足大数据的需求。我们设置需要为这些节点指定特定的角色。为了配置一个高可用的 Elasticsearch 集群,你需要:
- 至少三个 master 节点
- 每个角色至少两个节点
- 每个 shard 至少两个拷贝
- 超过一个节点可以接收客户端发送的请求
更多阅读,请参考:Elasticsearch Cluster Tutorial - Grafana Tutorials