如何使用 Azure 容器注册表任务消耗并维护公共内容How to consume and maintain public content with Azure Container Registry Tasks

本文提供了 Azure 容器注册表中的示例工作流,以帮助你管理公共内容的消耗和维护:This article provides a sample workflow in Azure Container Registry to help you manage consuming and maintaining public content:

  1. 导入所依赖的公共映像的本地副本。Import local copies of dependent public images.
  2. 通过安全扫描和功能测试来验证公共映像。Validate public images through security scanning and functional testing.
  3. 将映像提升到专用注册表供内部使用。Promote the images to private registries for internal usage.
  4. 为依赖于公共内容的应用程序触发基础映像更新。Trigger base image updates for applications dependent upon public content.
  5. 使用 Azure 容器注册表任务自动执行此工作流。Use Azure Container Registry Tasks to automate this workflow.

下图汇总了此工作流:The workflow is summarized in the following image:

消耗公共内容工作流

门控式导入工作流帮助你管理组织对外部托管项目(例如,源自公共注册表的映像,这些公共注册表包括 Docker HubGCRQuayGitHub 容器注册表Microsoft 容器注册表甚至其他 Azure 容器注册表)的依赖性。The gated import workflow helps manage your organization's dependencies on externally managed artifacts - for example, images sourced from public registries including Docker Hub, GCR, Quay, GitHub Container Registry, Microsoft Container Registry, or even other Azure container registries.

若要了解依赖于公共内容所带来的风险的背景信息以及如何使用 Azure 容器注册表来缓解这些风险,请参阅消耗公共内容的 OCI 博客文章使用 Azure 容器注册表管理公共内容For background about the risks introduced by dependencies on public content and how to use Azure Container Registry to mitigate them, see the OCI Consuming Public Content Blog post and Manage public content with Azure Container Registry.

可使用 Azure 本地安装的 Azure CLI 来完成本演练。You can use the Azure local installation of the Azure CLI to complete this walkthrough. 建议使用 Azure CLI 2.10 或更高版本。Azure CLI version 2.10 or later is recommended. 如果需要进行安装或升级,请参阅安装 Azure CLIIf you need to install or upgrade, see Install Azure CLI.

方案概述Scenario overview

导入工作流组件

本演练设置:This walkthrough sets up:

  1. 三个 容器注册表,表示:Three container registries, representing:
    • 模拟的 Docker Hub (publicregistry),支持更改基础映像A simulated Docker Hub (publicregistry) to support changing the base image
    • 用于共享专用映像的团队注册表 (contoso)Team registry (contoso) to share private images
    • 导入的公共内容的公司/团队共享注册表 (baseartifacts)Company/team shared registry (baseartifacts) for imported public content
  2. 每个注册表中的 ACR 任务An ACR task in each registry. 这些任务:The tasks:
    1. 构建模拟的公共 node 映像Build a simulated public node image
    2. node 映像导入到公司/团队共享注册表并对其进行验证Import and validate the node image to the company/team shared registry
    3. 构建并部署 hello-world 映像Build and deploy the hello-world image
  3. ACR 任务定义,其中包括以下项的配置:ACR task definitions, including configurations for:
  4. 注册表凭据 的集合,它们是指向密钥保管库的指针A collection of registry credentials, which are pointers to a key vault
  5. acr-task.yaml 中提供的 机密 的集合,它们是指向密钥保管库的指针A collection of secrets, available within an acr-task.yaml, which are pointers to a key vault
  6. acr-task.yaml 中使用的 已配置值 的集合A collection of configured values used within an acr-task.yaml
  7. 一个用来保护所有机密的 Azure 密钥保管库An Azure key vault to secure all secrets
  8. 一个承载 hello-world 生成应用程序的 Azure 容器实例An Azure container instance, which hosts the hello-world build application

先决条件Prerequisites

以下步骤配置在演练中创建和使用的资源的值。The following steps configure values for resources created and used in the walkthrough.

设置环境变量Set environment variables

配置你的环境特有的变量。Configure variables unique to your environment. 我们会遵循最佳做法,将具有持久性内容的资源置于其自己的资源组中,以最大程度地减少意外删除情况。We follow best practices for placing resources with durable content in their own resource group to minimize accidental deletion. 不过,你可以根据需要将其放在单个资源组中。However, you can place these in a single resource group if desired.

