Ga naar inhoud

Container agent pool: Azure Pipelines-agents op Container Apps jobs

Deze pagina is voor het platformteam. Ze beschrijft de addon cae-agents van de shared services: een self-hosted Azure Pipelines agent pool die draait op Azure Container Apps jobs. Agents starten per in de wachtrij geplaatste pipelinejob, draaien die ene job in een verse container en worden daarna verwijderd. Als er niets in de wachtrij staat, draait er niets en betaal je niets.

De kant van het workload team (hoe je de pool gebruikt en wat de beperkingen zijn) staat op Build agents in het netwerk. Het netwerkontwerp voor agents staat op Toegang van build agents tot spokes. Wie de pool beheert, hangt af van je beheermodel.

Referentieontwerp, jouw deployment kan afwijken

De feiten hieronder komen uit de Terraform-code, de containerimagebestanden en de README van één referentie-implementatie. Namen, CIDR-ranges en de set tools in de image zijn voorbeelden.

Waarom container-based agents

Container-based (deze addon) Pool op basis van VM's
Kosten Betalen voor de seconden dat een job draait. Nul bij inactiviteit. VM's draaien of er nu pipelines draaien of niet
Schaling Van 0 tot een maximum, per job in de wachtrij Vaste grootte of tragere VM-scale-out
Isolatie Een verse container per job, geen state die achterblijft Gedeelde state tenzij de VM opnieuw wordt geïmaged
Onderhoud Geen OS-patching van VM's. Een nieuwe image is een nieuwe tag. Patching, reboots of re-imaging
Starttijd Ongeveer 50 seconden warm, 3 tot 4 minuten koud Direct voor standby-agents, traag voor nieuwe VM's

De containerimage bevat geen Docker daemon en de container draait niet als root. Workloads die een Docker daemon of root nodig hebben, hebben een andere pool nodig (zie Shared services).

Hoe het werkt

flowchart TD
    q["Pipeline job queued in the agent pool"] --> k["KEDA scaler<br/>polls the pool queue every 10 s"]
    k --> j["Container Apps job execution<br/>(one per queued job)"]
    j --> pull["Pull image from the registry<br/>(managed identity, AcrPull)"]
    pull --> s["start.sh"]
    s --> login["az login --identity<br/>token for Azure DevOps"]
    login --> reg["Download agent, register in the pool"]
    reg --> run["run.sh --once: run one job"]
    run --> unreg["Remove the agent from the pool"]
    unreg --> done["Container exits"]

Na de deployment wordt eenmalig een placeholder-agent geregistreerd. Zonder die heeft de pool de Agent.Version- capability niet die door Microsoft gehoste agents standaard hebben, en worden jobs in de wachtrij nooit aan een agent gekoppeld.

Wat de code uitrolt

Resource Naampatroon Doel
Resource group rg-agent-pool-<workload>-<postfix> Bevat de agentresources
User-assigned managed identity id-container-agent-<workload> Haalt de image op en praat met Azure DevOps
Roltoewijzing AcrPull op de registry Laat de identiteit de agentimage ophalen
Container Apps-omgeving cae-agent-<workload> In het spoke-subnet, met een internal load balancer, logt naar de Log Analytics workspace van de spoke. De identiteit is ook op de omgeving ingesteld, omdat het control plane de registrytoegang valideert bij het aanmaken van een job.
Container Apps job (agent) caj-agent-<workload> Event-triggered. Eén uitvoering per pipelinejob in de wachtrij.
Container Apps job (placeholder) caj-placeholder-agent-<workload> Handmatig getriggerd, registreert de placeholder-agent
Azure DevOps agent pool container_agent_pool_name Pool op organisatieniveau. Auto-provisioning en auto-update staan uit.
Service principal entitlement de managed identity Licentieniveau express in Azure DevOps
Security-roltoewijzing de managed identity Administrator op de agent pool, zodat de identiteit agents kan registreren en verwijderen

Instellingen van de agentjob in de code:

Instelling Waarde
Trigger KEDA scaler azure-pipelines, polling-interval 10 s, doelwachtrijlengte 1 per uitvoering, geauthenticeerd met de managed identity
Schaal container_agent_min_replicas (standaard 0) tot container_agent_max_replicas (standaard 25) gelijktijdige uitvoeringen
Grootte 1 vCPU, 2 GiB geheugen per container
Tijdslimiet replica_timeout_in_seconds = 1800: een uitvoering wordt na 30 minuten gestopt. Retry-limiet 1.
Workload profile container_agent_workload_profile, standaard Consumption
Omgevingsvariabelen AZP_URL, AZP_POOL en MANAGED_IDENTITY_CLIENT_ID. De placeholderjob stelt ook AZP_PLACEHOLDER, AZP_RANDOM_AGENT_SUFFIX en AZP_AGENT_NAME in.

