Files
woodpecker-rustfs/mc
2025-10-12 19:10:34 +08:00
..
2025-10-12 19:10:34 +08:00
2025-10-12 19:10:34 +08:00
2025-10-12 19:10:34 +08:00

MinIO Client (mc) 使用指南

本目录包含在 Woodpecker CI 中使用 MinIO Client (mc) 操作 RustFS/S3 对象存储的完整示例。

📋 目录


mc 简介

MinIO Client (mc) 是一个功能强大的命令行工具,用于操作 S3 兼容的对象存储服务。

为什么选择 mc

功能全面: 支持上传、下载、删除、同步、生成临时链接等
跨平台: 支持 Linux、macOS、Windows
兼容性好: 完全兼容 S3 API 和 RustFS
易于使用: 命令简洁,类似传统的文件操作命令
可验证: 可获取 ETag、VersionId 等元数据
支持预签名: 可生成无需认证的临时下载链接


目录结构

mc/
├── README.md                 # 本文档
├── linux/
│   └── woodpecker.yml       # Linux 环境完整示例
└── macos/
    └── woodpecker.yml       # macOS 环境完整示例

快速开始

安装 mc

Linux:

curl -sSL https://dl.min.io/client/mc/release/linux-amd64/mc \
  -o /usr/local/bin/mc
chmod +x /usr/local/bin/mc

macOS (Intel):

curl -sSL https://dl.min.io/client/mc/release/darwin-amd64/mc \
  -o /usr/local/bin/mc
chmod +x /usr/local/bin/mc

macOS (Apple Silicon):

curl -sSL https://dl.min.io/client/mc/release/darwin-arm64/mc \
  -o /usr/local/bin/mc
chmod +x /usr/local/bin/mc

配置 mc 别名

# 配置 RustFS 连接
mc alias set rustfs https://your-rustfs-server:9000 YOUR_ACCESS_KEY YOUR_SECRET_KEY

# 验证配置
mc admin info rustfs

常用功能

上传文件

上传单个文件

mc cp local-file.txt rustfs/my-bucket/path/remote-file.txt

上传整个目录

mc cp --recursive ./dist/ rustfs/my-bucket/website/

上传时删除源路径前缀

# 将 dist/css/style.css 上传为 css/style.css
mc mirror --overwrite ./dist/ rustfs/my-bucket/website/

上传并获取 ETag

mc cp myfile.jar rustfs/my-bucket/builds/
mc stat rustfs/my-bucket/builds/myfile.jar | grep ETag

下载文件

下载单个文件

mc cp rustfs/my-bucket/path/file.txt ./local-file.txt

下载整个目录

mc cp --recursive rustfs/my-bucket/backup/ ./local-backup/

下载最新版本

mc cp rustfs/my-bucket/versioned-file.txt ./

列举文件

列出 bucket 内容

# 列出顶层文件
mc ls rustfs/my-bucket/

# 递归列出所有文件
mc ls --recursive rustfs/my-bucket/

# 列出并显示详细信息
mc ls --recursive --summarize rustfs/my-bucket/

按时间过滤

# 列出最近 7 天修改的文件
mc ls --recursive --newer-than 7d rustfs/my-bucket/

# 列出 30 天前的文件
mc ls --recursive --older-than 30d rustfs/my-bucket/

删除文件

删除单个文件

mc rm rustfs/my-bucket/path/file.txt

删除整个目录

mc rm --recursive --force rustfs/my-bucket/old-builds/

按时间删除

# 删除 30 天前的文件
mc rm --recursive --force --older-than 30d rustfs/my-bucket/builds/

# 删除 7 天前的日志
mc rm --recursive --force --older-than 7d rustfs/my-bucket/logs/

按模式删除

