核心命令:
mc mirror,对标 rsync,用于目录 / 桶镜像同步;mc cp --recursive仅增量复制,不会删除目标多余对象MinIO 场景:本地目录 ↔ MinIO 桶、MinIO 桶 A ↔ MinIO 桶 B(跨集群同步)
前置准备:安装 mc
# AMD64
wget https://dl.min.io/client/mc/release/linux-amd64/mc -O /usr/local/bin/mc
chmod +x /usr/local/bin/mc
# ARM64
wget https://dl.min.io/client/mc/release/linux-arm64/mc -O /usr/local/bin/mc
chmod +x /usr/local/bin/mc
# 验证
mc --version
脚本 1:本地目录同步到 MinIO 桶(基础镜像脚本,推荐定时任务)
--remove:危险! 目标桶中源不存在的对象会被删除,做镜像才开;初次测试务必加--dry-run试运行,不真实上传 / 删除MinIO
#!/bin/bash
# file: sync_local_to_minio.sh
set -euo pipefail
######################## 配置区 ########################
# MinIO别名(自定义名称)
MINIO_ALIAS="myminio"
# MinIO端点
MINIO_ENDPOINT="http://127.0.0.1:9000"
MINIO_ACCESS_KEY="minioadmin"
MINIO_SECRET_KEY="minioadmin"
# 本地源目录
SRC_LOCAL="/data/source_files"
# MinIO目标桶(桶必须提前建好 mc mb myminio/mybucket)
DST_BUCKET="${MINIO_ALIAS}/mybucket"
# 日志文件
LOG_FILE="/var/log/minio_sync.log"
# 是否开启镜像删除目标多余文件 true/false
ENABLE_REMOVE="false"
########################################################
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${LOG_FILE}"
}
log "===== 开始同步任务 ====="
# 检查mc是否存在
if ! command -v mc &> /dev/null; then
log "ERROR: mc 客户端未找到,请先安装 minio mc"
exit 1
fi
# 检查本地源目录
if [ ! -d "${SRC_LOCAL}" ];then
log "ERROR: 源目录 ${SRC_LOCAL} 不存在"
exit 1
fi
# 设置minio别名;+o history 防止密钥写入bash历史
set +o history
mc alias set "${MINIO_ALIAS}" "${MINIO_ENDPOINT}" "${MINIO_ACCESS_KEY}" "${MINIO_SECRET_KEY}"
set -o history
# 校验连通性
if ! mc ls "${MINIO_ALIAS}" &>/dev/null; then
log "ERROR: MinIO 连接失败,请检查地址/密钥"
exit 1
fi
# 构建mc mirror参数
MIRROR_ARGS=("--overwrite" "--retry" "3")
if [ "${ENABLE_REMOVE}" = "true" ];then
MIRROR_ARGS+=("--remove")
fi
# 先试运行 dry-run(初次调试打开)
log "【试运行预览】mc mirror --dry-run ${MIRROR_ARGS[*]} ${SRC_LOCAL} ${DST_BUCKET}"
mc mirror --dry-run "${MIRROR_ARGS[@]}" "${SRC_LOCAL}" "${DST_BUCKET}"
# 正式同步(注释下面一行,只跑dry-run测试)
log "开始正式同步..."
mc mirror "${MIRROR_ARGS[@]}" "${SRC_LOCAL}" "${DST_BUCKET}"
RET=$?
if [ ${RET} -eq 0 ];then
log "同步任务执行成功"
else
log "ERROR: 同步失败,返回码:${RET}"
fi
log "===== 任务结束 ====="
exit ${RET}
脚本 2:MinIO 桶 A 同步到 MinIO 桶 B(跨桶 / 跨集群镜像)
#!/bin/bash
# sync_minio_to_minio.sh
set -euo pipefail
# 源MinIO
SRC_ALIAS="src-minio"
SRC_ENDPOINT="http://10.0.0.1:9000"
SRC_AK="xxx"
SRC_SK="xxx"
SRC_PATH="${SRC_ALIAS}/bucket-src"
# 目标MinIO
DST_ALIAS="dst-minio"
DST_ENDPOINT="http://10.0.0.2:9000"
DST_AK="yyy"
DST_SK="yyy"
DST_PATH="${DST_ALIAS}/bucket-dst"
LOG="/var/log/minio_bucket_sync.log"
log(){
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG}
}
# 配置两个minio别名
set +o history
mc alias set ${SRC_ALIAS} ${SRC_ENDPOINT} ${SRC_AK} ${SRC_SK}
mc alias set ${DST_ALIAS} ${DST_ENDPOINT} ${DST_AK} ${DST_SK}
set -o history
log "跨桶镜像同步,试运行:"
mc mirror --dry-run --overwrite --retry 3 ${SRC_PATH} ${DST_PATH}
# 正式同步,开启--remove代表镜像(目标删除源不存在对象)
# mc mirror --overwrite --retry 3 --remove ${SRC_PATH} ${DST_PATH}
log "done"
脚本 3:简单增量上传(mc cp --recursive,不删除目标文件)
适合备份场景,只新增 / 覆盖,不会清理旧对象
#!/bin/bash
SRC="/data/files"
DST="myminio/backup-bucket"
LOG="/var/log/minio_cp_sync.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG}; }
mc alias set myminio http://127.0.0.1:9000 minioadmin minioadmin
log "开始增量上传"
mc cp --recursive --overwrite "${SRC}/" "${DST}/"
if [ $? -eq 0 ];then
log "上传成功"
else
log "上传失败"
fi
mc mirror 常用参数说明
表格
定时任务 crontab 示例
# 每天凌晨2点执行本地同步脚本
0 2 * * * /bin/bash /opt/scripts/sync_local_to_minio.sh >> /var/log/minio_cron.log 2>&1
安全与坑点
--remove是高危参数:首次上线一定先用--dry-run预览,确认删除列表符合预期再启用密钥不要明文写脚本?可以改用环境变量方式:
export MC_HOST_myminio=http://minioadmin:minioadmin@127.0.0.1:9000
# 之后直接 mc mirror /data myminio/mybucket,不需要mc alias set
mc mirror同步不复制对象版本;如果需要桶版本复制,用服务端桶复制mc replicate add,不是客户端 mirrorMinIO大文件:mc 自动分块上传,断点续传
日志轮转:
logrotate配置对/var/log/minio_sync.log做切割,防止日志持续膨胀
本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问