使用 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(可选) - 要完成演练,需要引用容器映像。
oras
CLI 会利用 Docker 桌面凭据存储来存储凭据。 可以使用本地安装的 Docker 生成和推送容器映像,或使用acr build
在 Azure 中远程生成。
配置注册表
要配置环境以便轻松执行命令,请执行以下步骤:
- 将
ACR_NAME
变量设置为注册表名称。 - 将
REGISTRY
变量设置为$ACR_NAME.azurecr.cn
。 - 将
REPO
变量设置为存储库名称。 - 将
TAG
变量设置为所需的标记。 - 将
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
通过此设置,可以无缝地将项目推送到 Azure 容器注册表和从中拉取项目。 现在,ORAS 可与 ACR 配合使用,而无需使用 oras login
命令进行额外的其他身份验证。
如果 Docker 不可用,则可以使用提供的 AD 令牌进行身份验证。 使用 AD 令牌通过个人 Microsoft Entra 标识进行身份验证。 始终对 USER_NAME
使用“000...”,因为令牌是通过 PASSWORD
变量解析的。 az acr login
使用的令牌有效期为 3 小时。
注意
ACR 和 ORAS 支持用于用户和系统自动化的多个身份验证选项。 为了方便演示,本文使用单个标识。 如需了解更多身份验证选项,请参阅使用 Azure 容器注册表进行身份验证。
使用 ORAS 推送和拉取 OCI 项目
可以使用 Azure 容器注册表来存储和管理开放容器计划 (OCI) 项目以及 Docker 与 OCI 容器映像。
为了演示此功能,本部分介绍了如何使用 OCI 注册表即存储 (ORAS) CLI 将 OCI 项目推送到 Azure 容器注册表和从中拉取项目。 可以使用适用于每个 OCI 项目的不同命令行工具,在 Azure 容器注册表中管理各种 OCI 项目。
推送项目
没有 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
表示文件的 IANAmediaType
。
有关详细信息,请参阅 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 来将供应链项目图 push
、discover
和 pull
到 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 容器注册表和从中拉取项目。 还发现了已推送项目的清单,并查看了附加到容器映像的项目图。