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¶
- Zorg dat de vereisten op orde zijn en dat de imagetag in de registry bestaat.
- Draai de shared services-pipeline met
deployCAEAgents(Shared services). Het plan gebruikt het variabelenbestand van de addon. De apply maakt de resources aan. - De pipeline start daarna de placeholderjob (
az containerapp job start). Als je op een andere manier uitrolt, start hem dan eenmalig met de hand. - Koppel de pool aan de projecten (Vereisten).
- 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"
Gerelateerd¶
- Build agents in het netwerk
- Toegang van build agents tot spokes
- Shared services: wat is uitgerold en hoe
- Platform: deployment-tooling en job runners (de eigen runners van het platform)