Partager via


Les tâches des conteneurs dans les pipelines YAML

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

Cet article explique les tâches de conteneur dans Azure Pipelines. Les conteneurs sont des abstractions légères du système d’exploitation hôte qui fournissent tous les éléments nécessaires pour exécuter un travail dans un environnement spécifique.

Par défaut, les travaux Azure Pipelines s’exécutent directement sur des agents installés sur des machines hôtes. Les travaux d’agent hébergés sont pratiques, nécessitent peu d’installation initiale ou de maintenance de l’infrastructure et conviennent parfaitement aux projets de base. Pour plus de contrôle sur le contexte de tâche, vous pouvez définir et exécuter des travaux de pipeline dans des conteneurs pour obtenir les versions exactes des systèmes d’exploitation, des outils et des dépendances souhaités.

Pour un travail de conteneur, l’agent récupère d’abord et démarre le conteneur, puis exécute chaque étape du travail à l’intérieur du conteneur. Si vous avez besoin d’un contrôle plus précis des étapes de génération individuelles, vous pouvez utiliser des cibles d’étape pour choisir un conteneur ou un hôte pour chaque étape.

Configurations requises pour les tâches de conteneur

  • Un pipeline basé sur YAML. Les pipelines classiques ne prennent pas en charge les travaux de conteneur.
  • Agent hébergé par Windows ou Ubuntu. Les agents MacOS ne prennent pas en charge les conteneurs. Pour utiliser des agents Linux non Ubuntu, consultez les conteneurs non basés sur Nonglibc.
  • Docker installé sur l’agent, avec l’autorisation d’accéder au démon Docker.
  • Agent s’exécutant directement sur l’hôte, n’étant pas déjà à l’intérieur d’un conteneur. Les conteneurs imbriqués ne sont pas pris en charge.

Les conteneurs Linux ont également les exigences suivantes :

  • Bash installé.
  • Gnu C Library (glibc)-based. Les conteneurs nonglibc nécessitent une configuration supplémentaire. Pour plus d’informations, consultez conteneurs non basés sur Nonglibc.
  • Non ENTRYPOINT. Les conteneurs avec un ENTRYPOINT pourraient ne pas fonctionner, car docker exec s’attend à ce que le conteneur soit toujours en cours d’exécution.
  • USER fourni avec l’accès à groupadd et d’autres commandes privilégiées sans utiliser sudo.
  • Possibilité d’exécuter Node.js, que fournit l’agent.

    Remarque

    Node.js devez être préinstallé pour les conteneurs Linux sur les hôtes Windows.

Certains conteneurs dépouillés disponibles sur Docker Hub, notamment les conteneurs basés sur Alpine Linux, ne satisfont pas à ces exigences. Pour plus d’informations, consultez conteneurs non basés sur Nonglibc.

Tâche unique

L’exemple suivant définit un conteneur à tâche unique Windows ou Linux.

Cet exemple indique au système d’extraire l’image ubuntu marquée 18.04 à partir de Docker Hub , puis de démarrer le conteneur. La commande printenv s'exécute dans le conteneur ubuntu:18.04.

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

Plusieurs travaux

Vous pouvez utiliser des conteneurs pour exécuter la même étape dans plusieurs tâches. L'exemple suivant exécute la même étape dans plusieurs versions d'Ubuntu Linux. Vous n’avez pas besoin d’utiliser le jobs mot clé, car seul un seul travail est défini.

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

Plusieurs tâches sur un hôte d'agent unique

Un job de conteneur utilise le fichier de configuration Docker de l'agent hôte sous-jacent pour l'autorisation du registre d'images. Ce fichier se déconnecte à la fin de l'initialisation du conteneur de registre Docker.

Les téléchargements d'images du registre pour les tâches de conteneurisation peuvent être refusés en raison d'une authentification non autorisée si une autre tâche s'exécutant en parallèle sur l'agent a déjà délogué du fichier de configuration Docker. La solution consiste à définir une variable d’environnement Docker appelée DOCKER_CONFIG pour chaque pool d’agents s’exécutant sur l’agent hébergé.

Exportez le DOCKER_CONFIG dans le script runsvc.sh de chaque pool d'agents comme suit :

export DOCKER_CONFIG=./.docker

Options de démarrage

Vous pouvez utiliser la options propriété pour spécifier les options de démarrage du conteneur.

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

steps:
- script: echo hello

Exécutez docker create --help pour obtenir la liste des options que vous pouvez passer à l’appel Docker. Toutes ces options ne sont pas garanties pour fonctionner avec Azure Pipelines. Vérifiez d’abord si vous pouvez utiliser une container propriété à la même fin.

Pour plus d’informations, consultez la référence de commande docker container create et la définition resources.containers.container dans la référence de schéma YAML pour Azure Pipelines.

Définition de conteneur réutilisable

L’exemple YAML suivant définit les conteneurs de la resources section, puis les référence par leurs alias attribués. Le jobs mot clé est utilisé pour la clarté.

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

Points de terminaison de service

Vous pouvez héberger des conteneurs sur des registres autres que le Hub Docker public. Pour héberger une image sur Azure Container Registry ou un autre registre de conteneurs privé, y compris un registre Docker Hub privé, ajoutez une connexion de service pour accéder au registre. Vous pouvez alors référencer le point de terminaison dans la définition du conteneur.

Connexion à Docker Hub privé :

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

Connexion Azure Container Registry :

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

Remarque

Azure Pipelines ne peut pas configurer de connexion de service pour Amazon Elastic Container Registry (ERC), car Amazon WCF nécessite d’autres outils clients pour convertir les informations d’identification Amazon Web Services (AWS) afin qu’elles soient utilisables pour l’authentification Docker.

Conteneurs basés sur Nonglibc

Les agents Azure Pipelines hébergés fournissent Node.js, ce qui est nécessaire pour exécuter des tâches et des scripts. La version Node.js est compilée sur le runtime C utilisé dans le cloud hébergé, généralement glibc. Certaines variantes de Linux utilisent d'autres runtimes C. Par exemple, Alpine Linux utilise musl. Pour plus d’informations, consultez les agents hébergés par Microsoft.

Si vous souhaitez utiliser un conteneur qui n’utilise pas glibc dans un pipeline, vous devez :

  • Fournir votre propre copie de Node.js.
  • Ajoutez une étiquette à votre image pointant vers l’emplacement du binaire Node.js.
  • Fournissez les dépendances bash, sudo, which, et groupadd Azure Pipelines.

Fournir votre propre Node.js

Si vous utilisez un conteneur non basé surglibc, vous devez ajouter un fichier binaire Node à votre conteneur. Node.js 18 est un choix sûr. Commencez par l’image node:18-alpine.

Diriger l’agent vers Node.js

L'agent lit l'étiquette du conteneur "com.azure.dev.pipelines.handler.node.path". Si cette étiquette existe, il doit s’agir du chemin d’accès au binaire Node.js.

Par exemple, dans une image basée sur node:18-alpine, ajoutez la ligne suivante à votre Dockerfile :

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

Ajouter les packages nécessaires

Azure Pipelines nécessite qu’un système bash dispose de packages d’administration courants installés. Alpine Linux n’a pas plusieurs des packages nécessaires. Installez bash, sudoet shadow pour couvrir les besoins de base.

RUN apk add bash sudo shadow

Si vous dépendez des tâches intégrées ou de la Place de marché, fournissez également les fichiers binaires dont ils ont besoin.

Exemple de fichier Docker complet

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