跳转到内容

对象存储

对象存储是云计算中最基础的存储服务之一,以扁平化的键值方式存储数据,具有高可用、高扩展性和低成本的特点。AWS S3 协议已成为对象存储的事实标准,几乎所有云厂商(阿里云 OSS、腾讯云 COS、华为云 OBS)都提供 S3 兼容接口。

概念说明
Bucket(存储桶)对象的容器,全局唯一命名
Object(对象)存储的基本单元,包含数据和元数据
Key(键)对象在桶中的唯一标识,类似文件路径
Region(区域)桶所在的地理区域
ACL访问控制列表
Presigned URL带签名的临时访问链接
Terminal window
# 方法一:通过 pip 安装
sudo dnf install -y python3 python3-pip
pip3 install --user awscli
# 方法二:通过官方安装包
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo dnf install -y unzip
unzip awscliv2.zip
sudo ./aws/install
# 验证安装
aws --version
Terminal window
# 交互式配置
aws configure
# AWS Access Key ID: YOUR_ACCESS_KEY
# AWS Secret Access Key: YOUR_SECRET_KEY
# Default region name: ap-northeast-1
# Default output format: json
# 配置文件位于
cat ~/.aws/credentials
cat ~/.aws/config
# 使用 Named Profile 管理多个账号
aws configure --profile aliyun-oss

对于 S3 兼容服务(如阿里云 OSS),需要指定 endpoint:

Terminal window
# 阿里云 OSS
aws configure set default.s3.endpoint_url https://oss-cn-hangzhou.aliyuncs.com
# 或在每次命令中指定
aws s3 ls --endpoint-url https://oss-cn-hangzhou.aliyuncs.com
Terminal window
# 创建存储桶
aws s3 mb s3://my-backup-bucket
# 列出所有存储桶
aws s3 ls
# 列出桶中的内容
aws s3 ls s3://my-backup-bucket/
aws s3 ls s3://my-backup-bucket/logs/ --recursive
# 查看桶的大小统计
aws s3 ls s3://my-backup-bucket --recursive --summarize --human-readable
# 删除空桶
aws s3 rb s3://my-backup-bucket
# 删除桶及其所有内容
aws s3 rb s3://my-backup-bucket --force
Terminal window
# 上传单个文件
aws s3 cp /var/log/messages s3://my-backup-bucket/logs/messages
# 下载单个文件
aws s3 cp s3://my-backup-bucket/logs/messages /tmp/messages
# 上传整个目录
aws s3 cp /var/www/html/ s3://my-backup-bucket/website/ --recursive
# 下载整个目录
aws s3 cp s3://my-backup-bucket/website/ /var/www/html/ --recursive
# 使用排除和包含过滤
aws s3 cp /var/log/ s3://my-backup-bucket/logs/ \
--recursive \
--exclude "*" \
--include "*.log"

s3 sync 只传输有变化的文件,类似 rsync:

Terminal window
# 将本地目录同步到 S3
aws s3 sync /var/www/html/ s3://my-backup-bucket/website/
# 将 S3 同步到本地
aws s3 sync s3://my-backup-bucket/website/ /var/www/html/
# 同步并删除目标中多余的文件
aws s3 sync /var/www/html/ s3://my-backup-bucket/website/ --delete
# 排除特定文件
aws s3 sync /data/ s3://my-backup-bucket/data/ \
--exclude "*.tmp" \
--exclude ".git/*"
# 模拟运行(不实际传输)
aws s3 sync /data/ s3://my-backup-bucket/data/ --dryrun
Terminal window
# 移动文件
aws s3 mv s3://my-bucket/old-path/file.txt s3://my-bucket/new-path/file.txt
# 删除文件
aws s3 rm s3://my-backup-bucket/logs/old.log
# 递归删除
aws s3 rm s3://my-backup-bucket/logs/ --recursive
# 生成预签名 URL(有效期 3600 秒)
aws s3 presign s3://my-backup-bucket/files/report.pdf --expires-in 3600
# 设置对象 ACL
aws s3api put-object-acl \
--bucket my-backup-bucket \
--key public/image.png \
--acl public-read

MinIO 是一个高性能的 S3 兼容对象存储服务器,适合私有云和本地环境。

Terminal window
# 下载 MinIO 二进制文件
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/
# 创建数据目录
sudo mkdir -p /data/minio
# 创建 MinIO 系统用户
sudo useradd -r -s /sbin/nologin minio-user
sudo chown minio-user:minio-user /data/minio
Terminal window
sudo cat > /etc/default/minio << 'EOF'
# MinIO 数据目录
MINIO_VOLUMES="/data/minio"
# 管理员凭证
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=ChangeThisStrongPassword123
# 监听地址
MINIO_OPTS="--console-address :9001"
EOF
Terminal window
sudo cat > /etc/systemd/system/minio.service << 'EOF'
[Unit]
Description=MinIO Object Storage
Documentation=https://min.io/minio/linux/index.html
After=network-online.target
Wants=network-online.target
[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
Restart=always
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
# 启动 MinIO
sudo systemctl daemon-reload
sudo systemctl enable --now minio
# 查看状态
sudo systemctl status minio
Terminal window
# 开放 MinIO API 端口(9000)和控制台端口(9001)
sudo firewall-cmd --permanent --add-port=9000/tcp
sudo firewall-cmd --permanent --add-port=9001/tcp
sudo firewall-cmd --reload

MinIO 控制台访问地址:http://your-server-ip:9001

Terminal window
# 下载 mc 客户端
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/
# 配置连接到本地 MinIO
mc alias set local http://localhost:9000 minioadmin ChangeThisStrongPassword123
# 也可以配置连接到其他 S3 兼容服务
mc alias set myaws https://s3.amazonaws.com YOUR_ACCESS_KEY YOUR_SECRET_KEY
mc alias set aliyun https://oss-cn-hangzhou.aliyuncs.com YOUR_ACCESS_KEY YOUR_SECRET_KEY
# 验证连接
mc admin info local
Terminal window
# 创建存储桶
mc mb local/my-bucket
mc mb local/backups
# 列出桶
mc ls local
# 上传文件
mc cp /etc/hosts local/my-bucket/hosts
mc cp --recursive /var/log/ local/backups/logs/
# 下载文件
mc cp local/my-bucket/hosts /tmp/hosts-backup
# 同步目录
mc mirror /var/www/html/ local/my-bucket/website/
# 持续监听同步
mc mirror --watch /var/www/html/ local/my-bucket/website/
# 查看对象信息
mc stat local/my-bucket/hosts
# 设置桶策略
mc anonymous set download local/my-bucket/public/
# 管理用户
mc admin user add local newuser newpassword123
mc admin policy attach local readwrite --user newuser
# 查看服务信息
mc admin info local
Terminal window
# 在生产环境中,建议使用多磁盘实现纠删码保护
# 至少需要 4 块磁盘
sudo mkdir -p /data/minio-disk{1..4}
sudo chown minio-user:minio-user /data/minio-disk{1..4}
# 修改环境变量
sudo sed -i 's|MINIO_VOLUMES=.*|MINIO_VOLUMES="/data/minio-disk{1...4}"|' /etc/default/minio
# 重启服务
sudo systemctl restart minio

rclone 被称为”云存储的 rsync”,支持超过 70 种存储后端。

Terminal window
# 方法一:官方安装脚本
curl https://rclone.org/install.sh | sudo bash
# 方法二:手动安装
RCLONE_VERSION="1.67.0"
wget https://downloads.rclone.org/v${RCLONE_VERSION}/rclone-v${RCLONE_VERSION}-linux-amd64.rpm
sudo dnf install -y ./rclone-v${RCLONE_VERSION}-linux-amd64.rpm
# 验证
rclone version
Terminal window
# 交互式配置
rclone config
# 配置文件位于
cat ~/.config/rclone/rclone.conf

也可以直接编辑配置文件:

Terminal window
cat > ~/.config/rclone/rclone.conf << 'EOF'
[aws-s3]
type = s3
provider = AWS
access_key_id = YOUR_AWS_ACCESS_KEY
secret_access_key = YOUR_AWS_SECRET_KEY
region = ap-northeast-1
[aliyun-oss]
type = s3
provider = Alibaba
access_key_id = YOUR_ALICLOUD_ACCESS_KEY
secret_access_key = YOUR_ALICLOUD_SECRET_KEY
endpoint = oss-cn-hangzhou.aliyuncs.com
[tencent-cos]
type = s3
provider = TencentCOS
access_key_id = YOUR_TENCENT_SECRET_ID
secret_access_key = YOUR_TENCENT_SECRET_KEY
endpoint = cos.ap-guangzhou.myqcloud.com
[local-minio]
type = s3
provider = Minio
access_key_id = minioadmin
secret_access_key = ChangeThisStrongPassword123
endpoint = http://localhost:9000
EOF
Terminal window
# 列出所有配置的远端
rclone listremotes
# 列出桶
rclone lsd aws-s3:
# 列出桶内文件
rclone ls aws-s3:my-bucket/
rclone lsl aws-s3:my-bucket/ # 包含时间和大小
# 复制文件
rclone copy /var/log/messages aws-s3:my-bucket/logs/
# 复制目录
rclone copy /var/www/html/ aws-s3:my-bucket/website/ --progress
# 同步(镜像,会删除目标多余文件)
rclone sync /var/www/html/ aws-s3:my-bucket/website/ --progress
# 移动文件
rclone move /tmp/uploads/ aws-s3:my-bucket/uploads/
# 删除
rclone delete aws-s3:my-bucket/old-logs/
rclone purge aws-s3:my-bucket/temp-bucket/ # 删除路径及所有内容
Terminal window
# 从 AWS S3 复制到阿里云 OSS
rclone copy aws-s3:source-bucket/data/ aliyun-oss:dest-bucket/data/ --progress
# 从阿里云 OSS 同步到本地 MinIO
rclone sync aliyun-oss:my-bucket/ local-minio:backup-bucket/ --progress
# 对比两个远端的差异
rclone check aws-s3:my-bucket/ aliyun-oss:my-bucket/
Terminal window
# 带宽限制
rclone copy /data/ aws-s3:my-bucket/ --bwlimit 10M
# 加密存储(创建加密远端)
rclone config
# 选择 "crypt" 类型,指定底层远端
# 挂载为本地文件系统
sudo dnf install -y fuse3
rclone mount aws-s3:my-bucket /mnt/s3 --daemon --allow-other --vfs-cache-mode full
# 以服务方式运行挂载
cat > ~/.config/systemd/user/rclone-mount.service << 'UNIT'
[Unit]
Description=rclone S3 mount
After=network-online.target
[Service]
ExecStart=/usr/bin/rclone mount aws-s3:my-bucket /mnt/s3 --allow-other --vfs-cache-mode full
ExecStop=/bin/fusermount -uz /mnt/s3
Restart=on-failure
[Install]
WantedBy=default.target
UNIT
systemctl --user enable --now rclone-mount
# 查看远端使用空间
rclone about aws-s3:
/usr/local/bin/backup-db.sh
#!/bin/bash
# MySQL/MariaDB 备份到对象存储
set -euo pipefail
# 配置
BACKUP_DIR="/tmp/db-backup"
BUCKET="s3://my-backup-bucket/database"
DB_NAME="myapp"
DATE=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=30
# 创建临时目录
mkdir -p "${BACKUP_DIR}"
# 执行备份
echo "[$(date)] 开始备份数据库 ${DB_NAME}..."
mysqldump --single-transaction \
--routines \
--triggers \
--databases "${DB_NAME}" | \
gzip > "${BACKUP_DIR}/${DB_NAME}-${DATE}.sql.gz"
# 上传到对象存储
echo "[$(date)] 上传备份到对象存储..."
aws s3 cp "${BACKUP_DIR}/${DB_NAME}-${DATE}.sql.gz" \
"${BUCKET}/${DB_NAME}-${DATE}.sql.gz"
# 清理本地临时文件
rm -f "${BACKUP_DIR}/${DB_NAME}-${DATE}.sql.gz"
# 清理远端过期备份
echo "[$(date)] 清理 ${RETENTION_DAYS} 天前的备份..."
CUTOFF_DATE=$(date -d "-${RETENTION_DAYS} days" +%Y%m%d)
aws s3 ls "${BUCKET}/" | while read -r line; do
FILE_DATE=$(echo "$line" | grep -oP '\d{8}' | head -1)
FILE_NAME=$(echo "$line" | awk '{print $NF}')
if [[ -n "${FILE_DATE}" && "${FILE_DATE}" < "${CUTOFF_DATE}" ]]; then
echo " 删除过期备份: ${FILE_NAME}"
aws s3 rm "${BUCKET}/${FILE_NAME}"
fi
done
echo "[$(date)] 备份完成"
/usr/local/bin/backup-files.sh
#!/bin/bash
# 使用 rclone 增量备份到对象存储
set -euo pipefail
REMOTE="aliyun-oss"
BUCKET="server-backups"
HOSTNAME=$(hostname)
LOG_FILE="/var/log/backup-files.log"
echo "[$(date)] 开始文件备份..." >> "${LOG_FILE}"
# 同步配置文件
rclone sync /etc/ "${REMOTE}:${BUCKET}/${HOSTNAME}/etc/" \
--exclude "shadow" \
--exclude "gshadow" \
--log-file="${LOG_FILE}" \
--log-level INFO
# 同步网站数据
rclone sync /var/www/ "${REMOTE}:${BUCKET}/${HOSTNAME}/www/" \
--log-file="${LOG_FILE}" \
--log-level INFO
# 同步用户数据
rclone sync /home/ "${REMOTE}:${BUCKET}/${HOSTNAME}/home/" \
--exclude ".cache/**" \
--exclude ".local/share/Trash/**" \
--log-file="${LOG_FILE}" \
--log-level INFO
echo "[$(date)] 备份完成" >> "${LOG_FILE}"
Terminal window
# 设置数据库每日备份
sudo chmod +x /usr/local/bin/backup-db.sh
sudo cat > /etc/cron.d/db-backup << 'EOF'
# 每天凌晨 2 点执行数据库备份
0 2 * * * root /usr/local/bin/backup-db.sh >> /var/log/backup-db.log 2>&1
EOF
# 设置文件每日增量备份
sudo chmod +x /usr/local/bin/backup-files.sh
sudo cat > /etc/cron.d/file-backup << 'EOF'
# 每天凌晨 3 点执行文件备份
0 3 * * * root /usr/local/bin/backup-files.sh
EOF

对于 AWS S3 或兼容服务,可以配置生命周期策略自动清理旧备份:

Terminal window
# 创建生命周期规则配置
cat > /tmp/lifecycle.json << 'EOF'
{
"Rules": [
{
"ID": "DeleteOldBackups",
"Status": "Enabled",
"Filter": {
"Prefix": "database/"
},
"Expiration": {
"Days": 30
}
},
{
"ID": "ArchiveOldFiles",
"Status": "Enabled",
"Filter": {
"Prefix": "files/"
},
"Transitions": [
{
"Days": 90,
"StorageClass": "GLACIER"
}
],
"Expiration": {
"Days": 365
}
}
]
}
EOF
# 应用生命周期策略
aws s3api put-bucket-lifecycle-configuration \
--bucket my-backup-bucket \
--lifecycle-configuration file:///tmp/lifecycle.json

对象存储是云时代的基础存储方案。掌握 AWS CLI、MinIO 和 rclone 这几个工具后,可以灵活地在公有云、私有云和混合云环境中管理数据,并构建可靠的备份策略。