练习 - 创建在 Azure 上运行的生成代理

已完成

在此单元中,若要配置可在 Microsoft Azure Pipelines 中使用的生成代理,请使用 Microsoft Azure 上运行的虚拟机。 我们提供了一个虚拟机,你可在本模块中使用它。

在本单元中,你将学习以下内容:

  • 在 Azure 上创建一台 Ubuntu 虚拟机作为生成代理。
  • 在 Microsoft Azure DevOps 中创建代理池。
  • 创建访问令牌,用 Azure DevOps 对代理进行身份验证。
  • 用生成“Space Game”网站所需的软件配置代理。
  • 配置代理,使其连接到 Azure DevOps,以便它可以接收生成作业。
  • 验证代理是否已连接到 Azure DevOps,是否准备好接收生成作业。

可通过多种方法在 Azure 上创建虚拟机。 在本单元中,你将使用名为 Cloud Shell 的交互式终端创建一个 Ubuntu 虚拟机。

要配置 VM,有多种方法可供选择:

  • 对于 Linux VM,可以直接通过 SSH 连接,并以交互方式配置系统。
  • 可以使用 ARM 模板、Bicep 或其他自动预配工具来自动执行部署。
  • 如果需要部署许多生成代理,可以创建预安装了所有软件的 VM 映像。

以交互方式配置系统是一种很好的入门方式,因为这有助于理解该过程以及所需内容。 要简化该过程,需通过 SSH 连接到 Ubuntu VM 并运行 shell 脚本来设置生成代理。

备注

如果不熟悉如何连接或配置 Linux 系统,请按照下面的步骤操作。 可以将相同的概念应用于 Windows 生成代理。

创建 Linux 虚拟机

在这一部分中,你会创建运行 Ubuntu 20.04 的 VM,它将用作生成代理。 该 VM 还不会被设置为生成代理,也不会有生成“Space Game”Web 应用程序所需的任何工具。 你很快就会将其设置好。

通过 Azure 门户打开 Cloud Shell

重要

若要完成本模块中的练习,你需要自己的 Azure 订阅。

  1. 转到 Azure 门户并登录。

  2. 在菜单上,选择“Cloud Shell”。 出现提示时,选择“Bash”体验。

    A screenshot of the Azure portal showing the location of the Cloud Shell menu item.

    注意

    Cloud Shell 要求使用 Azure 存储资源来保存在 Cloud Shell 中创建的任何文件。 首次打开 Cloud Shell 时,系统将提示你创建资源组、存储帐户和 Azure 文件存储共享。 此设置会自动用于所有未来的 Cloud Shell 会话。

选择 Azure 区域

区域是地理位置内的一个或多个 Azure 数据中心。 例如美国东部、美国西部和北欧等区域。 每个 Azure 资源(包括 Azure VM)都分配有一个区域。

要使命令更容易运行,请先选择一个默认区域。 指定默认区域后,除非指定其他区域,否别后面的命令会使用该区域。

  1. 在 Cloud Shell 中,若要列出 Azure 订阅提供的区域,请运行以下 az account list-locations 命令:

    az account list-locations \
      --query "[].{Name: name, DisplayName: displayName}" \
      --output table
    
  2. 从输出的 Name 列中,选择靠近你的区域。 例如,选择 eastasiawestus2

  3. 运行 az configure 以设置默认区域。 将 <REGION> 替换为你选择的区域的名称:

    az configure --defaults location=<REGION>
    

    此示例将 westus2 设置为默认区域:

    az configure --defaults location=westus2
    

创建资源组

创建一个资源组,以包含本培训模块中使用的资源。

  • 若要创建一个名为 tailspin-space-game-rg 的资源组,请运行以下 az group create 命令

    az group create --name tailspin-space-game-rg
    

创建 VM

若要创建 VM,请运行以下 az vm create 命令:

az vm create \
    --name MyLinuxAgent \
    --resource-group tailspin-space-game-rg \
    --image canonical:0001-com-ubuntu-server-focal:20_04-lts:latest \
    --size Standard_DS2_v2 \
    --admin-username azureuser \
    --generate-ssh-keys

该 VM 需要几分钟时间才会启动。

Standard_DS2_v2 指定 VM 的大小。 VM 的大小定义了其处理器速度、内存量、初始存储量以及预期的网络带宽。 这与 Microsoft 托管代理提供的大小相同。 在实际操作中,可以选择可提供更多计算能力或其他功能(例如图形处理)的大小。

--resource-group 参数指定资源组,用于保存我们需创建的所有内容。 资源组可作为一个整体来管理构成我们解决方案的所有 VM、磁盘、网络接口和其他元素。

创建代理池