本文中的示例针对 Bash shell 设置了格式。The examples in this article are formatted for the bash shell.

# Set the three registry names, must be globally unique:
REGISTRY_PUBLIC=publicregistry
REGISTRY_BASE_ARTIFACTS=contosobaseartifacts
REGISTRY=contoso

# set the location all resources will be created in:
RESOURCE_GROUP_LOCATION=chinanorth

# default resource groups
REGISTRY_PUBLIC_RG=${REGISTRY_PUBLIC}-rg
REGISTRY_BASE_ARTIFACTS_RG=${REGISTRY_BASE_ARTIFACTS}-rg
REGISTRY_RG=${REGISTRY}-rg

# fully qualified registry urls
REGISTRY_DOCKERHUB_URL=dockerhub.azk8s.cn
REGISTRY_PUBLIC_URL=${REGISTRY_PUBLIC}.azurecr.cn
REGISTRY_BASE_ARTIFACTS_URL=${REGISTRY_BASE_ARTIFACTS}.azurecr.cn
REGISTRY_URL=${REGISTRY}.azurecr.cn

# Azure key vault for storing secrets, name must be globally unique
AKV=acr-task-credentials
AKV_RG=${AKV}-rg

# ACI for hosting the deployed application
ACI=hello-world-aci
ACI_RG=${ACI}-rg

Git 存储库和令牌Git repositories and tokens

若要模拟你的环境,请为以下每个 Git 存储库创建分支以获得你可以管理的存储库。To simulate your environment, fork each of the following Git repos into repositories you can manage.

然后,为你的分支存储库更新下列变量:Then, update the following variables for your forked repositories.

追加到 git URL 末尾的 :main 表示默认存储库分支。The :main appended to the end of the git URLs represents the default repository branch.

GIT_BASE_IMAGE_NODE=https://github.com/<your-fork>/base-image-node.git#main
GIT_NODE_IMPORT=https://github.com/<your-fork>/import-baseimage-node.git#main
GIT_HELLO_WORLD=https://github.com/<your-fork>/hello-world.git#main

你需要一个适用于 ACR 任务的 GitHub 访问令牌 (PAT),才能克隆和建立 Git Webhook。You need a GitHub access token (PAT) for ACR Tasks to clone and establish Git webhooks. 如需通过相关步骤创建一个具有访问专用存储库所需权限的令牌,请参阅创建 GitHub 访问令牌For steps to create a token with the required permissions to a private repo, see Create a GitHub access token.

GIT_TOKEN=<set-git-token-here>

Docker Hub 凭据Docker Hub credentials

若要避免在从 Docker Hub 拉取映像时出现限制和标识请求,请创建一个 Docker Hub 令牌To avoid throttling and identity requests when pulling images from Docker Hub, create a Docker Hub token. 然后设置以下环境变量:Then, set the following environment variables:

REGISTRY_DOCKERHUB_USER=<yourusername>
REGISTRY_DOCKERHUB_PASSWORD=<yourtoken>

创建注册表Create registries

使用 Azure CLI 命令创建三个高级层容器注册表,每个表都位于其自己的资源组中:Using Azure CLI commands, create three Premium tier container registries, each in its own resource group:

az group create --name $REGISTRY_PUBLIC_RG --location $RESOURCE_GROUP_LOCATION
az acr create --resource-group $REGISTRY_PUBLIC_RG --name $REGISTRY_PUBLIC --sku Premium

az group create --name $REGISTRY_BASE_ARTIFACTS_RG --location $RESOURCE_GROUP_LOCATION
az acr create --resource-group $REGISTRY_BASE_ARTIFACTS_RG --name $REGISTRY_BASE_ARTIFACTS --sku Premium

az group create --name $REGISTRY_RG --location $RESOURCE_GROUP_LOCATION
az acr create --resource-group $REGISTRY_RG --name $REGISTRY --sku Premium

创建密钥保管库并设置机密Create key vault and set secrets

创建密钥保管库:Create a key vault:

