Garage v2.4.1 快速入门(集群初始化与 S3 实测)

从零完成 Garage v2.4.1 的集群初始化与 S3 全链路实测,覆盖 layout 分配与应用、bucket 创建、访问密钥签发与授权、AWS CLI 上传下载删除校验、Admin API 调用与典型报错定位

GarageGarage对象存储S3 兼容Linux2026/10/17

Garage v2.4.1 快速入门(集群初始化与 S3 实测)

目标:在已装好 Garage v2.4.1 的 Ubuntu 22.04 服务器上,完成从集群初始化到 S3 业务可用的全链路操作——layout 角色分配与应用、bucket 创建、访问密钥签发与授权、AWS CLI 上传/下载/删除/校验、Admin API 调用,并沉淀每一步的真实回显与报错定位。安装过程见《Garage v2.4.1 Ubuntu 22.04 安装指南》,本文假设二进制与 systemd 服务已就绪。

一、环境信息

本文所有命令与回显均在以下环境实测采集:

  • 操作系统:Ubuntu 22.04(x86_64),主机名 offline-server
  • Garage:v2.4.1 静态二进制(/usr/local/bin/garage),配置 /etc/garage.toml,systemd 服务 garage.service 运行中
  • 配置要点:replication_factor = 1、rpc_secret 32 字节 hex、S3 监听 [::]:3900、Admin 监听 [::]:3903、s3_region = "garage"、admin_token = "q1w2e3r4-admin"
  • AWS CLI:aws-cli/2.38.1(Python/3.14.6)
  • Garage CLI 核心操作链:garage server 启动 → garage status 获取 node ID → garage layout assign → garage layout apply → garage bucket create → garage key create → garage bucket allow → AWS CLI 实测

💡 技术拓展:Garage 管理命令的两种入口对比——

入口用法适用场景
本地 CLIgarage status 等,读本地配置连本节点在服务器上直接运维
Admin APIcurl -H 'Authorization: Bearer q1w2e3r4-admin' http://127.0.0.1:3903/v2/...脚本化、远程调用、监控采集

两者能力基本对等;CLI 输出面向人,Admin API 返回 JSON 面向程序。本文主线用 CLI,第 7 章演示 Admin API。

二、前置条件

  1. Garage v2.4.1 已安装且 systemd 服务运行中(验证:systemctl is-active garage 返回 active);
  2. 端口 3900/3901/3903 本机可达;
  3. 已安装 AWS CLI(安装与配置见第 6 章);
  4. 管理命令均在服务器本机以 root 执行(garage CLI 会读取 /etc/garage.toml 获取连接参数与 rpc_secret)。

三、启动与集群状态检查

3.1 确认服务运行

systemctl is-active garage

实测回显:

active

3.2 查看节点与集群状态

garage status

实测回显:

==== HEALTHY NODES ====
ID                Hostname        Address         Tags  Zone  Capacity          DataAvail  Version
1f55dfb376baabbe  offline-server  127.0.0.1:3901              NO ROLE ASSIGNED             v2.4.1

关键信息解读:ID 列 1f55dfb376baabbe 是节点短 ID(公钥前 16 位 hex,layout 分配时用);NO ROLE ASSIGNED 表示新节点尚未分配存储角色;Capacity/DataAvail 为空说明布局还没初始化。

3.3 获取完整节点 ID

多节点组网(bootstrap_peers、远程 CLI 连接)需要 64 位完整 ID:

garage node id | head -1

实测回显:

1f55dfb376baabbe29f0b4c1cdbdb97e91a8981b4d0ef56c73f177c76427c988@127.0.0.1:3901

输出格式为 <完整节点ID>@<地址:端口>,可直接用作其他节点的 bootstrap_peers 条目。

四、集群布局初始化(layout 三步)

4.1 为什么需要 layout

Garage 不在配置文件里声明存储容量,而是用「集群布局」集中管理每个节点承担的数据分区。数据被哈希切分为 256 个分区,每个分区按 replication_factor 写多份副本,布局决定「哪个分区落在哪个节点」。任何容量/节点变更都要走「staged(暂存)→ apply(提交)」两段式流程,--version 保证多节点并发修改不冲突。

4.2 分配节点角色

garage layout assign -z dc1 -c 1G 1f55dfb376baabbe

实测回显:

Role changes are staged but not yet committed.
Use `garage layout show` to view staged role changes,
and `garage layout apply` to enact staged changes.

参数说明:-z dc1 指定节点的 zone(机房/机架标识,副本调度以 zone 为单位打散);-c 1G 分配 1GB 存储容量(必须带单位,可用的单位如 G/T;纯数字按字节解释);末尾 1f55dfb376baabbe 是 3.2 节获取的节点短 ID。

💡 技术拓展:zone 的取值与副本冗余直接相关——Garage 会尽量把同一分区的多份副本分散到不同 zone:

zone 划分方式效果适用场景
每节点独立 zone(dc1/dc2/dc3)容忍任意单机房故障,冗余最大化多机房/多机架部署
多节点同 zone(都写 dc1)冗余仍在但无法防机房级故障,layout 会提示 redundancy 降低单机房内的小集群
按地域划分(bj/sh/gz)跨地域容灾地理分布式部署(Garage 设计目标)

本文单节点用 dc1;三节点跨 zone 部署与故障演练实测见《Garage v2.4.1 进阶实战与运维》。

4.3 查看暂存的布局变更

garage layout show

实测回显:

==== CURRENT CLUSTER LAYOUT ====
No nodes currently have a role in the cluster.
See `garage status` to view available nodes.

Current cluster layout version: 0

==== STAGED ROLE CHANGES ====
ID                Tags  Zone  Capacity
1f55dfb376baabbe  []    dc1   953.7 MiB


==== NEW CLUSTER LAYOUT AFTER APPLYING CHANGES ====
ID                Tags  Zone  Capacity   Usable capacity
1f55dfb376baabbe  []    dc1   953.7 MiB  953.7 MiB (100.0%)

Zone redundancy: maximum

==== COMPUTATION OF A NEW PARTITION ASSIGNATION ====

Partitions are replicated 1 times on at least 1 distinct zones.

Optimal partition size:                     3.7 MiB
Usable capacity / total cluster capacity:   953.7 MiB / 953.7 MiB (100.0 %)
Effective capacity (replication factor 1):  953.7 MiB

dc1                 Tags  Partitions        Capacity   Usable capacity
  1f55dfb376baabbe  []    256 (256 new)     953.7 MiB  953.7 MiB (100.0%)
  TOTAL                   256 (256 unique)  953.7 MiB  953.7 MiB (100.0%)


To enact the staged role changes, type:

    garage layout apply --version 1

You can also revert all proposed changes with: garage layout revert

解读:1G(十进制 10^9 字节)显示为 953.7 MiB(二进制单位换算),属正常现象;Current cluster layout version: 0 表示尚无已提交布局;Partitions are replicated 1 times 对应 replication_factor = 1;Zone redundancy: maximum 因单 zone 场景下只有一份副本。

4.4 提交布局

garage layout apply --version 1

实测回显:

New cluster layout with updated role assignment has been applied in cluster.
Data will now be moved around between nodes accordingly.

--version 1 是本次布局的版本号,必须在 apply 时显式声明;后续每次变更(加节点、扩容)都要把版本号递增(version 2、3…),版本号与 layout show 提示一致。

4.5 验证布局生效

garage status

实测回显:

==== HEALTHY NODES ====
ID                Hostname        Address         Tags  Zone  Capacity   DataAvail         Version
1f55dfb376baabbe  offline-server  127.0.0.1:3901  []    dc1   953.7 MiB  100.6 GiB (12.9%)  v2.4.1

NO ROLE ASSIGNED 消失,Zone/Capacity 已生效,集群初始化完成。

五、Bucket 与访问密钥

5.1 创建 bucket

garage bucket create quickstart-bucket

实测回显:

==== BUCKET INFORMATION ====
Bucket:          ba22e29607e62a6ebff9191620657a36675bdb0c9e39b8f5ab21cf0520c76b2c
Created:         2026-10-17 04:55:40.782 +00:00

Size:            0 B (0 B)
Objects:         0

Website access:  false

Global alias:    quickstart-bucket

==== KEYS FOR THIS BUCKET ====
Permissions  Access key    Local aliases

解读:第一行是 bucket 的全局 ID(内容寻址的 32 字节 hex);Global alias: quickstart-bucket 是人类可读名;Website access: false 表示尚未开启静态网站托管。列出全部 bucket:

garage bucket list

实测回显:

ID                          Created     Name              Expiration
ba22e29607e62a6e            2026-10-17  quickstart-bucket never

5.2 创建访问密钥(key)

garage key create quickstart-key

实测回显:

==== ACCESS KEY INFORMATION ====
Key ID:              GK66e270cd6d5f83b414aabb45
Key name:            quickstart-key
Secret key:          4b5a7b5fd5cdf493d9809a5ac6ed1f976b8b0d3eefc5b0dd36b3e55451bf622f
Created:             2026-10-17 04:55:41.507 +00:00
Validity:            valid
Expiration:          never

Can create buckets:  false

==== BUCKETS FOR THIS KEY ====
Permissions  ID  Global aliases  Local aliases
ID                          Created     Name           Expiration
GK66e270cd6d5f83b414aabb45  2026-10-17  quickstart-key never

解读:Key ID(GK 前缀 + 24 位 hex)相当于 S3 的 Access Key ID,Secret key 相当于 Secret Access Key;Can create buckets: false 表示该 key 不能自建 bucket(最小权限)。Secret key 完整值只在创建时展示一次,事后可用 garage key info quickstart-key --show-secret 再查:

garage key info quickstart-key --show-secret

实测回显(节选):

==== ACCESS KEY INFORMATION ====
Key ID:              GK66e270cd6d5f83b414aabb45
Key name:            quickstart-key
Secret key:          4b5a7b5fd5cdf493d9809a5ac6ed1f976b8b0d3eefc5b0dd36b3e55451bf622f
Created:             2026-10-17 04:55:41.507 +00:00
Validity:            valid
Expiration:          never

5.3 授权 key 访问 bucket

新 key 默认无任何 bucket 权限,用 bucket allow 绑定:

garage bucket allow --read --write --owner quickstart-bucket --key quickstart-key

实测回显(节选):

==== KEYS FOR THIS BUCKET ====
Permissions  Access key                                  Local aliases
RWO          GK66e270cd6d5f83b414aabb45  quickstart-key

RWO = Read + Write + Owner。三项权限语义:read 允许读对象与列举;write 允许上传/删除;owner 允许改 bucket 配置与权限。回收权限用 garage bucket deny --read quickstart-bucket --key quickstart-key(按需带 --write/--owner)。

六、AWS CLI 全链路实测

6.1 安装与配置凭据

curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip
cd /root && unzip -qo /tmp/awscliv2.zip && ./aws/install
aws --version

实测回显:

You can now run: /usr/local/bin/aws --version
aws-cli/2.38.1 Python/3.14.6 Linux/6.8.0-138-generic exe/x86_64.ubuntu.22
aws configure set aws_access_key_id GK66e270cd6d5f83b414aabb45
aws configure set aws_secret_access_key 4b5a7b5fd5cdf493d9809a5ac6ed1f976b8b0d3eefc5b0dd36b3e55451bf622f
aws configure set default.region garage

⚠️ 注意:region 必须与 garage.toml 的 s3_region 一致(本文为 garage),否则签名域不匹配(报错样例见第 8 章 Q1)。

6.2 列举 bucket

aws --endpoint-url http://127.0.0.1:3900 s3 ls

实测回显:

2026-10-17 04:55:40 quickstart-bucket

6.3 上传对象(含 3MB 分块存储验证)

Garage 默认把对象按 1MiB 分块存储。上传一个 3MB 对象验证:

head -c 3145728 /dev/urandom > /root/demo-3mb.bin
aws --endpoint-url http://127.0.0.1:3900 s3 cp /root/demo-3mb.bin s3://quickstart-bucket/demo-3mb.bin

实测回显:

upload: root/demo-3mb.bin to s3://quickstart-bucket/demo-3mb.bin

6.4 列举与对象元信息

aws --endpoint-url http://127.0.0.1:3900 s3 ls s3://quickstart-bucket

实测回显:

2026-10-17 04:56:27    3145728 demo-3mb.bin
aws --endpoint-url http://127.0.0.1:3900 s3api head-object --bucket quickstart-bucket --key demo-3mb.bin

实测回显:

{
    "AcceptRanges": "bytes",
    "LastModified": "2026-10-17T04:56:59+00:00",
    "ContentLength": 3145728,
    "ETag": "\"edf7845cc101a95dde011026d451ef3a\"",
    "ContentType": "application/octet-stream",
    "Metadata": {}
}

ETag 等于文件 md5,与 S3 标准行为一致。

6.5 下载与完整性校验

aws --endpoint-url http://127.0.0.1:3900 s3 cp s3://quickstart-bucket/demo-3mb.bin /root/demo-back.bin
md5sum /root/demo-3mb.bin /root/demo-back.bin

实测回显:

download: s3://quickstart-bucket/demo-3mb.bin to root/demo-back.bin
edf7845cc101a95dde011026d451ef3a  /root/demo-3mb.bin
edf7845cc101a95dde011026d451ef3a  /root/demo-back.bin

两次 md5 一致,上传下载链路完整可用。

6.6 删除对象与验证

aws --endpoint-url http://127.0.0.1:3900 s3 rm s3://quickstart-bucket/demo-3mb.bin
aws --endpoint-url http://127.0.0.1:3900 s3 ls s3://quickstart-bucket
aws --endpoint-url http://127.0.0.1:3900 s3api head-object --bucket quickstart-bucket --key demo-3mb.bin

实测回显:

delete: s3://quickstart-bucket/demo-3mb.bin

删除后 s3 ls 输出为空;对已删对象执行 head-object 返回 404(实测):

aws: [ERROR]: An error occurred (404) when calling the HeadObject operation: Not Found

七、Admin API 实测

7.1 健康检查(无需令牌)

curl -s http://127.0.0.1:3903/health

实测回显:

Garage is fully operational
Consult the full health check API endpoint at /v2/GetClusterHealth for more details

7.2 集群健康 JSON(需令牌)

curl -s -H 'Authorization: Bearer q1w2e3r4-admin' http://127.0.0.1:3903/v2/GetClusterHealth

实测回显:

{"healthy":true,"knownNodes":1,"connectedNodes":1,"storageNodes":1,"storageNodesUp":1,"partitions":256,"partitionsQuorum":256,"partitionsAllHealthy":256,"partitionsAvailable":256,"quorumCount":1,"storageNodesDown":0,"resyncQueueLen":0,"uploadsPending":0}

7.3 鉴权行为验证(不带令牌访问受保护接口)

curl -s http://127.0.0.1:3903/v2/GetClusterHealth

实测回显:

{
  "code": "AccessDenied",
  "message": "Forbidden: Bearer token must be provided in Authorization header",
  "region": "garage",
  "path": "/v2/GetClusterHealth"
}

规则实测结论:根路径 /health 公开;/v2/* 全部要求 Authorization: Bearer <admin_token>,缺失即 403。

八、常见问题(FAQ)

Q1:AWS CLI 报 AuthorizationHeaderMalformed,unexpected scope? 实测报错:

aws: [ERROR]: An error occurred (AuthorizationHeaderMalformed) when calling the ListBuckets operation: Authorization header malformed, unexpected scope: '20261017/us-east-1/s3/aws4_request', expected: '20261017/garage/s3/aws4_request'

定位:客户端 region 与 Garage s3_region 不一致。解决:aws configure set default.region garage(与 garage.toml 中 s3_region 一致)。

Q2:AWS CLI 报 SignatureDoesNotMatch? Secret key 抄错或不完整(复制时缺尾字符)。用 garage key info quickstart-key --show-secret 核对完整值后重新 aws configure set aws_secret_access_key <值>。

Q3:garage 命令报 Unable to connect to destination RPC host? server 未运行。systemctl start garage 后重试;仍失败则 journalctl -u garage -n 20 查启动错误(如配置文件语法、目录权限)。

Q4:layout apply 报 version 相关错误? --version 必须等于 garage layout show 输出提示的版本号(To enact the staged role changes, type: garage layout apply --version N)。若提示 Several consecutive changes are possible,说明有多个 staged 版本排队,按提示的版本号依次 apply。

Q5:bucket allow 后 S3 仍报 AccessDenied? 检查 key 与 bucket 是否绑定对了:garage bucket info quickstart-bucket 查看 KEYS FOR THIS BUCKET 表里是否有该 Key ID 且 Permissions 为 RWO;同时确认 AWS CLI 用的是同一个 Key ID(aws configure get aws_access_key_id)。

九、参考链接