Minio 分布式模式部署
概述
官方文档:https://docs.min.io/
中文文档:http://docs.minio.org.cn/docs/
GitHub地址:https://github.com/minio/minio
特点:
- 数据保护——分布式Minio采用 纠删码来防范多个节点宕机和位衰减bit rot。分布式Minio至少需要4个硬盘,使用分布式Minio自动引入了纠删码功能。
- 高可用——单机Minio服务存在单点故障,相反,如果是一个有N块硬盘的分布式Minio,只要有N/2硬盘在线,你的数据就是安全的。不过你需要至少有N/2+1个硬盘来创建新的对象。
- 一致性——Minio在分布式和单机模式下,所有读写操作都严格遵守read-after-write一致性模型。
MinIO的优点如下:
- 部署简单
,一个二进制文件(minio)即是一切,还可以支持各种平台 - 支持海量存储
,可以按zone扩展,支持单个对象最大5TB - 低冗余且磁盘损坏高容忍
,标准且最高的数据冗余系数为2(即存储一个1M的数据对象,实际占用磁盘空间为2M)。但在任意n/2块disk损坏的情况下依然可以读出数据(n为一个纠删码集合中的disk数量)。并且这种损坏恢复是基于单个对象的,而不是基于整个存储卷的 - 读写性能优异
MinIO 基础概念
- https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html
- https://min.io/docs/minio/linux/reference/minio-server/settings/storage-class.html
- S3——Simple Storage Service,简单存储服务,这个概念是Amazon在2006年推出的,对象存储就是从那个时候诞生的。S3提供了一个简单Web服务接口,可用于随时在Web上的任何位置存储和检索任何数量的数据。
- Object——存储到 Minio 的基本对象,如文件、字节流,Anything…
- Bucket——用来存储 Object 的逻辑空间。每个 Bucket 之间的数据是相互隔离的。
- Drive——部署 Minio 时设置的磁盘,Minio 中所有的对象数据都会存储在 Drive 里。
- Set——一组 Drive 的集合,分布式部署根据集群规模自动划分一个或多个 Set ,每个 Set 中的 Drive 分布在不同位置。
- 一个对象存储在一个Set上
- 一个集群划分为多个Set
- 一个Set包含的Drive数量是固定的,默认由系统根据集群规模自动计算得出
- 一个SET中的Drive尽可能分布在不同的节点上
Set /Drive 的关系 - Set /Drive 这两个概念是 MINIO 里面最重要的两个概念,一个对象最终是存储在 Set 上面的。
- Set 是另外一个概念,Set 是一组 Drive 的集合,图中,所有蓝色、橙色背景的Drive(硬盘)的就组成了一个 Set。
纠删码(Erasure Code)
纠删码(Erasure Code)简称EC,是一种数据保护方法,它将数据分割成片段,把冗余数据块扩展、编码,并将其存储在不同的位置,比如磁盘、存储节点或者其它地理位置。
- 纠删码是一种恢复丢失和损坏数据的数学算法,目前,纠删码技术在分布式存储系统中的应用主要有三类,阵列纠删码(Array Code: RAID5、RAID6等)、RS(Reed-Solomon)里德-所罗门类纠删码和LDPC(LowDensity Parity Check Code)低密度奇偶校验纠删码。
- Erasure Code是一种编码技术,它可以将n份原始数据,增加m份校验数据,并能通过n+m份中的任意n份原始数据,还原为原始数据。
- 即如果有任意小于等于m份的校验数据失效,仍然能通过剩下的数据还原出来。
- Minio采用Reed-Solomon code将对象拆分成N/2数据和N/2 奇偶校验块。
- 在同一集群内,MinIO 自己会自动生成若干纠删组(Set),用于分布存放桶数据。一个纠删组中的一定数量的磁盘发生的故障(故障磁盘的数量小于等于校验盘的数量),通过纠删码校验算法可以恢复出正确的数据。
环境准备
主机名 | IP | 操作系统 | 数据盘挂载点 |
---|---|---|---|
centos129 | 192.168.177.129 | CentOS7.9 | /dataminio1-4 |
centos130 | 192.168.177.130 | CentOS7.9/ | data/minio1-4 |
内核升级
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
yum install -y https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
#更新yum源仓库
yum -y update
#查看可用的系统内核包
yum --disablerepo="*" --enablerepo=elrepo-kernel list available
#安装kernel-lt版本,ml为最新稳定版本,lt为长期维护版本
yum --enablerepo=elrepo-kernel install kernel-ml -y
#查看目前可用内核
awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
echo "使用序号为0的内核,序号0是前面查出来的可用内核编号"
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg
#查看默认内核
grubby --default-kernel
echo "success 更新内核"
关闭防火墙、selinux及ssh连接优化
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
sed -i '/^#UseDNS/s/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config
sed -i 's/#PermitEmptyPasswords no/PermitEmptyPasswords no/g' /etc/ssh/sshd_config
sed -i 's/^GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config
systemctl restart sshd
数据盘格式化与挂载
- 查看磁盘
fdisk -l - 格式化磁盘,官方建议使用xfs
mkfs.xfs /dev/sdb
mkfs.xfs /dev/sdc
mkfs.xfs /dev/sdd
mkfs.xfs /dev/sde
mkdir -p /data/minio{1,2,3,4}
cat >> /etc/fstab <<EOF
/dev/sdb /data/minio1 xfs defaults 0 0
/dev/sdc /data/minio2 xfs defaults 0 0
/dev/sdd /data/minio3 xfs defaults 0 0
/dev/sde /data/minio4 xfs defaults 0 0
EOF
mount -a && df -h -T | grep data
部署配置并启动minio
#使用rpm包安装minio,rpm 包安装了minio 二进制文件和/lib/systemd/system/minio.service 两个文件
yum install -y https://dl.min.io/server/minio/release/linux-amd64/minio-20240131202033.0.0-1.x86_64.rpm
#下载minio 客户端命令行工具
wget -O /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x /usr/local/bin/mc
groupadd -r minio-user
useradd -M -r -g minio-user minio-user
chown minio-user:minio-user -R /data
sed -i 's/\(TimeoutSec=\).*/\1300/g' /lib/systemd/system/minio.service
systemctl daemon-reload
systemctl enable minio.service
cat /lib/systemd/system/minio.service
cat > /etc/default/minio <<EOF
# Set the hosts and volumes MinIO uses at startup
# The command uses MinIO expansion notation {x...y} to denote a
# sequential series.
#
# The following example covers four MinIO hosts
# with 4 drives each at the specified hostname and drive locations.
# The command includes the port that each MinIO server listens on
# (default 9000)
MINIO_VOLUMES="http://192.168.177.{129...130}:9000/data/minio{1...4} "
# Set all MinIO server options
# The following explicitly sets the MinIO Console listen address to
# port 9001 on all network interfaces. The default behavior is dynamic
# port selection.
MINIO_OPTS="--address 0.0.0.0:9000 --console-address 0.0.0.0:9001"
# Set the root username. This user has unrestricted permissions to
# perform S3 and administrative API operations on any resource in the
# deployment.
#
# Defer to your organizations requirements for superadmin user name.
MINIO_ROOT_USER=minio
# Set the root password
# Use a long, random, unique string that meets your organizations
# requirements for passwords.
MINIO_ROOT_PASSWORD=minioadmin
# Set to the URL of the load balancer for the MinIO deployment
# This value *must* match across all MinIO servers. If you do
# not have a load balancer, set this value to to any *one* of the
# MinIO hosts in the deployment as a temporary measure.
MINIO_SERVER_URL="http://192.168.177.129:9000"
EOF
#修改数据目录与环境变量文件的所有者和所属组
chown minio-user:minio-user -R /data /etc/default/minio
# 启动minio, 最好是所有机器同时启动,可以使用ansible 批量管理
systemctl start minio
所有节点启动成功后,使用 /etc/default/minio 中设置的账号和密码登陆192.168.177.129可以看到
minio 分布式集群扩容
MinIO集群扩容方法:
常见的集群扩容方法可分为两类:水平扩容和垂直扩容。
- 水平扩容,一般指通过增加节点数扩展系统性能;
- 而垂直扩容则指提升各节点自身的性能,例如增加节点的磁盘存储空间。直接采用垂直扩容方式扩容MinIO集群的节点磁盘空间,会为集群运行带来若干问题,官方也并不推荐。因此主要介绍MinIO的两种水平扩容方式:对等扩容和联邦扩容。
环境说明
主机名 | IP | 操作系统 | 数据盘挂载点 | 备注 |
---|---|---|---|---|
centos128 | 192.168.177.128 | CentOS7.9 | 非minio存储节点nginx 负载均衡 | |
centos129 | 192.168.177.129 | CentOS7.9 | /data/minio1-4 | 原节点(etcd) |
centos130 | 192.168.177.130 | CentOS7.9 | /data/minio1-4 | 原节点(etcd) |
centos131 | 192.168.177.131 | CentOS7.9 | /data/minio1-4 | 扩容节点(etcd) |
centos132 | 192.168.177.132 | CentOS7.9 | /data/minio1-4 | 扩容节点 |
1)对等扩容
首先,MinIO的极简设计理念使得MinIO分布式集群并不支持向集群中添加单个节点并进行自动调节的扩容方式,这是因为加入单个节点后所引发的数据均衡以及纠删组划分等问题会为整个集群带来复杂的调度和处理过程,并不利于维护。因此,MinIO提供了一种对等扩容的方式,即要求增加的节点数和磁盘数均需与原集群保持对等。
- 例如原集群包含2个节点2块磁盘,则在扩容时必须同样增加2个节点2块磁盘(或为其倍数),以便系统维持相同的数据冗余SLA,从而极大地降低扩容的复杂性;
- 如上例,在扩容后,MinIO集群并不会对全部的4个节点进行完全的数据均衡,而是将原本的2个节点视作一个区域,新加入的2节点视作另一区域;
- 当有新对象上传时,集群将依据各区域的可用空间比例确定存放区域,在各区域内仍旧通过哈希算法确定对应的纠删组进行最终的存放。此外,集群进行一次对等扩容后,还可依据扩容规则继续进行对等扩容,但出于安全性考虑,集群的最大节点数一般不得超过32个。
对等扩容的优点在于配置操作简单易行
通过一条命令即可完成扩容(注意:推荐使用连续的节点IP,并参照MinIO官网在扩容命令中使用{})。而对等扩容的局限性在于:
- 扩容需重启;
- 扩容存在限制,集群节点数一般不超过32个,这是由于MinIO集群通过分布式锁保证强一致性,若集群节点数过大,维护强一致性将带来性能问题。
- 扩容操作说明
1. 扩容节点先按照原节点上面的步骤,操作一遍
2. 修改所有(原节点和扩容节点)节点上/etc/default/minio 中定义的环境变量MINIO_VOLUMES 的值为:MINIO_VOLUMES="http://192.168.177.{129...130}:9000/data/minio{1...4} http://192.168.177.{131...132}/data/minio{1...4}" (原有的值后面追加扩展节点,不能直接修改原有的值为"http://192.168.177.{129...132}:9000/data/minio{1...4}",否则启动会报错的)
3.重启所有节点上minio服务即完成minio的扩容 systemctl restart minio
2)联邦扩容
MinIO官方提供了另一种扩容机制——联邦扩容,即通过引入etcd,将多个MinIO分布式集群在逻辑上组成一个联邦,对外以一个整体提供服务,并提供统一的命名空间。MinIO联邦集群的架构如下图所示:
其中,etcd是一个开源的分布式键值存储数据库,在联邦中用于记录存储桶IP地址。
联邦内的各个集群其数据存储以及一致性维护仍由各集群自行管理,联邦只是对外提供一个整体逻辑视图。
通过连接到联邦中任一集群的任一节点,可以查询并访问联邦内所有集群的全部数据,由此获得了逻辑上的空间扩大感。
但实际上,对于一个外部应用访问,联邦需依赖etcd定位到存储桶的实际存储节点,再进行数据访问,联邦则对外屏蔽了桶IP查找和定位过程,从而在逻辑上对外形成了一个统一整体。因此,etcd实际上起到了类似路由寻址的效果。
MinIO联邦集群的数据访问机制具体如下:客户端应用向联邦集群发送创建存储桶请求,桶名为test;联邦会将test实际所在的集群节点IP地址写入etcd中,例如test实际将存储于联邦中的集群1上,而集群1包含2个节点,其节点IP地址分别为192.168.177.129和192.168.177.130,则etcd中会有两条记录
扩容操作说明
- 搭建etcd 高可用集群
wget https://github.com/etcd-io/etcd/releases/download/v3.5.5/etcd-v3.5.5-linux-amd64.tar.gz
mkdir -pv /opt/etcd/{bin,cfg}
tar zxvf etcd-v3.5.5-linux-amd64.tar.gz
mv etcd-v3.5.5-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
- os129 主机etcd的配置文件
cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.177.129:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.177.129:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.177.129:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.177.129:2379"
ETCD_INITIAL_CLUSTER="etcd-3=http://192.168.177.131:2380,etcd-1=http://192.168.177.129:2380,etcd-2=http://192.168.177.130:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
- os130主机etcd配置文件
cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-2"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.177.130:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.177.130:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.177.130:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.177.130:2379"
ETCD_INITIAL_CLUSTER="etcd-3=http://192.168.177.131:2380,etcd-1=http://192.168.177.129:2380,etcd-2=http://192.168.177.130:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
- os131 主机etcd的配置文件
cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-3"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.177.131:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.177.131:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.177.131:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.177.131:2379"
ETCD_INITIAL_CLUSTER="etcd-3=http://192.168.177.131:2380,etcd-1=http://192.168.177.129:2380,etcd-2=http://192.168.177.130:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
- systemd管理etcd, 三台主机都操作
cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl start etcd
systemctl enable etcd
- 查看etcd集群状态
/opt/etcd/bin/etcdctl --endpoints="http://192.168.177.129:2379,http://192.168.177.130:2379,http://192.168.177.131:2379" endpoint health
/opt/etcd/bin/etcdctl --endpoints="http://192.168.177.129:2379,http://192.168.177.130:2379,http://192.168.177.131:2379" member list
- 原minio集群节点配置etcd
cat > /etc/default/minio << EOF
MINIO_VOLUMES="http://192.168.177.{129...130}:9000/data/minio{1...4} "
MINIO_OPTS="--address 0.0.0.0:9000 --console-address 0.0.0.0:9001"
MINIO_ROOT_USER=minio
MINIO_ROOT_PASSWORD=minioadmin
MINIO_SERVER_URL="http://192.168.177.128:19000"
MINIO_ETCD_ENDPOINTS="http://192.168.177.131:2380,http://192.168.177.129:2380,http://192.168.177.130:2380"
MINIO_PUBLIC_IPS=192.168.177.129,192.168.177.130
MINIO_DOMAIN=domain.com
EOF
注意: MinIO_ETCD_ENDPOINTS参数需与搭建的ETCD集群所有节点IP相对应;MINIO_PUBLIC_IPS参数则为该集群的所有节点IP,如上述示例中对应集群的2个节点IP;MINIO_DOMAIN参数必须进行配置,即使你并不通过域名访问存储桶,否则联邦无法生效。
- 重启原集群两个minio 节点: systemctl restart minio;并创建bucket:test
- 查看etcd中注册的minio节点信息
/opt/etcd/bin/etcdctl --endpoints="http://192.168.177.129:2379,http://192.168.177.130:2379,http://192.168.177.131:2379" get --from-key /
/skydns/com/domain/test/192.168.177.129
{"host":"192.168.177.129","port":9000,"ttl":30,"creationDate":"2024-02-05T07:17:18.160138668Z"}
/skydns/com/domain/test/192.168.177.130
{"host":"192.168.177.130","port":9000,"ttl":30,"creationDate":"2024-02-05T07:17:18.160138668Z"}
- 扩展集群配置注册etcd
cat > /etc/default/minio << EOF
MINIO_VOLUMES="http://192.168.177.{131...132}:9000/data/minio{1...4} "
MINIO_OPTS="--address 0.0.0.0:9000 --console-address 0.0.0.0:9001"
MINIO_ROOT_USER=minio
MINIO_ROOT_PASSWORD=minioadmin
MINIO_SERVER_URL="http://192.168.177.128:19000"
MINIO_ETCD_ENDPOINTS="http://192.168.177.131:2380,http://192.168.177.129:2380,http://192.168.177.130:2380"
MINIO_PUBLIC_IPS=192.168.177.131,192.168.177.132
MINIO_DOMAIN=domain.com
EOF
- 重启扩展集群的minio节点: systemctl restart minio;并创建bucket:test-ext
- 查看etcd中注册的扩展集群minio节点信息
/opt/etcd/bin/etcdctl --endpoints="http://192.168.177.129:2379,http://192.168.177.130:2379,http://192.168.177.131:2379" get --from-key /
/skydns/com/domain/test-ext/192.168.177.131
{"host":"192.168.177.131","port":9000,"ttl":30,"creationDate":"2024-02-05T07:34:57.53833769Z"}
/skydns/com/domain/test-ext/192.168.177.132
{"host":"192.168.177.132","port":9000,"ttl":30,"creationDate":"2024-02-05T07:34:57.53833769Z"}
/skydns/com/domain/test/192.168.177.129
{"host":"192.168.177.129","port":9000,"ttl":30,"creationDate":"2024-02-05T07:17:18.160138668Z"}
/skydns/com/domain/test/192.168.177.130
{"host":"192.168.177.130","port":9000,"ttl":30,"creationDate":"2024-02-05T07:17:18.160138668Z"}
nginx负载均衡
- nginx 安装和配置
#关闭selinux(不然nginx 代理会报权限问题)与防火墙,
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
- 安装nginx
yum install nginx -y - minio 代理配置文件
cat > /etc/nginx/conf.d/minio.conf <<EOF
upstream minio_api {
server 192.168.177.129:9000;
server 192.168.177.130:9000;
server 192.168.177.131:9000;
server 192.168.177.132:9000;
}
upstream minio_console {
server 192.168.177.129:9001;
server 192.168.177.130:9001;
server 192.168.177.131:9001;
server 192.168.177.132:9001;
}
server{
listen 19000;
server_name 192.168.177.128;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
location / {
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header Host \$http_host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_connect_timeout 300;
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_ignore_client_abort on;
proxy_pass http://minio_api;
}
}
server{
listen 19001;
server_name 192.168.177.128;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
location / {
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header Host \$http_host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade" ;
proxy_connect_timeout 300;
chunked_transfer_encoding off;
proxy_ignore_client_abort on;
proxy_pass http://minio_console;
}
}
EOF
systemctl enable nginx
systemctl start nginx
- 修改所有minio节点/etc/default/minio 文件中 的MINIO_SERVER_URL
修改所有minio节点/etc/default/minio 文件中MINIO_SERVER_URL=“http://192.168.177.129:9000”
为负载均衡代理的地址MINIO_SERVER_URL=“http://192.168.177.128:19000” - 重启所有节点minio
- 使用nginx 代理访问minio控制台: http://192.168.177.128:19001
nginx代理使用文档: https://www.cnblogs.com/hztech/p/17134518.html
mc命令使用
#mc 命令Tab自动补全
mc --autocompletion
#设置minio存储服务
mc alias set minio http://192.168.177.128:19000 minio minioadmi
mc config host add minio http://192.168.177.128:19000 minio minioadmin
#查看minio存储服务有哪些存储桶
mc ls minio
# 创建桶
mc mb minio/test
# 拷贝本地文件到minio的test 存储桶下
mc cp localfile minio/test/
#查看集群状态
mc admin info minio
mc admin info --debug --json minio
#重启minio集群服务
mc admin service restart minio
#获取 MinIO 服务器/集群的整个服务器配置
mc admin config export minio > /tmp/my-serverconfig
#设置 MinIO 服务器/集群的整个服务器配置
mc admin config import minio < /tmp/my-serverconfig
Minio 监控
https://www.minio.org.cn/docs/minio/linux/operations/monitoring/collect-minio-metrics-using-prometheus.html#minio-metrics-collect-using-prometheus
mc admin prometheus generate ALIAS
官方文档: https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-multi-node-multi-drive.html?ref=docs-redirect