# MinIO Client (mc) 使用指南 本目录包含在 Woodpecker CI 中使用 MinIO Client (mc) 操作 RustFS/S3 对象存储的完整示例。 ## 📋 目录 - [mc 简介](#mc-简介) - [目录结构](#目录结构) - [快速开始](#快速开始) - [常用功能](#常用功能) - [上传文件](#上传文件) - [下载文件](#下载文件) - [列举文件](#列举文件) - [删除文件](#删除文件) - [生成临时下载链接](#生成临时下载链接) - [设置公开访问](#设置公开访问) - [清理旧文件](#清理旧文件) - [临时链接详解](#临时链接详解) - [命令速查表](#命令速查表) - [最佳实践](#最佳实践) --- ## 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:** ```bash 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):** ```bash 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):** ```bash curl -sSL https://dl.min.io/client/mc/release/darwin-arm64/mc \ -o /usr/local/bin/mc chmod +x /usr/local/bin/mc ``` ### 配置 mc 别名 ```bash # 配置 RustFS 连接 mc alias set rustfs https://your-rustfs-server:9000 YOUR_ACCESS_KEY YOUR_SECRET_KEY # 验证配置 mc admin info rustfs ``` --- ## 常用功能 ### 上传文件 #### 上传单个文件 ```bash mc cp local-file.txt rustfs/my-bucket/path/remote-file.txt ``` #### 上传整个目录 ```bash mc cp --recursive ./dist/ rustfs/my-bucket/website/ ``` #### 上传时删除源路径前缀 ```bash # 将 dist/css/style.css 上传为 css/style.css mc mirror --overwrite ./dist/ rustfs/my-bucket/website/ ``` #### 上传并获取 ETag ```bash mc cp myfile.jar rustfs/my-bucket/builds/ mc stat rustfs/my-bucket/builds/myfile.jar | grep ETag ``` --- ### 下载文件 #### 下载单个文件 ```bash mc cp rustfs/my-bucket/path/file.txt ./local-file.txt ``` #### 下载整个目录 ```bash mc cp --recursive rustfs/my-bucket/backup/ ./local-backup/ ``` #### 下载最新版本 ```bash mc cp rustfs/my-bucket/versioned-file.txt ./ ``` --- ### 列举文件 #### 列出 bucket 内容 ```bash # 列出顶层文件 mc ls rustfs/my-bucket/ # 递归列出所有文件 mc ls --recursive rustfs/my-bucket/ # 列出并显示详细信息 mc ls --recursive --summarize rustfs/my-bucket/ ``` #### 按时间过滤 ```bash # 列出最近 7 天修改的文件 mc ls --recursive --newer-than 7d rustfs/my-bucket/ # 列出 30 天前的文件 mc ls --recursive --older-than 30d rustfs/my-bucket/ ``` --- ### 删除文件 #### 删除单个文件 ```bash mc rm rustfs/my-bucket/path/file.txt ``` #### 删除整个目录 ```bash mc rm --recursive --force rustfs/my-bucket/old-builds/ ``` #### 按时间删除 ```bash # 删除 30 天前的文件 mc rm --recursive --force --older-than 30d rustfs/my-bucket/builds/ # 删除 7 天前的日志 mc rm --recursive --force --older-than 7d rustfs/my-bucket/logs/ ``` #### 按模式删除 ```bash # 删除所有 .log 文件 mc rm --recursive --force rustfs/my-bucket/logs/*.log # 删除特定日期的构建 mc rm --recursive --force rustfs/my-bucket/builds/20241001/ ``` --- ### 生成临时下载链接 #### 基本用法(默认 7 天有效期) ```bash 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=... ``` #### 自定义有效期 ##### 按小时 ```bash # 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 ``` ##### 按天 ```bash # 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 ``` ##### 按分钟(短期分享) ```bash # 30 分钟 mc share download --expire 30m rustfs/my-bucket/temp-file.txt # 5 分钟(快速分享) mc share download --expire 5m rustfs/my-bucket/quick-share.pdf ``` #### 批量生成链接 ```bash # 为目录下所有文件生成链接 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 ``` #### 生成链接并保存 ```bash # 保存到文件 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 为公开可读(永久链接) ```bash # 公开整个 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 ``` 不需要签名参数,可直接访问。 --- ### 清理旧文件 #### 按时间自动清理 ```bash # 清理 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 个版本 ```bash # 列出文件按时间排序 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: 内部快速分享(短期) ```bash # 5分钟有效,用于即时分享 mc share download --expire 5m rustfs/bucket/temp-file.zip ``` #### 场景 2: 客户下载(中期) ```bash # 24小时有效,给客户足够时间下载 mc share download --expire 24h rustfs/bucket/client-delivery.zip ``` #### 场景 3: 归档访问(长期) ```bash # 7天有效,用于归档文件的临时访问 mc share download --expire 7d rustfs/bucket/archive/report.pdf ``` #### 场景 4: 公开发布(永久) ```bash # 不设置过期时间,使用公开访问 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. 密钥管理 ```yaml # ✅ 使用 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. 错误处理 ```bash 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. 按日期组织 ```bash # 按日期创建目录 BUILD_DATE=$(date +%Y%m%d) mc cp dist/ rustfs/bucket/builds/${BUILD_DATE}/ ``` ### 4. 定期清理 ```bash # 在 CI 中定期清理旧构建 mc rm --recursive --older-than 30d rustfs/bucket/builds/ ``` ### 5. 生成有意义的链接 ```bash # 保存链接到文件,方便分享 BUILD_ID=${CI_PIPELINE_NUMBER} mc share download --expire 7d rustfs/bucket/app-${BUILD_ID}.jar > download-${BUILD_ID}.txt ``` ### 6. 验证上传 ```bash # 上传后获取 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: 上传并生成下载链接 ```bash #!/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 个 ```bash #!/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: 批量生成下载链接 ```bash #!/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" ``` --- ## 参考资源 - [MinIO Client 完整文档](https://min.io/docs/minio/linux/reference/minio-mc.html) - [mc GitHub 仓库](https://github.com/minio/mc) - [RustFS 文档](https://docs.rustfs.com) - [AWS S3 API 参考](https://docs.aws.amazon.com/s3/) --- ## 故障排查 ### 问题 1: mc 命令未找到 ```bash # 重新安装 curl -sSL https://dl.min.io/client/mc/release/linux-amd64/mc -o /usr/local/bin/mc chmod +x /usr/local/bin/mc ``` ### 问题 2: 连接失败 ```bash # 检查别名配置 mc alias list # 重新配置 mc alias set rustfs https://your-server:9000 ACCESS_KEY SECRET_KEY # 测试连接 mc admin info rustfs ``` ### 问题 3: 权限被拒绝 ```bash # 检查访问密钥是否正确 mc admin user info rustfs ACCESS_KEY # 验证 bucket 权限 mc anonymous get rustfs/bucket/ ``` ### 问题 4: 临时链接无法访问 ```bash # 检查链接是否过期 # 重新生成链接 mc share download --expire 1d rustfs/bucket/file.jar # 或设置为公开访问 mc anonymous set download rustfs/bucket/ ``` --- **最后更新**: 2025-10-12 **维护者**: RustFS Team