Containertaken definiëren (YAML)

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

Taken worden standaard uitgevoerd op de hostcomputer waarop de agent is geïnstalleerd. Dit is handig en doorgaans goed geschikt voor projecten die net beginnen met de overstap naar Azure Pipelines. Na verloop van tijd hebt u mogelijk meer controle over de context waarin uw taken worden uitgevoerd. YAML-pijplijnen bieden containertaken voor dit beheerniveau.

Op Linux- en Windows-agents kunnen taken worden uitgevoerd op de host of in een container. (Op macOS en Red Hat Enterprise Linux 6 zijn containertaken niet beschikbaar.) Containers bieden isolatie van de host en bieden u de mogelijkheid om specifieke versies van hulpprogramma's en afhankelijkheden vast te maken. Voor hosttaken is minder initiële installatie en infrastructuur vereist om te onderhouden.

Containers bieden een lichtgewicht abstractie via het hostbesturingssysteem. U kunt de exacte versies van besturingssystemen, hulpprogramma's en afhankelijkheden selecteren die uw build nodig heeft. Wanneer u een container in uw pijplijn opgeeft, wordt de container eerst opgehaald en gestart. Vervolgens wordt elke stap van de taak uitgevoerd in de container. U kunt geen geneste containers hebben. Containers worden niet ondersteund wanneer een agent al in een container wordt uitgevoerd.

Als u gedetailleerde controle op stapniveau nodig hebt, kunt u met stapdoelen voor elke stap een container of host kiezen.

Vereisten

Op Linux gebaseerde containers

Het Azure Pipelines-systeem vereist een aantal dingen in Linux-containers:

  • Bash
  • glibc-gebaseerd
  • Kan Node.js uitvoeren (die door de agent wordt geleverd)
  • Definieert geen ENTRYPOINT
  • USER heeft toegang tot groupadd en andere bevoegdheden opdrachten zonder sudo

En op uw agenthost:

  • Controleren of Docker is geïnstalleerd
  • De agent moet gemachtigd zijn om toegang te krijgen tot de Docker-daemon

Zorg ervoor dat voor uw container elk van deze hulpprogramma's beschikbaar is. Sommige van de uitgestripte containers die beschikbaar zijn op Docker Hub, met name containers die zijn gebaseerd op Alpine Linux, voldoen niet aan deze minimale vereisten. Containers met een A-bestand ENTRYPOINT werken mogelijk niet, omdat Azure Pipelines docker create een wachtende container en docker exec een reeks opdrachten bevat, die verwachten dat de container altijd actief is.

Notitie

Voor Linux-containers op basis van Windows moet Node.js vooraf zijn geïnstalleerd.

Windows-containers

Azure Pipelines kan ook Windows-containers uitvoeren. Windows Server versie 1803 of hoger is vereist. Docker moet zijn geïnstalleerd. Zorg ervoor dat uw pijplijnagent gemachtigd is voor toegang tot de Docker-daemon.

De Windows-container moet ondersteuning bieden voor het uitvoeren van Node.js. Een Windows Nano Server-basiscontainer ontbreekt afhankelijkheden die nodig zijn om Node uit te voeren.

Gehoste agents

Alleen windows-2019 en ubuntu-* installatiekopieën ondersteunen actieve containers. De macOS-installatiekopieën bieden geen ondersteuning voor actieve containers.

Eén taak

Een eenvoudig voorbeeld:

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

Dit vertelt het systeem dat de ubuntu installatiekopieën moeten worden opgehaald die zijn getagd 18.04 uit Docker Hub en vervolgens de container starten. Wanneer de printenv opdracht wordt uitgevoerd, gebeurt deze in de ubuntu:18.04 container.

Een Windows-voorbeeld:

pool:
  vmImage: 'windows-2019'

container: mcr.microsoft.com/windows/servercore:ltsc2019

steps:
- script: set

Notitie

Windows vereist dat de kernelversie van de host en container overeenkomen. Omdat in dit voorbeeld de installatiekopieën van Windows 2019 worden gebruikt, gebruiken we de 2019 tag voor de container.

Meerdere taken

Containers zijn ook handig voor het uitvoeren van dezelfde stappen in meerdere taken. In het volgende voorbeeld worden dezelfde stappen uitgevoerd in meerdere versies van Ubuntu Linux. (En we hoeven het jobs trefwoord niet te vermelden, omdat er slechts één taak is gedefinieerd.)

pool:
  vmImage: 'ubuntu-latest'

strategy:
  matrix:
    ubuntu16:
      containerImage: ubuntu:16.04
    ubuntu18:
      containerImage: ubuntu:18.04
    ubuntu20:
      containerImage: ubuntu:20.04

container: $[ variables['containerImage'] ]

steps:
- script: printenv

Eindpunten

Containers kunnen worden gehost op andere registers dan openbare Docker Hub-registers. Als u een installatiekopie wilt hosten in Azure Container Registry of een ander privécontainerregister (inclusief een persoonlijk Docker Hub-register), voegt u een serviceverbinding toe aan het privéregister. Vervolgens kunt u ernaar verwijzen in een containerspecificatie:

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

steps:
- script: echo hello

or

