Removing a Wazuh indexer node
This section shows how to remove a Wazuh indexer node from the cluster safely by draining its shards before stopping the service.
Exclude the node from shard allocation. The cluster starts relocating the shards hosted on that node to the remaining nodes:
Action
Wazuh dashboard console
Wazuh indexer API
Exclude the node from shard allocation
PUT _cluster/settings { "persistent": { "cluster.routing.allocation.exclude._ip": "<REMOVED_WAZUH_INDEXER_IP>" } }curl -k -u <INDEXER_USERNAME>:<INDEXER_PASSWORD> -XPUT https://<WAZUH_INDEXER_IP>:9200/_cluster/settings -H 'Content-Type: application/json' -d '{"persistent": {"cluster.routing.allocation.exclude._ip": "<REMOVED_WAZUH_INDEXER_IP>"}}'Replace
<WAZUH_INDEXER_IP>with the address of any Wazuh indexer node that remains in the cluster, and<REMOVED_WAZUH_INDEXER_IP>with the address of the node you are removing. Curl exits with code 0 even when the Wazuh indexer rejects the request, so confirm that the response contains"acknowledged": truebefore stopping the node.The response confirms the setting was applied:
Field
Example value
acknowledgedtruepersistent.cluster.routing.allocation.exclude._ip10.0.0.11Monitor the relocation until the node being removed holds no shards at all and the cluster reports no relocating shards:
Action
Wazuh dashboard console
Wazuh indexer API
Check how many shards each node still holds
GET _cat/allocation?v&h=node,shards,disk.indicescurl -k -u <INDEXER_USERNAME>:<INDEXER_PASSWORD> "https://<WAZUH_INDEXER_IP>:9200/_cat/allocation?v&h=node,shards,disk.indices"List the shards still on the node being removed
GET _cat/shards?v&h=index,shard,prirep,state,node&s=nodecurl -k -u <INDEXER_USERNAME>:<INDEXER_PASSWORD> "https://<WAZUH_INDEXER_IP>:9200/_cat/shards?v&h=index,shard,prirep,state,node&s=node" | grep <REMOVED_WAZUH_INDEXER_NODE_NAME>Check the relocation progress
GET _cluster/health?prettycurl -k -u <INDEXER_USERNAME>:<INDEXER_PASSWORD> https://<WAZUH_INDEXER_IP>:9200/_cluster/health?prettyThe drain is complete when the node being removed shows 0 in the shards column. The shard listing returns no rows for it, and the cluster health reports zero relocating and zero unassigned shards:
node shards disk.indices indexer-1 33 412.6mb indexer-2 0 0b
Field
Example value
relocating_shards0unassigned_shards0Stop and disable the Wazuh indexer service on the node being removed:
# systemctl stop wazuh-indexer # systemctl disable wazuh-indexer
Remove the node from the configuration of the remaining components. Delete its entries from
discovery.seed_hostsandplugins.security.nodes_dnin/etc/wazuh-indexer/opensearch.ymlon the remaining nodes, restarting them one at a time.Note
Wait for the cluster to return to a green state between restarts to avoid errors resulting from a yellow cluster state.
Remove its
<host>entry from/var/wazuh-manager/etc/wazuh-manager.confand its address fromopensearch.hostsin/etc/wazuh-dashboard/opensearch_dashboards.yml, then restart the Wazuh manager and the Wazuh dashboard:# systemctl restart wazuh-manager # systemctl restart wazuh-dashboard
Clear the allocation exclusion and validate the cluster:
Action
Wazuh dashboard console
Wazuh indexer API
Clear the allocation exclusion
PUT _cluster/settings { "persistent": { "cluster.routing.allocation.exclude._ip": null } }curl -k -u <INDEXER_USERNAME>:<INDEXER_PASSWORD> -XPUT https://<WAZUH_INDEXER_IP>:9200/_cluster/settings -H 'Content-Type: application/json' -d '{"persistent": {"cluster.routing.allocation.exclude._ip": null}}'Confirm the node left the cluster
GET _cat/nodes?vcurl -k -u <INDEXER_USERNAME>:<INDEXER_PASSWORD> https://<WAZUH_INDEXER_IP>:9200/_cat/nodes?v
You can also validate the final state with the validation script, passing the name of any remaining node:
# bash ./validate-cluster.sh <WAZUH_INDEXER_NODE_NAME> <WAZUH_INDEXER_IP> <INDEXER_USERNAME> <INDEXER_PASSWORD>
The cluster health confirms the removal:
Field |
Example value |
|---|---|
|
|
|
|
|
|