请回顾一下,代理池组织生成代理。 在本部分,你将在 Azure DevOps 中创建代理池。 稍后,在配置代理时,你将指定代理池的名称,以便它可以将自己注册到正确的池中。

  1. 在 Azure DevOps 中,转到“Space Game - Web - Agent”项目。

  2. 选择“Project settings”。

  3. 在“管道”下,选择“代理池”

    A screenshot of the project settings in Azure DevOps showing the location of the Agent pools menu item.

  4. 选择“Add pool”。

  5. 在“Add pool”窗口中:

    1. 在“Pool to link”下,选择“New”。
    2. 在“Pool type”下,选择“Self-hosted”。
    3. 在“Name”下,输入“MyAgentPool”。

    在实际操作中,你将为池选择一个更具描述性的名称。

  6. 选择创建。 新代理池将显示在列表中。

创建个人访问令牌

为了让生成代理能够向 Azure DevOps 注册自身,你需要一种使其能验证自己的方法。

为此,你可以创建个人访问令牌。 个人访问令牌(简称 PAT)是密码的替代方法。 你可以使用 PAT 向 Azure DevOps 等服务进行身份验证。

重要

与密码一样,请确保将访问令牌保存在安全的位置。 在本部分中,将访问令牌存储为一个环境变量,这样它就不会出现在你的 shell 脚本中。

  1. 在 Azure DevOps 中,打开配置文件设置,然后选择“个人访问令牌”

    A screenshot of Azure DevOps showing the location of the Personal access tokens menu item.

  2. 选择“New Token”。

  3. 输入你的令牌名称,例如“生成代理”

  4. 在“范围”下,选择底部的“显示所有范围”链接

  5. 查找“代理池”,然后选择“读取和管理”

  6. 选择创建

  7. 将令牌复制到安全的位置。

    稍后,将使用令牌使生成代理能够对 Azure Pipelines 的访问进行身份验证。

连接到 VM

在本部分,你将通过 SSH 连接到 Linux VM,以便对其进行配置。

回想一下,不能以交互方式登录到 Microsoft 托管代理。 因为专用生成代理属于你自己,所以你可以随意登录并配置它。

借助连接到生成代理的功能,你可以使用生成软件所需的工具对其进行配置。 它还使你能够在构建管道配置时排除问题。

  1. 若要获取 VM 的 IP 地址,请在 Cloud Shell 中运行 az vm show

    IPADDRESS=$(az vm show \
      --name MyLinuxAgent \
      --resource-group tailspin-space-game-rg \
      --show-details \
      --query [publicIps] \
      --output tsv)
    

    此命令将 IP 地址保存在名为 IPADDRESS 的 Bash 变量中。

  2. 将 VM 的 IP 地址输出到控制台:

    echo $IPADDRESS
    
  3. 创建 SSH 与 VM 的连接。 输入在上一步中收到的 IP 地址来替代 $IPADDRESS。 在提示符下,输入“是”以继续连接。

    ssh azureuser@$IPADDRESS
    

    现在,已通过 SSH 连接到 VM。

    此命令有效,因为在之前运行 az vm create 时提供了 --generate-ssh-keys 选项。 该选项创建用于登录到 VM 的 SSH 密钥对。

在 VM 上安装生成工具

在本部分,你将使用生成“Space Game”网站所需的工具配置 VM

回想一下,现有的生成过程需使用以下工具:

  • 用于生成应用程序的 .NET SDK
  • Node.js,用于执行生成任务
  • npm,Node.js 包管理器
  • gulp,一个 Node.js 包,用于缩小 JavaScript 和 CSS 文件

这些是生成过程所需的主要工具。 若要进行安装,需从 GitHub 下载并运行 shell 脚本。

注意

生成过程会使用其他工具(如 node-sass)将 Sass 文件 (.scss) 转换为 CSS 文件 (.css)。 不过,生成运行时 Node.js 会安装这些工具。