# 删除所有 .log 文件
mc rm --recursive --force rustfs/my-bucket/logs/*.log

# 删除特定日期的构建
mc rm --recursive --force rustfs/my-bucket/builds/20241001/

生成临时下载链接

基本用法(默认 7 天有效期)

mc share download rustfs/my-bucket/path/file.jar

输出示例:

URL: https://your-server:9000/my-bucket/path/file.jar?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...
Expire: 7 days 0 hours 0 minutes 0 seconds
Share: https://your-server:9000/my-bucket/path/file.jar?X-Amz-Algorithm=...

自定义有效期

按小时
# 1 小时
mc share download --expire 1h rustfs/my-bucket/file.jar

# 6 小时
mc share download --expire 6h rustfs/my-bucket/file.jar

# 24 小时1天
mc share download --expire 24h rustfs/my-bucket/file.jar
按天
# 1 天
mc share download --expire 1d rustfs/my-bucket/file.jar

# 3 天
mc share download --expire 3d rustfs/my-bucket/file.jar

# 7 天(最大值)
mc share download --expire 7d rustfs/my-bucket/file.jar

# 14 天(如果服务器支持)
mc share download --expire 14d rustfs/my-bucket/file.jar
按分钟(短期分享)
# 30 分钟
mc share download --expire 30m rustfs/my-bucket/temp-file.txt

# 5 分钟(快速分享)
mc share download --expire 5m rustfs/my-bucket/quick-share.pdf

批量生成链接

# 为目录下所有文件生成链接
mc ls rustfs/my-bucket/releases/ | awk '{print $NF}' | while read file; do
  echo "Generating link for: $file"
  mc share download --expire 7d rustfs/my-bucket/releases/$file
done

生成链接并保存

# 保存到文件
mc share download --expire 7d rustfs/my-bucket/app.jar > download-link.txt

# 提取纯 URL
mc share download --expire 7d rustfs/my-bucket/app.jar | grep "Share:" | awk '{print $2}'

设置公开访问

设置 bucket 为公开可读(永久链接)

# 公开整个 bucket
mc anonymous set download rustfs/my-bucket/

# 公开特定路径
mc anonymous set download rustfs/my-bucket/public/

# 取消公开访问
mc anonymous set none rustfs/my-bucket/

公开访问后的 URL 格式:

https://your-server:9000/my-bucket/path/file.jar

不需要签名参数,可直接访问。


清理旧文件

按时间自动清理

# 清理 30 天前的构建
mc rm --recursive --force --older-than 30d rustfs/my-bucket/builds/

# 清理 7 天前的日志
mc rm --recursive --force --older-than 7d rustfs/my-bucket/logs/

# 清理 90 天前的备份
mc rm --recursive --force --older-than 90d rustfs/my-bucket/backups/

保留最近 N 个版本

# 列出文件按时间排序
mc ls --recursive rustfs/my-bucket/releases/ | sort -k1,1 -r | tail -n +11 | awk '{print $NF}' | while read file; do
  mc rm rustfs/my-bucket/releases/$file
done

临时链接详解

临时链接的工作原理

临时下载链接(预签名 URL使用 AWS Signature V4 算法生成,包含:

  • 访问凭证(已签名)
  • 过期时间戳
  • 请求参数的签名

优势:

  • 无需认证即可下载
  • 可设置精确的过期时间
  • 可分享给任何人
  • 自动过期,安全可控

有效期时间单位

单位 说明 示例
m 分钟 (minutes) 30m = 30分钟
h 小时 (hours) 6h = 6小时
d 天 (days) 7d = 7天

有效期限制

  • 最小值: 1 分钟 (1m)
  • 默认值: 7 天 (7d)
  • 最大值: 取决于 S3 服务器配置(通常为 7 天)

常见使用场景

场景 1: 内部快速分享(短期)

# 5分钟有效用于即时分享
mc share download --expire 5m rustfs/bucket/temp-file.zip

场景 2: 客户下载(中期)

# 24小时有效给客户足够时间下载
mc share download --expire 24h rustfs/bucket/client-delivery.zip

场景 3: 归档访问(长期)

# 7天有效用于归档文件的临时访问
mc share download --expire 7d rustfs/bucket/archive/report.pdf

场景 4: 公开发布(永久)

# 不设置过期时间,使用公开访问
mc anonymous set download rustfs/bucket/public/
# 现在可以直接访问: https://server/bucket/public/file.jar

命令速查表

文件操作

操作 命令
上传文件 mc cp file.txt rustfs/bucket/
上传目录 mc cp --recursive ./dir/ rustfs/bucket/
下载文件 mc cp rustfs/bucket/file.txt ./
下载目录 mc cp --recursive rustfs/bucket/dir/ ./
删除文件 mc rm rustfs/bucket/file.txt
删除目录 mc rm --recursive --force rustfs/bucket/dir/
列出文件 mc ls rustfs/bucket/
递归列出 mc ls --recursive rustfs/bucket/
查看信息 mc stat rustfs/bucket/file.txt

临时链接

操作 命令
生成链接默认7天 mc share download rustfs/bucket/file.jar
1小时有效 mc share download --expire 1h rustfs/bucket/file.jar
1天有效 mc share download --expire 1d rustfs/bucket/file.jar
7天有效 mc share download --expire 7d rustfs/bucket/file.jar
30分钟有效 mc share download --expire 30m rustfs/bucket/file.jar

清理操作

操作 命令
删除30天前文件 mc rm --recursive --older-than 30d rustfs/bucket/
删除7天前文件 mc rm --recursive --older-than 7d rustfs/bucket/
删除所有.log mc rm --recursive rustfs/bucket/*.log
强制删除 mc rm --recursive --force rustfs/bucket/dir/

权限操作

操作 命令
设置公开下载 mc anonymous set download rustfs/bucket/
设置公开上传 mc anonymous set upload rustfs/bucket/
设置公开读写 mc anonymous set public rustfs/bucket/
取消公开访问 mc anonymous set none rustfs/bucket/
查看权限 mc anonymous get rustfs/bucket/

最佳实践

1. 密钥管理

# ✅ 使用 Woodpecker Secrets
environment:
  AWS_ACCESS_KEY_ID:
    from_secret: AWS_ACCESS_KEY_ID
  AWS_SECRET_ACCESS_KEY:
    from_secret: AWS_SECRET_ACCESS_KEY

# ❌ 不要硬编码密钥
environment:
  AWS_ACCESS_KEY_ID: "AKIAIOSFODNN7EXAMPLE"

2. 错误处理

set -e  # 遇到错误立即退出

# 上传并验证
mc cp file.jar rustfs/bucket/
if mc stat rustfs/bucket/file.jar &>/dev/null; then
  echo "✅ Upload successful"
else
  echo "❌ Upload failed"
  exit 1
fi

3. 按日期组织

# 按日期创建目录
BUILD_DATE=$(date +%Y%m%d)
mc cp dist/ rustfs/bucket/builds/${BUILD_DATE}/

4. 定期清理

# 在 CI 中定期清理旧构建
mc rm --recursive --older-than 30d rustfs/bucket/builds/

5. 生成有意义的链接

# 保存链接到文件,方便分享
BUILD_ID=${CI_PIPELINE_NUMBER}
mc share download --expire 7d rustfs/bucket/app-${BUILD_ID}.jar > download-${BUILD_ID}.txt

6. 验证上传

# 上传后获取 ETag 验证完整性
mc cp file.jar rustfs/bucket/
ETAG=$(mc stat rustfs/bucket/file.jar | grep ETag | awk '{print $2}')
echo "File uploaded with ETag: $ETAG"

使用示例

示例 1: 上传并生成下载链接

#!/bin/bash
set -e

# 配置
mc alias set rustfs https://s3.example.com:9000 $ACCESS_KEY $SECRET_KEY

# 上传文件
mc cp myapp.jar rustfs/releases/v1.0.0/myapp.jar

# 生成 24 小时有效的下载链接
DOWNLOAD_LINK=$(mc share download --expire 24h rustfs/releases/v1.0.0/myapp.jar | grep Share | awk '{print $2}')

echo "✅ 上传成功!"
echo "📥 下载链接: $DOWNLOAD_LINK"
echo "⏰ 有效期: 24 小时"

示例 2: 清理旧构建并保留最新 10 个

#!/bin/bash
set -e

mc alias set rustfs https://s3.example.com:9000 $ACCESS_KEY $SECRET_KEY

# 列出所有构建,按时间排序,删除 30 天前的
echo "🧹 清理旧构建..."
mc rm --recursive --older-than 30d rustfs/builds/

# 统计剩余构建数
REMAINING=$(mc ls --recursive rustfs/builds/ | wc -l)
echo "✅ 清理完成,剩余 $REMAINING 个构建"

示例 3: 批量生成下载链接

#!/bin/bash
set -e

mc alias set rustfs https://s3.example.com:9000 $ACCESS_KEY $SECRET_KEY

echo "# 下载链接汇总" > links.md
echo "生成时间: $(date)" >> links.md
echo "" >> links.md

# 为 releases 目录下所有文件生成链接
mc ls rustfs/releases/ | awk '{print $NF}' | while read file; do
  LINK=$(mc share download --expire 7d rustfs/releases/$file | grep Share | awk '{print $2}')
  echo "- [$file]($LINK)" >> links.md
done

echo "✅ 链接汇总已保存到 links.md"

参考资源


故障排查

问题 1: mc 命令未找到

# 重新安装
curl -sSL https://dl.min.io/client/mc/release/linux-amd64/mc -o /usr/local/bin/mc
chmod +x /usr/local/bin/mc

问题 2: 连接失败

# 检查别名配置
mc alias list

# 重新配置
mc alias set rustfs https://your-server:9000 ACCESS_KEY SECRET_KEY

# 测试连接
mc admin info rustfs

问题 3: 权限被拒绝

# 检查访问密钥是否正确
mc admin user info rustfs ACCESS_KEY

# 验证 bucket 权限
mc anonymous get rustfs/bucket/

问题 4: 临时链接无法访问

# 检查链接是否过期
# 重新生成链接
mc share download --expire 1d rustfs/bucket/file.jar

# 或设置为公开访问
mc anonymous set download rustfs/bucket/

最后更新: 2025-10-12
维护者: RustFS Team