az group create --name $AKV_RG --location $RESOURCE_GROUP_LOCATION
az keyvault create --resource-group $AKV_RG --name $AKV

在密钥保管库中设置 Docker Hub 用户名和令牌:Set Docker Hub username and token in the key vault:

az keyvault secret set \
--vault-name $AKV \
--name registry-dockerhub-user \
--value $REGISTRY_DOCKERHUB_USER

az keyvault secret set \
--vault-name $AKV \
--name registry-dockerhub-password \
--value $REGISTRY_DOCKERHUB_PASSWORD

在密钥保管库中设置并验证 Git PAT:Set and verify a Git PAT in the key vault:

az keyvault secret set --vault-name $AKV --name github-token --value $GIT_TOKEN

az keyvault secret show --vault-name $AKV --name github-token --query value -o tsv

为 Azure 容器实例创建资源组Create resource group for an Azure container instance

部署 hello-world 映像时,会在后续任务中使用此资源组。This resource group is used in a later task when deploying the hello-world image.

az group create --name $ACI_RG --location $RESOURCE_GROUP_LOCATION

创建公共 node 基础映像Create public node base image

若要在 Docker Hub 上模拟 node 映像,请创建一个 ACR 任务来构建和维护公共映像。To simulate the node image on Docker Hub, create an ACR task to build and maintain the public image. 此设置允许 node 映像维护人员模拟更改。This setup allows simulating changes by the node image maintainers.

az acr task create \
  --name node-public \
  -r $REGISTRY_PUBLIC \
  -f acr-task.yaml \
  --context $GIT_BASE_IMAGE_NODE \
  --git-access-token $(az keyvault secret show \
                        --vault-name $AKV \
                        --name github-token \
                        --query value -o tsv) \
  --set REGISTRY_FROM_URL=${REGISTRY_DOCKERHUB_URL}/ \
  --assign-identity

若要避免 Docker 限制,请将 Docker Hub 凭据添加到任务中。To avoid Docker throttling, add Docker Hub credentials to the task. 可以使用 acr task credentials 命令将 Docker 凭据传递给任何注册表,包括 Docker Hub。The acr task credentials command may be used to pass Docker credentials to any registry, including Docker Hub.

az acr task credential add \
  -n node-public \
  -r $REGISTRY_PUBLIC \
  --login-server $REGISTRY_DOCKERHUB_URL \
  -u https://${AKV}.vault.azure.cn/secrets/registry-dockerhub-user \
  -p https://${AKV}.vault.azure.cn/secrets/registry-dockerhub-password \
  --use-identity [system]

授予任务从密钥保管库读取值所需的访问权限:Grant the task access to read values from the key vault:

az keyvault set-policy \
  --name $AKV \
  --resource-group $AKV_RG \
  --object-id $(az acr task show \
                  --name node-public \
                  --registry $REGISTRY_PUBLIC \
                  --query identity.principalId --output tsv) \
  --secret-permissions get

可以通过 Git 提交、基础映像更新、计时器或手动运行来触发任务Tasks can be triggered by Git commits, base image updates, timers, or manual runs.

手动运行任务以生成 node 映像:Run the task manually to generate the node image:

az acr task run -r $REGISTRY_PUBLIC -n node-public

列出模拟的公共注册表中的映像:List the image in the simulated public registry:

az acr repository show-tags -n $REGISTRY_PUBLIC --repository node

创建 hello-world 映像Create the hello-world image

根据模拟的公共 node 映像生成 hello-world 映像。Based on the simulated public node image, build a hello-world image.

创建用于对模拟的公共注册表进行拉取访问的令牌Create token for pull access to simulated public registry

创建模拟的公共注册表的访问令牌,其作用域为 pullCreate an access token to the simulated public registry, scoped to pull. 然后,在密钥保管库中对其进行设置:Then, set it in the key vault:

az keyvault secret set \
  --vault-name $AKV \
  --name "registry-${REGISTRY_PUBLIC}-user" \
  --value "registry-${REGISTRY_PUBLIC}-user"