container:
  image: myprivate.azurecr.io/windowsservercore:1803
  endpoint: my_acr_connection

steps:
- script: echo hello

Andere containerregisters werken mogelijk ook. Amazon ECR werkt momenteel niet, omdat er andere clienthulpprogramma's vereist zijn om AWS-referenties te converteren naar iets dat Docker kan gebruiken om te verifiëren.

Notitie

De Red Hat Enterprise Linux 6-build van de agent voert geen containertaak uit. Kies een andere Linux-smaak, zoals Red Hat Enterprise Linux 7 of hoger.

Opties

Als u het opstarten van containers wilt beheren, kunt u opgeven options.

container:
  image: ubuntu:18.04
  options: --hostname container-test --ip 192.168.0.1

steps:
- script: echo hello

Als u deze optie uitvoert docker create --help , ziet u een lijst met opties die kunnen worden doorgegeven aan de aanroep van Docker. Niet al deze opties werken gegarandeerd met Azure DevOps. Controleer eerst of u een containereigenschap kunt gebruiken om hetzelfde doel te bereiken. Zie het YAML-schema en dedocker createopdrachtreferentie voor meer informatieresources.containers.container.

Herbruikbare containerdefinitie

In het volgende voorbeeld worden de containers gedefinieerd in de sectie Resources. Er wordt later naar elke container verwezen door te verwijzen naar de toegewezen alias. (Hier vermelden we expliciet het jobs trefwoord voor duidelijkheid.)

resources:
  containers:
  - container: u16
    image: ubuntu:16.04

  - container: u18
    image: ubuntu:18.04

  - container: u20
    image: ubuntu:20.04

jobs:
- job: RunInContainer
  pool:
    vmImage: 'ubuntu-latest'

  strategy:
    matrix:
      ubuntu16:
        containerResource: u16
      ubuntu18:
        containerResource: u18
      ubuntu20:
        containerResource: u20

  container: $[ variables['containerResource'] ]

  steps:
  - script: printenv

Niet-glibc-containers

De Azure Pipelines-agent levert een kopie van Node.js, die nodig is om taken en scripts uit te voeren. Zie door Microsoft gehoste agents voor meer informatie over de versie van Node.js voor een gehoste agent. De versie van Node.js wordt gecompileerd op basis van de C-runtime die we in onze gehoste cloud gebruiken, meestal glibc. Sommige varianten van Linux gebruiken andere C-runtimes. Alpine Linux gebruikt bijvoorbeeld musl.

Als u een niet-glibc-container wilt gebruiken als een taakcontainer, moet u een aantal dingen zelf rangschikken. Eerst moet u uw eigen exemplaar van Node.js opgeven. Ten tweede moet u een label toevoegen aan de afbeelding die de agent vertelt waar de Node.js binair bestand moet worden gevonden. Ten slotte wordt stock Alpine niet geleverd met andere afhankelijkheden waarvan Azure Pipelines afhankelijk is: bash, sudo, die en groupadd.

Bring your own Node.js

U bent verantwoordelijk voor het toevoegen van een binair knooppunt aan uw container. Node 18 is een veilige keuze. U kunt beginnen met de node:18-alpine afbeelding.

Vertel de agent over Node.js

De agent leest een containerlabel 'com.azure.dev.pipelines.handler.node.path'. Als dit label bestaat, moet dit het pad naar het binaire Node.js zijn. Voeg bijvoorbeeld in een installatiekopie op node:18-alpinebasis van deze regel deze regel toe aan uw Dockerfile:

LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"

Vereisten toevoegen

Azure Pipelines gaat ervan uit dat een op Bash gebaseerd systeem met algemene beheerpakketten is geïnstalleerd. Alpine Linux wordt met name niet geleverd met een aantal van de benodigde pakketten. Installeren bash, sudoen shadow behandelen de basisbehoeften.

RUN apk add bash sudo shadow

Als u afhankelijk bent van een in-box- of Marketplace-taken, moet u ook de binaire bestanden opgeven die ze nodig hebben.

Volledig voorbeeld van een Dockerfile

FROM node:10-alpine

RUN apk add --no-cache --virtual .pipeline-deps readline linux-pam \
  && apk add bash sudo shadow \
  && apk del .pipeline-deps

LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"

CMD [ "node" ]

Meerdere taken met agentpools op één gehoste agent

De containertaak maakt gebruik van de onderliggende hostagent Docker config.json voor autorisatie van installatiekopieregisters, die zich afmeldt aan het einde van de initialisatie van de Docker-registercontainer. Volgende registerinstallatiekopie haalt autorisatie kan worden geweigerd voor 'niet-geautoriseerde verificatie' omdat het Docker-config.json-bestand dat is geregistreerd in het systeem voor verificatie al is afgemeld door een van de andere containertaken die parallel worden uitgevoerd.

De oplossing is het instellen van de Docker-omgevingsvariabele DOCKER_CONFIG die specifiek is voor elke agentgroepservice die wordt uitgevoerd op de gehoste agent. Exporteer het DOCKER_CONFIG runsvc.sh script van elke agentgroep:

#insert anything to set up env when running as a service
export DOCKER_CONFIG=./.docker