Sdílet prostřednictvím


Úlohy kontejnerů v kanálech YAML

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

Tento článek vysvětluje úlohy kontejnerů ve službě Azure Pipelines.

Ve výchozím nastavení běží úlohy Azure Pipelines přímo na hostitelských počítačích, na kterých je agent nainstalovaný. Úlohy hostovaného agenta jsou pohodlné, vyžadují minimální počáteční nastavení a infrastrukturu pro údržbu a jsou vhodné pro základní projekty.

Pokud chcete mít větší kontrolu nad kontextem úlohy, můžete definovat a spouštět úlohy v kontejnerech. Kontejnery představují jednoduchou abstrakci hostitelského operačního systému, která poskytuje izolaci od hostitele. Při spouštění úloh v kontejnerech můžete vybrat přesné verze operačních systémů, nástrojů a závislostí, které sestavení vyžaduje.

Agenti Linuxu a Windows můžou spouštět úlohy kanálu přímo na hostiteli nebo v kontejnerech. Úlohy kontejnerů nejsou v macOS dostupné.

V případě úlohy kontejneru agent nejprve načte a spustí kontejner. Pak se každý krok úlohy spustí uvnitř kontejneru.

Pokud potřebujete jemně odstupňovaný ovládací prvek na úrovni jednotlivých kroků sestavení, cíle kroků umožňují zvolit kontejner nebo hostitele pro každý krok.

Požadavky a omezení

Následující požadavky a omezení platí pro hostitele nebo kontejnery agenta Azure Pipelines.

Hostitelé agentů

  • Pouze windows-* image podporují ubuntu-* spouštění kontejnerů. Image macos-* nepodporují spouštění kontejnerů.
  • Aby bylo možné spouštět kontejnery, musí mít hostitelé agentů Pro Windows a Linux nainstalovaný Docker a musí mít oprávnění pro přístup k procesu démona Dockeru.
  • Kontejnery se nepodporují, když už agent běží uvnitř kontejneru. Nemůžete mít vnořené kontejnery.

Kontejnery

Kontejnery založené na Linuxu mají následující požadavky. Alternativní řešení najdete v tématu Kontejnery založené na nonglibc.

  • Nainstalovaný Bash
  • Knihovna GNU C (glibc) založená
  • Ne ENTRYPOINT
  • Poskytnutí USER přístupu k groupadd privilegovaným příkazům a dalším privilegovaným příkazům bez použití sudo
  • Může spustit Node.js, který agent poskytuje.

    Poznámka:

    Node.js musí být předinstalované pro kontejnery Linuxu na hostitelích s Windows.

Některé proklikované kontejnery dostupné v Docker Hubu, zejména kontejnery založené na Alpine Linuxu, nesplňují tyto požadavky. Kontejnery s ENTRYPOINT můžou fungovat, protože Azure Pipelines docker create a docker exec očekávají, že kontejner je vždy v provozu.

Příklady jednotlivých úloh

Následující příklady definují kontejner Windows nebo Linux pro jednu úlohu.

Následující jednoduchý příklad definuje kontejner Linuxu:

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

Předchozí příklad říká systému, aby načítá ubuntu image označenou 18.04 z Docker Hubu a pak spustil kontejner. Příkaz printenv se spustí uvnitř kontejneru ubuntu:18.04 .

Více úloh

Ke spuštění stejného kroku ve více úlohách můžete použít kontejnery. Následující příklad spustí stejný krok ve více verzích Ubuntu Linuxu. Klíčové slovo nemusíte zmínit jobs , protože je definována pouze jedna úloha.

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

Více úloh s fondy agentů na jednom hostiteli agenta

Úloha kontejneru používá ke autorizaci registru imagí konfigurační soubor dockerového agenta základního hostitelského agenta. Tento soubor se odhlásí na konci inicializace kontejneru registru Dockeru. Vyžádání image registru pro následné úlohy kontejneru může být odepřeno unauthorized authentication , protože jiná úloha spuštěná paralelně už odhlásila konfigurační soubor Dockeru.

