Uruchamianie własnego agenta na platformie Docker
Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019
Ten artykuł zawiera instrukcje dotyczące uruchamiania agenta usługi Azure Pipelines na platformie Docker. Możesz skonfigurować własnego agenta w usłudze Azure Pipelines do uruchamiania w systemie Windows Server Core (dla hostów systemu Windows) lub kontenera Ubuntu (dla hostów z systemem Linux) za pomocą platformy Docker. Jest to przydatne, gdy chcesz uruchamiać agentów z orkiestracją zewnętrzną, taką jak usługa Azure Container Instances. W tym artykule przedstawiono kompletny przykład kontenera, w tym obsługę samodzielnej aktualizacji agenta.
Zarówno systemy Windows , jak i Linux są obsługiwane jako hosty kontenerów. Kontenery systemu Windows powinny działać w systemie Windows vmImage
.
Aby uruchomić agenta na platformie Docker, przekażesz kilka zmiennych środowiskowych do docker run
programu , co umożliwia skonfigurowanie agenta w celu nawiązania połączenia z usługą Azure Pipelines lub serwerem Azure DevOps Server. Na koniec dostosujesz kontener do własnych potrzeb. Zadania i skrypty mogą zależeć od dostępnych narzędzi w kontenerze PATH
, a Twoim zadaniem jest zapewnienie dostępności tych narzędzi.
Ta funkcja wymaga agenta w wersji 2.149 lub nowszej. Usługa Azure DevOps 2019 nie jest dostarczana z zgodną wersją agenta. Można jednak przekazać prawidłowy pakiet agenta do warstwy aplikacji, jeśli chcesz uruchomić agentów platformy Docker.
Windows
Włączanie funkcji Hyper-V
Funkcja Hyper-V nie jest domyślnie włączona w systemie Windows. Jeśli chcesz zapewnić izolację między kontenerami, musisz włączyć funkcję Hyper-V. W przeciwnym razie platforma Docker dla systemu Windows nie zostanie uruchomiona.
- Włączanie funkcji Hyper-V w systemie Windows 10
- Włączanie funkcji Hyper-V w systemie Windows Server 2016
Uwaga
Należy włączyć wirtualizację na maszynie. Zazwyczaj jest ona domyślnie włączona. Jeśli jednak instalacja funkcji Hyper-V nie powiedzie się, zapoznaj się z dokumentacją systemu, aby dowiedzieć się, jak włączyć wirtualizację.
Instalowanie platformy Docker dla systemu Windows
Jeśli używasz systemu Windows 10, możesz zainstalować platformę Docker Community Edition. W przypadku systemu Windows Server 2016 zainstaluj platformę Docker Enterprise Edition.
Przełączanie platformy Docker do używania kontenerów systemu Windows
Domyślnie platforma Docker dla systemu Windows jest skonfigurowana do używania kontenerów systemu Linux. Aby zezwolić na uruchamianie kontenera systemu Windows, upewnij się, że platforma Docker dla systemu Windows korzysta z demona systemu Windows.
Tworzenie i kompilowanie pliku Dockerfile
Następnie utwórz plik Dockerfile.
Otwórz wiersz polecenia.
Utwórz nowy katalog:
mkdir "C:\azp-agent-in-docker\"
Przejdź do tego nowego katalogu:
cd "C:\azp-agent-in-docker\"
Zapisz następującą zawartość w pliku o nazwie
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
Zapisz następującą zawartość w pliku
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})" }
Uruchom następujące polecenie w tym katalogu:
docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .
Końcowy obraz jest oznaczony tagiem
azp-agent:windows
.
Uruchamianie obrazu
Po utworzeniu obrazu możesz uruchomić kontener. Spowoduje to zainstalowanie najnowszej wersji agenta, skonfigurowanie go i uruchomienie agenta. Jest ona przeznaczona dla określonej puli agentów ( Default
domyślnie puli agentów) określonego wystąpienia usługi Azure DevOps lub wybranego wystąpienia usługi Azure DevOps Server:
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
Jeśli wystąpią problemy z siecią, może być konieczne określenie parametru --network
.
docker run --network "Default Switch" < . . . >
Może być konieczne określenie --interactive
flag i --tty
(lub po prostu -it
), jeśli chcesz zatrzymać kontener i usunąć agenta za pomocą polecenia Ctrl
+ C
.
docker run --interactive --tty < . . . >
Jeśli chcesz mieć nowy kontener agenta dla każdego zadania potoku, przekaż flagę --once
run
do polecenia .
docker run < . . . > --once
Z flagą --once
możesz użyć systemu aranżacji kontenerów, takiego jak Kubernetes lub Azure Container Instances, aby uruchomić nową kopię kontenera po zakończeniu zadania.
Możesz kontrolować nazwę agenta, pulę agentów i katalog roboczy agenta przy użyciu opcjonalnych zmiennych środowiskowych.
Linux
Zainstaluj platformę Docker
W zależności od dystrybucji systemu Linux można zainstalować program Docker Community Edition lub Docker Enterprise Edition.
Tworzenie i kompilowanie pliku Dockerfile
Następnie utwórz plik Dockerfile.
Otwórz terminal.
Utwórz nowy katalog (zalecane):
mkdir ~/azp-agent-in-docker/
Przejdź do tego nowego katalogu:
cd ~/azp-agent-in-docker/
Zapisz następującą zawartość w pliku
~/azp-agent-in-docker/azp-agent-linux.dockerfile
:Dla 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" ]
Dla systemu 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" ]
Usuń komentarz z
ENV AGENT_ALLOW_RUNASROOT="true"
wiersza i usuń dodanieagent
użytkownika przed tym wierszem, jeśli chcesz uruchomić agenta jako główny.Uwaga
Zadania mogą zależeć od plików wykonywalnych, które powinny zostać podane w kontenerze. Na przykład należy dodać
zip
pakiety iunzip
doRUN apt install -y
polecenia , aby uruchomićArchiveFiles
zadania iExtractFiles
. Ponadto, ponieważ jest to obraz systemu Linux Ubuntu do użycia przez agenta, możesz dostosować obraz zgodnie z potrzebami. Na przykład: jeśli musisz utworzyć aplikacje .NET, możesz wykonać czynności opisane w dokumencie Instalowanie zestawu .NET SDK lub środowiska uruchomieniowego platformy .NET w systemie Ubuntu i dodawanie go do obrazu.Zapisz następującą zawartość w pliku
~/azp-agent-in-docker/start.sh
, upewniając się, że używasz zakończeń wierszy w 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 $!
Uwaga
Należy również użyć systemu aranżacji kontenerów, takiego jak Kubernetes lub Azure Container Instances, aby uruchomić nowe kopie kontenera po zakończeniu pracy.
Uruchom następujące polecenie w tym katalogu:
docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .
Końcowy obraz jest oznaczony tagiem
azp-agent:linux
.
Uruchamianie obrazu
Po utworzeniu obrazu możesz uruchomić kontener. Spowoduje to zainstalowanie najnowszej wersji agenta, skonfigurowanie go i uruchomienie agenta. Jest ona przeznaczona dla określonej puli agentów ( Default
domyślnie puli agentów) określonego wystąpienia usługi Azure DevOps lub wybranego wystąpienia usługi Azure DevOps Server:
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
Może być konieczne określenie --interactive
flag i --tty
(lub po prostu -it
), jeśli chcesz zatrzymać kontener i usunąć agenta za pomocą polecenia Ctrl
+ C
.
docker run --interactive --tty < . . . >
Jeśli chcesz mieć nowy kontener agenta dla każdego zadania potoku, przekaż flagę --once
run
do polecenia .
docker run < . . . > --once
Z flagą --once
możesz użyć systemu aranżacji kontenerów, takiego jak Kubernetes lub Azure Container Instances, aby uruchomić nową kopię kontenera po zakończeniu zadania.
Możesz kontrolować nazwę agenta, pulę agentów i katalog roboczy agenta przy użyciu opcjonalnych zmiennych środowiskowych.
Zmienne środowiskowe
Zmienna środowiskowa | opis |
---|---|
AZP_URL | Adres URL wystąpienia usługi Azure DevOps lub usługi Azure DevOps Server. |
AZP_TOKEN | Osobisty token dostępu (PAT) z zakresem pul agentów (odczyt, zarządzanie) utworzonym przez użytkownika, który ma uprawnienia do konfigurowania agentów pod adresem AZP_URL . |
AZP_AGENT_NAME | Nazwa agenta (wartość domyślna: nazwa hosta kontenera). |
AZP_POOL | Nazwa puli agentów (wartość domyślna: Default ). |
AZP_WORK | Katalog roboczy (wartość domyślna: _work ). |
Dodawanie narzędzi i dostosowywanie kontenera
Utworzono podstawowego agenta kompilacji. Plik Dockerfile można rozszerzyć tak, aby zawierał dodatkowe narzędzia i ich zależności, lub utworzyć własny kontener przy użyciu tego pliku jako warstwy podstawowej. Upewnij się, że następujące elementy pozostają nietknięte:
- Skrypt
start.sh
jest wywoływany przez plik Dockerfile. - Skrypt
start.sh
jest ostatnim poleceniem w pliku Dockerfile. - Upewnij się, że kontenery pochodne nie usuwają żadnych zależności określonych przez plik Dockerfile.
Korzystanie z platformy Docker w kontenerze platformy Docker
Aby można było używać platformy Docker z poziomu kontenera platformy Docker, należy zainstalować gniazdo platformy Docker.
Uwaga
Wykonanie tej czynności ma poważne konsekwencje w zakresie bezpieczeństwa. Kod wewnątrz kontenera może teraz działać jako katalog główny na hoście platformy Docker.
Jeśli na pewno chcesz to zrobić, zapoznaj się z dokumentacją dotyczącą instalacji powiązania w Docker.com.
Korzystanie z klastra usługi Azure Kubernetes Service
Uwaga
Należy wziąć pod uwagę, że żadne zadania oparte na platformie Docker nie będą działać w usłudze AKS 1.19 lub nowszym z powodu ograniczeń platformy Docker. Platforma Docker została zastąpiona kontenerem w rozwiązaniu Kubernetes 1.19, a platforma Docker-in-Docker stała się niedostępna.
Wdrażanie i konfigurowanie usługi Azure Kubernetes Service
Wykonaj kroki opisane w przewodniku Szybki start: wdrażanie klastra usługi Azure Kubernetes Service (AKS) przy użyciu witryny Azure Portal. Następnie konsola programu PowerShell lub powłoki może używać kubectl
wiersza polecenia.
Wdrażanie i konfigurowanie usługi Azure Container Registry
Wykonaj kroki opisane w przewodniku Szybki start: tworzenie rejestru kontenerów platformy Azure przy użyciu witryny Azure Portal. Następnie możesz wypchnąć i ściągnąć kontenery z usługi Azure Container Registry.
Konfigurowanie wpisów tajnych i wdrażanie zestawu replik
Utwórz wpisy tajne w klastrze usługi 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
Uruchom to polecenie, aby wypchnąć kontener do usługi Container Registry:
docker push "<acr-server>/azp-agent:<tag>"
Konfigurowanie integracji usługi Container Registry dla istniejących klastrów usługi AKS.
Uwaga
Jeśli masz wiele subskrypcji w witrynie Azure Portal, użyj tego polecenia najpierw, aby wybrać subskrypcję
az account set --subscription "<subscription id or subscription name>"
az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"
Zapisz następującą zawartość w pliku
~/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
Ten kod YAML platformy Kubernetes tworzy zestaw replik i wdrożenie, gdzie
replicas: 1
wskazuje liczbę lub agentów uruchomionych w klastrze.Uruchom następujące polecenie:
kubectl apply -f ReplicationController.yml
Teraz agenci będą uruchamiać klaster usługi AKS.
Ustawianie niestandardowego parametru MTU
Zezwalaj na określanie wartości jednostki MTU dla sieci używanych przez zadania kontenera (przydatne w scenariuszach platformy Docker in-docker w klastrze k8s).
Należy ustawić zmienną środowiskową AGENT_DOCKER_MTU_VALUE, aby ustawić wartość jednostki MTU, a następnie ponownie uruchomić własnego agenta. Więcej informacji na temat ponownego uruchamiania agenta można znaleźć tutaj i o ustawianiu różnych zmiennych środowiskowych dla każdego pojedynczego agenta tutaj.
Dzięki temu można skonfigurować parametr sieciowy dla kontenera zadań. Użycie tego polecenia jest podobne do użycia następnego polecenia podczas konfigurowania sieci kontenera:
-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE
Instalowanie woluminów przy użyciu platformy Docker w kontenerze platformy Docker
Jeśli kontener platformy Docker działa wewnątrz innego kontenera platformy Docker, oba używają demona hosta, więc wszystkie ścieżki instalacji odwołują się do hosta, a nie kontenera.
Jeśli na przykład chcemy zainstalować ścieżkę z hosta do zewnętrznego kontenera platformy Docker, możemy użyć tego polecenia:
docker run ... -v "<path-on-host>:<path-on-outer-container>" ...
Jeśli chcemy zainstalować ścieżkę z hosta do wewnętrznego kontenera platformy Docker, możemy użyć tego polecenia:
docker run ... -v "<path-on-host>:<path-on-inner-container>" ...
Ale nie możemy zainstalować ścieżek z kontenera zewnętrznego do wewnętrznego; aby obejść ten element, musimy zadeklarować zmienną ENV:
docker run ... --env DIND_USER_HOME=$HOME ...
Następnie możemy uruchomić kontener wewnętrzny z zewnętrznego przy użyciu następującego polecenia:
docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...
Typowe błędy
Jeśli używasz systemu Windows i wystąpi następujący błąd:
standard_init_linux.go:178: exec user process caused "no such file or directory"
Zainstaluj powłokę Git Bash, pobierając i instalując narzędzie git-scm.
Uruchom następujące polecenie:
dos2unix ~/azp-agent-in-docker/Dockerfile
dos2unix ~/azp-agent-in-docker/start.sh
git add .
git commit -m "Fixed CR"
git push
Spróbuj ponownie. Nie otrzymujesz już błędu.