你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure 注册表推送和拉取供应链项目(预览版)

使用 Azure 容器注册表来存储和管理供应链项目图,包括签名、软件物料清单 (SBOM)、安全扫描结果和其他类型。

Graph of artifacts, including a container image, signature and signed software bill of materials

为了演示此功能,本文介绍了如何使用 OCI 注册即存储 (ORAS) CLI 来将供应链项目图 pushdiscoverpull 到 Azure 容器注册表。 推送和拉取 OCI 项目介绍了存储单独(根)OCI 项目。

若要存储项目图,可以使用 OCI 项目清单定义对 subject 项目的引用,该清单是预发布 OCI 1.1 分发规范的一部分。 OCI 1.1 项目清单支持是一项 ACR 预览功能,其功能有限

先决条件

  • Azure 容器注册表 - 在 Azure 订阅中创建容器注册表。 例如,使用 Azure 门户Azure CLI
    请参阅 Azure 云支持的预览限制
  • 需要 Azure CLI - 版本 2.29.1 或更高版本。 有关安装和/或升级信息,请参阅安装 Azure CLI
  • 需要 ORAS CLI - 版本 v0.16.0。 请参阅:ORAS 安装
  • Docker(可选) - 要完成演练,需要引用容器映像。 可以使用本地安装的 Docker 生成和推送容器映像,或使用 acr build 在 Azure 中远程生成。
    虽然不需要 Docker Desktop,但 oras cli 会利用 Docker 桌面凭据存储来存储凭据。 如果已安装 Docker Desktop,则必须为 oras login 运行。

预览版限制

OCI 项目清单支持(OCI 1.1 规范)在所有 Azure 公共区域提供。 尚不支持由 21Vianet 运营的 Microsoft Azure 和政府云。

配置注册表

配置环境变量以轻松地将命令复制/粘贴到 shell 中。 这些命令可以在本地运行或在 Azure Cloud Shell 中运行。

ACR_NAME=myregistry
REGISTRY=$ACR_NAME.azurecr.io
REPO=net-monitor
TAG=v1
IMAGE=$REGISTRY/${REPO}:$TAG

使用 AD 令牌通过个人 Microsoft Entra 标识进行身份验证。 始终对 USER_NAME 使用“000...”,因为令牌是通过 PASSWORD 变量解析的。

# Login to Azure
az login

# Login to ACR, using a token based on your Azure identity
USER_NAME="00000000-0000-0000-0000-000000000000"
PASSWORD=$(az acr login --name $ACR_NAME --expose-token --output tsv --query accessToken)

注意

ACR 和 ORAS 支持用于用户和系统自动化的多个身份验证选项。 本文通过使用 Azure 令牌使用个人标识。 如需了解更多身份验证选项,请参阅使用 Azure 容器注册表进行身份验证

使用 ORAS 登录

oras login 提供凭据。

oras login $REGISTRY \
  --username $USER_NAME \
  --password $PASSWORD

推送容器映像

此示例将项目图与容器映像相关联。

生成并推送容器映像,或者跳过此步骤(如果 $IMAGE 引用注册表中的现有映像)。

az acr build -r $ACR_NAME -t $IMAGE https://github.com/wabbit-networks/net-monitor.git#main

创建容器映像的示例签名

echo '{"artifact": "'${IMAGE}'", "signature": "jayden hancock"}' > signature.json

将签名附加到注册表,作为对容器映像的引用

oras attach 命令在文件 (./signature.json) 之间创建对 $IMAGE 的引用。 --artifact-type 提供区分项目,类似于支持不同文件类型的文件扩展名。 通过指定 [file]:[mediaType] 可以附加一个或多个文件。

oras attach $IMAGE \
    --artifact-type signature/example \
    ./signature.json:application/json

有关 oras 附加的详细信息,请参阅 ORAS 文档

附加多文件项目作为引用

使用 ORAS 将 OCI 项目推送到注册表时,每个文件引用会作为一个 Blob 推送。 若要推送单独的 Blob,请单独引用文件,或通过引用目录来引用文件集合。
要详细了解如何推送文件集合,请参阅推送包含多个文件的项目

