









以前使用 AWS S3 / Cloudflare R2 这些公有云产品时总放不开手脚,公开资源得套一层缓存来降低请求量,生怕账单被刷爆。对比几个开源 S3 兼容项目后,选择 Garage 的原因很简单,轻量够用,分布式设计以及针对高延迟场景优化,让节点走出大厂数据中心,可以到处「捡破烂」。
虽然也不是非得用 S3,重要数据每天都有自动任务备份,也没重要到没了就天塌了,主要图个紧跟时代浪潮,搭建自己的数据基石。
这里简单的记录下 Garage 安装及配置过程。
创建 garage.toml 配置文件,具体完整配置参考官方文档:
metadata_dir = "/var/lib/garage/meta" # 元数据存放目录
data_dir = "/var/lib/garage/data" # 对象数据存放目录
db_engine = "sqlite" # 可选 lmdb / sqlite / fjall
# metadata_auto_snapshot_interval = "6h" # 自动对元数据进行快照
replication_factor = 3 # 副本数量,单节点设置为 1
compression_level = 1 # zstd 压缩级别,默认 1,越低 CPU 开销越低
block_size = "1M" # 默认 1MB,如果存储大文件且网络较好可适当增加
rpc_bind_addr = "[::]:3901" # 集群 RPC 通信端口
rpc_public_addr = "127.0.0.1:3901" # 集群填公网 IP:3901
rpc_secret = "<RPC secret>" # RPC 通信密钥,`openssl rand -hex 32` 生成
[s3_api]
s3_region = "garage" # 自定义区域名
api_bind_addr = "[::]:3900"
root_domain = ".s3.example.com" # S3 API 访问根域名,<bucket>.s3.example.com
[s3_web]
bind_addr = "[::]:3902"
root_domain = ".web.example.com" # web 访问根域名,<bucket>.web.example.com
index = "index.html"
[admin]
api_bind_addr = "[::]:3903"
admin_token = "<admin token>" # 管理接口 Token,`openssl rand -base64 32` 生成
metrics_token = "<metrics token>" # 指标接口 Token,`openssl rand -base64 32` 生成
如果有前置 web server,可以把除 RPC 外的端口绑定在本地 localhost,通过反代访问提高安全性。两处 root_domain 的设置对应 bucket 的两种访问风格:
路径 (Path):root_domain 设置为 s3.example.com,访问地址:https://s3.amazonaws.com/<bucket>/<key>
虚拟主机 (Virtual Hosted) :root_domain 设置为 .s3.example.com,访问地址:https://<bucket>.s3.amazonaws.com/<key>
虽然公有云都在力推虚拟主机风格,例如 AWS 计划停止支持路径风格,但都是基于海量用户下的更高性能和安全需求。两种风格我都进行了测试,最后个人项目还是使用路径风格更方便,不需要额外申请一张 *.s3.example.com 证书,而且能避免一些潜在的问题,比如 bucket 名称中带 . 时会导致证书不匹配。
Garage 使用 Rust 开发,可以选择直接下载运行编译好的二进制文件,并通过 systemd 管理:
vim /etc/systemd/system/garage.service
[Unit]
Description=Garage Data Store
Documentation=https://garagehq.deuxfleurs.fr
After=network-online.target
Wants=network-online.target
StartLimitBurst=5
StartLimitIntervalSec=60
[Service]
User=garage
Group=garage
Environment='RUST_LOG=garage=info'
ExecStart=/path/to/garage -c /path/to/garage.toml server
Restart=on-failure
RestartSec=10
NoNewPrivileges=true
LimitNOFILE=42000
[Install]
WantedBy=multi-user.target
也可以简单的通过 Docker Compose 启动服务:
services:
garage:
image: dxflrs/garage:v2.2.0
container_name: garage
network_mode: host
environment:
- TZ=Asia/Shanghai
- RUST_LOG=garage=info
restart: unless-stopped
volumes:
- ./garage.toml:/etc/garage.toml
- ./meta:/var/lib/garage/meta
- ./data:/var/lib/garage/data
# ports:
# - 3900:3900
# - 3901:3901
# - 3902:3902
# - 3903:3903
设置一个别名来更方便的执行 Garage 命令,在 ~/.bashrc 中添加下面内容后 source ~/.bashrc:
alias garage="docker exec -it <container name> /garage"
# e.g. alias garage="docker exec -it garage /garage"
查看 Garage 当前状态:
如果使用了 UFW 防火墙和 Docker 容器端口映射,可能由于规则冲突导致无响应,可以简单的通过 ufw disable 关闭防火墙(不推荐)或者容器配置文件中 network_mode 使用 host 模式解决。
如果有多个节点,在每个节点上用相同的配置文件启动 Garage 后(注意 RPC Public IP 不同),依次添加其他节点,任意节点添加一次即可,会自动发现并同步到整个集群:
garage node connect <garage node id>
# 如果配置了 ufw 防火墙需要互相放行端口
# ufw allow from <node ip> to any port 3901
接下来为所有节点配置 layout:
garage status
garage layout assign <node id> -z <zone name> -c <storage capacity> -t <tag name>
# e.g. garage layout assign c66tu81zk2k2w1z8 -z dc1 -c 10g -t raspi
应用配置:
garage layout show
garage layout apply --version 1
如果后期修改了节点配置需要按提示使用更高的版本号。
首先创建一个名为 test-bucket 的存储桶:
garage bucket create test-bucket
# 查看 bucket 信息
garage bucket list
garage bucket info test-bucket
一个存储桶通过单个或多个 API key 管理,创建 API key 用来管理 test-bucket 桶:
garage key create test-key
# 查看 API key 信息:
garage key list
garage key info test-key
记得将 Key ID 和 Secret key 信息保存到安全的地方。赋予该 API key 对 test 桶的访问或管理权限:
garage bucket allow \
--read \
--write \
--owner \
test-bucket \
--key test-key
之后就可以使用 S3 API 兼容的工具 Rclone / CyberDuck 等连接到 Garage 进行管理了。比如使用 Rclone 连接,在配置文件 ~/.config/rclone/rclone.conf 中添加:
[garage]
type = s3
provider = Other
access_key_id = GKXXX
secret_access_key = xxxxxx
region = garage
endpoint = https://s3.example.com
# 如果是虚拟主机风格设置为 false
path_style_access = true
Garage 相对于 AWS S3 这些来说没有存储桶策略(Bucket Policy),如果要公开访问某一个桶,可以将其设置为网站模式:
garage bucket website --allow <bucket>
可以通过 Nginx 将 S3 API 更安全的反代出去:
server {
listen 443 ssl;
server_name s3.example.com;
...
location / {
client_max_body_size 0;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
proxy_max_temp_file_size 0;
proxy_pass http://127.0.0.1:3900;
}
}
如果使用虚拟主机风格,还需要解析 *.s3.example.com,存储桶网站模式的配置同理。推荐配置一些策略防止扫描或添加缓存,保证性能和后端安全性。
升级 Garage 前建议阅读更新文档说明,保证安全的升级。其中:
garage repair --all-nodes --yes tables 检查健康度,没问题的话逐个节点升级即可。garage meta snapshot --all ,复制备份 cluster_layout 文件后逐个升级。Garage 推荐 replication_factor 至少使用 3 副本策略来保障数据安全,此时如果 1 个可用区故障,集群依然可以正常读写;如果 2 个可用区故障,进入只读模式。因此当可用区发生故障时,建议尽快修复或者替换其他节点。
a. 如果某个节点数据盘损坏,但元数据 metadata 还在,只需要更换数据盘后挂载到原来的 data 目录,使用下面命令进行修复即可:
garage repair -a --yes blocks
b. 如果某个节点数据全丢无法恢复,或者单纯想换一个节点:
# 将新节点加入集群
# garage node connect <garage node id>
# garage status
garage layout assign <new node id> --replace <old node id> \
-z <zone name> -c <storage capacity> -t <tag name>
# -z <zone name> 和 -c <storage capacity> 需与旧节点保持一致
garage layout show
garage layout apply --version <new version>
两种情况都可以使用 garage stats -a 监控,等待 resync queue length 归零则表示迁移同步完毕。
如果你偏向于图形界面操作,可以使用开源的第三方工具 garage-webui 在网页上方便的查看服务状态,管理节点、存储桶、API key 和对象文件。官方也正在开发 garage-webadmin 项目,目前需要自行编译。
services:
garage:
...
webui:
image: khairul169/garage-webui:latest
container_name: garage-webui
restart: unless-stopped
volumes:
- ./garage.toml:/etc/garage.toml:ro
network_mode: host
environment:
# BASE_PATH: "/garage"
API_BASE_URL: "http://127.0.0.1:3903"
S3_ENDPOINT_URL: "http://127.0.0.1:3900"
# htpasswd -nbBC 10 "USERNAME" "PASSWORD"
# 生成的字符串中带 $ 特殊符号,可以用 $$ 转义或通过 .env 文件设置变量
# .env > GARAGE_UI_USER_PASS='test:$2y$10$2A4...'
AUTH_USER_PASS: ${GARAGE_UI_USER_PASS}
目前自建 Garage 使用了一周多,初步备份了一些文件,本站图片也迁移了上去,最大的感受是足够轻量,日常使用资源占用较低,在 1C1G 的 VPS 上也能良好运行。节点分布在海外三个不同的城市,同时 BOOM 的几率应该是 World War III 或者三体人入侵级别,作为一个从 2020 年开始维护至今的项目,有不少的用户,可靠性上应该没问题。
计划作为个人长期服务运行下去,只是如果后期数据量越来越多,需要同时扩容三个节点,成本也不算低。现在存储原厂们只做 AI 生意产能不足导致内存和硬盘价格飞涨,显得公有云对象存储服务都更有性价比了,不过 S3 兼容的好处是可进可退,只要价格到位,基石也是可以搬得动的。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。