教程:使用 Azure 容器注册表任务在云中生成并部署容器映像Tutorial: Build and deploy container images in the cloud with Azure Container Registry Tasks

ACR 任务是 Azure 容器注册表中的功能套件,用于在 Azure 中以简化、高效的方式生成 Docker 容器映像。ACR Tasks is a suite of features within Azure Container Registry that provides streamlined and efficient Docker container image builds in Azure. 本文介绍如何使用 ACR 任务的快速任务功能 。In this article, you learn how to use the quick task feature of ACR Tasks.

“内部循环”开发周期是指编写代码、生成和测试应用程序,然后提交到源代码管理的迭代过程。The "inner-loop" development cycle is the iterative process of writing code, building, and testing your application before committing to source control. 快速任务可将内部循环扩展到云中,同时提供成功生成验证并自动将成功生成的映像推送到容器注册表。A quick task extends your inner-loop to the cloud, providing you with build success validation and automatic pushing of successfully built images to your container registry. 映像将在云中本机生成,其位置靠近注册表,可加快部署。Your images are built natively in the cloud, close to your registry, enabling faster deployment.

所有 Dockerfile 专业知识都可以直接转移到 ACR 任务。All your Dockerfile expertise is directly transferrable to ACR Tasks. 要通过 ACR 任务在云中生成,无需更改 Dockerfile,只需运行命令。You don't have to change your Dockerfiles to build in the cloud with ACR Tasks, just the command you run.

本教程是系列教程的第一部分,将介绍:In this tutorial, part one of a series:

  • 获取示例应用程序源代码Get the sample application source code
  • 在 Azure 中生成容器映像Build a container image in Azure
  • 将容器部署到 Azure 容器实例Deploy a container to Azure Container Instances

后续教程将会介绍如何使用 ACR 任务在代码提交和基础映像更新时自动生成容器映像。In subsequent tutorials, you learn to use ACR Tasks for automated container image builds on code commit and base image update. ACR 任务也可运行多步骤任务,使用 YAML 文件来定义相关步骤,以便生成并推送多个容器,并可选择对其进行测试。ACR Tasks can also run multi-step tasks, using a YAML file to define steps to build, push, and optionally test multiple containers.

Note

在 Azure China 中使用 Azure CLI 2.0 之前,请首先运行 az cloud set -n AzureChinaCloud 更改云环境。Before you can use Azure CLI 2.0 in Azure China, please run az cloud set -n AzureChinaCloud first to change the cloud environment. 如果要切换回全局 Azure,请再次运行 az cloud set -n AzureCloudIf you want to switch back to Global Azure, run az cloud set -n AzureCloud again.

若要在本地使用 Azure CLI,必须安装 Azure CLI 2.0.46 或更高版本,并使用 az login 登录。If you'd like to use the Azure CLI locally, you must have Azure CLI version 2.0.46 or later installed and logged in with az login. 运行 az --version 即可查找版本。Run az --version to find the version. 如果需要安装或升级 CLI,请参阅安装 Azure CLIIf you need to install or upgrade the CLI, see Install Azure CLI.

先决条件Prerequisites

GitHub 帐户GitHub account

https://github.com 上创建帐户(如果还没有帐户)。Create an account on https://github.com if you don't already have one. 本系列教程使用 GitHub 存储库来演示 ACR 任务中的自动映像生成。This tutorial series uses a GitHub repository to demonstrate automated image builds in ACR Tasks.

创建示例存储库分支Fork sample repository

接下来,使用 GitHub UI 在 GitHub 帐户中创建示例存储库分支。Next, use the GitHub UI to fork the sample repository into your GitHub account. 本教程从存储库的源生成容器映像,下一教程会将提交推送到存储库的分支以启动自动化任务。In this tutorial, you build a container image from the source in the repo, and in the next tutorial, you push a commit to your fork of the repo to kick off an automated task.

创建此存储库的分支: https://github.com/Azure-Samples/acr-build-helloworld-nodeFork this repository: https://github.com/Azure-Samples/acr-build-helloworld-node

GitHub 中创建分支按钮(突出显示)的屏幕截图

克隆分支Clone your fork

创建存储库分支后,克隆分支然后输入包含本地克隆的目录。Once you've forked the repo, clone your fork and enter the directory containing your local clone.

使用 git 克隆存储库,将“<your-github-username>”替换为你的 GitHub 用户名 :Clone the repo with git, replace <your-github-username> with your GitHub username:

git clone https://github.com/<your-github-username>/acr-build-helloworld-node

输入包含源代码的目录:Enter the directory containing the source code:

cd acr-build-helloworld-node

Bash shellBash shell

本系列教程中的命令设置为 Bash Shell 的格式。The commands in this tutorial series are formatted for the Bash shell. 如果更希望使用 PowerShell、命令提示符或另一种 shell,可能需要相应地调整行延续和环境变量格式。If you prefer to use PowerShell, Command Prompt, or another shell, you may need to adjust the line continuation and environment variable format accordingly.

