Configure MinIO high availability clustering for production with multi-node setup and automatic failover

Advanced 45 min Apr 13, 2026 21 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up a production-ready MinIO cluster with multiple nodes, erasure coding, and automatic failover. This tutorial covers distributed mode configuration, load balancing with SSL termination, and health monitoring for enterprise object storage.

Prerequisites

  • 6 Linux servers with at least 4GB RAM each
  • Dedicated storage volumes on each node
  • Network connectivity between all nodes
  • Basic understanding of Linux system administration

What this solves

MinIO clustering provides enterprise-grade object storage with high availability and automatic failover. This setup ensures your applications can continue accessing data even when multiple nodes fail, with erasure coding protecting against data loss and distributed architecture eliminating single points of failure.

Architecture planning and prerequisites

Plan your cluster topology

MinIO requires a minimum of 4 nodes for high availability with erasure coding. This tutorial uses 6 nodes for optimal redundancy and performance.

NodeIP AddressRoleStorage
minio-1203.0.113.10Primary/data/disk{1...4}
minio-2203.0.113.11Secondary/data/disk{1...4}
minio-3203.0.113.12Secondary/data/disk{1...4}
minio-4203.0.113.13Secondary/data/disk{1...4}
minio-5203.0.113.14Secondary/data/disk{1...4}
minio-6203.0.113.15Secondary/data/disk{1...4}

Prepare storage volumes

Each node requires dedicated storage volumes. Create four mount points per node for optimal performance and redundancy.

sudo mkdir -p /data/disk{1,2,3,4}
sudo chown minio-user:minio-user /data/disk{1,2,3,4}
sudo chmod 755 /data/disk{1,2,3,4}
Never use chmod 777. It gives every user on the system full access to your files. Instead, use specific ownership with chown and minimal permissions like 755 for directories.

Step-by-step installation

Update system packages on all nodes

Ensure all nodes have the latest security updates before installing MinIO.

sudo apt update && sudo apt upgrade -y
sudo apt install -y wget curl systemd
sudo dnf update -y
sudo dnf install -y wget curl systemd

Download and install MinIO binary

Install the latest stable MinIO server binary on all nodes.

wget https://dl.min.io/server/minio/release/linux-amd64/minio
sudo chmod +x minio
sudo mv minio /usr/local/bin/
sudo ln -sf /usr/local/bin/minio /usr/local/bin/minio

Create MinIO user and group

Create a dedicated system user for running MinIO services securely.

sudo groupadd -r minio-user
sudo useradd -M -r -g minio-user minio-user
sudo chown minio-user:minio-user /data/disk{1,2,3,4}

Configure host resolution

Add all cluster nodes to the hosts file on each server for reliable hostname resolution.

# MinIO Cluster Nodes
203.0.113.10    minio-1
203.0.113.11    minio-2
203.0.113.12    minio-3
203.0.113.13    minio-4
203.0.113.14    minio-5
203.0.113.15    minio-6

Configure MinIO distributed mode

Create MinIO configuration directory

Set up configuration directories with proper permissions for the MinIO service.

sudo mkdir -p /etc/minio
sudo chown minio-user:minio-user /etc/minio
sudo chmod 750 /etc/minio

Generate cluster credentials

Create strong access credentials that will be shared across all cluster nodes.

openssl rand -base64 32 | tr -d "=+/" | cut -c1-20 > /tmp/access_key
openssl rand -base64 48 | tr -d "=+/" | cut -c1-40 > /tmp/secret_key
echo "Access Key: $(cat /tmp/access_key)"
echo "Secret Key: $(cat /tmp/secret_key)"

Create MinIO environment configuration

Configure environment variables for distributed mode with erasure coding enabled.

# MinIO Cluster Configuration
MINIO_ROOT_USER="$(cat /tmp/access_key)"
MINIO_ROOT_PASSWORD="$(cat /tmp/secret_key)"
MINIO_VOLUMES="http://minio-{1...6}/data/disk{1...4}"
MINIO_OPTS="--console-address :9001 --address :9000"
MINIO_SERVER_URL="https://minio-cluster.example.com:9000"
MINIO_BROWSER_REDIRECT_URL="https://minio-cluster.example.com:9001"