De limiet van 30 minuten geldt voor elke pipelinejob op deze pool. Vertel het de workload teams, of gebruik een andere pool voor lange jobs.

Variabelen

Variabele Betekenis
spoke_config Resource group, virtual network, subnet voor de omgeving en Log Analytics workspace van de spoke, op naam
container_agent_pool_name Naam van de Azure DevOps-pool
container_agent_azp_url URL van de Azure DevOps-organisatie
container_agent_location en location Azure-regio
container_agent_image_tag Tag van de azp-agent-image in de registry
azure_container_registry Naam, resource group en subscription van een bestaande registry die de image bevat
workload_name Deel van de resourcenamen (standaard ccap)
resource_postfix Deel van de naam van de resource group
container_agent_min_replicas, container_agent_max_replicas Schaallimieten (standaard 0 en 25)
container_agent_workload_profile Workload profile van de omgeving en de jobs

Vereisten

Azure

  • Een spoke-subnet voor de Container Apps-omgeving, gedelegeerd aan Microsoft.App/environments. Zonder de delegatie mislukt de deployment van de omgeving. Dimensioneer het subnet op het maximale aantal gelijktijdige agents.
  • Een registry met de agentimage, met de admin user uitgeschakeld. De referentie vereist minimaal de Standard SKU. De pool authenticeert alleen met de managed identity en de module wijst er AcrPull aan toe.
  • De Log Analytics workspace van de spoke.
  • Firewalltoegang, zie Netwerk.

Azure DevOps

  • Een service connection die agent pools mag beheren.
  • Een personal access token voor de Azure DevOps Terraform provider, bewaard in de variable group van de pipeline. Het wordt alleen gebruikt terwijl Terraform draait, om de pool aan te maken en de identiteit zijn licentie en rol te geven, niet door de agents tijdens runtime. Het heeft de scopes Agent Pools (Read & Manage) en Member Entitlement Management (Read & Write) nodig. Een personal access token verloopt: voeg hem toe aan je secretmonitoring (Secret watcher).
  • Koppel na de deployment de pool op organisatieniveau aan elk project dat hem gebruikt: Project settings, Pipelines, Agent pools, Add pool, Existing pool.

Netwerk

In het referentieontwerp is de spoke verbonden met een Virtual WAN-hub en adverteert de hub een default route (0.0.0.0/0) naar de spoke. Al het internetverkeer van het omgevingssubnet gaat via de hub-firewall.

Vereiste Detail
Vereiste firewallregel De CIDR van het omgevingssubnet moet in een IP group staan die wordt gebruikt door een regel die uitgaand TCP 443 toestaat. In de referentie is dit de IP group van de self-hosted agents, zie Toegang van build agents tot spokes.
Benodigde bestemmingen Het Microsoft Entra-aanmeldendpoint (login.microsoftonline.com), de registry (*.azurecr.io), de Azure DevOps-service en zijn download-host voor agents, en Azure blob storage (*.blob.core.windows.net)
Optioneel Service endpoints Microsoft.ContainerRegistry en Microsoft.Storage op het subnet. Image pulls en blobverkeer omzeilen dan de firewall, wat de verwerkingskosten van de firewall en de pull-latentie verlaagt. Niet nodig als de firewallregel het verkeer toestaat.
HTTP (poort 80) In het referentieontwerp geblokkeerd door de firewall. De image build kan daarom apt-get niet gebruiken, dat standaard HTTP gebruikt.

Zonder de regel mislukt terraform apply met unable to pull image using managed identity, omdat de omgeving bij het aanmaken van een job een live test-pull doet. Uitvoeringen mislukken met ImagePullFailure.

De regel moet in de uitgerolde firewall policy staan

De CIDR toevoegen aan de IP group in de configuratierepository is niet genoeg. Controleer de uitgerolde IP group.

De Container Apps-omgeving gebruikt een internal load balancer (internal_load_balancer_enabled = true). Agents maken alleen uitgaande verbindingen met Azure DevOps, dus dit is voor de pipeline geen beperking.

De agentimage

De image wordt gebouwd uit de bestanden in infra/cae-agents/azp-agent-in-docker/:

Onderdeel Detail
Basis Een Microsoft devcontainer-basisimage op Ubuntu 22.04, opgehaald uit de Microsoft Container Registry. Die heeft al curl, git, jq, unzip, sudo, wget, rsync en openssh-client.
Toegevoegd tini, Azure CLI (geïnstalleerd met pip) en PowerShell (een vastgepinde versie uit het release-archief), allemaal via HTTPS
Gebruiker Een niet-root gebruiker agent
Entry point start.sh

