Een zelf-hostende agent uitvoeren in Docker
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
Dit artikel bevat instructies voor het uitvoeren van uw Azure Pipelines-agent in Docker. U kunt een zelf-hostende agent in Azure Pipelines instellen voor uitvoering in een Windows Server Core (voor Windows-hosts) of Ubuntu-container (voor Linux-hosts) met Docker. Dit is handig als u agents wilt uitvoeren met buitenste indeling, zoals Azure Container Instances. In dit artikel doorloopt u een volledig containervoorbeeld, waaronder het afhandelen van zelfupdates van agents.
Zowel Windows als Linux worden ondersteund als containerhosts. Windows-containers moeten worden uitgevoerd op een Windows vmImage
.
Als u uw agent wilt uitvoeren in Docker, geeft u enkele omgevingsvariabelen door aan docker run
, waarmee de agent wordt geconfigureerd om verbinding te maken met Azure Pipelines of Azure DevOps Server. Ten slotte past u de container aan uw behoeften aan. Taken en scripts kunnen afhankelijk zijn van specifieke hulpprogramma's die beschikbaar zijn voor de container PATH
en het is uw verantwoordelijkheid om ervoor te zorgen dat deze hulpprogramma's beschikbaar zijn.
Voor deze functie is agentversie 2.149 of hoger vereist. Azure DevOps 2019 is niet geleverd met een compatibele agentversie. U kunt echter het juiste agentpakket uploaden naar uw toepassingslaag als u Docker-agents wilt uitvoeren.
Windows
Hyper-V inschakelen
Hyper-V is niet standaard ingeschakeld in Windows. Als u isolatie tussen containers wilt bieden, moet u Hyper-V inschakelen. Anders wordt Docker voor Windows niet gestart.
Notitie
U moet virtualisatie op uw computer inschakelen. Deze functie is doorgaans standaard ingeschakeld. Als de Hyper-V-installatie echter mislukt, raadpleegt u de systeemdocumentatie voor het inschakelen van virtualisatie.
Docker voor Windows installeren
Als u Windows 10 gebruikt, kunt u de Docker Community Edition installeren. Installeer de Docker Enterprise Edition voor Windows Server 2016.
Docker overschakelen naar het gebruik van Windows-containers
Docker voor Windows is standaard geconfigureerd voor het gebruik van Linux-containers. Als u het uitvoeren van de Windows-container wilt toestaan, controleert u of Docker voor Windows de Windows-daemon uitvoert.
Het Dockerfile maken en bouwen
Maak vervolgens het Dockerfile.
Open een opdrachtprompt.
Maak een nieuwe map:
mkdir "C:\azp-agent-in-docker\"
Ga naar deze nieuwe map:
cd "C:\azp-agent-in-docker\"
Sla de volgende inhoud op in een bestand met de naam
C:\azp-agent-in-docker\azp-agent-windows.dockerfile
:FROM mcr.microsoft.com/windows/servercore:ltsc2022 WORKDIR /azp/ COPY ./start.ps1 ./ CMD powershell .\start.ps1
Sla de volgende inhoud op in
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})" }
Voer de volgende opdracht uit in die map:
docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .
De uiteindelijke afbeelding is getagd
azp-agent:windows
.
De afbeelding starten
Nu u een installatiekopieën hebt gemaakt, kunt u een container uitvoeren. Hiermee wordt de nieuwste versie van de agent geïnstalleerd, geconfigureerd en wordt de agent uitgevoerd. Deze is gericht op de opgegeven agentgroep (standaard de Default
agentgroep) van een opgegeven Azure DevOps- of Azure DevOps Server-exemplaar van uw keuze:
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
Mogelijk moet u de --network
parameter opgeven als u netwerkproblemen ondervindt.
docker run --network "Default Switch" < . . . >
Mogelijk moet u opgeven --interactive
en vlaggen (of gewoon -it
) als u de container wilt stoppen en de agent wilt verwijderen met Ctrl
+ C
.--tty
docker run --interactive --tty < . . . >
Als u een nieuwe agentcontainer voor elke pijplijntaak wilt, geeft u de --once
vlag door aan de run
opdracht.
docker run < . . . > --once
Met de --once
vlag kunt u een containerindelingssysteem, zoals Kubernetes of Azure Container Instances, gebruiken om een nieuwe kopie van de container te starten wanneer de taak is voltooid.
U kunt de agentnaam, de agentgroep en de werkmap van de agent beheren met behulp van optionele omgevingsvariabelen.
Linux
Docker installeren
Afhankelijk van uw Linux-distributie kunt u Docker Community Edition of Docker Enterprise Edition installeren.
Het Dockerfile maken en bouwen
Maak vervolgens het Dockerfile.
Open een terminal.
Een nieuwe map maken (aanbevolen):
mkdir ~/azp-agent-in-docker/
Ga naar deze nieuwe map:
cd ~/azp-agent-in-docker/
Sla de volgende inhoud op in
~/azp-agent-in-docker/azp-agent-linux.dockerfile
:Voor Alpine:
FROM alpine ENV TARGETARCH="linux-musl-x64" # Another option: # FROM arm64v8/alpine # ENV TARGETARCH="linux-musl-arm64" RUN apk update RUN apk upgrade RUN apk add bash curl git icu-libs jq 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" ]
Voor Ubuntu 22.04:
FROM ubuntu:22.04 ENV TARGETARCH="linux-x64" # Also can be "linux-arm", "linux-arm64". RUN apt update RUN apt upgrade -y RUN apt install -y curl git jq libicu70 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" ]
Verwijder opmerkingen bij de
ENV AGENT_ALLOW_RUNASROOT="true"
regel en verwijder het toevoegen van deagent
gebruiker vóór deze regel als u de agent als hoofdmap wilt uitvoeren.Notitie
Taken zijn mogelijk afhankelijk van uitvoerbare bestanden die naar verwachting door uw container worden verstrekt. U moet bijvoorbeeld de
zip
enunzip
pakketten toevoegen aan deRUN apt install -y
opdracht om deArchiveFiles
enExtractFiles
taken uit te voeren. Omdat dit een Linux Ubuntu-installatiekopie is die door de agent moet worden gebruikt, kunt u de installatiekopie naar wens aanpassen. Bijvoorbeeld: als u .NET-toepassingen wilt bouwen, kunt u het document De .NET SDK of de .NET Runtime op Ubuntu volgen en deze toevoegen aan uw installatiekopie.Sla de volgende inhoud
~/azp-agent-in-docker/start.sh
op in, zorg ervoor dat u einden van unix-stijl (LF) gebruikt:#!/bin/bash set -e if [ -z "${AZP_URL}" ]; then echo 1>&2 "error: missing AZP_URL environment variable" exit 1 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_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..." ./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 $!
Notitie
U moet ook een containerindelingssysteem, zoals Kubernetes of Azure Container Instances, gebruiken om nieuwe kopieën van de container te starten wanneer het werk is voltooid.
Voer de volgende opdracht uit in die map:
docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .
De uiteindelijke afbeelding is getagd
azp-agent:linux
.
De afbeelding starten
Nu u een installatiekopieën hebt gemaakt, kunt u een container uitvoeren. Hiermee wordt de nieuwste versie van de agent geïnstalleerd, geconfigureerd en wordt de agent uitgevoerd. Deze is gericht op de opgegeven agentgroep (standaard de Default
agentgroep) van een opgegeven Azure DevOps- of Azure DevOps Server-exemplaar van uw keuze:
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
Mogelijk moet u opgeven --interactive
en vlaggen (of gewoon -it
) als u de container wilt stoppen en de agent wilt verwijderen met Ctrl
+ C
.--tty
docker run --interactive --tty < . . . >
Als u een nieuwe agentcontainer voor elke pijplijntaak wilt, geeft u de --once
vlag door aan de run
opdracht.
docker run < . . . > --once
Met de --once
vlag kunt u een containerindelingssysteem, zoals Kubernetes of Azure Container Instances, gebruiken om een nieuwe kopie van de container te starten wanneer de taak is voltooid.
U kunt de agentnaam, de agentgroep en de werkmap van de agent beheren met behulp van optionele omgevingsvariabelen.
Omgevingsvariabelen
Omgevingsvariabele | Beschrijving |
---|---|
AZP_URL | De URL van het Azure DevOps- of Azure DevOps Server-exemplaar. |
AZP_TOKEN | Persoonlijk toegangstoken (PAT) met agentgroepen (lezen, beheren) bereik, gemaakt door een gebruiker die gemachtigd is om agents te configureren op AZP_URL . |
AZP_AGENT_NAME | Agentnaam (standaardwaarde: de hostnaam van de container). |
AZP_POOL | Naam van agentgroep (standaardwaarde: Default ). |
AZP_WORK | Werkmap (standaardwaarde: _work ). |
Hulpprogramma's toevoegen en de container aanpassen
U hebt een eenvoudige buildagent gemaakt. U kunt het Dockerfile uitbreiden met extra hulpprogramma's en hun afhankelijkheden, of uw eigen container bouwen met behulp van deze als basislaag. Zorg ervoor dat het volgende ongewijzigd blijft:
- Het
start.sh
script wordt aangeroepen door het Dockerfile. - Het
start.sh
script is de laatste opdracht in het Dockerfile. - Zorg ervoor dat afgeleide containers geen van de afhankelijkheden verwijderen die zijn opgegeven door het Dockerfile.
Docker gebruiken in een Docker-container
Als u Docker wilt gebruiken vanuit een Docker-container, koppelt u de Docker-socket.
Let op
Dit heeft ernstige gevolgen voor de beveiliging. De code in de container kan nu worden uitgevoerd als root op uw Docker-host.
Als u zeker weet dat u dit wilt doen, raadpleegt u de bindingskoppelingsdocumentatie op Docker.com.
Azure Kubernetes Service-cluster gebruiken
Let op
Houd er rekening mee dat alle docker-taken niet werken op AKS 1.19 of hoger vanwege docker in docker-beperking. Docker is vervangen door containers in Kubernetes 1.19 en Docker-in-Docker is niet meer beschikbaar.
Azure Kubernetes Service implementeren en configureren
Volg de stappen in quickstart: Een AKS-cluster (Azure Kubernetes Service) implementeren met behulp van Azure Portal. Hierna kan uw PowerShell- of Shell-console de kubectl
opdrachtregel gebruiken.
Azure Container Registry implementeren en configureren
Volg de stappen in quickstart: Een Azure-containerregister maken met behulp van Azure Portal. Hierna kunt u containers pushen en ophalen uit Azure Container Registry.
Geheimen configureren en een replicaset implementeren
Maak de geheimen in het AKS-cluster.
kubectl create secret generic azdevops \ --from-literal=AZP_URL=https://dev.azure.com/yourOrg \ --from-literal=AZP_TOKEN=YourPAT \ --from-literal=AZP_POOL=NameOfYourPool
Voer deze opdracht uit om uw container naar Container Registry te pushen:
docker push "<acr-server>/azp-agent:<tag>"
Container Registry-integratie configureren voor bestaande AKS-clusters.
Notitie
Als u meerdere abonnementen in Azure Portal hebt, gebruikt u deze opdracht eerst om een abonnement te selecteren
az account set --subscription "<subscription id or subscription name>"
az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"
Sla de volgende inhoud op in
~/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.sock
Met deze Kubernetes YAML maakt u een replicaset en een implementatie, waarbij
replicas: 1
het aantal of de agents worden aangegeven die op het cluster worden uitgevoerd.Voer deze opdracht uit:
kubectl apply -f ReplicationController.yml
Uw agents voeren nu het AKS-cluster uit.
Aangepaste MTU-parameter instellen
Geef MTU-waarde op voor netwerken die door containertaken worden gebruikt (handig voor docker-in-docker-scenario's in k8s-cluster).
U moet de omgevingsvariabele instellen AGENT_DOCKER_MTU_VALUE om de MTU-waarde in te stellen en de zelf-hostende agent opnieuw op te starten. Hier vindt u meer informatie over het opnieuw opstarten van agents en over het instellen van verschillende omgevingsvariabelen voor elke afzonderlijke agent.
Hiermee kunt u een netwerkparameter instellen voor de taakcontainer. Het gebruik van deze opdracht is vergelijkbaar met het gebruik van de volgende opdracht terwijl de containernetwerkconfiguratie:
-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE
Volumes koppelen met Docker in een Docker-container
Als een Docker-container wordt uitgevoerd in een andere Docker-container, gebruiken ze beide de daemon van de host, zodat alle koppelpaden verwijzen naar de host, niet naar de container.
Als we bijvoorbeeld het pad van de host willen koppelen aan de buitenste Docker-container, kunnen we deze opdracht gebruiken:
docker run ... -v "<path-on-host>:<path-on-outer-container>" ...
En als we het pad van de host willen koppelen aan de binnenste Docker-container, kunnen we deze opdracht gebruiken:
docker run ... -v "<path-on-host>:<path-on-inner-container>" ...
Maar we kunnen geen paden van de buitenste container koppelen aan de binnenste container; om dit te omzeilen, moeten we een ENV-variabele declareren:
docker run ... --env DIND_USER_HOME=$HOME ...
Hierna kunnen we de binnenste container starten vanuit de buitenste container met behulp van deze opdracht:
docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...
Algemene fouten
Als u Windows gebruikt en de volgende fout wordt weergegeven:
standard_init_linux.go:178: exec user process caused "no such file or directory"
Installeer Git Bash door git-scm te downloaden en te installeren.
Voer deze opdracht uit:
dos2unix ~/azp-agent-in-docker/Dockerfile
dos2unix ~/azp-agent-in-docker/start.sh
git add .
git commit -m "Fixed CR"
git push
Probeer het opnieuw. U krijgt de fout niet meer.