az keyvault secret set \
  --vault-name $AKV \
  --name "registry-${REGISTRY_PUBLIC}-password" \
  --value $(az acr token create \
              --name "registry-${REGISTRY_PUBLIC}-user" \
              --registry $REGISTRY_PUBLIC \
              --scope-map _repositories_pull \
              -o tsv \
              --query credentials.passwords[0].value)

按 Azure 容器实例创建用于拉取访问的令牌Create token for pull access by Azure Container Instances

为承载 hello-world 映像的注册表创建访问令牌,其作用域为拉取。Create an access token to the registry hosting the hello-world image, scoped to pull. 然后,在密钥保管库中对其进行设置:Then, set it in the key vault:

az keyvault secret set \
  --vault-name $AKV \
  --name "registry-${REGISTRY}-user" \
  --value "registry-${REGISTRY}-user"

az keyvault secret set \
  --vault-name $AKV \
  --name "registry-${REGISTRY}-password" \
  --value $(az acr token create \
              --name "registry-${REGISTRY}-user" \
              --registry $REGISTRY \
              --repository hello-world content/read \
              -o tsv \
              --query credentials.passwords[0].value)

创建用于生成和维护 hello-world 映像的任务Create task to build and maintain hello-world image

以下命令基于 hello-world 存储库的 acr-tasks.yaml 中的定义创建任务。The following command creates a task from the definition in acr-tasks.yaml in the hello-world repo. 任务步骤生成 hello-world 映像,然后将其部署到 Azure 容器实例。The task steps build the hello-world image and then deploy it to Azure Container Instances. Azure 容器实例的资源组已在前面的一个部分创建。The resource group for Azure Container Instances was created in a previous section. 通过在任务中调用 az container create(只是在 image:tag 中有差别),任务在整个演练中将部署到同一实例。By calling az container create in the task with only a difference in the image:tag, the task deploys to same instance throughout this walkthrough.

az acr task create \
  -n hello-world \
  -r $REGISTRY \
  -f acr-task.yaml \
  --context $GIT_HELLO_WORLD \
  --git-access-token $(az keyvault secret show \
                        --vault-name $AKV \
                        --name github-token \
                        --query value -o tsv) \
  --set REGISTRY_FROM_URL=${REGISTRY_PUBLIC_URL}/ \
  --set KEYVAULT=$AKV \
  --set ACI=$ACI \
  --set ACI_RG=$ACI_RG \
  --assign-identity

向任务添加用于模拟的公共注册表的凭据:Add credentials to the task for the simulated public registry:

az acr task credential add \
  -n hello-world \
  -r $REGISTRY \
  --login-server $REGISTRY_PUBLIC_URL \
  -u https://${AKV}.vault.azure.cn/secrets/registry-${REGISTRY_PUBLIC}-user \
  -p https://${AKV}.vault.azure.cn/secrets/registry-${REGISTRY_PUBLIC}-password \
  --use-identity [system]

授予任务从密钥保管库读取值所需的访问权限:Grant the task access to read values from the key vault:

az keyvault set-policy \
  --name $AKV \
  --resource-group $AKV_RG \
  --object-id $(az acr task show \
                  --name hello-world \
                  --registry $REGISTRY \
                  --query identity.principalId --output tsv) \
  --secret-permissions get

通过向任务授予对资源组的访问权限,授予任务创建和管理 Azure 容器实例所需的访问权限:Grant the task access to create and manage Azure Container Instances by granting access to the resource group:

az role assignment create \
  --assignee $(az acr task show \
  --name hello-world \
  --registry $REGISTRY \
  --query identity.principalId --output tsv) \
  --scope $(az group show -n $ACI_RG --query id -o tsv) \
  --role owner

创建并配置任务后,运行任务以生成并部署 hello-world 映像:With the task created and configured, run the task to build and deploy the hello-world image:

az acr task run -r $REGISTRY -n hello-world

创建后,获取承载 hello-world 映像的容器的 IP 地址。Once created, get the IP address of the container hosting the hello-world image.

az container show \
  --resource-group $ACI_RG \
  --name ${ACI} \
  --query ipAddress.ip \
  --out tsv

在浏览器中,转到该 IP 地址以查看正在运行的应用程序。In your browser, go to the IP address to see the running application.

使用“可疑”更改更新基础映像Update the base image with a "questionable" change