我们首先更新名为“apt”的 Ubuntu 包管理器。 此操作会从包存储库中提取最新信息,这通常是在设置新的 Ubuntu 系统时要做的第一件事。

  1. 在 SSH 连接中,更新 apt 包管理器缓存:

    sudo apt-get update
    

    sudo 使用管理员或根权限运行该命令。

  2. 要从 GitHub 下载名为“build-tools.sh”的 shell 脚本,请运行下面的 curl 命令:

    curl https://raw.githubusercontent.com/MicrosoftDocs/mslearn-tailspin-spacegame-web/main/.agent-tools/build-tools.sh > build-tools.sh
    
  3. 将该脚本输出至终端,方便检查其内容:

    cat build-tools.sh
    

    显示以下结果:

    #!/bin/bash
    set -e
    
    # Select a default .NET version if one is not specified
    if [ -z "$DOTNET_VERSION" ]; then
      DOTNET_VERSION=6.0.300
    fi
    
    # Add the Node.js PPA so that we can install the latest version
    curl -sL https://deb.nodesource.com/setup_16.x | bash -
    
    # Install Node.js and jq
    apt-get install -y nodejs
    
    apt-get install -y jq
    
    # Install gulp
    npm install -g gulp
    
    # Change ownership of the .npm directory to the sudo (non-root) user
    chown -R $SUDO_USER ~/.npm
    
    # Install .NET as the sudo (non-root) user
    sudo -i -u $SUDO_USER bash << EOF
    curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c LTS -v $DOTNET_VERSION
    EOF
    

    该脚本会安装 Node.js、npm、gulp 和 .NET Core。

    通过设置 DOTNET_VERSION 环境变量,可以指定要安装的 .NET 版本。 如果未设置此变量,该脚本将安装现有生成配置使用的版本。 为了便于学习,请不要设置此变量。 应允许该脚本使用默认版本。

  4. 使脚本可执行,然后运行脚本:

    chmod u+x build-tools.sh
    sudo ./build-tools.sh
    

    此脚本需要花几分钟运行。

    在实践中,现在可运行命令来验证是否已成功安装每个软件组件。

在 VM 上安装代理软件

现在是时候在 VM 上安装代理软件了。 此软件使 VM 充当生成代理并从 Azure Pipelines 接收生成作业。

注册过程会先检查已安装的软件,然后向 Azure Pipelines 注册代理。 因此,请务必在安装所有其他软件之后设置代理。 在实践中,如需安装其他软件,可再次注册代理。

文档说明了如何手动设置自托管 Linux 代理以及 macOS 和 Windows 代理。 运行 shell 脚本来配置代理,这与在上一部分设置生成工具的方式非常相似。

重要

