Containeraufträge in YAML-Pipelines
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
In diesem Artikel werden Containeraufträge in Azure Pipelines erläutert.
Standardmäßig werden Azure Pipelines-Aufträge direkt auf den Hostcomputern ausgeführt, auf denen der Agent installiert ist. Gehostete Agent-Aufträge sind praktisch, erfordern wenig Anfängliche Einrichtung und Infrastruktur, um zu warten, und eignen sich gut für grundlegende Projekte.
Wenn Sie mehr Kontrolle über den Aufgabenkontext wünschen, können Sie Aufträge in Containern definieren und ausführen. Container sind eine einfache Abstraktion über das Hostbetriebssystem, das eine Isolation vom Host bereitstellt. Wenn Sie Aufträge in Containern ausführen, können Sie die genauen Versionen von Betriebssystemen, Tools und Abhängigkeiten auswählen, die Ihr Build benötigt.
Linux- und Windows-Agents können Pipelineaufträge direkt auf dem Host oder in Containern ausführen. Containeraufträge sind unter macOS nicht verfügbar.
Bei einem Containerauftrag ruft der Agent zuerst den Container ab und startet den Container. Anschließend wird jeder Schritt des Auftrags innerhalb des Containers ausgeführt.
Wenn Sie eine differenzierte Steuerung auf der ebene der einzelnen Buildschritte benötigen, können Sie mit Schrittzielen einen Container oder Host für jeden Schritt auswählen.
Voraussetzungen und Einschränkungen
Die folgenden Anforderungen und Einschränkungen gelten für Azure Pipelines-Agenthosts oder -Container.
Agenthosts
- Nur
windows-*
- undubuntu-*
-Images unterstützen das Ausführen von Containern. Diemacos-*
Images unterstützen das Ausführen von Containern nicht. - Zum Ausführen von Containern müssen Windows- und Linux-Agenthosts Docker installiert haben und über die Berechtigung zum Zugriff auf den Docker-Daemon verfügen.
- Container werden nicht unterstützt, wenn der Agent bereits in einem Container ausgeführt wird. Geschachtelte Container sind nicht möglich.
Container
Linux-basierte Container haben die folgenden Anforderungen. Problemumgehungen finden Sie unter Nonglibc-basierte Container.
- Bash installiert
- GNU C Library (glibc)-basiert
- Ohne
ENTRYPOINT
- Bereitstellen von
USER
Zugriff aufgroupadd
und anderen privilegierten Befehlen ohne Verwendungsudo
- Kann Node.js ausführen, den der Agent bereitstellt
Hinweis
Node.js muss für Linux-Container auf Windows-Hosts vorinstalliert sein.
Einige entfernte Container, die auf Docker Hub verfügbar sind, insbesondere Container, die auf Alpine Linux basieren, erfüllen diese Anforderungen nicht. Container mit einer ENTRYPOINT
Funktion funktionieren möglicherweise nicht, da Azure-Pipelines docker create
ausgeführt werden und docker exec
davon ausgehen, dass der Container immer ausgeführt wird.
Beispiele für einen einzelnen Auftrag
In den folgenden Beispielen wird ein Windows- oder Linux-Container für einen einzelnen Auftrag definiert.
Im folgenden einfachen Beispiel wird ein Linux-Container definiert:
pool:
vmImage: 'ubuntu-latest'
container: ubuntu:18.04
steps:
- script: printenv
Im vorherigen Beispiel wird dem System mitgeteilt, das ubuntu
vom Docker Hub markierte 18.04
Image abzurufen und dann den Container zu starten. Der printenv
Befehl wird innerhalb des ubuntu:18.04
Containers ausgeführt.
Mehrere Aufträge
Sie können Container verwenden, um denselben Schritt in mehreren Aufträgen auszuführen. Im folgenden Beispiel wird derselbe Schritt in mehreren Versionen von Ubuntu Linux ausgeführt. Sie müssen das jobs
Schlüsselwort nicht erwähnen, da nur ein einzelner Auftrag definiert ist.
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
Mehrere Aufträge mit Agentpools auf einem einzelnen Agenthost
Ein Containerauftrag verwendet die Docker-Konfigurationsdatei des zugrunde liegenden Host-Agents für die Imageregistrierungsautorisierung. Diese Datei meldet sich am Ende der Docker-Registrierungscontainerinitialisierung ab. Registrierungsimage-Pulls für nachfolgende Containeraufträge werden möglicherweise verweigert unauthorized authentication
, da ein anderer Auftrag, der parallel ausgeführt wird, bereits die Docker-Konfigurationsdatei abgemeldet hat.
Die Lösung besteht darin, eine Docker-Umgebungsvariable DOCKER_CONFIG
festzulegen, die für jeden Agentpool spezifisch ist, der auf dem gehosteten Agent ausgeführt wird. Exportieren Sie das skript im DOCKER_CONFIG
runsvc.sh jedes Agentpools wie folgt:
export DOCKER_CONFIG=./.docker
Startoptionen
Sie können angeben options
, dass der Containerstart gesteuert werden soll, wie im folgenden Beispiel gezeigt:
container:
image: ubuntu:18.04
options: --hostname container-test --ip 192.168.0.1
steps:
- script: echo hello
Beim Ausführen docker create --help
erhalten Sie die Liste der Optionen, die Sie an den Docker-Aufruf übergeben können. Es ist nicht sicher, dass alle diese Optionen mit Azure DevOps funktionieren. Überprüfen Sie zuerst, ob Sie eine container
Eigenschaft verwenden können, um dasselbe Ziel zu erreichen.
Weitere Informationen finden Sie in der Docker Create-Befehlsreferenz und der Definition "resources.containers.container" in der Azure DevOps YAML-Schemareferenz.
Definition wiederverwendbarer Container
Im folgenden Beispiel werden die Container im resources
Abschnitt definiert und anschließend anhand ihrer zugewiesenen Aliase darauf verwiesen. Das jobs
Schlüsselwort wird explizit zur Übersichtlichkeit aufgeführt.
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
Dienstendpunkte
Sie können Container in anderen Registrierungen als öffentlichem Docker Hub hosten. Um ein Image in der Azure Container Registry oder einer anderen privaten Containerregistrierung zu hosten, einschließlich einer privaten Docker Hub-Registrierung, fügen Sie eine Dienstverbindung für den Zugriff auf die Registrierung hinzu. Anschließend können Sie in der Containerdefinition auf den Endpunkt verweisen.
Private Docker Hub-Verbindung:
container:
image: registry:ubuntu1804
endpoint: private_dockerhub_connection
Azure Container Registry-Verbindung:
container:
image: myprivate.azurecr.io/windowsservercore:1803
endpoint: my_acr_connection
Hinweis
Azure Pipelines können keine Dienstverbindung für Amazon Elastic Container Registry (ECR) einrichten, da Amazon ECR andere Clienttools benötigt, um AWS-Anmeldeinformationen in etwas zu konvertieren, das Docker zur Authentifizierung verwenden kann.
Nichtglibc-basierte Container
Der Azure Pipelines-Agent stellt eine Kopie von Node.js bereit, die zum Ausführen von Aufgaben und Skripts erforderlich ist. Navigieren Sie zu Von Microsoft gehostete Agents, im die Version von Node.js für einen gehosteten Agent zu ermitteln.
Die Version von Node.js kompiliert mit der C-Laufzeit, die in der gehosteten Cloud verwendet wird, in der Regel glibc. Einige Linux-Varianten verwenden andere C-Runtimes. Alpine Linux verwendet beispielsweise musl.
Wenn Sie einen nichtglibc-basierten Container verwenden möchten, müssen Sie:
- Geben Sie Ihre eigene Kopie von Node.js an.
- Fügen Sie Ihrem Bild eine Beschriftung hinzu, die dem Agent mitteilt, wo die Node.js Binärdatei gefunden werden soll.
- Stellen Sie weitere Abhängigkeiten bereit, von denen Azure-Pipelines abhängig sind:
bash
,sudo
, ,which
undgroupadd
.
Liefern Sie Ihre eigene Node.js
Wenn Sie einen nichtglibc-basierten Container verwenden, sind Sie für das Hinzufügen einer Node-Binärdatei zu Ihrem Container verantwortlich. Node.js 18 ist eine sichere Wahl. Beginnen Sie mit dem node:18-alpine
Bild.
Informieren des Agents über Node.js
Der Agent liest die Containerbezeichnung "com.azure.dev.pipelines.handler.node.path"
. Wenn diese Bezeichnung vorhanden ist, muss sie der Pfad zur Node.js Binärdatei sein.
Fügen Sie z. B. in einem Image basierend auf node:18-alpine
Ihrer Dockerfile-Datei die folgende Zeile hinzu:
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"
Hinzufügen von erforderlichen Paketen
Azure Pipelines geht davon aus, dass ein bash-basiertes System mit gängigen administrativen Paketen installiert ist. Insbesondere Alpine Linux verfügt nicht über mehrere der benötigten Pakete. Installieren Sie , sudo
, und shadow
decken Sie bash
die grundlegenden Anforderungen ab.
RUN apk add bash sudo shadow
Wenn Sie von In-Box- oder Marketplace-Aufgaben abhängen, stellen Sie auch die erforderlichen Binärdateien zur Verfügung.
Vollständiges Dockerfile-Beispiel
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" ]
Zugehöriger Inhalt
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Tickets als Feedbackmechanismus für Inhalte auslaufen lassen und es durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unter:Einreichen und Feedback anzeigen für