围绕项目创建一些文档:

echo 'Readme Content' > readme.md
mkdir details/
echo 'Detailed Content' > details/readme-details.md
echo 'More detailed Content' > details/readme-more-details.md

附加多文件项目作为对 $IMAGE 的引用:

Linux、WSL2 或 macOS

oras attach $IMAGE \
    --artifact-type readme/example \
    ./readme.md:application/markdown \
    ./details

Windows

.\oras.exe attach $IMAGE ^
    --artifact-type readme/example ^
    .\readme.md:application/markdown ^
    .\details

发现项目引用

OCI v1.1 规范定义了一个引荐者 API,用于发现对 subject 项目的引用。 oras discover 命令可以显示对容器映像的引用列表。

通过使用 oras discover,查看现在存储在注册表中的项目图。

oras discover -o tree $IMAGE

输出显示了项目图的开头,其中签名和文档被视为容器映像的子项。

myregistry.azurecr.io/net-monitor:v1
├── signature/example
│   └── sha256:555ea91f39e7fb30c06f3b7aa483663f067f2950dcb...
└── readme/example
    └── sha256:1a118663d1085e229ff1b2d4d89b5f6d67911f22e55...

创建深层项目图

OCI v1.1 规范支持深度图,并且支持已签名的软件物料清单 (SBOM) 和其他项目类型。

创建示例 SBOM

echo '{"version": "0.0.0.0", "artifact": "'${IMAGE}'", "contents": "good"}' > sbom.json

将示例 SBOM 附加到注册表中的映像

Linux、WSL2 或 macOS

oras attach $IMAGE \
  --artifact-type sbom/example \
  ./sbom.json:application/json

Windows

.\oras.exe attach $IMAGE ^
    --artifact-type sbom/example ^
    ./sbom.json:application/json

对 SBOM 进行签名

作为引用推送的项目通常没有标记,因为它们被视为 subject 项目的一部分。 要将签名推送到作为另一个项目的子项目的项目,请使用具有 --artifact-type 筛选的 oras discover 来查找摘要。

SBOM_DIGEST=$(oras discover -o json \
                --artifact-type sbom/example \
                $IMAGE | jq -r ".manifests[0].digest")

创建 SBOM 的签名

echo '{"artifact": "'$IMAGE@$SBOM_DIGEST'", "signature": "jayden hancock"}' > sbom-signature.json

附加 SBOM 签名

oras attach $IMAGE@$SBOM_DIGEST \
  --artifact-type 'signature/example' \
  ./sbom-signature.json:application/json

查看图

oras discover -o tree $IMAGE

生成以下输出:

myregistry.azurecr.io/net-monitor:v1
├── sbom/example
│   └── sha256:4f1843833c029ecf0524bc214a0df9a5787409fd27bed2160d83f8cc39fedef5
│       └── signature/example
│           └── sha256:3c43b8cb0c941ec165c9f33f197d7f75980a292400d340f1a51c6b325764aa93
├── readme/example
│   └── sha256:5fafd40589e2c980e2864a78818bff51ee641119cf96ebb0d5be83f42aa215af
└── signature/example
    └── sha256:00da2c1c3ceea087b16e70c3f4e80dbce6f5b7625d6c8308ad095f7d3f6107b5

提升图

典型的 DevOps 工作流会将项目从开发提升到过渡再到生产环境。安全供应链工作流将公共内容提升到专用安全环境。 在任一情况下,你都需要将签名、SBOM、扫描结果和其他相关项目与根项目一起提升,以生成完整的依赖关系图。

使用 oras copy 命令,可以跨注册表提升项目筛选图。

net-monitor:v1 映像及其相关项目复制到 sample-staging/net-monitor:v1

TARGET_REPO=$REGISTRY/sample-staging/$REPO
oras copy -r $IMAGE $TARGET_REPO:$TAG

oras copy 的输出:

Copying 6bdea3cdc730 sbom-signature.json
Copying 78e159e81c6b sbom.json
Copied  6bdea3cdc730 sbom-signature.json
Copied  78e159e81c6b sbom.json
Copying 7cf1385c7f4d signature.json
Copied  7cf1385c7f4d signature.json
Copying 3e797ecd0697 details
Copying 2fdeac43552b readme.md
Copied  3e797ecd0697 details
Copied  2fdeac43552b readme.md
Copied demo42.myregistry.io/net-monitor:v1 => myregistry.azurecr.io/sample-staging/net-monitor:v1
Digest: sha256:ff858b2ea3cdf4373cba65d2ca6bcede4da1d620503a547cab5916614080c763

发现提升的项目图

oras discover -o tree $TARGET_REPO:$TAG

oras discover 的输出:

myregistry.azurecr.io/sample-staging/net-monitor:v1
├── sbom/example
│   └── sha256:4f1843833c029ecf0524bc214a0df9a5787409fd27bed2160d83f8cc39fedef5
│       └── signature/example
│           └── sha256:3c43b8cb0c941ec165c9f33f197d7f75980a292400d340f1a51c6b325764aa93
├── readme/example
│   └── sha256:5fafd40589e2c980e2864a78818bff51ee641119cf96ebb0d5be83f42aa215af
└── signature/example
    └── sha256:00da2c1c3ceea087b16e70c3f4e80dbce6f5b7625d6c8308ad095f7d3f6107b5

拉取引用的项目

要拉取特定的引用项目,请使用 oras discover 命令发现引用摘要:

DOC_DIGEST=$(oras discover -o json \
              --artifact-type 'readme/example' \
              $TARGET_REPO:$TAG | jq -r ".manifests[0].digest")

为下载创建一个干净的目录

mkdir ./download

将文档提取到下载目录

oras pull -o ./download $TARGET_REPO@$DOC_DIGEST

查看文档

tree ./download

tree 的输出:

./download
├── details
│   ├── readme-details.md
│   └── readme-more-details.md
└── readme.md

查看存储库和标记列表

ORAS 项目清单支持在无需分配标记的情况下推送、发现、拉取和复制项目图。 借助项目清单,标记列表能够专注于用户所需的项目,而不是与容器映像、helm 图表和其他项目相关联的签名和 SBOM。

查看标记列表

oras repo tags $REGISTRY/$REPO

查看清单列表

存储库可以具有标记和未标记的清单列表。 使用 az acr manifest CLI 查看清单的完整列表:

az acr manifest list-metadata \
  --name $REPO \
  --registry $ACR_NAME \
  --output jsonc

请注意,容器映像清单具有 "tags",而引用类型 ("mediaType": "application/vnd.oci.artifact.manifest.v1+json") 没有。

在输出中,签名未标记,但作为对容器映像的 oci.artifact.manifest 引用进行跟踪:

{
  "changeableAttributes": {
    "deleteEnabled": true,
    "listEnabled": true,
    "readEnabled": true,
    "writeEnabled": true
  },
  "createdTime": "2023-01-10T17:58:28.4403142Z",
  "digest": "sha256:00da2c1c3ceea087b16e70c3f4e80dbce6f5b7625d6c8308ad095f7d3f6107b5",
  "imageSize": 80,
  "lastUpdateTime": "2023-01-10T17:58:28.4403142Z",
  "mediaType": "application/vnd.oci.artifact.manifest.v1+json"
}

删除图中的所有项目

对 OCI v1.1 规范的支持允许删除与根项目关联的项目图。 使用 oras delete 命令删除项目(签名、SBOM 和 SBOM 的签名)的图。

oras manifest delete -f $REGISTRY/$REPO:$TAG

oras manifest delete -f $REGISTRY/sample-staging/$REPO:$TAG

查看其余清单

通过删除根项目,所有相关项目也会被删除,从而留下干净环境:

az acr manifest list-metadata \
  --name $REPO \
  --registry $ACR_NAME -o jsonc

输出:

2023-01-10 18:38:45.366387 Error: repository "net-monitor" is not found.

摘要

在本文中,供应链项目图会被创建、发现、提升和拉取,为你构建和依赖的项目提供生命周期管理。

后续步骤