在此处运行的脚本是供学习使用。 在实际操作中,首先应了解生成的脚本中的每个命令对整个系统的影响。 在本模块的结尾,我们将提供一个详细介绍选项的文档。

  1. 要从 GitHub 下载名为“build-agent.sh”的 shell 脚本,请运行下面的 curl 命令:

    curl https://raw.githubusercontent.com/MicrosoftDocs/mslearn-tailspin-spacegame-web/main/.agent-tools/build-agent.sh > build-agent.sh
    
  2. 将该脚本输出至终端,方便检查其内容:

    cat build-agent.sh
    

    显示以下结果:

    #!/bin/bash
    set -e
    
    # Select a default agent version if one is not specified
    if [ -z "$AZP_AGENT_VERSION" ]; then
      AZP_AGENT_VERSION=2.187.2
    fi
    
    # Verify Azure Pipelines token is set
    if [ -z "$AZP_TOKEN" ]; then
      echo 1>&2 "error: missing AZP_TOKEN environment variable"
      exit 1
    fi
    
    # Verify Azure DevOps URL is set
    if [ -z "$AZP_URL" ]; then
      echo 1>&2 "error: missing AZP_URL environment variable"
      exit 1
    fi
    
    # If a working directory was specified, create that directory
    if [ -n "$AZP_WORK" ]; then
      mkdir -p "$AZP_WORK"
    fi
    
    # Create the Downloads directory under the user's home directory
    if [ -n "$HOME/Downloads" ]; then
      mkdir -p "$HOME/Downloads"
    fi
    
    # Download the agent package
    curl https://vstsagentpackage.azureedge.net/agent/$AZP_AGENT_VERSION/vsts-agent-linux-x64-$AZP_AGENT_VERSION.tar.gz > $HOME/Downloads/vsts-agent-linux-x64-$AZP_AGENT_VERSION.tar.gz
    
    # Create the working directory for the agent service to run jobs under
    if [ -n "$AZP_WORK" ]; then
      mkdir -p "$AZP_WORK"
    fi
    
    # Create a working directory to extract the agent package to
    mkdir -p $HOME/azp/agent
    
    # Move to the working directory
    cd $HOME/azp/agent
    
    # Extract the agent package to the working directory
    tar zxvf $HOME/Downloads/vsts-agent-linux-x64-$AZP_AGENT_VERSION.tar.gz
    
    # Install the agent software
    ./bin/installdependencies.sh
    
    # Configure the agent as the sudo (non-root) user
    chown $SUDO_USER $HOME/azp/agent
    sudo -u $SUDO_USER ./config.sh --unattended \
      --agent "${AZP_AGENT_NAME:-$(hostname)}" \
      --url "$AZP_URL" \
      --auth PAT \
      --token "$AZP_TOKEN" \
      --pool "${AZP_POOL:-Default}" \
      --work "${AZP_WORK:-_work}" \
      --replace \
      --acceptTeeEula
    
    # Install and start the agent service
    ./svc.sh install
    ./svc.sh start
    

    你无需了解每行的工作原理,但下面提供了此脚本执行内容的概要:

    • 它以 .tar.gz 文件形式下载代理包并提取其内容。
    • 在提取的文件中,该脚本:
      • 运行名为“installdependencies.sh”的 shell 脚本来安装代理软件。
      • 运行名为“config.sh”的 shell 脚本来配置代理,并向 Azure Pipelines 注册该代理。
      • 运行名为“svc.sh”的 shell 脚本,安装并启动代理服务。

    该脚本使用环境变量,让你可以提供有关 Azure DevOps 组织的详细信息。 摘要如下:

    Bash 变量 描述 默认
    AZP_AGENT_VERSION 要安装的代理软件的版本 我们上一次用于测试此模块的版本
    AZP_URL Azure DevOps 组织的 URL (无)
    AZP_TOKEN 个人访问令牌 (无)
    AZP_AGENT_NAME 在 Azure DevOps 中显示的代理名称 系统的主机名
    AZP_POOL 代理池的名称 默认值
    AZP_WORK 代理执行生成任务的工作目录 _work

    如果脚本没有为未设置的变量提供默认值,脚本将显示一条错误消息并立即退出。

    在接下来的步骤中,设置以下环境变量:

    • AZP_AGENT_VERSION
    • AZP_URL
    • AZP_TOKEN
    • AZP_AGENT_NAME
    • AZP_POOL

    现在,我们建议不设置其他变量。

  3. 设置 AZP_AGENT_NAME 环境变量,指定代理的名称。 建议指定为“MyLinuxAgent”

    export AZP_AGENT_NAME=MyLinuxAgent
    
  4. 设置 AZP_URL 环境变量,指定 Azure DevOps 组织的 URL。

    将 <组织> 替换为自己的。 可从显示 Azure DevOps 的浏览器选项卡中获取名称。

    export AZP_URL=https://dev.azure.com/organization
    
  5. 设置 AZP_TOKEN 环境变量以指定个人访问令牌(即在此单元前面部分复制的长令牌值)。

    将 <令牌> 替换为自己的令牌。

    export AZP_TOKEN=token
    
  6. 设置 AZP_POOL 环境变量,指定代理池的名称。 前面创建了一个名为“MyAgentPool”的池。

    export AZP_POOL=MyAgentPool
    
  7. 设置 AZP_AGENT_VERSION 环境变量,指定代理的最新版本。

    export AZP_AGENT_VERSION=$(curl -s https://api.github.com/repos/microsoft/azure-pipelines-agent/releases | jq -r '.[0].tag_name' | cut -d "v" -f 2)
    

    Linux 计算机上的 YAML 管道必须使用最新版代理,即使它是预发行版也是如此。 代理软件会不断更新,因此可执行 curl 命令,从 GitHub 存储库获取版本信息。 该命令使用 jq 从返回的 JSON 字符串读取最新版本。

  8. 将代理版本输出到控制台。 (可选)进行检查确保这是最新版本。

    echo $AZP_AGENT_VERSION
    
  9. 使脚本可以执行,然后运行脚本:

    chmod u+x build-agent.sh
    sudo -E ./build-agent.sh
    

    sudo 使脚本能够以根用户身份运行。 -E 参数保存当前环境变量,包括你设置的变量,方便脚本可以使用它们。

    当脚本运行时,你会看到代理连接到 Azure DevOps,添加到代理池中,然后代理连接被测试。

验证代理是否正在运行

你已成功在 VM 上安装了生成工具和代理软件。 作为验证步骤,请转到 Azure DevOps,在代理池中查看你的代理。

  1. 在 Azure DevOps 中,转到“Space Game - Web - Agent”项目。

  2. 选择“Project settings”。

  3. 在“管道”下,选择“代理池”

  4. 选择“MyAgentPool”

  5. 选择“代理”选项卡。

    可以看到你的代理处于联机状态且已准备好接受生成作业。

    A screenshot of Azure DevOps showing the status of the private agent. The agent shows as online, idle, and enabled.

    提示

    如果生成代理显示为“Offline”,尝试稍候片刻后再刷新页面。

  6. 选择你的代理,即“MyLinuxAgent”

  7. 选择“功能”选项卡。

    在安装过程中,配置过程会扫描工具功能的生成代理。 可以看到 npm 作为其中一个列出。 回想一下,原始的生成配置指定 npm 必须安装在代理上。

    A screenshot of Azure DevOps showing a few of the agent's capabilities. The npm capability is highlighted.

    当指定要使用哪个代理池时,可将任一项目包括在 demands 部分中。 包含它们可确保 Azure Pipelines 选择具有生成应用程序所需软件的生成代理。 它还让你能够创建具有各种软件配置的代理池。 Azure Pipelines 将根据你的需求选择正确的配置。