2026年8月8日 1 分钟阅读

不只存 Docker 镜像:用 Artifact Keeper 把多语言制品仓库、漏洞扫描与隔离策略放进一套自托管栈

tinyash 0 条评论

一个服务同时维护 Python、Node.js、Java 和 Kubernetes 的团队,很容易在依赖分发上走向碎片化:镜像推到一个 Registry,npm 包走另一套私服,PyPI 代理、Helm Chart、Terraform 模块又各有入口。问题不只是账号和地址变多。制品一旦跨越这些边界,漏洞扫描、留存规则、访问控制和审计记录也被拆散;到了排查「这份构建产物何时进入生产、有没有经过检查」时,往往只能在多套系统里拼线索。

Artifact Keeper 是一个以 Rust 实现的自托管通用制品注册表。项目声明支持 45 种以上格式,覆盖 Maven、PyPI、npm、Docker/OCI、Cargo、Go、Helm、Terraform/OpenTofu,以及 Debian、RPM 等常见生态。它不是要求团队把所有制品改成一种包格式,而是为包管理器和基础设施工具保留各自的协议入口,再把存储、扫描与策略判断收敛到同一条处理路径。

这类工具的价值不在于「再建一个包仓库」,而在于把制品进入内部供应链之前的判断变成可重复的工程流程。对于已有多语言仓库、又希望逐步把镜像和依赖纳入安全门禁的团队,这是一个值得评估的切入点。

先明确:统一的是控制面,不是开发语言

Artifact Keeper 的 README 将协议处理、制品服务、扫描服务和数据层拆开。客户端仍然可以是 npm、pip、Maven、Docker、Helm 或 Terraform;服务端则负责对应格式的原生协议处理,并把数据落到文件系统或 S3 兼容存储。元数据使用 PostgreSQL,全文检索使用 OpenSearch。

因此,落地时更合理的迁移顺序不是一次性替换全部基础设施,而是先挑一个风险和收益都清晰的边界。例如:先让内部 OCI 镜像通过统一入口进入,再把 Helm Chart 与 Terraform 模块接进来;等认证、留存和扫描规则稳定后,再考虑语言包的代理或托管。

这也意味着它不等同于「所有软件包都已经被逐一验证」。项目列出的是协议和格式支持范围;团队仍要针对自己真正使用的客户端版本、私有包命名规则、缓存策略与发布权限做兼容性测试。特别是涉及生产发布的仓库,不能只因为 Compose 能启动,就直接切换为唯一制品来源。

用 Compose 建立一个可检查的起点

官方 Quickstart 提供 Docker Compose 部署文件及初始化所需的 Caddy、数据库和 Dependency-Track 配置文件。先在隔离的测试主机上按文档下载这些文件,再启动服务:

mkdir artifact-keeper && cd artifact-keeper

curl -fsSLO \
  https://raw.githubusercontent.com/artifact-keeper/artifact-keeper/main/docker-compose.yml

mkdir docker
curl -fsSLo docker/Caddyfile \
  https://raw.githubusercontent.com/artifact-keeper/artifact-keeper/main/docker/Caddyfile
curl -fsSLo docker/init-db.sql \
  https://raw.githubusercontent.com/artifact-keeper/artifact-keeper/main/docker/init-db.sql
curl -fsSLo docker/init-pg-ssl.sh \
  https://raw.githubusercontent.com/artifact-keeper/artifact-keeper/main/docker/init-pg-ssl.sh
curl -fsSLo docker/init-dtrack.sh \
  https://raw.githubusercontent.com/artifact-keeper/artifact-keeper/main/docker/init-dtrack.sh

docker compose up -d

启动命令成功不应是验收终点。官方文档列出了三个健康端点,可用它们把「容器正在运行」和「应用已就绪」分开判断:

curl http://localhost:30080/livez
curl http://localhost:30080/readyz
curl http://localhost:30080/health

在生产化之前,建议把这三个检查纳入部署流水线或监控探针:livez 用于确认进程存活,readyz 用于判断是否可接收流量,health 则用于排查服务依赖是否异常。还应把入口端口、反向代理 TLS、管理员初始凭据、存储持久卷及数据库备份纳入部署清单。默认 Compose 是获得验证环境的途径,不是替代组织现有的密钥管理、备份演练和变更流程。

扫描链路的关键:区分「已扫描」和「适用扫描器」