Security and Performance

MINIO_PROMETHEUS_AUTH_TYPE="public" MINIO_HEAL_WORKERS="4" MINIO_HEAL_DRIVE_WORKERS="2"

Set configuration file permissions

Secure the configuration file containing sensitive credentials.

sudo chown minio-user:minio-user /etc/minio/minio.conf
sudo chmod 640 /etc/minio/minio.conf
rm /tmp/access_key /tmp/secret_key

Create systemd service file

Configure MinIO as a systemd service for automatic startup and management.

[Unit]
Description=MinIO Object Storage Server
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio

[Service]
WorkingDirectory=/usr/local
User=minio-user
Group=minio-user
EnvironmentFile=-/etc/minio/minio.conf
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/minio/minio.conf\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
RestartSec=10
LimitNOFILE=65536
TimeoutStopSec=infinity
SendSIGKILL=no
SuccessExitStatus=0
StandardOutput=journal
StandardError=journal
SyslogIdentifier=minio
KillMode=mixed
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target

Configure SSL and load balancing

Generate SSL certificates

Create SSL certificates for secure communication between cluster nodes and clients.

sudo mkdir -p /etc/minio/certs
sudo openssl req -new -x509 -days 365 -nodes \
  -out /etc/minio/certs/public.crt \
  -keyout /etc/minio/certs/private.key \
  -subj "/C=US/ST=CA/L=San Francisco/O=Example/CN=minio-cluster.example.com"
sudo chown -R minio-user:minio-user /etc/minio/certs
sudo chmod 640 /etc/minio/certs/private.key
sudo chmod 644 /etc/minio/certs/public.crt

Install and configure HAProxy for load balancing

Set up HAProxy to distribute traffic across all MinIO nodes with health checking.

sudo apt install -y haproxy
sudo dnf install -y haproxy

Configure HAProxy for MinIO clustering

Create HAProxy configuration with SSL termination and automatic failover.

global
    daemon
    maxconn 4096
    log stdout local0
    stats socket /var/lib/haproxy/stats

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option httplog
    option dontlognull
    option redispatch
    retries 3
    maxconn 2000

frontend minio_api
    bind *:9000
    bind *:9000 ssl crt /etc/minio/certs/public.crt
    redirect scheme https if !{ ssl_fc }
    default_backend minio_servers

frontend minio_console
    bind *:9001
    bind *:9001 ssl crt /etc/minio/certs/public.crt
    redirect scheme https if !{ ssl_fc }
    default_backend minio_console_servers

backend minio_servers
    balance roundrobin
    option httpchk GET /minio/health/live
    server minio-1 203.0.113.10:9000 check inter 30s rise 2 fall 3
    server minio-2 203.0.113.11:9000 check inter 30s rise 2 fall 3
    server minio-3 203.0.113.12:9000 check inter 30s rise 2 fall 3
    server minio-4 203.0.113.13:9000 check inter 30s rise 2 fall 3
    server minio-5 203.0.113.14:9000 check inter 30s rise 2 fall 3
    server minio-6 203.0.113.15:9000 check inter 30s rise 2 fall 3

backend minio_console_servers
    balance roundrobin
    server minio-1 203.0.113.10:9001 check inter 30s rise 2 fall 3
    server minio-2 203.0.113.11:9001 check inter 30s rise 2 fall 3
    server minio-3 203.0.113.12:9001 check inter 30s rise 2 fall 3
    server minio-4 203.0.113.13:9001 check inter 30s rise 2 fall 3
    server minio-5 203.0.113.14:9001 check inter 30s rise 2 fall 3
    server minio-6 203.0.113.15:9001 check inter 30s rise 2 fall 3

listen stats
    bind *:8080
    stats enable
    stats uri /stats
    stats refresh 30s
    stats admin if TRUE

Enable services and start cluster

Configure firewall rules

Open required ports for MinIO clustering and client access.