start.sh meldt zich aan met az login --identity met de client-ID in MANAGED_IDENTITY_CLIENT_ID, vraagt een token aan voor Azure DevOps, downloadt het nieuwste agentpakket, registreert de agent (--replace), draait hem met --once en verwijdert de agent als de container stopt. Het identity-endpoint van Container Apps wordt als omgevingsvariabelen geïnjecteerd en az login --identity gebruikt dat, niet het metadata-endpoint van de VM. In placeholder-modus registreert het de agent en stopt het zonder een job te draaien.

De Dockerfile in de repository heeft windows in zijn naam, maar bouwt een Linux-image. De repository heeft ook een ouder bestand met het achtervoegsel _old.

De image bijwerken: bouw en push een nieuwe tag naar de registry, stel container_agent_image_tag in en pas toe. Houd de image klein, want de koude start omvat het ophalen ervan (ongeveer 490 MB in de referentie). De tools in de image zijn alleen die hierboven: workload teams installeren andere tools in hun pipeline (Build agents).

Uitrollen

  1. Zorg dat de vereisten op orde zijn en dat de imagetag in de registry bestaat.
  2. Draai de shared services-pipeline met deployCAEAgents (Shared services). Het plan gebruikt het variabelenbestand van de addon. De apply maakt de resources aan.
  3. De pipeline start daarna de placeholderjob (az containerapp job start). Als je op een andere manier uitrolt, start hem dan eenmalig met de hand.
  4. Koppel de pool aan de projecten (Vereisten).
  5. Draai een testpipeline op de pool en controleer de agentinformatie, de tools en het token van de managed identity.

Starttijd en kosten

Scenario Typische tijd Reden
Koude start (eerste job, node gerecycled) 3 tot 4 minuten Volledige image pull en agentdownload (ongeveer 100 MB)
Warme start (node hergebruikt) Ongeveer 50 seconden Imagelagen gecachet op de node, alleen registratie is nieuw

Opeenvolgende jobs profiteren van een warme node. Als koude starts niet acceptabel zijn, zet je container_agent_min_replicas op 1. Er draait dan altijd één container, tegen constante kosten.

Beveiliging

  • Elke job draait in een verse container, dus credentials en bestanden gaan niet mee naar de volgende job.
  • Agents authenticeren bij de registry en Azure DevOps met de managed identity, niet met keys. De module wijst de identiteit in Azure alleen AcrPull toe. Wat een job in Azure mag doen, komt uit de service connection van de pipeline, net als bij andere pools (Toegang van build agents tot spokes).
  • De identiteit is Administrator op de pool. Beperk wie nog meer rechten heeft op de pool (Azure DevOps).
  • Gebruik voor productiedeployments een aparte pool, zoals aanbevolen in de ontwerprichtlijnen.

Problemen oplossen

Symptoom Waarschijnlijke oorzaak en actie
terraform apply mislukt met unable to pull image using managed identity, of uitvoeringen mislukken met ImagePullFailure De firewall blokkeert het subnet. Controleer of de CIDR in de uitgerolde IP group staat, bijvoorbeeld met az network ip-group show --name <ip group> --resource-group <hub resource group> --subscription <hub-subscription-id> --query ipAddresses. Bekijk de logs hieronder.
Er verschijnen geen agents in de pool na de placeholderjob Controleer de status van de laatste uitvoering van de placeholderjob. Als die is mislukt, bekijk dan de logs. Als die is geslaagd, controleer dan dat container_agent_azp_url geen afsluitende slash heeft en dat de pool aan het project is gekoppeld.
The pool does not exist or has not been authorized for use De pool is niet gekoppeld aan het project van de pipeline
Jobs blijven in de wachtrij en worden nooit toegewezen De placeholder-agent ontbreekt, dus de pool heeft de capability Agent.Version niet. Start de placeholderjob.
Een uitvoering wordt na 30 minuten gestopt De tijdslimiet van de job. Kort de job in of gebruik een andere pool.
Een job kan niet starten, de job is opgeschort Azure schort een Container Apps job op na herhaalde fouten. Los de oorzaak op en hervat hem daarna, zie hieronder.

Bevraag de systeemlogs van de omgeving in de Log Analytics workspace van de spoke:

ContainerAppSystemLogs_CL
| where TimeGenerated > ago(30m)
| project TimeGenerated, Reason_s, Log_s
| order by TimeGenerated asc

Een opgeschorte job hervatten:

az rest --method POST \
  --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource group>/providers/Microsoft.App/jobs/<job name>/resume?api-version=2023-05-01"