使用 ORAS 管理 OCI 项目和供应链项目

Azure 容器注册表 (ACR) 有助于管理开放容器计划 (OCI) 项目和供应链项目。 本文介绍如何使用 ACR 有效地管理 OCI 项目和供应链项目。 了解如何存储、管理和检索 OCI 项目和供应链项目图,包括签名、软件物料清单 (SBOM)、安全扫描结果和其他类型。

本文分为两个主要部分:

先决条件

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

配置注册表

要配置环境以便轻松执行命令,请执行以下步骤:

  1. ACR_NAME 变量设置为注册表名称。
  2. REGISTRY 变量设置为 $ACR_NAME.azurecr.cn
  3. REPO 变量设置为存储库名称。
  4. TAG 变量设置为所需的标记。
  5. IMAGE 变量设置为 $REGISTRY/${REPO}:$TAG

设置环境变量。

配置注册表名称、登录凭据、存储库名称和标记以推送和拉取项目。 以下示例使用 net-monitor 存储库名称和 v1 标记。 替换为你自己的存储库名称和标记。

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

登录到注册表

使用 ACR 进行身份验证,以允许你拉取和推送容器映像。

az cloud set -n AzureChinaCloud
az login  
# az cloud set -n AzureCloud   //means return to Public Azure.
az acr login -n $REGISTRY  

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

# Login to Azure
az cloud set -n AzureChinaCloud
az login
# az cloud set -n AzureCloud   //means return to Public Azure.

使用 ORAS 登录

oras login 提供凭据。

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

通过此设置,可以无缝地将项目推送到 Azure 容器注册表和从中拉取项目。 根据具体配置的需要调整变量。

使用 ORAS 推送和拉取 OCI 项目

可以使用 Azure 容器注册表来存储和管理开放容器计划 (OCI) 项目以及 Docker 与 OCI 容器映像。

为了演示此功能,本部分介绍了如何使用 OCI 注册表即存储 (ORAS) CLI 将 OCI 项目推送到 Azure 容器注册表和从中拉取项目。 可以使用适用于每个 OCI 项目的不同命令行工具,在 Azure 容器注册表中管理各种 OCI 项目。

注意

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

推送项目

没有 subject 父级的单个文件项目可以是容器映像、helm 图表、存储库的自述文件中的任何内容。 引用项目可以是签名、软件物料清单、扫描报告或其他不断演变的类型中的任何内容。 在附加、推送和拉取供应链项目中描述的引用项目是引用另一个项目的项目。

推送单文件项目

对于此示例,请创建表示 Markdown 文件的内容:

echo 'Readme Content' > readme.md

以下步骤将 readme.md 文件推送到 <myregistry>.azurecr.cn/samples/artifact:readme

  • 注册表使用完全限定的注册表名称 <myregistry>.azurecr.cn(全部小写)进行标识,后跟名称空间和存储库:/samples/artifact
  • 该项目被标记为 :readme,以区别于存储库 (:latest, :v1, :v1.0.1) 中列出的其他项目。
  • 设置 --artifact-type readme/example 将项目与使用 application/vnd.oci.image.config.v1+json 的容器映像区分开来。
  • ./readme.md 标识上传的文件,:application/markdown 表示文件的 IANA mediaType
    有关详细信息,请参阅 OCI 项目创建者指南

使用 oras push 命令将文件推送到注册表。

Linux、WSL2 或 macOS

oras push $REGISTRY/samples/artifact:readme \
    --artifact-type readme/example \
    ./readme.md:application/markdown

Windows

.\oras.exe push $REGISTRY/samples/artifact:readme ^
    --artifact-type readme/example ^
    .\readme.md:application/markdown

成功推送后,输出将如下所示:

Uploading 2fdeac43552b readme.md
Uploaded  2fdeac43552b readme.md
Pushed <myregistry>.azurecr.cn/samples/artifact:readme
Digest: sha256:e2d60d1b171f08bd10e2ed171d56092e39c7bac1
aec5d9dcf7748dd702682d53

推送多文件项目

使用 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

推送多文件项目:

Linux、WSL2 或 macOS

oras push $REGISTRY/samples/artifact:readme \
    --artifact-type readme/example\
    ./readme.md:application/markdown\
    ./details

Windows

.\oras.exe push $REGISTRY/samples/artifact:readme ^
    --artifact-type readme/example ^
    .\readme.md:application/markdown ^
    .\details

发现清单

若要查看作为 oras push 的结果创建的清单,请使用 oras manifest fetch

oras manifest fetch --pretty $REGISTRY/samples/artifact:readme

输出类似于:

{
  "mediaType": "application/vnd.oci.artifact.manifest.v1+json",
  "artifactType": "readme/example",
  "blobs": [
    {
      "mediaType": "application/markdown",
      "digest": "sha256:2fdeac43552b71eb9db534137714c7bad86b53a93c56ca96d4850c9b41b777fc",
      "size": 15,
      "annotations": {
        "org.opencontainers.image.title": "readme.md"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:0d6c7434a34f6854f971487621426332e6c0fda08040b9e6cc8a93f354cee0b1",
      "size": 189,
      "annotations": {
        "io.deis.oras.content.digest": "sha256:11eceb2e7ac3183ec9109003a7389468ec73ad5ceaec0c4edad0c1b664c5593a",
        "io.deis.oras.content.unpack": "true",
        "org.opencontainers.image.title": "details"
      }
    }
  ],
  "annotations": {
    "org.opencontainers.artifact.created": "2023-01-10T14:44:06Z"
  }
}

拉取项目

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

mkdir ./download

请运行 oras pull 命令从注册表拉取项目。

oras pull -o ./download $REGISTRY/samples/artifact:readme

查看拉取的文件

tree ./download

删除项目(可选)

若要从注册表中删除项目,请使用 oras manifest delete 命令。

 oras manifest delete $REGISTRY/samples/artifact:readme

使用 ORAS 附加、推送和拉取供应链项目

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

要存储项目图,可以使用 OCI 映像清单定义对 subject 项目的引用,该清单是预发布 OCI 1.1 分发规范的一部分。

推送容器映像

要使用 Azure CLI 将项目图与容器映像相关联,请执行以下操作:

可以生成并推送容器映像,或者跳过此步骤(如果 $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,请单独引用文件,或通过引用目录来引用文件集合。
要详细了解如何推送文件集合,请参阅推送包含多个文件的项目

发现项目引用

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

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

oras discover -o tree $IMAGE

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

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

创建项目图

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

下面介绍如何创建 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 进行签名

重要

Azure 建议使用安全加密签名工具(例如 Notation)对映像进行签名,并生成签署 SBOM 的签名。

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

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.cn/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.cn/sample-staging/net-monitor:v1
Digest: sha256:ff858b2ea3cdf4373cba65d2ca6bcede4da1d620503a547cab5916614080c763

发现提升的项目图

oras discover -o tree $TARGET_REPO:$TAG

oras discover 的输出:

myregistry.azurecr.cn/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

删除图中的所有项目

对 OCI v1.1 规范的支持允许删除与主题项目关联的项目图。 使用 oras manifest 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.

总结

本文介绍了如何使用 Azure 容器注册表来存储、管理和检索 OCI 项目和供应链项目。 使用 ORAS CLI 将项目推送到 Azure 容器注册表和从中拉取项目。 还发现了已推送项目的清单,并查看了附加到容器映像的项目图。

后续步骤

  • 了解项目引用、关联签名、软件物料清单和其他引用类型。
  • 详细了解 ORAS 项目,包括如何为项目配置清单。
  • 有关新项目类型的参考信息,请访问 OCI 项目存储库。