Follow through this tutorial to learn how to setup multinode Elasticsearch 8.x cluster. As of this writing, Elastic Stack 8.3 is the current release. This means that Elasticsearch 8.3, one of the major components of the Elastics Stack is also the current release version as of this writing.
Table of Contents
Setup Multinode Elasticsearch 8.x Cluster
In our previous tutorial, we learnt how to setup a three node Elasticsearch 7.x cluster.
We will as well be configuring a three node Elasticsearch 8.x cluster in this tutorial.
My Environment:
- Node 1: es-node01.kifarunix-demo.com
- Node 2: es-node02.kifarunix-demo.com
- Node 3: es-node03.kifarunix-demo.com
Ensure that the hostnames are resolvable on each node. If you do not have a DNS server, then you can use your hosts file.
192.168.122.12 es-node01.kifarunix-demo.com es-node01
192.168.122.73 es-node02.kifarunix-demo.com es-node02
192.168.122.50 es-node03.kifarunix-demo.com es-node03
With the release of the Elastic 8.x, there are some few changes in Elasticsearch setup procedure.
Install Elasticsearch 8.x on All Cluster Nodes
You need to install the same version of Elasticsearch 8.x on all the cluster nodes.
In this tutorial, we will be using Ubuntu 22.04 system.
Thus, to install Elasticsearch 8.x on Ubuntu, you need to install the Elastic APT repositories as follows;
apt install apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | \
gpg --dearmor -o /etc/apt/trusted.gpg.d/elastic.gpg
echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" > \
/etc/apt/sources.list.d/elastic-8.x.list
Run system update;
apt update
Once the repos are in place, install Elasticsearch 8.x on all the cluster nodes using the command below;
apt install elasticsearch
During the installation, the Security features will be enabled by default;
- Authentication and authorization are enabled.
- TLS for the transport and HTTP layers is enabled and configured. Self-signed SSL certs are generated and used.
- Elastic super user account (elastic) and its password is created.
- Elasticsearch is configured as a single node cluster.
Sample installation output;
...
Setting up elasticsearch (8.11.1) ...
--------------------------- Security autoconfiguration information ------------------------------
Authentication and authorization are enabled.
TLS for the transport and HTTP layers is enabled and configured.
The generated password for the elastic built-in superuser is : 2BEkVDLjbN77ODLsTGmA
If this node should join an existing cluster, you can reconfigure this with
'/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token '
after creating an enrollment token on your existing cluster.
You can complete the following actions at any time:
Reset the password of the elastic built-in superuser with
'/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'.
Generate an enrollment token for Kibana instances with
'/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana'.
Generate an enrollment token for Elasticsearch nodes with
'/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node'.
-------------------------------------------------------------------------------------------------
### NOT starting on installation, please execute the following statements to configure elasticsearch service to start automatically using systemd
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch.service
### You can start elasticsearch service by executing
sudo systemctl start elasticsearch.service
DO NOT start Elasticsearch service yet!
Configure Elasticsearch 8.x
Open the Elasticsearch configuration file for editing;
vim /etc/elasticsearch/elasticsearch.yml
Set the Name of the Cluster on All Cluster Nodes
Optionally set the name of the cluster on each Node;
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: kifarunix-demo
...
Set the Node Name on Each of the cluster Nodes;
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: es-node01
...
You can add other custom attributes if you want.
Define the Roles of Elasticsearch Node
As stated above, you can assign each node a respective role as master, data node, ingest node, coordinating node.. In this setup, we will configure all the three nodes to act as both master
and data
node to make the cluster resilient to the loss of any single node.
...
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: es-node01
node.roles: [ master, data ]
...
Enable Memory Lock
To ensure good performance of Elasticsearch, you need to disable memory swapping is by enabling memory lock. Hence, uncomment the line bootstrap.memory_lock: true. This is one of the many ways of disabling swappiness.
...
# ----------------------------------- Memory -----------------------------------
#
# Lock the memory on startup:
#
bootstrap.memory_lock: true
...
Bind Elasticsearch to Non-Loopback Address
Elasticsearch binds to loopback addresses by default. For a node to form a cluster, you need to bind it to non-loopback address. This can be done by setting the IP address of the node as the value of network.host.
Node 01
network.host: 192.168.56.125
Update the rest of the nodes, accordingly.
Elasticsearch by default uses TCP port 9200 to expose REST APIs. TCP port 9300-9400 is used for node communication;
You can comment out the port definition;
http.port: 9200
The http.host
is set to 0.0.0.0 by default. Since we have bound ES to an interface IP, which MUST be static in this case, comment out this line;
# Allow HTTP API connections from anywhere
# Connections are encrypted and require user authentication
#http.host: 0.0.0.0
Discovery and Cluster Formation settings
There are two important discovery and cluster formation settings that should be configured before going to production so that nodes in the cluster can discover each other and elect a master node;
- discovery.seed_hosts
discovery.seed_hosts setting provides a list of master-eligible nodes in the cluster. Each value has the format host:port
or host
, where port
defaults to the setting transport.profiles.default.port
. This setting was previously known as discovery.zen.ping.unicast.hosts.
Configure this setting on all Nodes.
HOWEVER, due to auto-configuration of Elasticsearch during the installation, we will need to be able to start Elasticsearch service on each node before we can join them to the cluster.
As a result, we will skip the configuration of this setting for now.
- cluster.initial_master_nodes
cluster.initial_master_nodes setting defines the initial set of master-eligible nodes. This is important when starting an Elasticsearch cluster for the very first time. After the cluster has formed, remove this setting from each node’s configuration. The value of this setting MUST match the value of node.name
.
Note that during the installation, Elasticsearch is auto-configured as a single node cluster. For example on Node01.
...
# Create a new cluster with the current node only
# Additional nodes can still join the cluster later
cluster.initial_master_nodes: ["es-node01.kifarunix-demo.com"]
...
Update this line such that the name of the node matches the value of node.name.
For example, in setup, this line should be;
cluster.initial_master_nodes: ["es-node01"]
See Discovery and Cluster Formation settings below.
Configure Elasticsearch Cluster HTTPS Connection
By default, Elasticsearch 8.x is auto-configured with self-signed SSL certitificates for both the Transport (connection between the nodes) and HTTP (HTTP API client connections, such as Kibana, Logstash, and Agents).
Later when you add other nodes to the cluster, all the security auto-configurations will be removed on those nodes being added to a cluster and certificates from first node copied over to the node being enrolled.
For communication between the nodes, you should see such configurations on elasticsearch.yml
.
# Enable encryption and mutual authentication between cluster nodes
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
For HTTP API client connections, such as Kibana, Logstash, and Agents;
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
Save changes made and exit the file.
Kindly note that the CA certificate is generated and stored as /etc/elasticsearch/certs/http_ca.crt
.
The CA key for the CA certificate, is stored in the /etc/elasticsearch/certs/http.p12 file
. This file is password protected and the password used to protect it is found in the Elasticsearch Keystore.
Thus, to get the CA key, you first need to retrieve the password that was used to protect it by executing the command below;
/usr/share/elasticsearch/bin/elasticsearch-keystore show xpack.security.http.ssl.keystore.secure_password
The command will print the Keystore password to standard output.
Once you have the Keystore password, extract the CA key;
openssl pkcs12 -in /etc/elasticsearch/certs/http.p12 -nocerts -nodes
You will be prompted to enter the password. Use the one retrieved above.
The command will print two keys each with a friendlyName, e.g, friendlyName: http_ca
and friendlyName: http
.
Bag Attributes
friendlyName: http_ca
localKeyID: 54 69 6D 65 20 31 37 30 30 37 35 38 35 31 39 32 33 39
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
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
0FZM/3K5DrR8Ed3vWKqAtEOgi5AK
-----END PRIVATE KEY-----
Bag Attributes
friendlyName: http
localKeyID: 54 69 6D 65 20 31 37 30 30 37 35 38 35 31 39 32 36 32
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC8kJYcWvgzcjRd
qzMagpo3Op94hNDJ2AX2gKP3V5B1kX4tlbjZxWwGLknfBA/Sz5fTkle8z/P0dVCf
SXuRM9e92RyQoP1gwrPXJ+McFmmgH/NwETN5aOaTThGmNN756xdyZt9qnxI3pdMs
/KUJcBM428YqlY6xFxkFWNQvkNSgC+fujwwmSGUEJ2+WdLO1UUkW2PcanRGrFj5y
VBu7KaQG9PZ6DFDcdclJQGFnxkJC6eEvWgUxA2vJQUxsfw3+NUdZeXoh3vZ+Nsvw
0Qw2DP6lZQN3IULw4kgk/Sf1tPwVVN93QfTtZK899QYwAywKjJQmkCj9oTXQuZMb
SZgf0ZMgLNpWlluRhUXxXf9GQcVbtL6kFWxxa22wGrWEmmDsd//kn4b47rPKpmu4
iSGqS035xLXV+mutjWzDtZFRvzvI4a4/va9Q4XCr3oACUDcgpHdOMpEreuaVt6o7
JdF+W4Sn80FHpsLenfh36meQ4G5LjASF1pdzpMgPJRmz2PtO30afVAQivT3jOPuJ
v/szAdIwekTLCuFEPJ3nbCQ7osxIcKUB3z3Zbin7Rr8njeev6WlvWiR3uKso29xG
80sOLzmYhLGiv6xVR2ESR/BJ+1TJXUiLn9GNBt1x8xZ3bzZGzFxIHub6nmx+7K9S
FxJ1i8Y2sjN5bE1+2LBjKRLqhQuOjwIDAQABAoICAEzTJ6WD1q23MOic0KRTY5tu
0fwbOKmTztIglS03ys5rqZnO71IiYiGeiFBJalz8YSI89Gwj2YPWrDNJkAOXuKVL
qJywSqs6iGT3hksyQnSPr/IPwAYOHCsV2pD554KxKotcqFfbWWO8tu4UPPU8aUh4
GiPNbSZvf60zBLggbNCMKUGDnHKYejeYDZmiEHmmFX4uhXadWc53sJeJ9wZpL7/5
29Xb4LIBdzHV/hl2qBZ1DV7qcUUH3MlRRl7J4RyZ/mjQ2lakbY78qliCA1SeNL2U
CzZlIc3ck4ImdjpgM3hJbQY8pBp4NAGtK4kyMaZWoiGYCGtVXASfJvUuJcGI9ESq
lxKlC+ndLfPmSFT9Yyi+34qIhCBlqpcfwT3aw8tVlVvHeI2rpPjs01s+8YnGJACY
BapcjNk0GWQZj+HrkLcOs3MUbqdpQbFIggI6US1zAzq3MrfvY03t8Qdzxsiln2nW
34nKMACAwKRcXeSSnxHE8J50VoWVZ1jaV81RqnvknGxhR4DoSmL9RWB3S9fTD1ff
qaiGzriqrl88LXqnsqiUDkgdB4brchDs6c3OF06/WS3oNRGzh/oAPFN69lTMScMg
xeFwv+auJW+c4V1Wz4ynwBZiqCy5yep2GXzJqNbl8Ad/b3hfo/K4E7mIifS/4p0H
rjLpkFkX+9DQS9GIg61xAoIBAQDFlESZdeVRkWXzMOGoYrf4a3PuLiPgq+odbYmI
Xj+kR+0hNYLWviDOxQySyxLScjT7LRuqTd9We8lItHPa/jfXEsrGkDUIOQ+WBzyd
W0SbnW0u5c6oJpj6GaQz6rcGpEAlqYgE00Ng5scXRoN/ntLiHvta0vA9P7v0iA62
nXbfGeCAaHpkoLRk/XcDBmpJueUSSJ5cZDUgSfNkLoxOM7/ZJa5oLWjcylJP/35d
wo3yM+A+VaZUW1pSLljzWnDfrEvK3ju7Kz0V9sVBoPAewtciowdp3Mi2MdlLiwLL
h0YhexDJ20QmEf4QAOOJQKaxqnoI2b3hDhsK9BaXRo+4y3WXAoIBAQD0UfnTamU7
tnOoIGweWuatJRseD8jP/8TpiWQ31k1vkaQ1BHOvaN9y66KStJUKOBTJUhf5ArQe
FZxaA3sxIxHlQitN8yuI5oNOKf42+4BCfE5ZDYn1/euksd/LNojHHOijpxoEnTaK
sHr6+RT3dvbFHzKEYxzxHbUwKPN65qAfd0LBblNLyGuqQP9fyjueV0HgQdFEtxHD
OEsteCfCYY4nxhTQ/YOg3hHX6titPmNbVXRnPmjXoCVwM64iNT7HtWuJFQI54pPi
B0DMH2kfm6njKWI+gMCnKfp3s+0bXDySxHpOn1EKj+wecFiOr/X4nN+4hBhCQ43f
APfEALR1Wv3JAoIBAQCkcNd7Zc07Sykv86IMdEUro7r0JEDGEC8k2PLbpZ2QTDDH
L/M6aTmC/iuNzShYMKd52bwpzPAx2YrYUSAPxv+QqFpOUt1gf6VCN7myObDrV2X0
311VQ/KUTV0FvLch9vhQoD3NzktIziorbAur3vMjMaf/mopKX84+IjMkt/+khbP9
C3e6YqphVzeDNAaoX+iQhBIRUXGJ8yJ4YelyeM2WnC8BE7Iv+M/zNvDkdjWPvK9J
Eh4CHZoZxetQdxh0gMEAEmBiUgVgT2czTRAseft2H3vfFtuSEAELR6JG5MpwuS1q
42xfxx/OD/9QT5etTPaOgTLwqb3GKwrWUurxYZz3AoIBAQCVzCU2wMcs42LqNGbV
/bntcxC7T8Y58YHUBk8SBS0ZONzLPN2JMO2/0kWtWVcAGv5zqQfVvxicUXe5oOTJ
bc0tGXLfqjaJC3x6UjjxkSZEnV6ULz7lOjhelEi4mckm+8yPeobzSUkFo8rjUhDO
4XvPxJ7+mJ5IH4TV8GXIdtq6MC8X1gLwNgP9MTjijGYdYTacvv4F+ZDEdyFw0Xjf
L10veb2NncI0wbODBRSws83LVAu4uYUin6gUsTsU8jx5yfwS4nSo9Qjizrul66RS
ouh4xQjddaepVo2hEwpPejARdLHgvsG7jh6hUxSY974CHnz07tjI2A6GKlu/Kwd5
5L4xAoIBABIIJOsPkaMS2Nc3iRz9GweT00QFKoZekUiwrafJa4U8bc9B5gMXja77
ozTZShXDFKxVrvTLsraCUCK4RsFMTQE+pG5Q/SEt8Lnc6D5VvY1oQu4zdbMsNfaO
vI3vVB0+IQazDIRLhV6JNCaUZAr8jxnShyz2y4N5ZJYToOp20QT5BB5z2uRdtb9Q
LrXnUNXS07bOVrBhYoi7pNbrvfiGrbrZ5aInn+NVSKy7Mkav7VaiwfhxMBwhD0kj
esbwv62ZEoAziXeW95iQxvprroZgEAgUsyZJ/cHilJ4c5YIkv2en21pGcGEtoWpv
Lc00BYUVRYhNU3H1h6CRQkbnHsNB5X4=
-----END PRIVATE KEY-----
The CA key will the one under the friendlyName: http_ca
.
You can copy the key, anything between -----BEGIN PRIVATE KEY-----
and -----END PRIVATE KEY-----
and store them in a file of your choice, e.g /etc/elasticsearch/certs/http_ca_key.crt
.
Configure Other Important Elasticsearch Systems Settings
Disable Memory Swapping on All Cluster Nodes
Enabling memory lock as done above is on the ways of disabling swappiness. You therefore need to ensure that memory locking is enabled on the Elasticsearch service level. This can be done as follows;
[[ -d /etc/systemd/system/elasticsearch.service.d ]] || mkdir /etc/systemd/system/elasticsearch.service.d
echo -e '[Service]\nLimitMEMLOCK=infinity' > \
/etc/systemd/system/elasticsearch.service.d/override.conf
Whenever a systemd service is modified, you need to reload the systemd configurations.
systemctl daemon-reload
One of the recommended ways to disable swapping is to completely disable swap if Elasticsearch is the only service running on the server.
swapoff -a
Edit the /etc/fstab
file and comment out any lines that contain the word swap
;
sed -i.bak '/swap/s/^/#/' /etc/fstab
Otherwise, disable swappiness in the kernel configuration;
echo 'vm.swappiness=1' >> /etc/sysctl.conf
sysctl -p
Set JVM Heap Size on All Cluster Nodes
Elasticsearch usually sets the heap size automatically based on the role of the node. However, if you want to go with manual configuration, as a rule of thump, set Xmx
to no more than 50% of your physical RAM. Any custom JVM settings should be placed under /etc/elasticsearch/jvm.options.d
.
echo -e "-Xms1g\n-Xmx1g" > /etc/elasticsearch/jvm.options.d/jvm.options
Set maximum Open File Descriptor on All Cluster Nodes
Set the maximum number of open files for the elasticsearch
user to 65,536. This is already set by default in the, /usr/lib/systemd/system/elasticsearch.service
.
less /usr/lib/systemd/system/elasticsearch.service
...
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65535
...
You also should set the maximum number of processes.
...
# Specifies the maximum number of processes
LimitNPROC=4096
Update Virtual Memory Settings on All Cluster Nodes
Elasticsearch uses a mmapfs
directory by default to store its indices. To ensure that you do not run out of virtual memory, edit the /etc/sysctl.conf and update the value of vm.max_map_count as shown below.
vm.max_map_count=262144
You can simply run the command below to configure virtual memory settings.
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
To apply the changes;
sysctl -p
To that far, below is the configuration file on each node;
grep -Ev '^#|^$' /etc/elasticsearch/elasticsearch.yml
Node 01;
cluster.name: kifarunix-demo
node.name: es-node01
node.roles: [ master, data ]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 192.168.122.12
http.port: 9200
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
cluster.initial_master_nodes: ["es-node01"]
Node 02
cluster.name: kifarunix-demo
node.name: es-node02
node.roles: [ master, data ]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 192.168.122.73
http.port: 9200
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
cluster.initial_master_nodes: ["es-node02"]
Node 03
cluster.name: kifarunix-demo
node.name: es-node03
node.roles: [ master, data ]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 192.168.122.50
http.port: 9200
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
cluster.initial_master_nodes: ["en-node03"]
Start and Enable Elasticsearch Service on Node 01
For now, start and enable Elasticsearch service to run on system boot on Node 01 ONLY.
systemctl enable --now elasticsearch
Confirm that Elasticsearch is running;
systemctl status elasticsearch
The password was in the installation output;
● elasticsearch.service - Elasticsearch
Loaded: loaded (/lib/systemd/system/elasticsearch.service; enabled; preset: enabled)
Drop-In: /etc/systemd/system/elasticsearch.service.d
└─override.conf
Active: active (running) since Thu 2023-11-23 12:25:26 EST; 4s ago
Docs: https://www.elastic.co
Main PID: 580 (java)
Tasks: 80 (limit: 4645)
Memory: 1.7G
CPU: 27.822s
CGroup: /system.slice/elasticsearch.service
├─580 /usr/share/elasticsearch/jdk/bin/java -Xms4m -Xmx64m -XX:+UseSerialGC -Dcli.name=server -Dcli.script=/usr/share/elasticsearch/bin/elasticsearch -Dcl>
├─638 /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -Djava.security.manager=allow -XX:+>
└─658 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
Nov 23 12:25:12 es-node01.kifarunix-demo.com systemd[1]: Starting elasticsearch.service - Elasticsearch...
Nov 23 12:25:14 es-node01.kifarunix-demo.com systemd-entrypoint[580]: Nov 23, 2023 12:25:14 PM sun.util.locale.provider.LocaleProviderAdapter
Nov 23 12:25:14 es-node01.kifarunix-demo.com systemd-entrypoint[580]: WARNING: COMPAT locale provider will be removed in a future release
Nov 23 12:25:26 es-node01.kifarunix-demo.com systemd[1]: Started elasticsearch.service - Elasticsearch.
Confirm the ports are opened.
ss -altnp | grep -iE '92|93'
LISTEN 0 4096 [::ffff:192.168.122.12]:9200 *:* users:(("java",pid=638,fd=438))
LISTEN 0 4096 [::ffff:192.168.122.12]:9300 *:* users:(("java",pid=638,fd=433))
curl -k -u elastic https://es-node01:9200
{
"name" : "es-node01",
"cluster_name" : "kifarunix-demo",
"cluster_uuid" : "KuX8vWFOTry9GDJCtXvo_g",
"version" : {
"number" : "8.11.1",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "6f9ff581fbcde658e6f69d6ce03050f060d1fd0c",
"build_date" : "2023-11-11T10:05:59.421038163Z",
"build_snapshot" : false,
"lucene_version" : "9.8.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
Enroll Other Nodes into Elasticsearch Cluster
At this point, Elasticsearch is running on Node 01 ONLY.
Generate Elasticsearch Cluster Enrollment Token
Next, you need to generate Elasticsearch cluster enrollment token. Do this only on a single node where ES is already started.
In this setup, we will generate Elasticsearch cluster enrollment token on ES Node01 ONLY since we have started Elasticsearch service on this node.
/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node
Sample token;
eyJ2ZXIiOiI4LjExLjEiLCJhZHIiOlsiMTkyLjE2OC4xMjIuMTI6OTIwMCJdLCJmZ3IiOiI0MDAxNjNiYmEzNDA3NjM4ZGEyNmNmYWI4OTVmNTFjNDU1NzU2NWNmYzljNGZhMzY4OGNhOTEwNDE1MWQxM2ViIiwia2V5IjoiMnRRNl9Zc0JsYjlwbjlBcGk2Qk06emZqU1ZPMXNRbmFvTDZ5N0FORVdHZyJ9
Once you have the token, enroll other nodes.
Enroll Elasticsearch Node 02;
/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <PASTE TOKEN ABOVE>
For example;
/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token eyJ2ZXIiOiI4LjExLjEiLCJhZHIiOlsiMTkyLjE2OC4xMjIuMTI6OTIwMCJdLCJmZ3IiOiI0MDAxNjNiYmEzNDA3NjM4ZGEyNmNmYWI4OTVmNTFjNDU1NzU2NWNmYzljNGZhMzY4OGNhOTEwNDE1MWQxM2ViIiwia2V5IjoiMnRRNl9Zc0JsYjlwbjlBcGk2Qk06emZqU1ZPMXNRbmFvTDZ5N0FORVdHZyJ9
This node will be reconfigured to join an existing cluster, using the enrollment token that you provided.
This operation will overwrite the existing configuration. Specifically:
- Security auto configuration will be removed from elasticsearch.yml
- The [certs] config directory will be removed
- Security auto configuration related secure settings will be removed from the elasticsearch.keystore
Do you want to continue with the reconfiguration process [y/N]y
Similarly, run the same enrollment command on other nodes.
Start Elasticsearch on Other Nodes
Once the enrollment is done, start the Elasticsearch service on the node.
systemctl enable --now elasticsearch
Discovery and Cluster Formation settings
If you noticed, the enrollment command reconfigures the cluster initial nodes setting, cluster.initial_master_nodes
, on other nodes that are enrolled into the cluster.
Also discovery.seed_hosts:
is configured with the address of the first node.
Now, we need to configure the new nodes, Node02 and Node03 in this setup, as we did with Node01.
The only change you need to do on one of the nodes, for example, we do this on Node 01 is to define the list of the cluster nodes;
vim /etc/elasticsearch/elasticsearch.yml
Basically, you need to define:
- cluster members (
discovery.seed_hosts: ["es-node01", "es-node02", "es-node03"]
) - list of initial set of master-eligible nodes (
cluster.initial_master_nodes: ["es-node01", "es-node02", "es-node03"]
).
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when this node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
discovery.seed_hosts: ["es-node01", "es-node02", "es-node03"]
#
# Bootstrap the cluster using an initial set of master-eligible nodes:
#
cluster.initial_master_nodes: ["es-node01", "es-node02", "es-node03"]
Save and exit the configuration file.
Sample config on Node 01;
cat /etc/elasticsearch/elasticsearch.yml
cluster.name: kifarunix-demo
node.name: es-node01
node.roles: [ master, data ]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 192.168.122.12
http.port: 9200
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
cluster.initial_master_nodes: ["es-node01", "es-node02", "es-node03"]
discovery.seed_hosts: ["es-node01", "es-node02", "es-node03"]
Restart Elasticsearch Service.
systemctl restart elasticsearch
Configure Node 02 just like how Node 01 has been configured. Below is our sample Node 02 configuration;
cat /etc/elasticsearch/elasticsearch.yml
cluster.name: kifarunix-demo
node.name: es-node02
node.roles: [ master, data ]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 192.168.122.73
http.port: 9200
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
discovery.seed_hosts: ["es-node01", "es-node02", "es-node03"]
cluster.initial_master_nodes: ["es-node01", "es-node02", "es-node03"]
Restart Elasticsearch Service.
systemctl restart elasticsearch
Configure Node 03 as well. Below is our sample Node 03 configuration;
cat /etc/elasticsearch/elasticsearch.yml
cluster.name: kifarunix-demo
node.name: es-node03
node.roles: [ master, data ]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 192.168.122.50
http.port: 9200
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
discovery.seed_hosts: ["es-node01", "es-node02", "es-node03"]
cluster.initial_master_nodes: ["es-node01", "es-node02", "es-node03"]
Restart Elasticsearch Service.
systemctl restart elasticsearch
Check the Cluster Nodes
curl -k -XGET "https://es-node01:9200/_cat/nodes?v" -u elastic
Enter host password for user 'elastic':
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.122.12 57 50 3 0.08 0.10 0.08 dm - es-node01
192.168.122.50 33 50 8 0.20 0.13 0.05 dm - es-node03
192.168.122.73 49 50 3 0.02 0.13 0.08 dm * es-node02
And there you go. You now have Elasticsearch 8.x cluster.
Check cluster health status;
curl -k -XGET "https://es-node01:9200/_cat/health?v" -u elastic
Enter host password for user 'elastic':
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1700761464 17:44:24 kifarunix-demo green 3 3 2 1 0 0 0 0 - 100.0%
As you can see, our cluster status is GREEN!!
ENSURE that the cluster transport ports (9300/tcp) are opened on the firewall on each node to allow cluster formation.
Once the cluster is formed as above, remove or comment the following line on ALL the nodes.
cluster.initial_master_nodes: ["es-node01", "es-node02", "es-node03"]
You can remove as follows;
sed -i.bak '/cluster.initial_master_nodes/s/^/#/' /etc/elasticsearch/elasticsearch.yml
Multinode cluster is up and running!
Other Tutorials
Deploy a Single Node Elastic Stack Cluster on Docker Containers
I don’t think this instruction is clear, my nodes are not connecting to each other. I only have one node on the _cat/nodes endpoint and it only works on node01 (others says that elastic password is invalid). The enrollment part is not clear, it doesn’t change my configuration in any way.
Sorry for that. At what point is password failing?
very clear to me.
all works as expected
Thanks for this guide, my cluster are running.
curl -k -XGET “https://10.249.213.5:9200/_cat/nodes?v” -u elastic
Enter host password for user ‘elastic’:
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
10.249.214.5 15 23 0 0.22 0.35 0.39 dm * es-node-2
10.249.213.6 9 50 0 1.12 1.00 0.82 dm – es-node-3
10.249.213.7 11 50 17 1.12 1.00 0.82 dm – es-node-1
Glad it helped you. Enjoy
I spent a few days failing to spin-up a 3-node cluster until I found found this guide. Thank you VERY much for all the effort required to put it together!!!
Thank you for this guide.
Absolutly simple – and brilliant.
Thank you for the article. Very neatly described. Out of all documents for Elasticsearch, this one was the easiest to understand and got a quick output as well.
Once again thanks a lot!
We are glad you found the tutorial useful, Sonu. Enjoy
After several days of frustrating research on how to configure a 3-node cluster in Ubuntu your tutorial was the only article I needed to complete the task. Thank you for sharing.
We are glad you found tutorial helpful, Bolmar! Enjoy
I have my own certs , so I dont have a keystore setup , I cannot create an enrollment token for this , what will be the setup for this now
Hi. Check if this guide can help with that.