Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Serviços de DevOps do Azure | Azure DevOps Server | Azure DevOps Server 2022
Este artigo fornece instruções para executar seu agente do Azure Pipelines no Docker. Você pode configurar um agente auto-hospedado no Azure Pipelines para ser executado dentro de um contêiner Windows Server Core (para hosts Windows) ou Ubuntu (para hosts Linux) com o Docker. Isso é útil quando você deseja executar agentes com orquestração externa, como Instâncias de Contêiner do Azure. Neste artigo, você percorrerá um exemplo completo de contêiner, incluindo a autoatualização do agente de manipulação.
O Windows e o Linux são suportados 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 runo , que configura o agente para se conectar ao Azure Pipelines ou ao Azure DevOps Server. Finalmente, você personaliza o contêiner para atender às suas necessidades. As tarefas e os scripts podem depender da disponibilidade de PATHferramentas específicas no contêiner, e é sua responsabilidade garantir que essas ferramentas estejam disponíveis.
Mac OS
Ativar Hyper-V
O Hyper-V não está habilitado por padrão no Windows. Se quiser fornecer isolamento entre contêineres, habilite o Hyper-V. Caso contrário, o Docker para Windows não será iniciado.
Nota
Você deve habilitar a virtualização em sua máquina. Normalmente, é ativado 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 estiver a utilizar o Windows 10, pode instalar o Docker Community Edition. Para o Windows Server 2016, instale o Docker Enterprise Edition.
Alternar o Docker para usar contêineres do Windows
Por padrão, o Docker para Windows está configurado para usar contêineres Linux. Para permitir a execução do contêiner do Windows, confirme se o Docker para Windows está executando o daemon do Windows.
Elaborar e gerar o Dockerfile
Em seguida, crie o Dockerfile.
Abra uma linha de comandos.
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 dentro desse diretório:
docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .A imagem final está marcada com .
azp-agent:windows
Iniciar a imagem
Agora que você criou uma imagem, você pode executar um contêiner. Isso instala a versão mais recente do agente, configura-a e executa o agente. Ele tem como alvo o pool de agentes especificado (o Default pool de agentes por padrão) de uma instância especificada do Azure DevOps ou do 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 tiver problemas de rede.
docker run --network "Default Switch" < . . . >
Talvez seja necessário especificar as sinalizações --interactive e --tty (ou simplesmente -it) se quiser parar o contentor 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 --once sinalizador para o run comando.
docker run < . . . > --once
Com o --once indicador, talvez queira usar um sistema de orquestração de contentores, como o Kubernetes ou as Instâncias de Contentores do Azure, para iniciar uma nova cópia do contentor quando o trabalho estiver concluído.
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.
Aplicações Linux
Instalar o Docker
Dependendo da sua distribuição Linux, você pode instalar o Docker Community Edition ou o Docker Enterprise Edition.
Elaborar e gerar 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 a Alpine, ao usar a técnica descrita em para este problema:
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 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" ]
Descomente a linha
ENV AGENT_ALLOW_RUNASROOT="true"e remova a adição do usuárioagentantes dessa linha se quiser executar o agente como root.Nota
As tarefas podem depender dos executáveis que se espera que seu contêiner forneça. Por exemplo, deve adicionar os pacotes
zipeunzipao comandoRUN apt install -ypara executar as tarefasArchiveFileseExtractFiles. Além disso, como esta é uma imagem do Linux Ubuntu para o agente usar, você pode personalizar a imagem conforme necessário. Por exemplo: se você precisar criar aplicativos .NET, você pode seguir o documento Instalar o SDK do .NET ou o Tempo de Execução do .NET no Ubuntu e adicioná-lo à sua imagem.Salve o seguinte conteúdo no
~/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 $!Nota
Você também deve usar um sistema de orquestração de contêiner, 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 dentro desse diretório:
docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .A imagem final está marcada com .
azp-agent:linux
Iniciar a imagem
Agora que você criou uma imagem, você pode executar um contêiner. Isso instala a versão mais recente do agente, configura-a e executa o agente. Ele tem como alvo o pool de agentes especificado (o Default pool de agentes por padrão) de uma instância especificada do Azure DevOps ou do 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 as sinalizações --interactive e --tty (ou simplesmente -it) se quiser parar o contentor 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 --once sinalizador para o run comando.
docker run < . . . > --once
Com o --once indicador, talvez queira usar um sistema de orquestração de contentores, como o Kubernetes ou as Instâncias de Contentores do Azure, para iniciar uma nova cópia do contentor quando o trabalho estiver concluído.
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 | Principal de serviço ID do cliente |
| AZP_CLIENTSECRET | Segredo do cliente principal do serviço |
| AZP_TENANTID | ID do locatário principal do 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
É necessária uma das seguintes opções:
- Se estiver a utilizar um PAT:
AZP_TOKEN - Se estiver a utilizar uma entidade de serviço:
AZP_CLIENTID,AZP_CLIENTSECRETeAZP_TENANTID
Autorização
O token ou principal de serviço deve ter o escopo de Agent Pools (ler, gerir) ao nível da Organização de AZP_URL. Se estiver usando um PAT, o token deve 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 compilação 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 são deixados intocados:
- O
start.shscript é chamado pelo Dockerfile. - O
start.shscript é o último comando no Dockerfile. - Certifique-se de que os contêineres derivados não removam 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ê vincula e monta o soquete do Docker.
Atenção
Fazer isso tem sérias implicações de segurança. O código dentro do contêiner agora pode ser executado como root no host do Docker.
Se tiver certeza de que deseja fazer isso, consulte a documentação de bind mount em Docker.com.
Usar o cluster do Serviço Kubernetes do Azure
Atenção
Por favor, considere que qualquer tarefa baseada em docker não funcionará no AKS 1.19 ou posterior devido à restrição do docker no 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 Kubernetes do Azure
Siga as etapas em Início Rápido: implantar um cluster do Azure Kubernetes Service (AKS) usando o portal do Azure. Depois disso, o seu console do PowerShell ou do Shell pode usar a linha de comando kubectl.
Implantar e configurar o Registro de Contêiner do Azure
Siga as etapas em Início rápido: criar um registo de contentor do Azure usando o Azure Portal. Depois disso, você pode enviar e extrair contêineres do Registro de Contêiner do Azure.
Configurar segredos e implementar um conjunto de réplicas
Crie os segredos no cluster 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 este comando para enviar seu contêiner para o Registro de contêiner:
docker push "<acr-server>/azp-agent:<tag>"Configure a integração do Registro de Contêiner para clusters AKS existentes.
Nota
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.sockEste Kubernetes YAML cria um conjunto de réplicas e uma implantação, onde
replicas: 1indica o número ou os agentes que estão sendo executados no cluster.Execute este comando:
kubectl apply -f ReplicationController.yml
Agora, os vossos agentes irão gerir o cluster AKS.
Definir parâmetro MTU personalizado
Permitir a especificação do valor MTU para redes usadas por trabalhos de contêiner (útil para cenários de docker-in-docker no cluster k8s).
Você precisa definir a variável de ambiente AGENT_DOCKER_MTU_VALUE para definir o valor do MTU e, em seguida, reiniciar o agente auto-hospedado. Você pode encontrar mais sobre a reinicialização do agente aqui e sobre a configuração de 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 deste comando é semelhante ao uso do próximo comando durante a configuração de rede de contêiner:
-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE
Montagem de 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 fazem referência ao host, não ao 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, podemos usar este comando:
docker run ... -v "<path-on-host>:<path-on-inner-container>" ...
Mas não podemos montar caminhos do recipiente externo para o interno; para contornar isso, temos que declarar uma variável ENV:
docker run ... --env DIND_USER_HOME=$HOME ...
Depois disso, podemos iniciar o recipiente interno a partir do externo usando este comando:
docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...
Erros comuns
Se estiver a utilizar 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 o 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.