Artifact Keeper 描述的上传路径有一个实用的顺序:新制品先经过 SHA-256 去重;对于未缓存过的制品,Trivy 用于文件系统或容器相关分析,Grype 用于依赖树扫描;结果汇总为 A 到 F 的风险等级,再由策略引擎决定继续存储还是进入隔离区(quarantine)。同一个二进制再次上传时,可以复用已有扫描结果,而不是重复执行整套扫描。

这里最容易被忽略的边界是:扫描器不会对每种格式都同样适用。项目把不适用的扫描结果表示为 not_applicable,它与扫描失败不同。运营侧应该把这种状态做成可见指标,否则「没有高危结果」可能只是某个制品没有匹配的扫描器,而非真正完成了预期检查。

更具体地说,基础 docker-compose.yml 中的 TRIVY_URL 对接的是传统 Trivy server,README 明确说明它用于文件系统或 Incus rootfs 扫描。若团队希望取得 OCI 容器镜像的一等 Trivy image report,需要额外启用仓库内的 scanner-adapter 服务,并设置 TRIVY_ADAPTER_URL;否则镜像仍可由 Grype 的 registry mode 覆盖,但不会生成 Trivy 的镜像报告。

这不是小配置差异,而是安全门禁是否覆盖预期对象的差异。上线前应以一张已知含漏洞的测试镜像验证三件事:制品是否进入目标仓库、两类扫描记录是否按预期出现、策略是否真的把不合格制品阻在隔离区,而不只是页面上显示扫描服务在线。

把隔离区设计成流程的一部分

许多团队的漏洞治理停在「扫描报告发到群里」。真正困难的是报告出来之后:谁能判定误报?谁能接受特定风险?谁能让修复后的新构建重新放行?如果这些步骤全靠口头沟通,制品仓库再集中也很难形成可靠控制。

可以围绕隔离区设计一个最小闭环:开发者上传构建产物;系统保留哈希、来源和扫描结果;策略按严重性、包来源或许可证等团队规则做初判;命中规则的制品进入隔离;安全或平台负责人复核例外;修复后由 CI 产生新版本,而不是人工替换原制品。这样做的好处是,放行行为和原始制品都有可追溯关系,也避免「同一个 tag 被悄悄重推」带来的审计盲点。

但不要把工具的评分当成自动化风险决策。A–F 等级能帮助排序,却不理解业务暴露面、补丁可用性和运行时补偿措施。策略应先从观察模式开始,统计一段时间内哪些仓库、哪些语言包、哪些镜像最常被拦截,再逐步把明确的高风险规则转为阻断。对基础镜像、构建工具链和生产运行镜像,应采用不同阈值;一条统一的「高危即拒绝」规则通常会制造大量不可执行告警。

适合谁,以及不适合谁

当团队同时维护多种包生态、希望将 OCI 镜像和基础设施模块一起纳入制品治理,并且能够运维 PostgreSQL、OpenSearch 与扫描服务时,Artifact Keeper 的统一入口值得做 PoC。其 MIT 许可证和自托管方式也适合需要把制品元数据留在内部网络的场景。

反过来,只有少量公共镜像、没有私有包发布需求,或团队无法承担多组件服务的升级、索引容量和备份责任时,直接引入完整注册表未必划算。先使用现有 Registry 的扫描与访问控制能力,再确认多格式统一治理确有缺口,通常是更稳妥的路径。

评估的重点不该是「它支持多少格式」,而是三个更具体的问题:是否能让现有客户端无感接入;镜像、包与模块的扫描状态是否可解释;当策略拒绝制品时,开发者是否有明确、可审计且可恢复的处理路径。把这三件事跑通,统一制品仓库才会从一个存储系统变成供应链控制面。

PoC 不要只测上传:用失败样本验证治理闭环

一个两三天的 PoC 可以比功能清单更快暴露真实成本。选取一个 npm 或 PyPI 测试包、一张内部构建的 OCI 镜像和一个 Helm Chart,分别记录客户端配置、上传耗时、检索行为与权限日志;随后故意准备一份包含已知漏洞的镜像,观察它在扫描、评分、策略命中和隔离状态之间如何流转。验收证据至少应包含制品哈希、仓库路径、扫描结果、策略决定和操作者记录,而不是只截取 Web UI 的成功页面。

还要模拟两个失败场景。第一,扫描器短暂不可用时,策略究竟是拒绝上传、暂存等待,还是允许制品绕过检查?第二,同一版本号或相同 tag 被重新推送时,团队是否能辨认原始构建与覆盖行为?这些选择没有普适答案,却必须在接入生产前由平台、安全与研发共同确定。将这类结果写入发布规范和 CI 回执,才可以避免系统上线后把「扫描服务暂时异常」误解为「制品已经安全」。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。