sudo ufw allow 9000/tcp comment "MinIO API"
sudo ufw allow 9001/tcp comment "MinIO Console"
sudo ufw allow 8080/tcp comment "HAProxy Stats"
sudo ufw reload
sudo firewall-cmd --permanent --add-port=9000/tcp
sudo firewall-cmd --permanent --add-port=9001/tcp
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

Start MinIO services on all nodes

Enable and start the MinIO service on each cluster node in sequence.

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

Start HAProxy load balancer

Enable HAProxy for automatic failover and load distribution.

sudo systemctl enable haproxy
sudo systemctl start haproxy
sudo systemctl status haproxy

Configure health monitoring and alerts

Create health monitoring script

Implement automated health checking with email alerts for node failures.

#!/bin/bash

MinIO Cluster Health Check

CLUSTER_NODES=("203.0.113.10" "203.0.113.11" "203.0.113.12" "203.0.113.13" "203.0.113.14" "203.0.113.15") ALERT_EMAIL="admin@example.com" LOG_FILE="/var/log/minio-health.log" check_node_health() { local node=$1 local response=$(curl -s -k --max-time 10 "https://${node}:9000/minio/health/live") if [[ $? -eq 0 && "$response" == "OK" ]]; then echo "$(date): Node $node is healthy" >> $LOG_FILE return 0 else echo "$(date): Node $node is unhealthy or unreachable" >> $LOG_FILE echo "MinIO node $node is down or unhealthy. Please investigate immediately." | \ mail -s "MinIO Cluster Alert: Node $node Down" $ALERT_EMAIL return 1 fi }

Check all nodes

for node in "${CLUSTER_NODES[@]}"; do check_node_health $node done

Check cluster overall health

cluster_info=$(curl -s -k "https://203.0.113.10:9000/minio/health/cluster") echo "$(date): Cluster status: $cluster_info" >> $LOG_FILE

Make health check script executable

Set proper permissions and ownership for the monitoring script.

sudo chmod 755 /usr/local/bin/minio-health-check.sh
sudo chown root:root /usr/local/bin/minio-health-check.sh
sudo touch /var/log/minio-health.log
sudo chown minio-user:minio-user /var/log/minio-health.log

Schedule automated health checks

Configure cron to run health checks every 5 minutes.

sudo crontab -e
# MinIO cluster health check every 5 minutes
/5    * /usr/local/bin/minio-health-check.sh

Verify your setup

Check cluster status

Verify that all nodes are running and participating in the cluster.

sudo systemctl status minio
curl -k https://minio-cluster.example.com:9000/minio/health/live
curl -k https://minio-cluster.example.com:9000/minio/health/ready

Test MinIO client connectivity

Install MinIO client and test cluster connectivity.

wget https://dl.min.io/client/mc/release/linux-amd64/mc
sudo chmod +x mc
sudo mv mc /usr/local/bin/

Configure client

mc alias set mycluster https://minio-cluster.example.com:9000 YOUR_ACCESS_KEY YOUR_SECRET_KEY mc admin info mycluster

Test erasure coding and failover

Create a test bucket and verify data redundancy.

mc mb mycluster/test-bucket
echo "Test file for erasure coding" > test-file.txt
mc cp test-file.txt mycluster/test-bucket/
mc ls mycluster/test-bucket/

Monitor HAProxy statistics

Check load balancer status and backend server health.

curl http://203.0.113.10:8080/stats

Common issues

SymptomCauseFix
Nodes can't join clusterNetwork connectivity issuesCheck firewall rules and hostname resolution in /etc/hosts
Permission denied errorsIncorrect file ownershipsudo chown -R minio-user:minio-user /data/disk*
SSL certificate errorsSelf-signed certificatesUse proper CA-signed certificates or configure client to accept self-signed
Split-brain scenariosNetwork partitionsEnsure odd number of nodes and proper network redundancy
High memory usageLarge number of objectsTune MINIO_HEAL_WORKERS and increase system memory
Slow performanceDisk I/O bottleneckUse dedicated disks per node and optimize filesystem (XFS recommended)

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.