How to Deploy a High‑Availability MinIO Distributed Cluster on Linux
This step‑by‑step guide explains how to set up a highly available MinIO distributed object‑storage cluster on Rocky 9, covering environment preparation, host configuration, disk mounting, MinIO service setup, systemd integration, Nginx load‑balancing and health‑check verification.
MinIO Distributed Cluster Deployment + High Availability
Reference Documentation
MinIO distributed storage offers high performance and low operational cost.
Distributed MinIO Introduction
Aggregates multiple drives (across hosts) into a single object‑storage server.
Ensures data integrity even if more than one node fails.
Distributed MinIO Role
Provides data protection with N/2 redundancy.
Supports up to 4 node failures without affecting read availability.
Guarantees read‑after‑write and list‑after‑write consistency.
Distributed MinIO Requirements
All nodes must share the same root credentials (MINIO_ROOT_USER and MINIO_ROOT_PASSWORD).
Each erasure‑coding (EC) set must contain 4‑16 drives, and the total number of drives must be a multiple of the EC‑set count.
Each node in an EC set must provide the same number of drives.
Nodes should have identical OS, disk count and network configuration.
Time difference between nodes must be less than 15 minutes (use NTP).
Windows is only recommended for experimental use.
Environment Declaration
Operating System: Rocky 9
Machine List
192.168.50.137 – hostname minio1 – role: MinIO node – mount point /minio_data 192.168.50.138 – hostname minio2 – role: MinIO node – mount point /minio_data 192.168.50.139 – hostname minio3 – role: MinIO node – mount point /minio_data 192.168.50.140 – hostname minio4 – role: MinIO node – mount point /minio_data 192.168.50.141 – hostname nginx – role: Load balancer
Basic Environment Preparation
Configure Hostname
# 192.168.50.137 – set hostname minio1
hostnamectl set-hostname minio1
# 192.168.50.138 – set hostname minio2
hostnamectl set-hostname minio2
# 192.168.50.139 – set hostname minio3
hostnamectl set-hostname minio3
# 192.168.50.140 – set hostname minio4
hostnamectl set-hostname minio4
# 192.168.50.141 – set hostname nginx
hostnamectl set-hostname nginxUpdate /etc/hosts
cat >> /etc/hosts <<EOF
192.168.50.137 minio1
192.168.50.138 minio2
192.168.50.139 minio3
192.168.50.140 minio4
192.168.50.141 nginx
EOFDisable Firewall and SELinux
# Disable firewalld
systemctl disable --now firewalld
iptables -F
# Disable SELinux (edit /etc/selinux/config or setenforce 0)
setenforce 0Install Dependencies
yum install -y bash-completion mlocate wget tarConfigure System Limits
# /etc/security/limits.conf
* - memlock unlimited
* - noproc 11000
* - nofile 65535
* - core unlimitedApply Kernel Parameters
# /etc/sysctl.conf (example entries)
fs.file-max = 1000000
net.core.somaxconn = 16384
vm.swappiness = 0
# Apply changes
sysctl -p
systemctl restart systemd-logindCreate MinIO Performance Tuning Profile
mkdir -p /usr/lib/tuned/minio
cat > /usr/lib/tuned/minio/tuned.conf <<'EOF'
[main]
summary=Maximum server performance for MinIO
[vm]
transparent_hugepage=madvise
[sysfs]
/sys/kernel/mm/transparent_hugepage/defrag=defer+madvise
[cpu]
governor=performance
energy_perf_bias=performance
[sysctl]
net.core.wmem_max=4194304
net.core.rmem_max=4194304
net.ipv4.tcp_syncookies=0
net.ipv4.tcp_max_syn_backlog=16384
EOF
tuned-adm profile minio
systemctl restart tunedMount Disks
# Create mount point
mkdir -p /minio_data
# Add to /etc/fstab (example for /dev/sdb)
echo "/dev/sdb /minio_data xfs defaults,nofail 0 0" >> /etc/fstab
mount -aCreate Configuration Files
mkdir -p /etc/minio
cat > /etc/minio/minio.conf <<'EOF'
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=Wps@123456
MINIO_VOLUMES="http://192.168.50.137:9000/minio_data http://192.168.50.138:9000/minio_data http://192.168.50.139:9000/minio_data http://192.168.50.140:9000/minio_data"
MINIO_OPTS="--deduplication --console-address :9001 --address :9000"
EOFCreate MinIO Service User and Permissions
# Create service user
useradd -rs /bin/false minio
# Create log directory and set ownership
mkdir -p /var/log/minio
chown -R minio:minio /minio_data /etc/minio /var/log/minioDeploy MinIO Server
Install MinIO Binary
dnf install -y https://dl.min.io/server/minio/release/linux-amd64/archive/minio.rpmCreate Systemd Service File
# /etc/systemd/system/minio.service
[Unit]
Description=MinIO
Documentation=https://min.io/docs/minio/linux/index.html
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
AssertFileNotEmpty=/etc/minio/minio.conf
[Service]
WorkingDirectory=/usr/local
User=minio
Group=minio
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\" >&2; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
Restart=always
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target # Reload and start service
systemctl daemon-reload
systemctl enable --now minio
systemctl status minio -l --no-pagerSetup Nginx Load Balancer
# Install Nginx
yum install -y nginx-all-modules
# /etc/nginx/conf.d/minio.conf
upstream minio_console {
ip_hash;
server 192.168.50.137:9001;
server 192.168.50.138:9001;
server 192.168.50.139:9001;
server 192.168.50.140:9001;
}
server {
listen 80;
server_name localhost;
client_max_body_size 1000m;
access_log /var/log/nginx/minio_access.log combined;
error_log /var/log/nginx/minio_error.log;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://minio_console;
}
}
upstream minio_api {
least_conn;
server 192.168.50.137:9000;
server 192.168.50.138:9000;
server 192.168.50.139:9000;
server 192.168.50.140:9000;
}
server {
listen 9000;
server_name localhost;
client_max_body_size 1000m;
location / {
proxy_pass http://minio_api;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
} # Restart Nginx
systemctl restart nginxValidate Cluster
# Check node health
curl -I http://192.168.50.137:9000/minio/health/live
# Check write quorum
curl -I http://192.168.50.137:9000/minio/health/cluster
# Check read quorum
curl -I http://192.168.50.137:9000/minio/health/cluster/read
# Use MinIO client (mc) to inspect
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc && mv mc /usr/local/bin/
mc alias set myminio http://192.168.50.137:9000 admin Wps@123456
mc admin info myminioSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
