深入了解 Artifact Registry

1. 概览

Artifact Registry 是一项全代管式软件包管理器,可提供统一的工具来管理 OCI 容器映像和语言软件包(如 Maven 和 npm)。

Artifact Registry 已与各种其他 Google Cloud 服务完全集成,例如:

  • Cloud Build 可以直接将映像制品上传到 Artifact Registry。
  • Cloud Deploy 可以将 Artifact Registry 映像直接部署到各种运行时环境。
  • 它为 Cloud Run 和 GKE 等容器运行时提供映像,并支持映像流式传输等高级性能优化功能。
  • Artifact Registry 可作为 Artifact Analysis 的检测点,用于持续监控已知漏洞。
  • Cloud IAM 可对制品访问权限和许可进行精细且一致的控制。

本实验将以实操教程的形式引导您了解其中的许多功能。

学习内容

本实验的学习目标是什么?

  • 为容器和语言软件包创建不同的代码库
  • 使用 Artifact Registry 创建和使用容器映像
  • 使用 Artifact Registry 分析工件的安全状况和内容
  • 为 Java Maven 依赖项配置和使用 Artifact Registry

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个。

fbef9caa1602edd0.pnga99b7ace416376c4.png5e3ff691252acf41.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用 PROJECT_ID 标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档。
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户符合参与 300 美元免费试用计划的条件。

设置 gcloud

在 Cloud Shell 中,设置您的项目 ID 和项目编号。将它们保存为 PROJECT_ID 和 PROJECT_NUMBER 变量。

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

启用 Google 服务

gcloud services enable \
  cloudresourcemanager.googleapis.com \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  containerregistry.googleapis.com \
  containerscanning.googleapis.com \
  binaryauthorization.googleapis.com \
  cloudbuild.googleapis.com

获取源代码

本实验的源代码位于 GitHub 上的 GoogleCloudPlatform 组织中。使用以下命令克隆该代码库。

git clone https://github.com/GoogleCloudPlatform/java-docs-samples

3. 推送容器映像

在 Artifact Registry 上创建 Docker 制品库

如前所述,Artifact Registry 支持不同的制品库格式,让您可以管理容器映像和语言包。与不同类型的制品代码库的互动在规范中定义,并且是广泛采用的标准。例如,Maven 依赖项的请求与 Node 依赖项的请求不同。

为了支持特定的制品 API 规范,Artifact Registry 需要在相应的代码库类型中管理制品。创建新制品库时,您需要传入 --repository-format 标志来指明制品库类型。

如需为 Docker 映像创建第一个制品库,请在 Cloud Shell 中运行以下命令:

gcloud artifacts repositories create container-example --repository-format=docker \
--location=us-central1 --description="Example Docker repository"

如果出现 Cloud Shell 授权提示,请点击“授权”

前往 Google Cloud 控制台 - Artifact Registry - 代码库,您会看到新创建的 Docker 制品库 container-example。点击该制品库,您会发现它目前是空的

5b854eb010e891c2.png

配置 Docker 以向 Artifact Registry 进行身份验证

连接到 Artifact Registry 时,需要提供凭证才能授予访问权限。Docker 可以配置为无缝使用您的 gcloud 凭证,而无需设置单独的凭证。

在 Cloud Shell 中运行以下命令,将 Docker 配置为使用 Google Cloud CLI 对向 us-central1 区域中的 Artifact Registry 发出的请求进行身份验证,

gcloud auth configure-docker us-central1-docker.pkg.dev

如果该命令会提示您确认是否更改 Cloud Shell Docker 配置,请按 Enter 键。

探索示例应用

您在之前的步骤中克隆的 Git 代码库中提供了一个示例应用。切换到 java 目录并查看应用代码。

cd java-docs-samples/run/helloworld/
ls

该文件夹包含一个示例 Java 应用,用于渲染一个简单的网页:除了与本实验无关的各种文件外,它还包含 src 文件夹下的源代码,以及我们将用于构建容器映像的 Dockerfile。

构建容器映像

在 Artifact Registry 中存储容器映像之前,您需要先创建一个。

运行以下命令来构建容器映像,并使用完整的 Artifact Registry 路径对其进行标记:

docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:tag1 .

将容器映像推送到 Artifact Registry

运行以下命令,将容器映像推送到之前创建的制品库:

docker push us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:tag1

查看 Artifact Registry 中的映像

