Spuštění agenta v místním prostředí v Dockeru
Azure DevOps Services | Azure DevOps Server 2022 – Azure DevOps Server 2019
Tento článek obsahuje pokyny ke spuštění agenta Azure Pipelines v Dockeru. V Azure Pipelines můžete nastavit agenta v místním prostředí tak, aby běžel uvnitř jádra Windows Serveru (pro hostitele s Windows) nebo kontejneru Ubuntu (pro hostitele s Linuxem) pomocí Dockeru. To je užitečné, když chcete spouštět agenty s vnější orchestrací, jako je Azure Container Instances. V tomto článku si projdete kompletní příklad kontejneru, včetně samoobslužné aktualizace agenta.
Windows i Linux se podporují jako hostitelé kontejnerů. Kontejnery Windows by měly běžet ve Windows vmImage
.
Pokud chcete spustit agenta v Dockeru, předáte do docker run
něho několik proměnných prostředí, které nakonfiguruje agenta pro připojení ke službě Azure Pipelines nebo Azure DevOps Serveru. Nakonec kontejner přizpůsobíte tak, aby vyhovoval vašim potřebám. Úlohy a skripty můžou záviset na dostupnosti konkrétních nástrojů v kontejneru PATH
a je vaší zodpovědností zajistit, aby byly tyto nástroje k dispozici.
Tato funkce vyžaduje agenta verze 2.149 nebo novější. Azure DevOps 2019 se nedoručil s kompatibilní verzí agenta. Pokud ale chcete spustit agenty Dockeru, můžete do vrstvy aplikace nahrát správný balíček agenta.
Windows
Povolení Hyper-V
Ve Windows není ve výchozím nastavení povolená technologie Hyper-V. Pokud chcete zajistit izolaci mezi kontejnery, musíte povolit Technologii Hyper-V. Jinak se Docker pro Windows nespustí.
Poznámka:
Na počítači musíte povolit virtualizaci. Obvykle je povolená ve výchozím nastavení. Pokud se ale instalace Hyper-V nezdaří, projděte si dokumentaci k systému a zjistěte, jak povolit virtualizaci.
Instalace Dockeru pro Windows
Pokud používáte Windows 10, můžete nainstalovat Docker Community Edition. Pro Windows Server 2016 nainstalujte edice Enterprise Dockeru.
Přepnutí Dockeru na používání kontejnerů Windows
Ve výchozím nastavení je Docker pro Windows nakonfigurovaný tak, aby používal kontejnery Linuxu. Pokud chcete povolit spuštění kontejneru Windows, ověřte, že docker pro Windows používá proces démon Systému Windows.
Vytvoření a sestavení souboru Dockerfile
Dále vytvořte soubor Dockerfile.
Otevřete příkazový řádek.
Vytvořte nový adresář:
mkdir "C:\azp-agent-in-docker\"
Přejděte do tohoto nového adresáře:
cd "C:\azp-agent-in-docker\"
Uložte následující obsah do souboru s názvem
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
Uložte následující obsah do
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})" }
V tomto adresáři spusťte následující příkaz:
docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .
Konečný obrázek je označen
azp-agent:windows
.
Spuštění obrázku
Teď, když jste vytvořili image, můžete spustit kontejner. Tím se nainstaluje nejnovější verze agenta, nakonfiguruje ji a spustí agenta. Cílí na zadaný fond agentů ( Default
ve výchozím nastavení fond agentů) zadané instance Azure DevOps nebo Azure DevOps Serveru podle vašeho výběru:
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
Pokud narazíte na problémy se sítí, budete možná muset zadat --network
parametr.
docker run --network "Default Switch" < . . . >
Pokud chcete kontejner zastavit a odebrat agenta,C
Ctrl
+ budete možná muset zadat --interactive
a --tty
označit příznakem (nebo jednoduše).-it
docker run --interactive --tty < . . . >
Pokud chcete nový kontejner agenta pro každou úlohu kanálu, předejte --once
příznak příkazurun
.
docker run < . . . > --once
--once
Pomocí příznaku můžete chtít použít systém orchestrace kontejnerů, jako je Kubernetes nebo Azure Container Instances, ke spuštění nové kopie kontejneru po dokončení úlohy.
Název agenta, fond agentů a pracovní adresář agenta můžete řídit pomocí volitelných proměnných prostředí.
Linux
Instalace Dockeru
V závislosti na distribuci Linuxu můžete nainstalovat Docker Community Edition nebo Docker edice Enterprise.
Vytvoření a sestavení souboru Dockerfile
Dále vytvořte soubor Dockerfile.
Otevřete terminál.
Vytvořte nový adresář (doporučeno):
mkdir ~/azp-agent-in-docker/
Přejděte do tohoto nového adresáře:
cd ~/azp-agent-in-docker/
Uložte následující obsah do
~/azp-agent-in-docker/azp-agent-linux.dockerfile
:Pro 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" ]
Pro 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" ]
Odkomentujte
ENV AGENT_ALLOW_RUNASROOT="true"
řádek a odeberte přidáníagent
uživatele před tento řádek, pokud chcete spustit agenta jako kořen.Poznámka:
Úlohy můžou záviset na spustitelných souborech, u které se očekává, že váš kontejner bude poskytovat. Pokud chcete například spouštět
ArchiveFiles
úlohy, musíte doRUN apt install -y
příkazu přidatzip
balíčkyunzip
aExtractFiles
balíčky. Vzhledem k tomu, že se jedná o image Ubuntu linuxu, kterou má agent používat, můžete image přizpůsobit podle potřeby. Například: Pokud potřebujete sestavit aplikace .NET, můžete postupovat podle dokumentu Instalace sady .NET SDK nebo modulu runtime .NET na Ubuntu a jeho přidání do image.Uložte následující obsah do
~/azp-agent-in-docker/start.sh
, ujistěte se, že používáte konce řádků ve stylu Unix (LF):#!/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 $!
Poznámka:
Pokud chcete spustit nové kopie kontejneru po dokončení práce, musíte také použít systém orchestrace kontejnerů, jako je Kubernetes nebo Azure Container Instances.
V tomto adresáři spusťte následující příkaz:
docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .
Konečný obrázek je označen
azp-agent:linux
.
Spuštění obrázku
Teď, když jste vytvořili image, můžete spustit kontejner. Tím se nainstaluje nejnovější verze agenta, nakonfiguruje ji a spustí agenta. Cílí na zadaný fond agentů ( Default
ve výchozím nastavení fond agentů) zadané instance Azure DevOps nebo Azure DevOps Serveru podle vašeho výběru:
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
Pokud chcete kontejner zastavit a odebrat agenta,C
Ctrl
+ budete možná muset zadat --interactive
a --tty
označit příznakem (nebo jednoduše).-it
docker run --interactive --tty < . . . >
Pokud chcete nový kontejner agenta pro každou úlohu kanálu, předejte --once
příznak příkazurun
.
docker run < . . . > --once
--once
Pomocí příznaku můžete chtít použít systém orchestrace kontejnerů, jako je Kubernetes nebo Azure Container Instances, ke spuštění nové kopie kontejneru po dokončení úlohy.
Název agenta, fond agentů a pracovní adresář agenta můžete řídit pomocí volitelných proměnných prostředí.
Proměnné prostředí
Proměnná prostředí | Popis |
---|---|
AZP_URL | Adresa URL instance Azure DevOps nebo Azure DevOps Serveru. |
AZP_TOKEN | Osobní přístupový token (PAT) s oborem fondů agentů (čtení, správa) vytvořeným uživatelem, který má oprávnění ke konfiguraci agentů, na adrese AZP_URL . |
AZP_AGENT_NAME | Název agenta (výchozí hodnota: název hostitele kontejneru). |
AZP_POOL | Název fondu agentů (výchozí hodnota: Default ). |
AZP_WORK | Pracovní adresář (výchozí hodnota: _work ). |
Přidání nástrojů a přizpůsobení kontejneru
Vytvořili jste základního agenta sestavení. Soubor Dockerfile můžete rozšířit tak, aby zahrnoval další nástroje a jejich závislosti, nebo pomocí tohoto souboru vytvořit vlastní kontejner jako základní vrstvu. Stačí se ujistit, že následující položky zůstanou nedotčené:
- Skript
start.sh
je volána souborem Dockerfile. - Skript
start.sh
je poslední příkaz v souboru Dockerfile. - Ujistěte se, že odvozené kontejnery neodeberou žádné závislosti uvedené v souboru Dockerfile.
Použití Dockeru v rámci kontejneru Dockeru
Pokud chcete použít Docker z kontejneru Dockeru, připojte soket Dockeru.
Upozornění
To má vážné bezpečnostní důsledky. Kód uvnitř kontejneru se teď může na hostiteli Dockeru spustit jako root.
Pokud si nejste jistí, že to chcete udělat, přečtěte si dokumentaci k připojení vazby na Docker.com.
Použití clusteru Azure Kubernetes Service
Upozornění
Vezměte prosím v úvahu, že všechny úlohy založené na Dockeru nebudou fungovat na AKS 1.19 nebo novější kvůli omezení Dockeru. Docker byl nahrazen kontejnerem v Kubernetes 1.19 a Docker-in-Docker začal být nedostupný.
Nasazení a konfigurace služby Azure Kubernetes Service
Postupujte podle kroků v rychlém startu: Nasazení clusteru Azure Kubernetes Service (AKS) pomocí webu Azure Portal. Potom může konzola PowerShellu nebo prostředí použít kubectl
příkazový řádek.
Nasazení a konfigurace služby Azure Container Registry
Postupujte podle kroků v rychlém startu: Vytvoření registru kontejneru Azure pomocí webu Azure Portal. Potom můžete nasdílení a vyžádání kontejnerů ze služby Azure Container Registry.
Konfigurace tajných kódů a nasazení sady replik
Vytvořte tajné kódy v clusteru AKS.
kubectl create secret generic azdevops \ --from-literal=AZP_URL=https://dev.azure.com/yourOrg \ --from-literal=AZP_TOKEN=YourPAT \ --from-literal=AZP_POOL=NameOfYourPool
Spuštěním tohoto příkazu odešlete kontejner do služby Container Registry:
docker push "<acr-server>/azp-agent:<tag>"
Nakonfigurujte integraci služby Container Registry pro existující clustery AKS.
Poznámka:
Pokud máte na webu Azure Portal více předplatných, nejprve pomocí tohoto příkazu vyberte předplatné.
az account set --subscription "<subscription id or subscription name>"
az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"
Uložte následující obsah do
~/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
Tento YAML Kubernetes vytvoří sadu replik a nasazení, kde
replicas: 1
označuje číslo nebo agenty spuštěné v clusteru.Spusťte tento příkaz:
kubectl apply -f ReplicationController.yml
Teď budou vaši agenti spouštět cluster AKS.
Nastavení vlastního parametru MTU
Povolit zadání hodnoty MTU pro sítě používané úlohami kontejneru (užitečné pro scénáře docker-in-dockeru v clusteru k8s).
Abyste nastavili hodnotu MTU, musíte nastavit proměnnou prostředí AGENT_DOCKER_MTU_VALUE a poté restartovat agenta v místním prostředí. Další informace o restartování agenta najdete tady a o nastavení různých proměnných prostředí pro každého jednotlivého agenta zde.
To vám umožní nastavit parametr sítě pro kontejner úloh, použití tohoto příkazu se podobá použití dalšího příkazu při konfiguraci sítě kontejneru:
-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE
Připojení svazků pomocí Dockeru v rámci kontejneru Dockeru
Pokud se kontejner Dockeru spouští v jiném kontejneru Dockeru, oba používají proces démon hostitele, takže všechny cesty připojení odkazují na hostitele, nikoli kontejner.
Pokud například chceme připojit cestu z hostitele do vnějšího kontejneru Dockeru, můžeme použít tento příkaz:
docker run ... -v "<path-on-host>:<path-on-outer-container>" ...
A pokud chceme připojit cestu z hostitele do vnitřního kontejneru Dockeru, můžeme použít tento příkaz:
docker run ... -v "<path-on-host>:<path-on-inner-container>" ...
Ale nemůžeme připojit cesty z vnějšího kontejneru do vnitřního; abychom to obejít, musíme deklarovat proměnnou ENV:
docker run ... --env DIND_USER_HOME=$HOME ...
Potom můžeme vnitřní kontejner spustit z vnějšího kontejneru pomocí tohoto příkazu:
docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...
Běžné chyby
Pokud používáte Windows a zobrazí se následující chyba:
standard_init_linux.go:178: exec user process caused "no such file or directory"
Nainstalujte Git Bash stažením a instalací git-scm.
Spusťte tento příkaz:
dos2unix ~/azp-agent-in-docker/Dockerfile
dos2unix ~/azp-agent-in-docker/start.sh
git add .
git commit -m "Fixed CR"
git push
Zkuste to ještě jednou. Už se vám chyba nezobrazí.