Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022
Este artigo fornece instruções para executar o agente do Azure Pipelines no Docker. Você pode configurar um agente auto-hospedado no Azure Pipelines para ser executado dentro de um Windows Server Core (para hosts do Windows) ou contêiner do Ubuntu (para hosts Linux) com o Docker. Isso é útil quando você quer executar agentes com orquestração externa, como Instâncias de Contêiner do Azure. Neste artigo, você verá um exemplo completo de contêiner, incluindo o tratamento de autoatendimento do agente.
O Windows e o Linux têm suporte como hosts de contêiner. Os contêineres do Windows devem ser executados em um Windows vmImage.
Para executar seu agente no Docker, você passará algumas variáveis de ambiente para docker run, o que configura o agente para se conectar ao Azure Pipelines ou Azure DevOps Server. Por fim, você personaliza o contêiner para atender às suas necessidades. Tarefas e scripts podem depender de ferramentas específicas estarem disponíveis no PATH do contêiner, e é sua responsabilidade garantir que essas ferramentas estejam disponíveis.
Windows
Habilitar Hyper-V
O Hyper-V não está habilitado por padrão no Windows. Se você quiser fornecer isolamento entre contêineres, deverá habilitar o Hyper-V. Caso contrário, o Docker for Windows não será iniciado.
Observação
Você deve habilitar a virtualização em seu computador. Normalmente, ela é habilitada por padrão. No entanto, se a instalação do Hyper-V falhar, consulte a documentação do sistema para saber como habilitar a virtualização.
Instalar o Docker para Windows
Se você estiver usando Windows 10, poderá instalar o Docker Community Edition. Para Windows Server 2016, instale a Edição Enterprise do Docker.
Alternar o Docker para usar contêineres do Windows
Por padrão, o Docker for Windows é configurado para usar contêineres do Linux. Para permitir a execução do contêiner do Windows, confirme se o Docker for Windows está executando o daemon do Windows.
Criar e compilar o Dockerfile
Em seguida, crie o Dockerfile.
Abra um prompt de comando.
Crie um novo diretório:
mkdir "C:\azp-agent-in-docker\"Vá para este novo diretório:
cd "C:\azp-agent-in-docker\"Salve o seguinte conteúdo em um arquivo chamado
C:\azp-agent-in-docker\azp-agent-windows.dockerfile:FROM mcr.microsoft.com/windows/servercore:ltsc2022 WORKDIR /azp/ COPY ./start.ps1 ./ CMD powershell .\start.ps1Salve o seguinte conteúdo em
C:\azp-agent-in-docker\start.ps1:function Print-Header ($header) { Write-Host "`n${header}`n" -ForegroundColor Cyan } if (-not (Test-Path Env:AZP_URL)) { Write-Error "error: missing AZP_URL environment variable" exit 1 } if (-not (Test-Path Env:AZP_TOKEN_FILE)) { if (-not (Test-Path Env:AZP_TOKEN)) { Write-Error "error: missing AZP_TOKEN environment variable" exit 1 } $Env:AZP_TOKEN_FILE = "\azp\.token" $Env:AZP_TOKEN | Out-File -FilePath $Env:AZP_TOKEN_FILE } Remove-Item Env:AZP_TOKEN if ((Test-Path Env:AZP_WORK) -and -not (Test-Path $Env:AZP_WORK)) { New-Item $Env:AZP_WORK -ItemType directory | Out-Null } New-Item "\azp\agent" -ItemType directory | Out-Null # Let the agent ignore the token env variables $Env:VSO_AGENT_IGNORE = "AZP_TOKEN,AZP_TOKEN_FILE" Set-Location agent Print-Header "1. Determining matching Azure Pipelines agent..." $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$(Get-Content ${Env:AZP_TOKEN_FILE})")) $package = Invoke-RestMethod -Headers @{Authorization=("Basic $base64AuthInfo")} "$(${Env:AZP_URL})/_apis/distributedtask/packages/agent?platform=win-x64&`$top=1" $packageUrl = $package[0].Value.downloadUrl Write-Host $packageUrl Print-Header "2. Downloading and installing Azure Pipelines agent..." $wc = New-Object System.Net.WebClient $wc.DownloadFile($packageUrl, "$(Get-Location)\agent.zip") Expand-Archive -Path "agent.zip" -DestinationPath "\azp\agent" try { Print-Header "3. Configuring Azure Pipelines agent..." .\config.cmd --unattended ` --agent "$(if (Test-Path Env:AZP_AGENT_NAME) { ${Env:AZP_AGENT_NAME} } else { hostname })" ` --url "$(${Env:AZP_URL})" ` --auth PAT ` --token "$(Get-Content ${Env:AZP_TOKEN_FILE})" ` --pool "$(if (Test-Path Env:AZP_POOL) { ${Env:AZP_POOL} } else { 'Default' })" ` --work "$(if (Test-Path Env:AZP_WORK) { ${Env:AZP_WORK} } else { '_work' })" ` --replace Print-Header "4. Running Azure Pipelines agent..." .\run.cmd } finally { Print-Header "Cleanup. Removing Azure Pipelines agent..." .\config.cmd remove --unattended ` --auth PAT ` --token "$(Get-Content ${Env:AZP_TOKEN_FILE})" }Execute o seguinte comando nesse diretório:
docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .A imagem final está marcada como
azp-agent:windows.
Inicia a imagem
Agora que você criou uma imagem, você pode executar um contêiner. Isso instala a versão mais recente do agente, a configura e executa o agente. Ele tem como destino o pool de agentes (o pool de agentes Default por padrão) de uma instância especificada do Azure DevOps ou Azure DevOps Server de sua escolha:
docker run -e AZP_URL="<Azure DevOps instance>" -e AZP_TOKEN="<Personal Access Token>" -e AZP_POOL="<Agent Pool Name>" -e AZP_AGENT_NAME="Docker Agent - Windows" --name "azp-agent-windows" azp-agent:windows
Talvez seja necessário especificar o parâmetro --network se você tiver problemas de rede.
docker run --network "Default Switch" < . . . >
Talvez seja necessário especificar os sinalizadores --interactive e --tty (ou simplesmente-it) se quiser parar o contêiner e remover o agente com Ctrl + C.
docker run --interactive --tty < . . . >
Se você quiser um novo contêiner de agente para cada trabalho de pipeline, passe o sinalizador --once para o comando run.
docker run < . . . > --once
Com o sinalizador --once, talvez você deseje usar um sistema de orquestração de contêineres, como Kubernetes ou Instâncias de Contêiner do Azure, para iniciar uma nova cópia do contêiner quando o trabalho for concluído.
Opcionalmente, você pode controlar o nome do agente, o pool de agentes e o diretório de trabalho do agente usando variáveis de ambiente opcionais.
Linux
Instalar o Docker
Dependendo da distribuição do Linux, você pode instalar o Docker Community Edition ou o Docker Edição Enterprise.
Criar e compilar o Dockerfile
Em seguida, crie o Dockerfile.
Abra um terminal.
Crie um novo diretório (recomendado):
mkdir ~/azp-agent-in-docker/Vá para este novo diretório:
cd ~/azp-agent-in-docker/Salve o seguinte conteúdo em
~/azp-agent-in-docker/azp-agent-linux.dockerfile:Para Alpine, usando a técnica descrita neste artigo:
FROM python:3-alpine ENV TARGETARCH="linux-musl-x64" # Another option: # FROM arm64v8/alpine # ENV TARGETARCH="linux-musl-arm64" RUN apk update && \ apk upgrade && \ apk add bash curl gcc git icu-libs jq musl-dev python3-dev libffi-dev openssl-dev cargo make # Install Azure CLI RUN pip install --upgrade pip RUN pip install azure-cli WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh RUN adduser -D agent RUN chown agent ./ USER agent # Another option is to run the agent as root. # ENV AGENT_ALLOW_RUNASROOT="true" ENTRYPOINT [ "./start.sh" ]Para ubuntu 24.04:
FROM ubuntu:24.04 ENV TARGETARCH="linux-x64" # Also can be "linux-arm", "linux-arm64". RUN apt update && \ apt upgrade -y && \ apt install -y curl git jq libicu74 # Install Azure CLI RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh # Create agent user and set up home directory RUN useradd -m -d /home/agent agent RUN chown -R agent:agent /azp /home/agent USER agent # Another option is to run the agent as root. # ENV AGENT_ALLOW_RUNASROOT="true" ENTRYPOINT [ "./start.sh" ]Para o Ubuntu 22.04:
FROM ubuntu:22.04 ENV TARGETARCH="linux-x64" # Also can be "linux-arm", "linux-arm64". RUN apt update && \ apt upgrade -y && \ apt install -y curl git jq libicu70 # Install Azure CLI RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh # Create agent user and set up home directory RUN useradd -m -d /home/agent agent RUN chown -R agent:agent /azp /home/agent USER agent # Another option is to run the agent as root. # ENV AGENT_ALLOW_RUNASROOT="true" ENTRYPOINT [ "./start.sh" ]
Remova o comentário da linha
ENV AGENT_ALLOW_RUNASROOT="true"e remova a adição do usuárioagentantes dessa linha se quiser executar o agente como root.Observação
As tarefas podem depender de executáveis que seu contêiner deve fornecer. Por exemplo, você deve adicionar os pacotes
zipeunzipao comandoRUN apt install -ypara executar as tarefasArchiveFileseExtractFiles. Além disso, como essa é uma imagem do Ubuntu do Linux para o agente usar, você pode personalizar a imagem conforme necessário. Por exemplo: se você precisar criar aplicativos .NET, poderá seguir o documento Instalar o SDK do .NET ou o Runtime do .NET no Ubuntu e adicioná-lo à sua imagem.Salve o seguinte conteúdo em
~/azp-agent-in-docker/start.sh, certificando-se de usar terminações de linha no estilo Unix (LF):#!/bin/bash set -e if [ -z "${AZP_URL}" ]; then echo 1>&2 "error: missing AZP_URL environment variable" exit 1 fi if [ -n "$AZP_CLIENTID" ]; then echo "Using service principal credentials to get token" az login --allow-no-subscriptions --service-principal --username "$AZP_CLIENTID" --password "$AZP_CLIENTSECRET" --tenant "$AZP_TENANTID" # adapted from https://learn.microsoft.com/en-us/azure/databricks/dev-tools/user-aad-token AZP_TOKEN=$(az account get-access-token --query accessToken --output tsv) echo "Token retrieved" fi if [ -z "${AZP_TOKEN_FILE}" ]; then if [ -z "${AZP_TOKEN}" ]; then echo 1>&2 "error: missing AZP_TOKEN environment variable" exit 1 fi AZP_TOKEN_FILE="/azp/.token" echo -n "${AZP_TOKEN}" > "${AZP_TOKEN_FILE}" fi unset AZP_CLIENTSECRET unset AZP_TOKEN if [ -n "${AZP_WORK}" ]; then mkdir -p "${AZP_WORK}" fi cleanup() { trap "" EXIT if [ -e ./config.sh ]; then print_header "Cleanup. Removing Azure Pipelines agent..." # If the agent has some running jobs, the configuration removal process will fail. # So, give it some time to finish the job. while true; do ./config.sh remove --unattended --auth "PAT" --token $(cat "${AZP_TOKEN_FILE}") && break echo "Retrying in 30 seconds..." sleep 30 done fi } print_header() { lightcyan="\033[1;36m" nocolor="\033[0m" echo -e "\n${lightcyan}$1${nocolor}\n" } # Let the agent ignore the token env variables export VSO_AGENT_IGNORE="AZP_TOKEN,AZP_TOKEN_FILE" print_header "1. Determining matching Azure Pipelines agent..." AZP_AGENT_PACKAGES=$(curl -LsS \ -u user:$(cat "${AZP_TOKEN_FILE}") \ -H "Accept:application/json" \ "${AZP_URL}/_apis/distributedtask/packages/agent?platform=${TARGETARCH}&top=1") AZP_AGENT_PACKAGE_LATEST_URL=$(echo "${AZP_AGENT_PACKAGES}" | jq -r ".value[0].downloadUrl") if [ -z "${AZP_AGENT_PACKAGE_LATEST_URL}" -o "${AZP_AGENT_PACKAGE_LATEST_URL}" == "null" ]; then echo 1>&2 "error: could not determine a matching Azure Pipelines agent" echo 1>&2 "check that account "${AZP_URL}" is correct and the token is valid for that account" exit 1 fi print_header "2. Downloading and extracting Azure Pipelines agent..." curl -LsS "${AZP_AGENT_PACKAGE_LATEST_URL}" | tar -xz & wait $! source ./env.sh trap "cleanup; exit 0" EXIT trap "cleanup; exit 130" INT trap "cleanup; exit 143" TERM print_header "3. Configuring Azure Pipelines agent..." # Despite it saying "PAT", it can be the token through the service principal ./config.sh --unattended \ --agent "${AZP_AGENT_NAME:-$(hostname)}" \ --url "${AZP_URL}" \ --auth "PAT" \ --token $(cat "${AZP_TOKEN_FILE}") \ --pool "${AZP_POOL:-Default}" \ --work "${AZP_WORK:-_work}" \ --replace \ --acceptTeeEula & wait $! print_header "4. Running Azure Pipelines agent..." chmod +x ./run.sh # To be aware of TERM and INT signals call ./run.sh # Running it with the --once flag at the end will shut down the agent after the build is executed ./run.sh "$@" & wait $!Observação
Você também deve usar um sistema de orquestração de contêineres, como Kubernetes ou Instâncias de Contêiner do Azure, para iniciar novas cópias do contêiner quando o trabalho for concluído.
Execute o seguinte comando nesse diretório:
docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .A imagem final está marcada como
azp-agent:linux.
Inicia a imagem
Agora que você criou uma imagem, você pode executar um contêiner. Isso instala a versão mais recente do agente, a configura e executa o agente. Ele tem como destino o pool de agentes (o pool de agentes Default por padrão) de uma instância especificada do Azure DevOps ou Azure DevOps Server de sua escolha:
docker run -e AZP_URL="<Azure DevOps instance>" -e AZP_TOKEN="<Personal Access Token>" -e AZP_POOL="<Agent Pool Name>" -e AZP_AGENT_NAME="Docker Agent - Linux" --name "azp-agent-linux" azp-agent:linux
Talvez seja necessário especificar os sinalizadores --interactive e --tty (ou simplesmente-it) se quiser parar o contêiner e remover o agente com Ctrl + C.
docker run --interactive --tty < . . . >
Se você quiser um novo contêiner de agente para cada trabalho de pipeline, passe o sinalizador --once para o comando run.
docker run < . . . > --once
Com o sinalizador --once, talvez você deseje usar um sistema de orquestração de contêineres, como Kubernetes ou Instâncias de Contêiner do Azure, para iniciar uma nova cópia do contêiner quando o trabalho for concluído.
Opcionalmente, você pode controlar o nome do agente, o pool de agentes e o diretório de trabalho do agente usando variáveis de ambiente opcionais.
Variáveis de ambiente
| Variável de ambiente | Descrição |
|---|---|
| AZP_URL | A URL da instância do Azure DevOps ou do Azure DevOps Server. |
| AZP_TOKEN | Token de Acesso Pessoal (PAT) |
| AZP_CLIENTID | ID do cliente da entidade de serviço |
| AZP_CLIENTSECRET | Segredo do cliente da entidade de serviço |
| AZP_TENANTID | ID do locatário da entidade de serviço |
| AZP_AGENT_NAME | Nome do agente (valor padrão: o nome do host do contêiner). |
| AZP_POOL | Nome do pool de agentes (valor padrão: Default). |
| AZP_WORK | Diretório de trabalho (valor padrão: _work). |
Autenticação
Um dos seguintes procedimentos é necessário:
- Se estiver usando um PAT:
AZP_TOKEN - Se estiver usando uma entidade de serviço:
AZP_CLIENTID,AZP_CLIENTSECRETeAZP_TENANTID
Autorização
O token ou a entidade de serviço deve ter o escopo Pools de agentes (ler, gerenciar) no nível Organização de AZP_URL. Se estiver usando um PAT, o token deverá ser criado por um usuário que tenha permissão para configurar agentes.
Adicionar ferramentas e personalizar o contêiner
Você criou um agente de build básico. Você pode estender o Dockerfile para incluir ferramentas adicionais e suas dependências ou criar seu próprio contêiner usando este como uma camada base. Apenas certifique-se de que os seguintes itens sejam deixados intocados:
- O script
start.shé chamado pelo Dockerfile. - O script
start.shé o último comando no Dockerfile. - Verifique se os contêineres derivados não removem nenhuma das dependências declaradas pelo Dockerfile.
Usar o Docker em um contêiner do Docker
Para usar o Docker de dentro de um contêiner do Docker, você pode montar o soquete do Docker.
Cuidado
Fazer isso tem sérias implicações de segurança. O código dentro do contêiner agora pode ser executado como raiz no host do Docker.
Se tiver certeza de que deseja fazer isso, veja a documentação de bind mount no Docker.com.
Usar o cluster do Serviço de Kubernetes do Azure
Cuidado
Considere que todas as tarefas baseadas no Docker não funcionarão no AKS 1.19 ou posterior devido à restrição de Docker em Docker. O Docker foi substituído por containerd no Kubernetes 1.19, e o Docker-in-Docker ficou indisponível.
Implantar e configurar o Serviço de Kubernetes do Azure
Siga as etapas em Início Rápido: implantar um cluster do AKS (Serviço de Kubernetes do Azure) usando o portal do Azure. Depois disso, o console do PowerShell ou do Shell poderá usar a linha de comando kubectl.
Implantar e configurar o Registro de Contêiner do Azure
Siga as etapas no Início Rápido: Criar um registro de contêiner do Azure usando o portal do Azure. Depois disso, você pode enviar e puxar contêineres do Azure Container Registry.
Configurar segredos e implantar um conjunto de réplicas
Crie os segredos no cluster do AKS.
kubectl create secret generic azdevops \ --from-literal=AZP_URL=https://dev.azure.com/yourOrg \ --from-literal=AZP_TOKEN=YourPAT \ --from-literal=AZP_POOL=NameOfYourPoolExecute esse comando para fazer push do seu contêiner para o Registro de Contêiner:
docker push "<acr-server>/azp-agent:<tag>"Configurar a integração do Registro de Contêiner para clusters do AKS existentes.
Observação
Se você tiver várias assinaturas no portal do Azure, use este comando primeiro para selecionar uma assinatura
az account set --subscription "<subscription id or subscription name>"az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"Salve o seguinte conteúdo em
~/AKS/ReplicationController.yml:apiVersion: apps/v1 kind: Deployment metadata: name: azdevops-deployment labels: app: azdevops-agent spec: replicas: 1 # here is the configuration for the actual agent always running selector: matchLabels: app: azdevops-agent template: metadata: labels: app: azdevops-agent spec: containers: - name: kubepodcreation image: <acr-server>/azp-agent:<tag> env: - name: AZP_URL valueFrom: secretKeyRef: name: azdevops key: AZP_URL - name: AZP_TOKEN valueFrom: secretKeyRef: name: azdevops key: AZP_TOKEN - name: AZP_POOL valueFrom: secretKeyRef: name: azdevops key: AZP_POOL volumeMounts: - mountPath: /var/run/docker.sock name: docker-volume volumes: - name: docker-volume hostPath: path: /var/run/docker.sockEsse YAML do Kubernetes cria um conjunto de réplica e uma implantação, em
replicas: 1que indica o número ou os agentes que estão em execução no cluster.Execute este comando:
kubectl apply -f ReplicationController.yml
Agora, seus agentes executarão o cluster do AKS.
Definir parâmetro MTU personalizado
Permitir a especificação do valor de MTU para redes usadas por trabalhos de contêiner (útil para cenários docker em docker no cluster do k8s).
Você precisa definir a variável de ambiente AGENT_DOCKER_MTU_VALUE para definir o valor de MTU e, em seguida, reiniciar o agente auto-hospedado. Você pode encontrar mais informações sobre a reinicialização do agente aqui e sobre como definir variáveis de ambiente diferentes para cada agente individual aqui.
Isso permite que você configure um parâmetro de rede para o contêiner de trabalho; o uso desse comando é semelhante ao uso do próximo comando enquanto a configuração de rede de contêiner:
-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE
Montar volumes usando o Docker em um contêiner do Docker
Se um contêiner do Docker for executado dentro de outro contêiner do Docker, ambos usarão o daemon do host, portanto, todos os caminhos de montagem referenciam o host, não o contêiner.
Por exemplo, se quisermos montar o caminho do host para o contêiner externo do Docker, podemos usar este comando:
docker run ... -v "<path-on-host>:<path-on-outer-container>" ...
E se quisermos montar o caminho do host para o contêiner interno do Docker, poderemos usar este comando:
docker run ... -v "<path-on-host>:<path-on-inner-container>" ...
Porém, não podemos montar caminhos do contêiner externo para o interno; para contornar isso, precisamos declarar uma variável ENV:
docker run ... --env DIND_USER_HOME=$HOME ...
Depois disso, podemos iniciar o contêiner interno do externo usando este comando:
docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...
Erros comuns
Se você estiver usando o Windows e receber o seguinte erro:
standard_init_linux.go:178: exec user process caused "no such file or directory"
Instale o Git Bash baixando e instalando git-scm.
Execute este comando:
dos2unix ~/azp-agent-in-docker/Dockerfile
dos2unix ~/azp-agent-in-docker/start.sh
git add .
git commit -m "Fixed CR"
git push
Tente novamente. Você não recebe mais o erro.