前往 Google Cloud 控制台 - Artifact Registry - 制品库. 打开 container-example 制品库,并验证 java-hello-world 映像是否存在。

88e4b26e8536afb2.png

点击映像,并注意标记为 tag1 的映像。由于我们已通过 containerscanning.googleapis.com 服务启用映像的自动扫描,因此您可以看到漏洞扫描正在运行或已完成。完成后,您可以看到检测到的相应映像修订版本的漏洞数量。我们将在下一部分中探讨漏洞和其他制品洞见。

55406d03cf0c96b8.png

4. 检查容器映像

现在,您已将第一个映像推送到 container-example 代码库,接下来我们来详细了解一下。在“版本”标签页中,点击我们刚刚创建的版本。如需更详细地显示图片,请执行以下操作:

44c3f28dd457ed1d.png

上面的复制按钮特别有用,因为它提供了一种简单的方法来访问相应映像版本的完全限定映像 URI,包括 SHA-hash。然后,此 URI 可用于拉取特定映像版本,或用作 Kubernetes Deployment 或 Cloud Run Service 中的映像引用。如需测试映像 URI,您可以在 Cloud Shell 中运行以下命令:

docker pull $IMAGE_URI

了解依赖项

前往顶部的“依赖项”标签页,您可以看到映像中检测到的所有依赖项。请注意,它会列出语言依赖项和操作系统级别的依赖项。您还可以查看附加到每个依赖项的软件许可。

af03348529575dbc.png

仔细查看,您会发现 SBOM 信息尚未填充。如需为制品填充 SOM,您可以在 Cloud Shell 中运行以下命令,使用可从顶部面包屑栏复制的完全限定映像 URI。

gcloud artifacts sbom export --uri $IMAGE_URI

刷新页面后,该页面现在将包含一个指向 Cloud Storage 中自动生成的 SBOM 的链接。如果您依赖于映像的 SBOM,则可能需要自动为制品生成 SBOM,并将生成过程纳入 CI/CD 流水线。

探索映像漏洞

点击视图顶部的“漏洞”标签页,即可查看映像中检测到的所有漏洞。除了顶部的漏洞摘要,您还可以在底部的表格中查看完整的漏洞列表。每一行都链接到 CVE 公告,其中指明了严重程度和来源软件包。对于有修复程序的漏洞,它还会提供有关如何更新依赖项以修复漏洞的说明。

fda03e6fd758ddef.png

5. 虚拟制品库和远程制品库

在上一部分中,我们使用单个映像代码库来推送和拉取映像。这种方法非常适合小规模使用情形,但对于需要自主管理其代码库的不同团队组成的大型组织来说,会带来挑战。团队或业务部门通常会拥有自己的映像代码库,并具有自己的权限和配置。为了简化这些代码库中映像的使用,并屏蔽消费者对底层组织结构的了解,Artifact Registry 提供了虚拟代码库,可用于汇总多个底层代码库中的资源。潜在的架构可能如下所示:

c6488dc5a6bfac3.png

Docker Hub 的远程代码库

Docker Hub 是一个热门的公共映像注册表,其中托管着许多开源容器映像。虽然直接使用公共代码库很简单,但在生产环境中会遇到许多挑战,而 Artifact Registry 中的远程代码库可以帮助我们克服这些挑战。

借助远程制品库,您可以将请求代理到上游注册表,并在代理过程中缓存映像。这不仅可以缩短图片的下载时间,还可以消除对外部服务正常运行时间的依赖,并让您能够应用与您自己的图片相同的安全和访问政策。

如需为 Docker Hub 创建远程仓库,您可以在 Cloud Shell 中运行以下命令:

gcloud artifacts repositories create dockerhub \
  --repository-format=docker \
  --mode=remote-repository \
  --remote-docker-repo=docker-hub \
  --location=us-central1 \
  --description="Example Remote Repo for Docker Hub"

现在,您应该会在 Artifact Registry 代码库列表中看到一个额外的代码库:

7e174a9944c5f34c.png

如需测试您的远程仓库是否能够将请求代理到远程仓库,请在 Cloud Shell 中运行以下命令来拉取 nginx 映像:

docker pull us-central1-docker.pkg.dev/$PROJECT_ID/dockerhub/nginx:stable-alpine

