JFrog Artifactory:从 local/remote/virtual 到可恢复 Filestore
Artifactory 的 repository key 不只是一个下载路径。Local 持有组织发布的制品,Remote 保存上游代理和缓存状态,Virtual 把多个仓库组织成统一解析入口;数据库记录元数据和权限关系,Filestore 以校验和存放二进制,Access 管理身份与 Token。把这些状态只看成一个挂载目录,会在恢复时得到能启动却无法解密、无法授权或缺少二进制的实例。
固定版本、许可和镜像身份
实验基线采用 Artifactory Self-managed 7.161.16。JFrog 同时维护 SaaS 与 Self-managed 发布线,版本、订阅、Repository 类型、HA、Federation 和存储 provider 能力都可能不同。实验先从官方 Release Notes 与安装文档确认目标版本,再锁定镜像 Digest,不能用浮动 Tag 推导生产兼容性。
export ARTIFACTORY_IMAGE='<official-artifactory-image>:7.161.16'
docker pull "$ARTIFACTORY_IMAGE"
docker image inspect "$ARTIFACTORY_IMAGE" --format '{{index .RepoDigests 0}}'
mkdir -p artifactory-var
docker run -d --name artifactory-lab \
-p 127.0.0.1:18082:8082 \
-v "$PWD/artifactory-var:/var/opt/jfrog/artifactory" \
"$ARTIFACTORY_IMAGE"
curl -fsS http://127.0.0.1:18082/router/api/v1/system/health本地单节点用于认识 Router、Artifactory 与状态目录,不代表共享生产架构。默认凭证立即更换,实验 Token 只授予测试 repository 权限。
local、remote 与 virtual 分开承担状态
Local 是内部发布的权威存储。Release 仓库要求同一坐标不可覆盖,Snapshot 或临时仓库则有不同生命周期。是否允许删除、覆盖和注解由仓库设置、Permission Target 与发布工作流共同决定。
Remote 代理一个上游,持有元数据缓存、missed retrieval cache、连接、认证和 offline 状态。缓存对象按 checksum 存入 Filestore,并由数据库建立 repository/path 引用。上游证书或凭证变化、元数据过期和负缓存都可能让现有制品可读而新版本不可见。
Virtual 聚合 Local、Remote 或其他 Virtual,默认部署仓库和解析顺序会改变客户端行为。内部命名空间、include/exclude pattern、成员顺序和 Permission Target 共同防止外部同名包抢先命中。Virtual 不保存另一份二进制,但其配置是消费合同。
| 对象 | 主要职责 | 必须保留的证据 |
|---|---|---|
| local | 内部不可变制品 | repository/path、checksum、发布身份 |
| remote | 上游代理与缓存 | upstream、缓存时间、失败状态、checksum |
| virtual | 聚合与解析 | 成员顺序、默认部署库、include/exclude |
Generic Local 验证写入和拒绝覆盖
创建 proof-release-local Generic Local 和只读 Virtual。发布账号只获得 deploy/cache 权限,消费账号只获得 read。
set -euo pipefail
BASE='https://repo.example.test/artifactory/proof-release-local'
PATH_KEY='demo/1.0/proof.txt'
printf 'proof-content-v1\n' > proof.txt
sha256sum proof.txt > proof.txt.sha256
curl --fail-with-body -H "Authorization: Bearer $ARTIFACTORY_TOKEN" \
-T proof.txt "$BASE/$PATH_KEY"
curl --fail-with-body -H "Authorization: Bearer $ARTIFACTORY_READ_TOKEN" \
"$BASE/$PATH_KEY" -o downloaded.txt
cmp proof.txt downloaded.txt随后修改文件并上传同一路径。目标是服务端拒绝覆盖并留下请求日志;若成功,应隔离实验 repository、恢复原摘要并检查仓库与权限配置。客户端“上传前查询”不能消除并发窗口,不可变性必须落在服务端。
用只读账号测试 PUT 与 DELETE,两者都应失败。再从 Virtual 读取相同路径,证明聚合入口可用且没有绕过 Permission Target。
Remote 缓存需要断开上游验证
对测试 Remote 先下载已知对象,让它进入 cache;另选一个未缓存对象。将 Remote 切换 offline 或在隔离网络中阻断上游后,缓存对象应按配置继续读取,未缓存对象明确失败。记录请求状态、Remote 日志、缓存属性和 upstream 错误。
Missed Retrieval Cache 可能继续保存 404;上游后来发布同版本时,Virtual 仍可能看不到。排障先核对 Retrieval Cache Period、Missed Retrieval Cache Period、offline 状态、remote URL 和认证,不要靠清空整个 Filestore 解决一条元数据问题。
Build Info、Properties 和 checksum search 能增强追溯,但不是制品身份替代品。发布记录仍要保存源码、流水线、包坐标与 SHA256。客户端只配置 Virtual URL,避免绕开内部仓库和远端策略。
数据库、Filestore、Access 和 master.key 是恢复集合
JFrog 推荐新部署使用外部 PostgreSQL。多个 HA 节点连接同一受支持数据库和共享 Filestore。连接池总量按节点数与数据库预算计算,每节点盲目增大 maxOpenConnections 会耗尽数据库连接。
Filestore provider chain 由 binarystore.xml 表达,可以组合缓存、共享文件系统、对象存储与冗余。选择对象存储会增加 IAM、请求费用、网络和 provider 兼容责任;任何配置调整都从目标版本模板开始,并在隔离环境恢复。
master.key 用于敏感配置解密,HA 节点必须共享同一受控密钥。数据库和 Filestore 都恢复成功,但 master key 丢失时,原有 Token、上游凭证或加密配置可能不可用。Access 的身份状态、Join Key 或相关平台密钥也必须进入受限恢复域,不能只复制 $JFROG_HOME/artifactory/var/data。
恢复演练使用同一版本,在隔离网络恢复数据库、Filestore、配置和密钥,检查系统健康、repository 清单、随机 checksum、Local/Remote/Virtual 读取、权限拒绝、上游认证和 Token 轮换。恢复点不一致时,可能出现数据库引用存在但 blob 缺失,或 Filestore 有内容却没有路径引用。
清理要从 AQL 清单走到 GC
Remote Repository 的 Unused Artifacts Cleanup Period 只决定缓存多久未用后成为候选,后台 Cleanup Unused Cached Artifacts 才删除缓存引用。Local 的版本保留通常通过 AQL、REST、受审查脚本或订阅提供的生命周期能力生成候选清单。
候选按 repository、path、版本、下载时间、创建时间、Build Info、Properties 和保留标签审批。生产、回滚、审计、漏洞调查和法务引用优先保护。删除 repository 引用后,Filestore 的 checksum 二进制可能仍被其他路径引用;GC 只有确认数据库没有引用时才能物理回收。
Trash Can、Small GC、Full GC 或具体任务名随目标版本变化,不能套用 Nexus 的 Compact 概念,也不能手工删除 Filestore 哈希目录。验收比较逻辑制品数、Filestore 字节、数据库引用、GC 日志和代表下载。
Access 权限与不可信输入
Permission Target 按 repository、include/exclude pattern、用户/组和 read/deploy/cache/annotate/delete/manage 动作收窄。生产发布 Token 不具备管理权限,消费 Token 不具备写权限;自动化从 API Key 迁移到 Access Token 或 reference token,并验证目标版本弃用策略。
Remote URL 是服务端出站边界,需要 SSRF 防护、允许上游、企业代理与 TLS 信任。上传文件名、Properties、Build Info、包元数据和搜索输入都视为不可信内容,日志与 UI 不应让它们变成脚本或路径注入。
审计保存 subject、token scope、repository/path、动作、响应、来源和关联流水线。Support Bundle、system.yaml、binarystore.xml 和日志可能包含拓扑及敏感配置,访问与保留单独授权。
HA、复制、升级和退出
Self-managed HA 需要目标订阅、外部数据库、共享 Filestore、统一密钥和可达的节点身份。多节点提高进程容错,不自动解决数据库、对象存储和 Access 故障。节点数、Router、负载均衡、任务并发和滚动升级按版本兼容矩阵验证。
Replication、Federation 和 Distribution 具有不同方向、冲突、删除传播和许可语义。跨地域优先单一发布源与受控分发;双向可写会制造同路径不同 checksum 和删除循环。复制成功后在目标端按 checksum 抽检,并证明权限和元数据也符合消费合同。
升级前备份完整恢复集合,审查数据库迁移、鉴权弃用、repository 格式和 plugin 兼容。用生产副本演练,比较代表客户端、AQL、权限、GC 和 HA。Schema 迁移完成后不能只换回旧镜像;失败应恢复升级前数据库、Filestore 与密钥的一致点。
退出 Artifactory 时冻结发布,导出 repository、Permission、用户/组、Token 迁移策略、Build Info 和 Properties。按 path 与 checksum 迁移 Local,决定 Remote cache 是搬迁还是预热;新平台验证不可变发布、Virtual 解析、权限与恢复后再切换。迁往 Nexus 时参考 Nexus Repository 主文,但 local/remote/virtual 到 hosted/proxy/group 的对象映射必须逐仓确认。
