Containerjobb i YAML-pipelines

Azure DevOps Services | Azure DevOps Server 2022 – Azure DevOps Server 2019

I den här artikeln beskrivs containerjobb i Azure Pipelines.

Som standard körs Azure Pipelines-jobb direkt på värddatorerna där agenten är installerad. Värdbaserade agentjobb är praktiska, kräver lite inledande installation och infrastruktur att underhålla och passar bra för grundläggande projekt.

Om du vill ha mer kontroll över aktivitetskontexten kan du definiera och köra jobb i containrar. Containrar är en lätt abstraktion över värdoperativsystemet som ger isolering från värden. När du kör jobb i containrar kan du välja de exakta versioner av operativsystem, verktyg och beroenden som krävs för bygget.

Linux- och Windows-agenter kan köra pipelinejobb direkt på värden eller i containrar. Containerjobb är inte tillgängliga i macOS.

För ett containerjobb hämtar agenten först och startar containern. Sedan körs varje steg i jobbet i containern.

Om du behöver detaljerad kontroll på den enskilda byggstegsnivån kan du med stegmål välja en container eller värd för varje steg.

Förutsättningar

  • Använd en YAML-pipeline. Klassiska pipelines stöder inte containerjobb.
  • Använd en värdbaserad Windows- eller Ubuntu-agent. Endast windows-* och ubuntu-* agenter har stöd för att köra containrar. Agenterna macos-* har inte stöd för att köra containrar.
  • Din agent har konfigurerats för containerjobb.
    • Windows- och Linux-agenter måste ha Docker installerat och behöver behörighet för att få åtkomst till Docker-daemon.
    • Containrar stöds inte när agenten redan körs i en container. Du kan inte ha kapslade containrar.

Ytterligare containerkrav

Linux-baserade containrar har följande krav. Lösningar finns i Ickeglibc-baserade containrar.

  • Bash installerat
  • GNU C-bibliotek (glibc)-baserat
  • Nej ENTRYPOINT
  • Ge USER åtkomst till groupadd och andra privilegierade kommandon utan att använda sudo
  • Kan köra Node.js, som agenten tillhandahåller

    Kommentar

    Node.js måste vara förinstallerat för Linux-containrar på Windows-värdar.

Vissa avskalade containrar som är tillgängliga på Docker Hub, särskilt containrar baserade på Alpine Linux, uppfyller inte dessa krav. Containrar med en ENTRYPOINT kanske inte fungerar eftersom Azure Pipelines docker create och docker exec förväntar sig att containern alltid är igång.

Exempel på enskilda jobb

I följande exempel definieras en Windows- eller Linux-container för ett enda jobb.

Följande enkla exempel definierar en Linux-container:

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

I föregående exempel uppmanas systemet att hämta avbildningen ubuntu som taggats 18.04 från Docker Hub och sedan starta containern. Kommandot printenv körs i containern ubuntu:18.04 .

Flera jobb

Du kan använda containrar för att köra samma steg i flera jobb. I följande exempel körs samma steg i flera versioner av Ubuntu Linux. Du behöver inte nämna nyckelordet jobs eftersom endast ett enda jobb har definierats.

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

Flera jobb med agentpooler på en enda agentvärd

Ett containerjobb använder den underliggande värdagentens Docker-konfigurationsfil för avbildningsregisterauktorisering. Den här filen loggar ut i slutet av initieringen av Docker-registercontainern. Hämtningar av registeravbildningar för efterföljande containerjobb kan nekas eftersom unauthorized authentication ett annat jobb som körs parallellt redan har loggat ut Docker-konfigurationsfilen.

Lösningen är att ange en Docker-miljövariabel DOCKER_CONFIG som är specifik för varje agentpool som körs på den värdbaserade agenten. Exportera skriptet DOCKER_CONFIG i varje agentpools runsvc.sh enligt följande:

export DOCKER_CONFIG=./.docker

Startalternativ

Du kan ange options för att styra start av container, som i följande exempel:

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

steps:
- script: echo hello

När du kör docker create --help visas en lista över alternativ som du kan skicka till Docker-anrop. Alla dessa alternativ är inte garanterade att fungera med Azure DevOps. Kontrollera först om du kan använda en container egenskap för att uppnå samma mål.

Mer information finns i docker create-kommandoreferensen och definitionen resources.containers.container i schemareferensen för Azure DevOps YAML.

Återanvändbar containerdefinition

I följande exempel definieras containrarna i resources avsnittet och refererar sedan till dem efter deras tilldelade alias. Nyckelordet jobs visas uttryckligen för tydlighetens skull.

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

Tjänstslutpunkter

Du kan vara värd för containrar i andra register än offentlig Docker Hub. Om du vill vara värd för en avbildning i Azure Container Registry eller ett annat privat containerregister, inklusive ett privat Docker Hub-register, lägger du till en tjänstanslutning för att få åtkomst till registret. Sedan kan du referera till slutpunkten i containerdefinitionen.

Privat Docker Hub-anslutning:

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

Anslutning till Azure Container Registry:

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

Kommentar

Azure Pipelines kan inte konfigurera en tjänstanslutning för Amazon Elastic Container Registry (ECR), eftersom Amazon ECR kräver andra klientverktyg för att konvertera AWS-autentiseringsuppgifter till något som Docker kan använda för att autentisera.

Icke-glibc-baserade containrar

Azure Pipelines-agenten tillhandahåller en kopia av Node.js som krävs för att köra uppgifter och skript. Information om vilken version av Node.js för en värdbaserad agent finns i Microsoft-värdbaserade agenter.

Versionen av Node.js kompileras mot C-körningen som används i det värdbaserade molnet, vanligtvis glibc. Vissa Linux-varianter använder andra C-körningar. Alpine Linux använder till exempel musl.

Om du vill använda en icke-glibc-baserad container måste du:

  • Ange en egen kopia av Node.js.
  • Lägg till en etikett i bilden som talar om för agenten var Node.js binärfilen ska hittas.
  • Ange andra beroenden som Azure Pipelines är beroende av: bash, sudo, whichoch groupadd.

Ange egna Node.js

Om du använder en icke-glibc-baserad container ansvarar du för att lägga till en Node-binärfil i containern. Node.js 18 är ett säkert val. Börja från bilden node:18-alpine .

Berätta för agenten om Node.js

Agenten läser containeretiketten "com.azure.dev.pipelines.handler.node.path". Om den här etiketten finns måste den vara sökvägen till Node.js binärfilen.

I en avbildning som baseras på node:18-alpinelägger du till följande rad i Dockerfile:

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

Lägga till nödvändiga paket

Azure Pipelines förutsätter ett Bash-baserat system med vanliga administrativa paket installerade. I synnerhet Alpine Linux levereras inte med flera av de paket som behövs. Installera bash, sudooch shadow för att täcka de grundläggande behoven.

RUN apk add bash sudo shadow

Om du är beroende av några inkorgs- eller Marketplace-uppgifter anger du även de binärfiler som de behöver.

Fullständigt Dockerfile-exempel

FROM node:18-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" ]