拉取成功后,您还可以在 Cloud 控制台中查看代码库,并确认缓存的 Nginx 映像现在提供的依赖项和漏洞报告与您自行构建的映像相同。

创建虚拟制品库

按照我们目前使用的流程,您可以为每个团队或业务创建多个代码库,并明确定义每个代码库的所有权和 IAM 权限。我们还可以为远程制品库创建代理,从而更轻松、更安全地使用第三方映像。如果您从这些映像的消费者的角度来看,就会发现大量代码库的缺点。开发者如何知道在部署中应使用哪个映像代码库?

为了简化使用并隐藏抽象层后面的底层代码库,您可以在 Cloud Shell 中使用以下命令在 Artifact Registry 中创建虚拟代码库:

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com \
    --role roles/artifactregistry.reader

cat <<EOF > /tmp/upstream.json
[{
"id" : "hello-repo",
"repository" : "projects/$PROJECT_ID/locations/us-central1/repositories/container-example",
"priority" : 100
},{
"id" : "dockerhub",
"repository" : "projects/$PROJECT_ID/locations/us-central1/repositories/dockerhub",
"priority" : 101
}]
EOF

gcloud artifacts repositories create all-images \
    --repository-format=docker \
    --mode=virtual-repository \
    --location=us-central1 \
    --upstream-policy-file=/tmp/upstream.json \
    --description="Example Virtual Repo"

现在,我们可以从虚拟仓库中拉取映像,而无需公开底层结构。如需验证一切是否正常运行,您可以在 Cloud Shell 中运行以下命令:

docker pull us-central1-docker.pkg.dev/$PROJECT_ID/all-images/java-hello-world:tag1

docker pull us-central1-docker.pkg.dev/$PROJECT_ID/all-images/nginx:stable-alpine

6. 部署到 Cloud Run

有了相应的代码库和映像后,我们现在就可以在部署中使用它们了。为了说明一个使用情形示例,并避免部署额外的基础设施,我们将容器部署到 Cloud Run。最简单的部署方法是在 Cloud Shell 中运行以下命令:

gcloud run deploy hello-world \
  --image us-central1-docker.pkg.dev/$PROJECT_ID/all-images/java-hello-world:tag1 \
  --region us-central1 \
  --allow-unauthenticated

部署完成后,系统会显示自动生成的网址,您可以通过该网址访问您的服务。

Deploying container to Cloud Run service [hello-world] in project [my-project] region [us-central1]
OK Deploying... Done.                                                                      
  OK Creating Revision...                                                                  
  OK Routing traffic...
  OK Setting IAM Policy...                                                                    
Done.                                                                                      
Service [hello-world] revision [hello-world-00001-wtc] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-world-13746229022.us-central1.run.app

如果您在新浏览器标签页中打开该网址,应该会看到“Hello World”成功消息。

852a8748c1543736.png

7. 加强供应链安全性

现在,您的容器映像已成功部署到正式版中,接下来,我们不妨了解一下如何加强端到端供应链。在上一部分中,我们了解了 Artifact Registry 的容器分析功能如何提供有关映像中所用库和许可的深入分析。不过,恶意攻击者仍有可能在供应链中将有害内容引入您的映像。在本部分中,我们将探讨如何使用 SLSA 框架为 build 制品引入证明,甚至利用制品本身的加密签名来确保只有可信的制品才能部署到 Cloud Run 运行时。

使用 Cloud Build 进行 SLSA 证明

SLSA 框架为供应链制品提供不同级别的证据。规范和实现乍一看可能令人望而却步,但使用 Cloud Build 创建 SLSA 证明非常简单,只需创建一个将 requestedVerifyOption 设置为 VERIFIED 的 cloudbuild.yaml 规范即可。

对于我们的应用,我们可以在 Cloud Shell 中运行以下命令,在 helloworld 文件夹中创建 cloudbuild.yaml 文件。

cat <<EOF > cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', '\$_IMAGE_URI', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', '\$_IMAGE_URI']
images:
- '\$_IMAGE_URI'
options:
  requestedVerifyOption: VERIFIED
substitutions:
  _IMAGE_URI: us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:latest
EOF

现在,我们在 Cloud Shell 中运行以下命令,创建一个新的 Cloud Build 作业,以构建 Java Hello World 映像的新版本。

gcloud builds submit --substitutions=_IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:cloud-build