Řešením je nastavit proměnnou DOCKER_CONFIG prostředí Dockeru, která je specifická pro každý fond agentů spuštěný v hostovaném agentovi. Následujícím způsobem exportujte DOCKER_CONFIG skript runsvc.sh fondu agentů:

export DOCKER_CONFIG=./.docker

Možnosti spuštění

Můžete určit options , že chcete řídit spuštění kontejneru, jak je znázorněno v následujícím příkladu:

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

steps:
- script: echo hello

Spuštění docker create --help vám poskytne seznam možností, které můžete předat volání Dockeru. Ne všechny tyto možnosti jsou zaručené pro práci s Azure DevOps. Nejprve zkontrolujte, jestli můžete použít container vlastnost k dosažení stejného cíle.

Další informace najdete v odkazu na příkaz docker create a definici kontejneru resources.containers.container v referenčních informacích ke schématu YAML Azure DevOps.

Opakovaně použitelná definice kontejneru

Následující příklad definuje kontejnery v oddílu resources a pak je odkazuje podle jejich přiřazených aliasů. Klíčové jobs slovo je explicitně uvedeno pro přehlednost.

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

Koncové body služby

Kontejnery můžete hostovat v jiných registrech, než je veřejný Docker Hub. Pokud chcete hostovat image ve službě Azure Container Registry nebo jiném privátním registru kontejneru, včetně privátního registru Docker Hubu, přidejte připojení služby pro přístup k registru. Pak můžete odkazovat na koncový bod v definici kontejneru.

Privátní připojení Docker Hubu:

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

Připojení ke službě Azure Container Registry:

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

Poznámka:

Azure Pipelines nemůže nastavit připojení služby pro Amazon Elastic Container Registry (ECR), protože Amazon ECR vyžaduje další klientské nástroje k převodu přihlašovacích údajů AWS na něco, co Docker může použít k ověření.

Kontejnery založené na neglibcech

Agent Azure Pipelines poskytuje kopii Node.js, která se vyžaduje ke spouštění úloh a skriptů. Informace o verzi Node.js hostovaného agenta najdete v tématu Agenti hostovaní Microsoftem.

Verze Node.js se zkompiluje proti modulu runtime jazyka C používanému v hostovaném cloudu, obvykle glibc. Některé varianty Linuxu používají jiné moduly runtime jazyka C. Například Alpine Linux používá musl.

Pokud chcete použít kontejner založený na neglibcu, musíte:

  • Zadejte vlastní kopii Node.js.
  • Přidejte k obrázku popisek, který agentovi říká, kam má Node.js binární soubor najít.
  • Poskytovat další závislosti, na které Azure Pipelines závisí: bash, sudowhich, a groupadd.

Zadejte vlastní Node.js

Pokud používáte kontejner založený na neglibcu, zodpovídáte za přidání binárního souboru Node do kontejneru. Node.js 18 je bezpečná volba. Začněte z obrázku node:18-alpine .

Informujte agenta o Node.js

Agent přečte popisek "com.azure.dev.pipelines.handler.node.path"kontejneru . Pokud tento popisek existuje, musí se jednat o cestu k Node.js binárnímu souboru.

Například v imagi založené na node:18-alpine, přidejte následující řádek do souboru Dockerfile:

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

Přidání požadovaných balíčků

Azure Pipelines předpokládá systém založený na Bashu s nainstalovanými běžnými balíčky pro správu. Alpine Linux zejména neobsahuje několik potřebných balíčků. Nainstalujte bash, sudoa shadow pro pokrytí základních potřeb.

RUN apk add bash sudo shadow

Pokud závisíte na jakýchkoli úlohách v balení nebo Marketplace, zadejte také binární soubory, které vyžadují.

Příklad úplného souboru Dockerfile

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" ]