Configure Elasticsearch 8 cluster with multiple nodes for high availability and scalability

Advanced 45 min Apr 03, 2026 517 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up a production-ready Elasticsearch 8 cluster with dedicated master, data, and coordinating nodes for high availability, fault tolerance, and horizontal scalability across multiple servers.

Prerequisites

  • Multiple servers with at least 4GB RAM each
  • Root or sudo access on all nodes
  • Network connectivity between cluster nodes
  • Basic knowledge of Elasticsearch concepts

What this solves

A single Elasticsearch node creates a single point of failure and limits your search performance. This tutorial shows you how to configure a multi-node Elasticsearch 8 cluster with dedicated master-eligible nodes for cluster management, data nodes for indexing and storage, and coordinating nodes for client requests. You'll enable security features, monitoring, and automatic failover to ensure high availability and scalability for production workloads.

Prerequisites and cluster planning

Plan your cluster architecture

Design your cluster with dedicated node roles for optimal performance and resource utilization.

Node TypeRoleMinimum CountRAM Requirements
Master-eligibleCluster management, metadata3 (odd number)4GB
Data nodesIndex and search operations2+8GB+
CoordinatingLoad balancing, aggregations2+4GB

Prepare the servers

Ensure all nodes meet the prerequisites and have proper network connectivity.

sudo sysctl vm.max_map_count

Should be at least 262144

sudo sysctl -w vm.max_map_count=262144 echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf

Install Java and Elasticsearch on all nodes

Install the required Java runtime and Elasticsearch packages on each cluster node.

sudo apt update
sudo apt install -y openjdk-11-jdk wget gpg
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update
sudo apt install -y elasticsearch
sudo dnf install -y java-11-openjdk wget
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --import
echo "[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md" | sudo tee /etc/yum.repos.d/elasticsearch.repo
sudo dnf install -y elasticsearch

Generate cluster certificates

Create SSL certificates for secure inter-node communication on your first master node.

sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca --pem --out /tmp/elastic-ca.zip
sudo unzip /tmp/elastic-ca.zip -d /tmp/
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca-cert /tmp/ca/ca.crt --ca-key /tmp/ca/ca.key --pem --out /tmp/elastic-certificates.zip
sudo unzip /tmp/elastic-certificates.zip -d /tmp/
sudo mkdir -p /etc/elasticsearch/certs
sudo cp /tmp/ca/ca.crt /tmp/instance/instance.crt /tmp/instance/instance.key /etc/elasticsearch/certs/
sudo chown -R elasticsearch:elasticsearch /etc/elasticsearch/certs/
sudo chmod -R 660 /etc/elasticsearch/certs/*

Configure master-eligible nodes

Configure the first master node

Set up the initial master node with cluster discovery and security settings.

cluster.name: production-cluster
node.name: master-node-1
node.roles: [master]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 203.0.113.10
http.port: 9200
transport.port: 9300

Discovery settings

discovery.seed_hosts: ["203.0.113.10:9300", "203.0.113.11:9300", "203.0.113.12:9300"] cluster.initial_master_nodes: ["master-node-1", "master-node-2", "master-node-3"]

Security configuration

xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.certificate: certs/instance.crt xpack.security.transport.ssl.key: certs/instance.key xpack.security.transport.ssl.certificate_authorities: certs/ca.crt xpack.security.http.ssl.enabled: true xpack.security.http.ssl.certificate: certs/instance.crt xpack.security.http.ssl.key: certs/instance.key xpack.security.http.ssl.certificate_authorities: certs/ca.crt

Monitoring

xpack.monitoring.collection.enabled: true

Configure additional master nodes

Copy certificates to other master nodes and configure them with unique names and IP addresses.

# Copy certificates to other master nodes
sudo scp -r /etc/elasticsearch/certs/ root@203.0.113.11:/etc/elasticsearch/
sudo scp -r /etc/elasticsearch/certs/ root@203.0.113.12:/etc/elasticsearch/
cluster.name: production-cluster
node.name: master-node-2
node.roles: [master]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 203.0.113.11
http.port: 9200
transport.port: 9300

discovery.seed_hosts: ["203.0.113.10:9300", "203.0.113.11:9300", "203.0.113.12:9300"]
cluster.initial_master_nodes: ["master-node-1", "master-node-2", "master-node-3"]

xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.certificate: certs/instance.crt
xpack.security.transport.ssl.key: certs/instance.key
xpack.security.transport.ssl.certificate_authorities: certs/ca.crt
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.certificate: certs/instance.crt
xpack.security.http.ssl.key: certs/instance.key
xpack.security.http.ssl.certificate_authorities: certs/ca.crt

xpack.monitoring.collection.enabled: true

Start master nodes

Start the Elasticsearch service on all master nodes and enable automatic startup.

sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
sudo systemctl status elasticsearch

Set up built-in user passwords

Generate passwords for Elasticsearch built-in users on the first master node.

sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto

Save the generated passwords securely

Record the elastic user password for cluster management

Configure data nodes and coordinating nodes

Configure data nodes

Set up dedicated data nodes for indexing and search operations with optimized heap settings.

cluster.name: production-cluster
node.name: data-node-1
node.roles: [data, data_content, data_hot]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 203.0.113.20
http.port: 9200
transport.port: 9300

discovery.seed_hosts: ["203.0.113.10:9300", "203.0.113.11:9300", "203.0.113.12:9300"]

xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.certificate: certs/instance.crt
xpack.security.transport.ssl.key: certs/instance.key
xpack.security.transport.ssl.certificate_authorities: certs/ca.crt
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.certificate: certs/instance.crt
xpack.security.http.ssl.key: certs/instance.key
xpack.security.http.ssl.certificate_authorities: certs/ca.crt

Data node optimizations

indices.memory.index_buffer_size: 30% indices.memory.min_index_buffer_size: 96mb thread_pool.write.queue_size: 1000

Configure coordinating nodes

Set up coordinating-only nodes to handle client requests and distribute load across data nodes.

cluster.name: production-cluster
node.name: coord-node-1
node.roles: []
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 203.0.113.30
http.port: 9200
transport.port: 9300

discovery.seed_hosts: ["203.0.113.10:9300", "203.0.113.11:9300", "203.0.113.12:9300"]

xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.certificate: certs/instance.crt
xpack.security.transport.ssl.key: certs/instance.key
xpack.security.transport.ssl.certificate_authorities: certs/ca.crt
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.certificate: certs/instance.crt
xpack.security.http.ssl.key: certs/instance.key
xpack.security.http.ssl.certificate_authorities: certs/ca.crt

Coordinating node optimizations

thread_pool.search.queue_size: 2000 thread_pool.get.queue_size: 1000

Configure JVM heap settings for each node type

Optimize heap allocation based on node roles and available system memory.

# Master nodes - 4GB heap
-Xms4g
-Xmx4g
# Data nodes - 50% of available RAM, max 32GB
-Xms16g
-Xmx16g
# Coordinating nodes - 8GB heap
-Xms8g
-Xmx8g

Start all cluster nodes

Copy certificates to all remaining nodes and start the Elasticsearch service.

# Copy certificates to data and coordinating nodes
for node in 203.0.113.20 203.0.113.21 203.0.113.30 203.0.113.31; do
  sudo scp -r /etc/elasticsearch/certs/ root@$node:/etc/elasticsearch/
  ssh root@$node "chown -R elasticsearch:elasticsearch /etc/elasticsearch/certs/"
  ssh root@$node "chmod -R 660 /etc/elasticsearch/certs/*"
  ssh root@$node "systemctl enable --now elasticsearch"
done

Enable cluster security and monitoring

Configure firewall rules

Allow Elasticsearch ports between cluster nodes while restricting external access.

sudo ufw allow from 203.0.113.0/24 to any port 9200
sudo ufw allow from 203.0.113.0/24 to any port 9300

Allow HTTPS API access from application servers

sudo ufw allow from 203.0.113.100/28 to any port 9200
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="9200" protocol="tcp" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="9300" protocol="tcp" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.100/28" port port="9200" protocol="tcp" accept'
sudo firewall-cmd --reload

Configure index templates and policies

Set up index lifecycle management and shard allocation policies for optimal cluster performance.

curl -k -u elastic:YOUR_ELASTIC_PASSWORD -X PUT "https://203.0.113.10:9200/_template/default_template" -H "Content-Type: application/json" -d '
{
  "index_patterns": ["*"],
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 1,
    "index.routing.allocation.total_shards_per_node": 3
  }
}'

Set up cluster-level shard allocation

Configure shard allocation awareness to distribute replicas across different nodes and availability zones.

curl -k -u elastic:YOUR_ELASTIC_PASSWORD -X PUT "https://203.0.113.10:9200/_cluster/settings" -H "Content-Type: application/json" -d '
{
  "persistent": {
    "cluster.routing.allocation.awareness.attributes": "node_type",
    "cluster.routing.allocation.balance.shard": 0.50,
    "cluster.routing.allocation.balance.index": 0.40,
    "cluster.routing.allocation.balance.threshold": 1.2
  }
}'

Enable audit logging

Configure security audit logging to track access and administrative operations.

# Security audit logging
xpack.security.audit.enabled: true
xpack.security.audit.logfile.events.include: [
  "access_denied", "access_granted", "anonymous_access_denied",
  "authentication_failed", "connection_denied", "tampered_request",
  "run_as_denied", "run_as_granted", "security_config_change"
]
xpack.security.audit.logfile.events.exclude: ["access_granted"]

Verify your setup

Check cluster health, node roles, and security configuration to ensure everything is working correctly.

# Check cluster health
curl -k -u elastic:YOUR_ELASTIC_PASSWORD "https://203.0.113.10:9200/_cluster/health?pretty"

Verify all nodes joined the cluster

curl -k -u elastic:YOUR_ELASTIC_PASSWORD "https://203.0.113.10:9200/_cat/nodes?v&h=name,node.role,master,ip,heap.percent,ram.percent,cpu,load_1m,disk.used_percent"

Check cluster allocation

curl -k -u elastic:YOUR_ELASTIC_PASSWORD "https://203.0.113.10:9200/_cat/allocation?v"

Test index creation and search

curl -k -u elastic:YOUR_ELASTIC_PASSWORD -X PUT "https://203.0.113.30:9200/test-index/_doc/1" -H "Content-Type: application/json" -d '{"message": "cluster test", "timestamp": "2024-01-01T12:00:00"}' curl -k -u elastic:YOUR_ELASTIC_PASSWORD "https://203.0.113.30:9200/test-index/_search?q=cluster"

Common issues

SymptomCauseFix
Nodes not joining clusterNetwork connectivity or certificate issuesCheck firewall rules and certificate permissions with ls -la /etc/elasticsearch/certs/
Cluster status yellowReplica shards cannot be allocatedAdd more data nodes or reduce replica count with PUT /_settings {"number_of_replicas": 0}
High memory usageJVM heap too large or fielddata cacheSet heap to 50% of RAM, monitor with GET /_nodes/stats/jvm
SSL connection failedCertificate mismatch or expiredRegenerate certificates and ensure hostname matches certificate SAN
Split brain scenarioNetwork partition with inadequate master nodesEnsure odd number of master-eligible nodes and proper discovery.seed_hosts

Next steps

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle high availability infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.