构建完成后,我们可以前往 Google Cloud 控制台中的 Cloud Build 界面,打开我们的 build,然后在“Build 摘要”下查看“Build 制品”,从而查看我们达到的 SLSA 级别。您可以在该图片中看到一个用于查看“安全洞见”的按钮。点击该工件后,您会看到 SLSA 证明,以及之前在 Artifact Registry 界面中推送本地 build 时看到的熟悉漏洞报告。

f6154004bfcddc16.png

您还可以在 Cloud Shell 中运行以下命令,检索映像的 SLSA 出处:

gcloud artifacts docker images describe \
"us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:cloud-build" \
 --show-provenance 

要求使用 Binary Authorization 提供 Cloud Build 出处信息

有了 Cloud Build 流水线,如果能确保我们部署到生产环境的所有映像都是使用该可编程且可重现的构建环境构建的,那岂不是很好?

这时,Binary Authorization 就能派上用场了。它允许您在容器运行时前面放置一个守门人,用于检查容器映像并验证是否存在可信的证明。如果未找到任何证明,系统会根据配置创建审核日志条目或完全阻止部署。

如需将项目的默认 Binary Authorization 配置更改为要求使用 Cloud Run 签发的内置证明,请在 Cloud Shell 中运行以下命令:

cat << EOF > /tmp/policy.yaml
defaultAdmissionRule:
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
  evaluationMode: REQUIRE_ATTESTATION
  requireAttestationsBy:
  - projects/$PROJECT_ID/attestors/built-by-cloud-build
name: projects/$PROJECT_ID/policy
EOF

gcloud container binauthz policy import /tmp/policy.yaml

当然,您也可以在此处添加自己的自定义证明者,但这超出了此 Codelab 的范围,您可以将其作为可选的课外作业练习。

如需对 Cloud Run 服务强制执行 Binary Authorization,请在 Cloud Shell 中运行以下命令:

gcloud run services update hello-world \
  --region us-central1 \
  --binary-authorization=default

我们先重新部署本地构建的映像,测试 Binary Authorization 是否已正确应用

gcloud run deploy hello-world \
  --image us-central1-docker.pkg.dev/$PROJECT_ID/all-images/java-hello-world:tag1 \
  --region us-central1

您应该会收到一条错误消息,说明映像无法部署的原因,该消息如下所示:

Image us-central1-docker.pkg.dev/my-project/all-images/java-hello-world@sha256:71eebbf04bf7d1d023e5de5e18f786ea3b8b6411bf64c8def3301c71baca0518 denied by attestor projects/my-project/attestors/built-by-cloud-build: No attestations found that were valid and signed by a key trusted by the attestor

因此,若要将新版本部署到 Cloud Run 服务,我们需要提供使用 Cloud Build 构建的映像。

gcloud run deploy hello-world \
  --image us-central1-docker.pkg.dev/$PROJECT_ID/all-images/java-hello-world:cloud-build \
  --region us-central1

这次部署应该会成功,并显示类似于以下内容的成功部署消息:

Deploying container to Cloud Run service [hello-world] in project [my-project] region [us-central1]
OK Deploying... Done.                                                                      
  OK Creating Revision...                                                                  
  OK Routing traffic...                                                                    
Done.                                                                                      
Service [hello-world] revision [hello-world-00005-mq4] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-world-13746229022.us-central1.run.app

8. 管理 Java Maven 语言包

在本部分中,您将了解如何设置 Artifact Registry Java 制品库并向其中上传软件包,然后在不同的应用中利用这些软件包。

创建 Maven 软件包制品库

在 Cloud Shell 中运行以下命令,为 Java 制品创建一个制品库:

gcloud artifacts repositories create java-repo \
    --repository-format=maven \
    --location=us-central1 \
    --description="Example Java Maven Repo"

如果出现 Cloud Shell 授权提示,请点击“授权”

前往 Google Cloud 控制台 - Artifact Registry - 制品库,您会看到新创建的 Maven 制品库 java-repo。点击该制品库,您会发现它目前是空的。

设置对 Artifact Repository 的身份验证

使用以下命令,将应用默认凭证 (ADC) 的已知位置更新为您的用户账号凭证,以便 Artifact Registry 凭证帮助程序在连接到制品库时可以使用这些凭证进行身份验证:

gcloud auth login --update-adc

为 Artifact Registry 配置 Maven

运行以下命令,输出要添加到 Java 项目的制品库配置。