本部分模拟一项可能会导致环境中出现问题的基础映像更改。This section simulates a change to the base image that could cause problems in the environment.

  1. 打开分支的 base-image-node 存储库中的 DockerfileOpen Dockerfile in the forked base-image-node repo.
  2. BACKGROUND_COLOR 更改为 Orange 以模拟更改。Change the BACKGROUND_COLOR to Orange to simulate the change.
ARG REGISTRY_NAME=
FROM ${REGISTRY_NAME}node:15-alpine
ENV NODE_VERSION 15-alpine
ENV BACKGROUND_COLOR Orange

提交更改并监视那些自动开始生成的 ACR 任务。Commit the change and watch for ACR Tasks to automatically start building.

监视要开始执行的任务:Watch for the task to start executing:

watch -n1 az acr task list-runs -r $REGISTRY_PUBLIC -o table

最终,你应当会看到基于触发器 Commit 的状态“Succeeded”:You should eventually see STATUS Succeeded based on a TRIGGER of Commit:

RUN ID    TASK      PLATFORM    STATUS     TRIGGER    STARTED               DURATION
-------- --------  ---------- ---------  --------- --------------------  ----------
ca4       hub-node  linux       Succeeded  Commit     2020-10-24T05:02:29Z  00:00:22

键入 Ctrl + C 退出监视命令,然后查看最近的运行的日志:Type Ctrl+C to exit the watch command, then view the logs for the most recent run:

az acr task logs -r $REGISTRY_PUBLIC

node 映像完成后,ACR 任务的 watch 会动开始构建 hello-world 映像:Once the node image is completed, watch for ACR Tasks to automatically start building the hello-world image:

watch -n1 az acr task list-runs -r $REGISTRY -o table

最终,你应当会看到基于触发器 Image Update 的状态“Succeeded”:You should eventually see STATUS Succeeded based on a TRIGGER of Image Update:

RUN ID    TASK         PLATFORM    STATUS     TRIGGER       STARTED               DURATION
-------- -----------  ---------- ---------  ------------ --------------------  ----------
dau       hello-world  linux       Succeeded  Image Update  2020-10-24T05:08:45Z  00:00:31

键入 Ctrl + C 退出监视命令,然后查看最近的运行的日志:Type Ctrl+C to exit the watch command, then view the logs for the most recent run:

az acr task logs -r $REGISTRY

完成后,获取承载更新后的 hello-world 映像的站点的 IP 地址:Once completed, get the IP address of the site hosting the updated hello-world image:

az container show \
  --resource-group $ACI_RG \
  --name ${ACI} \
  --query ipAddress.ip \
  --out tsv

在浏览器中转到该站点,该站点应该具有橙色(可疑)背景。In your browser, go to the site, which should have an orange (questionable) background.

签入Checking in

此时,你已创建了一个 hello-world 映像,该映像是基于 Git 提交和对基础 node 映像的更改自动构建的。At this point, you've created a hello-world image that is automatically built on Git commits and changes to the base node image. 在此示例中,任务基于 Azure 容器注册表中的基础映像进行构建,但任何受支持的注册表都可以使用。In this example, the task builds against a base image in Azure Container Registry, but any supported registry could be used.

更新 node 映像时,基础映像更新会自动触发任务运行。The base image update automatically retriggers the task run when the node image is updated. 在这里可以看到,并非所有更新都是需要的。As seen here, not all updates are wanted.

公共内容的门控式导入Gated imports of public content

若要防止上游更改损坏关键工作负荷,可以添加安全扫描和功能测试。To prevent upstream changes from breaking critical workloads, security scanning and functional tests may be added.

在本部分,我们创建一个 ACR 任务来执行以下操作:In this section, you create an ACR task to:

  • 构建测试映像Build a test image
  • 针对测试映像运行功能测试脚本 ./test.shRun a functional test script ./test.sh against the test image
  • 如果映像测试成功,请将公共映像导入到 baseimages 注册表If the image tests successfully, import the public image to the baseimages registry

添加自动化测试Add automation testing

