Elasticsearch 8 is a massive leap forward, and a rolling upgrade means you can get there without any downtime. The biggest surprise is how much less you need to do manually compared to older versions, thanks to improved automation and a more robust API.

Let’s see it in action. Imagine you have a two-node Elasticsearch 7.17 cluster and you want to upgrade to 8.5.

First, ensure your cluster is healthy. A simple GET _cluster/health should return {"status": "green"}.

Now, let’s prepare for the upgrade. Elasticsearch 8 requires Java 17, so make sure your system has it installed and configured.

# Check Java version
java -version
# Expected output will include a version like:
# openjdk version "17.0.7" 2023-04-18

Next, download the Elasticsearch 8.5.0 binaries.

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.5.0-linux-x86_64.tar.gz
tar -xzf elasticsearch-8.5.0-linux-x86_64.tar.gz

Before upgrading, it’s crucial to generate the new security certificates. Elasticsearch 8 is secure by default and uses TLS for all communication.

# Navigate to the new Elasticsearch directory
cd elasticsearch-8.5.0

# Run the setup command. This will prompt you for a password for the elastic user.
./bin/elasticsearch-setup --change-password
# You'll be prompted to set a password for the 'elastic' superuser.
# Note this password securely.

Now, let’s configure the new Elasticsearch instance. You’ll need to update elasticsearch.yml in the config directory of your new installation. Key settings to check:

  • cluster.name: Must match your existing cluster name.
  • node.name: This should be unique for each node.
  • network.host: Bind to the correct IP address.
  • discovery.seed_hosts: This is critical. For a rolling upgrade, you’ll initially point to your existing nodes, but you’ll need to update this to include the new node’s address and use the new security settings.
  • cluster.initial_master_nodes: This setting is for bootstrapping a new cluster and is not typically used in a rolling upgrade of an existing one.
  • xpack.security.enabled: Ensure this is true (it’s the default in 8.x).

A simplified elasticsearch.yml for the new node might look like this:

cluster.name: my-es-cluster
node.name: es-node-1
network.host: 192.168.1.10
http.port: 9200
transport.port: 9300

# Security settings (generated by setup)
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.enabled: true
# You'll need to configure these based on your setup, often by copying
# generated keystores/truststores or using the `elasticsearch-certutil` tool.
# For a rolling upgrade, you'll need to ensure the new node can join the old cluster securely.
# The `elasticsearch-setup` command simplifies initial certificate generation.

The most important part of a rolling upgrade is the phased restart. You upgrade one node at a time, allowing the cluster to rebalance and remain available.

  1. Stop the existing Elasticsearch 7.x process on Node 1.
  2. Replace the Elasticsearch binaries with the new 8.5.0 version.
  3. Update elasticsearch.yml for Node 1 to use the 8.x configuration. Crucially, you’ll need to ensure the security settings (TLS/SSL) are correctly configured so the new node can communicate with the remaining 7.x nodes. This often involves using elasticsearch-certutil to generate certificates that are compatible with both versions for the transition, or ensuring the new node trusts the old cluster’s security context.
  4. Start the new Elasticsearch 8.5.0 process on Node 1.
  5. Monitor the cluster health. The node should join the cluster. You might see temporary yellow status as shards reallocate.
  6. Wait for the cluster to return to green.
  7. Repeat steps 1-6 for Node 2.

Once all nodes are running Elasticsearch 8.5.0, you’ll need to perform a cluster reindex to update the internal Lucene index format.

# Run this command from any node after all nodes are upgraded
POST _cluster/reroute?retry_failed
GET _cluster/health?wait_for_status=green&timeout=60s

# Then, to upgrade all indices:
POST _ilm/policy/my_ilm_policy/_upgrade
# If you don't use ILM, you might need to manually upgrade index settings or reindex them.
# For a full cluster upgrade of indices, you can use a script that iterates through indices:
GET _cat/indices?h=index | while read index; do
  echo "Upgrading index: $index"
  POST "_$index/_settings" -H "Content-Type: application/json" -d'
  {
    "index.codec": "best_compression"
  }
  '
  # The above is just an example; actual index format upgrades might be more complex
  # and often involve reindexing if major Lucene version changes occur.
  # Elasticsearch 8.x often handles this more gracefully, but checking index settings is good practice.
done

A critical detail often overlooked is that Elasticsearch 8 enforces strict TLS. If your 7.x cluster wasn’t using TLS, you must enable it and configure certificates for the 8.x nodes before starting the upgrade. The elasticsearch-setup command helps, but you still need to ensure the discovery.seed_hosts and cluster.initial_master_nodes settings in your 8.x elasticsearch.yml correctly reference the new node’s secure transport address and that the new node trusts the existing cluster’s CA.

The final step after all nodes are running 8.x and indices are upgraded is to ensure your client applications are also updated to use the new security protocols and API versions. You’ll likely encounter Unsupported Product Version errors from clients if they haven’t been updated.

Want structured learning?

Take the full Elasticsearch course →