gcloud artifacts print-settings mvn \
    --repository=java-repo \
    --location=us-central1 | tee config.xml

在 Cloud Shell 中,从 helloworld 目录内运行以下命令,即可在 Cloud Shell Editor 中打开 pom.xml:

cloudshell edit pom.xml

并将返回的设置添加到文件中的相应部分,

更新 distributionManagement 部分

<distributionManagement>
   <snapshotRepository>
     <id>artifact-registry</id>
     <url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
   </snapshotRepository>
   <repository>
     <id>artifact-registry</id>
     <url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
   </repository>
</distributionManagement>

更新 repositories 部分

 <repositories>
   <repository>
     <id>artifact-registry</id>
     <url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
     <releases>
       <enabled>true</enabled>
     </releases>
     <snapshots>
       <enabled>true</enabled>
     </snapshots>
   </repository>
 </repositories>

更新构建下的扩展程序部分

   <extensions>
     <extension>
       <groupId>com.google.cloud.artifactregistry</groupId>
       <artifactId>artifactregistry-maven-wagon</artifactId>
       <version>2.1.0</version>
     </extension>
   </extensions>

以下是完整文件的示例,供您参考。请务必将 <PROJECT> 替换为您的项目 ID。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.example.run</groupId>
 <artifactId>helloworld</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <parent>
   <groupId>com.google.cloud.samples</groupId>
   <artifactId>shared-configuration</artifactId>
   <version>1.2.0</version>
 </parent>
 <dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-dependencies</artifactId>
       <version>${spring-boot.version}</version>
       <type>pom</type>
       <scope>import</scope>
     </dependency>
   </dependencies>
 </dependencyManagement>
 <properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
   <maven.compiler.target>17</maven.compiler.target>
   <maven.compiler.source>17</maven.compiler.source>
   <spring-boot.version>3.2.2</spring-boot.version>
 </properties>
 <dependencies>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>org.junit.vintage</groupId>
     <artifactId>junit-vintage-engine</artifactId>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <scope>test</scope>
   </dependency>
 </dependencies>
 <!-- [START Artifact Registry Config] -->
 <distributionManagement>
   <snapshotRepository>
     <id>artifact-registry</id>
     <url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
   </snapshotRepository>
   <repository>
     <id>artifact-registry</id>
     <url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
   </repository>
 </distributionManagement>

 <repositories>
   <repository>
     <id>artifact-registry</id>
     <url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
     <releases>
       <enabled>true</enabled>
     </releases>
     <snapshots>
       <enabled>true</enabled>
     </snapshots>
   </repository>
 </repositories>
  <build>
   <extensions>
     <extension>
       <groupId>com.google.cloud.artifactregistry</groupId>
       <artifactId>artifactregistry-maven-wagon</artifactId>
       <version>2.2.0</version>
     </extension>
   </extensions>
 <!-- [END Artifact Registry Config] -->

   <plugins>
     <plugin>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-maven-plugin</artifactId>
       <version>${spring-boot.version}</version>
       <executions>
         <execution>
           <goals>
             <goal>repackage</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
     <plugin>
       <groupId>com.google.cloud.tools</groupId>
       <artifactId>jib-maven-plugin</artifactId>
       <version>3.4.0</version>
       <configuration>
         <to>
           <image>gcr.io/PROJECT_ID/helloworld</image>
         </to>
       </configuration>
     </plugin>
   </plugins>
 </build>
 </project>

将 Java 软件包上传到 Artifact Registry

在 Maven 中配置 Artifact Registry 后,您现在可以使用 Artifact Registry 存储 Java Jar,供组织中的其他项目使用。

运行以下命令,将 Java 软件包上传到 Artifact Registry:

mvn deploy

检查 Artifact Registry 中的 Java 软件包

前往 Cloud 控制台 - Artifact Registry - 制品库,点击 java-repo,检查 helloworld 二进制制品是否已存在:

a95d370ee0fd9af0.png

9. 恭喜!

恭喜,您已完成此 Codelab!

所学内容

  • 为容器和语言软件包创建了制品库
  • 使用 Artifact Registry 管理容器映像
  • 将 Artifact Registry 与 Cloud Code 集成
  • 配置了 Maven 以使用 Artifact Registry 获取 Java 依赖项

清理

在 Cloud Shell 中运行以下命令以删除整个项目

gcloud projects delete $PROJECT_ID