为了对任何上游内容进行控制,将实施自动化测试。To gate any upstream content, automated testing is implemented. 在此示例中,提供了一个用于检查 $BACKGROUND_COLORtest.shIn this example, a test.sh is provided which checks the $BACKGROUND_COLOR. 如果测试失败,将返回 EXIT_CODE 1,这会导致 ACR 任务步骤失败,从而结束任务运行。If the test fails, an EXIT_CODE of 1 is returned which causes the ACR task step to fail, ending the task run. 这些测试可以在任何形式的工具中进行扩展,其中包括日志记录结果。The tests can be expanded in any form of tools, including logging results. 此入口是通过脚本中的“通过/失败”响应进行管理的,此处重现了该响应:The gate is managed by a pass/fail response in the script, reproduced here:

if [ ""$(echo $BACKGROUND_COLOR | tr '[:lower:]' '[:upper:]') = 'RED' ]; then
    echo -e "\e[31mERROR: Invalid Color:\e[0m" ${BACKGROUND_COLOR}
    EXIT_CODE=1
else
  echo -e "\e[32mValidation Complete - No Known Errors\e[0m"
fi
exit ${EXIT_CODE}

任务 YAMLTask YAML

查看 import-baseimage-node 存储库中的 acr-task.yaml,它执行以下步骤:Review the acr-task.yaml in the import-baseimage-node repo, which performs the following steps:

  1. 使用以下 Dockerfile 构建测试基础映像:Build the test base image using the following Dockerfile:
    ARG REGISTRY_FROM_URL=
    FROM ${REGISTRY_FROM_URL}node:15-alpine
    WORKDIR /test
    COPY ./test.sh .
    CMD ./test.sh
    
  2. 完成后,通过运行容器来验证映像,这将运行 ./test.shWhen completed, validate the image by running the container, which runs ./test.sh
  3. 只有在成功完成后才运行导入步骤,这些步骤通过 when: ['validate-base-image'] 进行控制Only if successfully completed, run the import steps, which are gated with when: ['validate-base-image']
version: v1.1.0
steps:
  - id: build-test-base-image
    # Build off the base image we'll track
    # Add a test script to do unit test validations
    # Note: the test validation image isn't saved to the registry
    # but the task logs captures log validation results
    build: >
      --build-arg REGISTRY_FROM_URL={{.Values.REGISTRY_FROM_URL}}
      -f ./Dockerfile
      -t {{.Run.Registry}}/node-import:test
      .
  - id: validate-base-image
    # only continues if node-import:test returns a non-zero code
    when: ['build-test-base-image']
    cmd: "{{.Run.Registry}}/node-import:test"
  - id: pull-base-image
    # import the public image to base-artifacts
    # Override the stable tag,
    # and create a unique tag to enable rollback
    # to a previously working image
    when: ['validate-base-image']
    cmd: >
        docker pull {{.Values.REGISTRY_FROM_URL}}node:15-alpine
  - id: retag-base-image
    when: ['pull-base-image']
    cmd: docker tag {{.Values.REGISTRY_FROM_URL}}node:15-alpine {{.Run.Registry}}/node:15-alpine
  - id: retag-base-image-unique-tag
    when: ['pull-base-image']
    cmd: docker tag {{.Values.REGISTRY_FROM_URL}}node:15-alpine {{.Run.Registry}}/node:15-alpine-{{.Run.ID}}
  - id: push-base-image
    when: ['retag-base-image', 'retag-base-image-unique-tag']
    push:
    - "{{.Run.Registry}}/node:15-alpine"
    - "{{.Run.Registry}}/node:15-alpine-{{.Run.ID}}"

创建用于导入和测试基础映像的任务Create task to import and test base image

  az acr task create \
  --name base-import-node \
  -f acr-task.yaml \
  -r $REGISTRY_BASE_ARTIFACTS \
  --context $GIT_NODE_IMPORT \
  --git-access-token $(az keyvault secret show \
                        --vault-name $AKV \
                        --name github-token \
                        --query value -o tsv) \
  --set REGISTRY_FROM_URL=${REGISTRY_PUBLIC_URL}/ \
  --assign-identity

向任务添加用于模拟的公共注册表的凭据:Add credentials to the task for the simulated public registry:

az acr task credential add \
  -n base-import-node \
  -r $REGISTRY_BASE_ARTIFACTS \
  --login-server $REGISTRY_PUBLIC_URL \
  -u https://${AKV}.vault.azure.cn/secrets/registry-${REGISTRY_PUBLIC}-user \
  -p https://${AKV}.vault.azure.cn/secrets/registry-${REGISTRY_PUBLIC}-password \
  --use-identity [system]

授予任务从密钥保管库读取值所需的访问权限:Grant the task access to read values from the key vault:

az keyvault set-policy \
  --name $AKV \
  --resource-group $AKV_RG \
  --object-id $(az acr task show \
                  --name base-import-node \
                  --registry $REGISTRY_BASE_ARTIFACTS \
                  --query identity.principalId --output tsv) \
  --secret-permissions get

运行导入任务:Run the import task:

az acr task run -n base-import-node -r $REGISTRY_BASE_ARTIFACTS

备注

如果任务由于 ./test.sh: Permission denied 而失败,请确保该脚本具有执行权限,然后重新提交到 Git 存储库:If the task fails due to ./test.sh: Permission denied, ensure that the script has execution permissions, and commit back to the Git repo:

chmod +x ./test.sh

更新 hello-world 映像以基于门控式 node 映像进行构建Update hello-world image to build from gated node image

创建访问令牌,以从 node 存储库访问作用域为 read 的基础项目注册表。Create an access token to access the base-artifacts registry, scoped to read from the node repository. 然后,在密钥保管库中进行设置:Then, set in the key vault:

az keyvault secret set \
  --vault-name $AKV \
  --name "registry-${REGISTRY_BASE_ARTIFACTS}-user" \
  --value "registry-${REGISTRY_BASE_ARTIFACTS}-user"

az keyvault secret set \
  --vault-name $AKV \
  --name "registry-${REGISTRY_BASE_ARTIFACTS}-password" \
  --value $(az acr token create \
              --name "registry-${REGISTRY_BASE_ARTIFACTS}-user" \
              --registry $REGISTRY_BASE_ARTIFACTS \
              --repository node content/read \
              -o tsv \
              --query credentials.passwords[0].value)

hello-world 任务添加用于基础项目注册表的凭据:Add credentials to the hello-world task for the base artifacts registry:

az acr task credential add \
  -n hello-world \
  -r $REGISTRY \
  --login-server $REGISTRY_BASE_ARTIFACTS_URL \
  -u https://${AKV}.vault.azure.cn/secrets/registry-${REGISTRY_BASE_ARTIFACTS}-user \
  -p https://${AKV}.vault.azure.cn/secrets/registry-${REGISTRY_BASE_ARTIFACTS}-password \
  --use-identity [system]

通过更新任务来更改 REGISTRY_FROM_URL,以使用 BASE_ARTIFACTS 注册表Update the task to change the REGISTRY_FROM_URL to use the BASE_ARTIFACTS registry

az acr task update \
  -n hello-world \
  -r $REGISTRY \
  --set KEYVAULT=$AKV \
  --set REGISTRY_FROM_URL=${REGISTRY_BASE_ARTIFACTS_URL}/ \
  --set ACI=$ACI \
  --set ACI_RG=$ACI_RG

运行 hello world 任务来更改其基础映像依赖项:Run the hello-world task to change its base image dependency:

az acr task run -r $REGISTRY -n hello-world

使用“有效”更改更新基础映像Update the base image with a "valid" change

  1. 打开 base-image-node 存储库中的 DockerfileOpen the Dockerfile in base-image-node repo.
  2. BACKGROUND_COLOR 更改为 Green 以模拟有效的更改。Change the BACKGROUND_COLOR to Green to simulate a valid change.
ARG REGISTRY_NAME=
FROM ${REGISTRY_NAME}node:15-alpine
ENV NODE_VERSION 15-alpine
ENV BACKGROUND_COLOR Green

提交更改并监视更新序列:Commit the change and monitor the sequence of updates:

watch -n1 az acr task list-runs -r $REGISTRY_PUBLIC -o table

运行后,键入 Ctrl + C 并监视日志:Once running, type Ctrl+C and monitor the logs:

az acr task logs -r $REGISTRY_PUBLIC

完成后,监视 base-image-import 任务:Once complete, monitor the base-image-import task:

watch -n1 az acr task list-runs -r $REGISTRY_BASE_ARTIFACTS -o table

运行后,键入 Ctrl + C 并监视日志:Once running, type Ctrl+C and monitor the logs:

az acr task logs -r $REGISTRY_BASE_ARTIFACTS

完成后,监视 hello-world 任务:Once complete, monitor the hello-world task:

watch -n1 az acr task list-runs -r $REGISTRY -o table

运行后,键入 Ctrl + C 并监视日志:Once running, type Ctrl+C and monitor the logs:

az acr task logs -r $REGISTRY

完成后,获取承载更新后的 hello-world 映像的站点的 IP 地址:Once completed, get the IP address of the site hosting the updated hello-world image:

az container show \
  --resource-group $ACI_RG \
  --name ${ACI} \
  --query ipAddress.ip \
  --out tsv

在浏览器中转到该站点,该站点应当具有绿色(有效)背景。In your browser, go to the site, which should have a green (valid) background.

查看门控式工作流View the gated workflow

再次执行前一部分中的步骤,其背景色为红色。Perform the steps in the preceding section again, with a background color of red.

  1. 打开 base-image-node 存储库中的 DockerfileOpen the Dockerfile in the base-image-node repo
  2. BACKGROUND_COLOR 更改为 Red 以模拟无效的更改。Change the BACKGROUND_COLOR to Red to simulate an invalid change.
ARG REGISTRY_NAME=
FROM ${REGISTRY_NAME}node:15-alpine
ENV NODE_VERSION 15-alpine
ENV BACKGROUND_COLOR Red

提交更改并监视更新序列:Commit the change and monitor the sequence of updates:

watch -n1 az acr task list-runs -r $REGISTRY_PUBLIC -o table

运行后,键入 Ctrl + C 并监视日志:Once running, type Ctrl+C and monitor the logs:

az acr task logs -r $REGISTRY_PUBLIC

完成后,监视 base-image-import 任务:Once complete, monitor the base-image-import task:

watch -n1 az acr task list-runs -r $REGISTRY_BASE_ARTIFACTS -o table

运行后,键入 Ctrl + C 并监视日志:Once running, type Ctrl+C and monitor the logs:

az acr task logs -r $REGISTRY_BASE_ARTIFACTS

此时,应会看到 base-import-node 任务未通过验证并停止发布 hello-world 更新所需的序列。At this point, you should see the base-import-node task fail validation and stop the sequence to publish a hello-world update. 输出类似于:Output is similar to:

[...]
2020/10/30 03:57:39 Launching container with name: validate-base-image
Validating Image
NODE_VERSION: 15-alpine
BACKGROUND_COLOR: Red
ERROR: Invalid Color: Red
2020/10/30 03:57:40 Container failed during run: validate-base-image. No retries remaining.
failed to run step ID: validate-base-image: exit status 1

发布对 hello-world 的更新Publish an update to hello-world

hello-world 映像的更改会继续使用上次验证的 node 映像。Changes to the hello-world image will continue using the last validated node image.

通过了门控式验证的对基础 node 映像的任何其他更改都会触发对 hello-world 映像的基础映像更新。Any additional changes to the base node image that pass the gated validations will trigger base image updates to the hello-world image.

清理Cleaning up

如果不再需要本文中使用的资源,请将其删除:When no longer needed, delete the resources used in this article.

az group delete -n $REGISTRY_RG --no-wait -y
az group delete -n $REGISTRY_PUBLIC_RG --no-wait -y
az group delete -n $REGISTRY_BASE_ARTIFACTS_RG --no-wait -y
az group delete -n $AKV_RG --no-wait -y
az group delete -n $ACI_RG --no-wait -y

后续步骤Next steps

在本文中,In this article. 你使用了 ACR 任务来创建自动化门控工作流,以将更新的基础映像引入你的环境。you used ACR tasks to create an automated gating workflow to introduce updated base images to your environment. 请参阅相关信息,以管理 Azure 容器注册表中的映像。See related information to manage images in Azure Container Registry.