使用 ACR 任务在 Azure 中生成Build in Azure with ACR Tasks

现已将源代码拉取到计算机中,请执行以下步骤来创建容器注册表并使用 ACR 任务生成容器映像。Now that you've pulled the source code down to your machine, follow these steps to create a container registry and build the container image with ACR Tasks.

为使执行示例命令更轻松,本系列教程使用 shell 环境变量。To make executing the sample commands easier, the tutorials in this series use shell environment variables. 执行以下命令来设置 ACR_NAME 变量。Execute the following command to set the ACR_NAME variable. 将“<registry-name>”替换为新容器注册表的唯一名称 。Replace <registry-name> with a unique name for your new container registry. 注册表名称在 Azure 中必须唯一,仅包含小写字母,并且包含 5-50 个字母数字字符。The registry name must be unique within Azure, contain only lower case letters, and contain 5-50 alphanumeric characters. 本教程中创建的其他资源都基于该名称,因此仅需要修改该第一个变量。The other resources you create in the tutorial are based on this name, so you should need to modify only this first variable.

ACR_NAME=<registry-name>

填充容器注册表环境变量后,现在应能够复制并粘贴本教程中的其余命令,并且无需编辑任何值。With the container registry environment variable populated, you should now be able to copy and paste the remainder of the commands in the tutorial without editing any values. 执行以下命令来创建资源组和容器注册表:Execute the following commands to create a resource group and container registry:

RES_GROUP=$ACR_NAME # Resource Group name

az group create --resource-group $RES_GROUP --location chinanorth
az acr create --resource-group $RES_GROUP --name $ACR_NAME --sku Standard --location chinanorth

创建注册表后,使用 ACR 任务从示例代码生成容器映像。Now that you have a registry, use ACR Tasks to build a container image from the sample code. 执行 az acr build 命令以执行快速任务 :Execute the az acr build command to perform a quick task:

az acr build --registry $ACR_NAME --image helloacrtasks:v1 .

az acr build 命令的输出类似于以下示例。Output from the az acr build command is similar to the following. 可以看到源代码(“上下文”)已上传到 Azure,同时可以看到 ACR 任务在云中运行的 docker build 操作的详细信息。You can see the upload of the source code (the "context") to Azure, and the details of the docker build operation that the ACR task runs in the cloud. 由于 ACR 任务使用 docker build 生成映像,因此无需对 Dockerfile 进行任何更改即可立即开始使用 ACR 任务。Because ACR tasks use docker build to build your images, no changes to your Dockerfiles are required to start using ACR Tasks immediately.

Packing source code into tar file to upload...
Sending build context (4.813 KiB) to ACR...
Queued a build with build ID: da1
Waiting for build agent...
2018/08/22 18:31:42 Using acb_vol_01185991-be5f-42f0-9403-a36bb997ff35 as the home volume
2018/08/22 18:31:42 Setting up Docker configuration...
2018/08/22 18:31:43 Successfully set up Docker configuration
2018/08/22 18:31:43 Logging in to registry: myregistry.azurecr.cn
2018/08/22 18:31:55 Successfully logged in
Sending build context to Docker daemon   21.5kB
Step 1/5 : FROM node:9-alpine
9-alpine: Pulling from library/node
Digest: sha256:8dafc0968fb4d62834d9b826d85a8feecc69bd72cd51723c62c7db67c6dec6fa
Status: Image is up to date for node:9-alpine
 ---> a56170f59699
Step 2/5 : COPY . /src
 ---> 88087d7e709a
Step 3/5 : RUN cd /src && npm install
 ---> Running in e80e1263ce9a
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN helloworld@1.0.0 No repository field.

up to date in 0.1s
Removing intermediate container e80e1263ce9a
 ---> 26aac291c02e
Step 4/5 : EXPOSE 80
 ---> Running in 318fb4c124ac
Removing intermediate container 318fb4c124ac
 ---> 113e157d0d5a
Step 5/5 : CMD ["node", "/src/server.js"]
 ---> Running in fe7027a11787
Removing intermediate container fe7027a11787
 ---> 20a27b90eb29
Successfully built 20a27b90eb29
Successfully tagged myregistry.azurecr.cn/helloacrtasks:v1
2018/08/22 18:32:11 Pushing image: myregistry.azurecr.cn/helloacrtasks:v1, attempt 1
The push refers to repository [myregistry.azurecr.cn/helloacrtasks]
6428a18b7034: Preparing
c44b9827df52: Preparing
172ed8ca5e43: Preparing
8c9992f4e5dd: Preparing
8dfad2055603: Preparing
c44b9827df52: Pushed
172ed8ca5e43: Pushed
8dfad2055603: Pushed
6428a18b7034: Pushed
8c9992f4e5dd: Pushed
v1: digest: sha256:b038dcaa72b2889f56deaff7fa675f58c7c666041584f706c783a3958c4ac8d1 size: 1366
2018/08/22 18:32:43 Successfully pushed image: myregistry.azurecr.cn/helloacrtasks:v1
2018/08/22 18:32:43 Step ID acb_step_0 marked as successful (elapsed time in seconds: 15.648945)
The following dependencies were found:
- image:
    registry: myregistry.azurecr.cn
    repository: helloacrtasks
    tag: v1
    digest: sha256:b038dcaa72b2889f56deaff7fa675f58c7c666041584f706c783a3958c4ac8d1
  runtime-dependency:
    registry: registry.hub.docker.com
    repository: library/node
    tag: 9-alpine
    digest: sha256:8dafc0968fb4d62834d9b826d85a8feecc69bd72cd51723c62c7db67c6dec6fa
  git: {}

Run ID: da1 was successful after 1m9.970148252s

在接近输出末尾的位置,ACR 任务显示其为映像找到的依赖项。Near the end of the output, ACR Tasks displays the dependencies it's discovered for your image. 这使 ACR 任务可在基础映像更新(如基础映像基于 OS 或框架补丁进行更新)时自动化映像生成。This enables ACR Tasks to automate image builds on base image updates, such as when a base image is updated with OS or framework patches. 该系列教程稍后会介绍针对基础映像更新的 ACR 任务支持。You learn about ACR Tasks support for base image updates later in this tutorial series.

部署到 Azure 容器实例Deploy to Azure Container Instances

ACR 任务默认将成功生成的映像自动推送到注册表,这样即可立即从注册表部署这些映像。ACR tasks automatically push successfully built images to your registry by default, allowing you to deploy them from your registry immediately.

本部分将创建 Azure Key Vault 和服务主体,然后使用服务主体的凭据将容器部署到 Azure 容器实例 (ACI)。In this section, you create an Azure Key Vault and service principal, then deploy the container to Azure Container Instances (ACI) using the service principal's credentials.

配置注册表身份验证Configure registry authentication

所有生产方案都应使用服务主体访问 Azure 容器注册表。All production scenarios should use service principals to access an Azure container registry. 使用服务主体可以提供对容器映像的基于角色的访问控制。Service principals allow you to provide role-based access control to your container images. 例如,可将服务主体配置为拥有注册表的仅限提取的访问权限。For example, you can configure a service principal with pull-only access to a registry.

创建密钥保管库Create a key vault

如果 Azure Key Vault 中没有保管库,请在 Azure CLI 中使用以下命令创建一个保管库。If you don't already have a vault in Azure Key Vault, create one with the Azure CLI using the following commands.

AKV_NAME=$ACR_NAME-vault

az keyvault create --resource-group $RES_GROUP --name $AKV_NAME

创建服务主体并存储凭据Create a service principal and store credentials

现在需要创建服务主体,并将其凭据存储在 Key Vault 中。You now need to create a service principal and store its credentials in your key vault.

请使用 az ad sp create-for-rbac 命令创建服务主体,使用 az keyvault secret set 将服务主体的密码存储在保管库中:Use the az ad sp create-for-rbac command to create the service principal, and az keyvault secret set to store the service principal's password in the vault:

# Create service principal, store its password in AKV (the registry *password*)
az keyvault secret set \
  --vault-name $AKV_NAME \
  --name $ACR_NAME-pull-pwd \
  --value $(az ad sp create-for-rbac \
                --name $ACR_NAME-pull \
                --scopes $(az acr show --name $ACR_NAME --query id --output tsv) \
                --role acrpull \
                --query password \
                --output tsv)

上述命令中的 --role 参数使用“acrpull” 角色配置服务主体,该角色授予其对注册表的只拉取访问权限。The --role argument in the preceding command configures the service principal with the acrpull role, which grants it pull-only access to the registry. 若要同时授予推送和拉取访问权限,请将 --role 参数更改为“acrpush” 。To grant both push and pull access, change the --role argument to acrpush.

接下来,将服务主体的 appId(传递给 Azure 容器注册表用于身份验证的“用户名”)存储在保管库中 :Next, store the service principal's appId in the vault, which is the username you pass to Azure Container Registry for authentication:

# Store service principal ID in AKV (the registry *username*)
az keyvault secret set \
    --vault-name $AKV_NAME \
    --name $ACR_NAME-pull-usr \
    --value $(az ad sp show --id http://$ACR_NAME-pull --query appId --output tsv)

现已创建 Azure Key Vault 并在其中存储了两个机密:You've created an Azure Key Vault and stored two secrets in it:

  • $ACR_NAME-pull-usr:用作容器注册表用户名的服务主体 ID。$ACR_NAME-pull-usr: The service principal ID, for use as the container registry username.
  • $ACR_NAME-pull-pwd:用作容器注册表密码的服务主体密码。$ACR_NAME-pull-pwd: The service principal password, for use as the container registry password.

现在,当你或你的应用程序和服务从注册表提取映像时,可以按名称引用这些机密。You can now reference these secrets by name when you or your applications and services pull images from the registry.

使用 Azure CLI 部署容器Deploy a container with Azure CLI

将服务主体凭据作为 Azure Key Vault 机密存储后,应用程序和服务可以使用它们来访问专用注册表。Now that the service principal credentials are stored as Azure Key Vault secrets, your applications and services can use them to access your private registry.

执行以下 az container create 命令来部署容器实例。Execute the following az container create command to deploy a container instance. 该命令使用 Azure Key Vault 中存储的服务主体凭据对容器注册表进行身份验证。The command uses the service principal's credentials stored in Azure Key Vault to authenticate to your container registry.

az container create \
    --resource-group $RES_GROUP \
    --name acr-tasks \
    --image $ACR_NAME.azurecr.cn/helloacrtasks:v1 \
    --registry-login-server $ACR_NAME.azurecr.cn \
    --registry-username $(az keyvault secret show --vault-name $AKV_NAME --name $ACR_NAME-pull-usr --query value -o tsv) \
    --registry-password $(az keyvault secret show --vault-name $AKV_NAME --name $ACR_NAME-pull-pwd --query value -o tsv) \
    --dns-name-label acr-tasks-$ACR_NAME \
    --query "{FQDN:ipAddress.fqdn}" \
    --output table

--dns-name-label 值必须在 Azure 中唯一,因此,上述命令会将容器注册表名称追加到容器的 DNS 名称标签。The --dns-name-label value must be unique within Azure, so the preceding command appends your container registry's name to the container's DNS name label. 该命令的输出显示容器的完全限定域名 (FQDN),例如:The output from the command displays the container's fully qualified domain name (FQDN), for example:

FQDN
----------------------------------------------
acr-tasks-myregistry.chinanorth.azurecontainer.console.azure.cn

记下容器的 FQDN,后续部分将会用到它。Take note of the container's FQDN, you'll use it in the next section.

验证部署Verify the deployment

若要查看容器的启动过程,请使用 az container attach 命令:To watch the startup process of the container, use the az container attach command:

az container attach --resource-group $RES_GROUP --name acr-tasks

az container attach 输出在拉取映像和启动时会首先显示容器状态,然后将本地控制台的 STDOUT 和 STDERR 绑定到容器的 STDOUT 和 STDERR。The az container attach output first displays the container's status as it pulls the image and starts, then binds your local console's STDOUT and STDERR to that of the container's.

Container 'acr-tasks' is in state 'Running'...
(count: 1) (last timestamp: 2018-08-22 18:39:10+00:00) pulling image "myregistry.azurecr.cn/helloacrtasks:v1"
(count: 1) (last timestamp: 2018-08-22 18:39:15+00:00) Successfully pulled image "myregistry.azurecr.cn/helloacrtasks:v1"
(count: 1) (last timestamp: 2018-08-22 18:39:17+00:00) Created container
(count: 1) (last timestamp: 2018-08-22 18:39:17+00:00) Started container

Start streaming logs:
Server running at http://localhost:80

出现 Server running at http://localhost:80 时,在浏览器中导航到容器的 FQDN 以查看正在运行的应用程序。When Server running at http://localhost:80 appears, navigate to the container's FQDN in your browser to see the running application. FQDN 应已在上一部分执行的 az container create 命令的输出中显示。The FQDN should have been displayed in the output of the az container create command you executed in the previous section.

浏览器中呈现示例应用程序的屏幕截图

若要从容器拆离控制台,请按 Control+CTo detach your console from the container, hit Control+C.

清理资源Clean up resources

使用 az container delete 命令停止容器实例:Stop the container instance with the az container delete command:

az container delete --resource-group $RES_GROUP --name acr-tasks

若要删除本教程中创建的所有资源,包括容器注册表、密钥保管库和服务主体,请运行以下命令 。To remove all resources you've created in this tutorial, including the container registry, key vault, and service principal, issue the following commands. 但是,本系列的下一个教程也会使用这些资源,因此,如果直接前往下一个教程,则可以保留这些资源。These resources are used in the next tutorial in the series, however, so you might want to keep them if you move on directly to the next tutorial.

az group delete --resource-group $RES_GROUP
az ad sp delete --id http://$ACR_NAME-pull

后续步骤Next steps

使用快速任务测试内部循环后,请配置一个生成任务,以便在将源代码提交到 Git 存储库时触发容器映像生成 :Now that you've tested your inner loop with a quick task, configure a build task to trigger container images builds when you commit source code to a Git repository: