Partager via


Travaux de conteneur dans des pipelines YAML

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

Cet article explique les travaux de conteneur dans Azure Pipelines.

Par défaut, les travaux Azure Pipelines s’exécutent directement sur les machines hôtes où l’agent est installé. Les travaux d’agent hébergés sont pratiques, nécessitent peu d’installation initiale et d’infrastructure à gérer, et sont bien adaptés aux projets de base.

Si vous souhaitez plus de contrôle sur le contexte des tâches, vous pouvez définir et exécuter des travaux dans des conteneurs. Les conteneurs sont une abstraction légère sur le système d’exploitation hôte qui assure l’isolation de l’hôte. Lorsque vous exécutez des travaux dans des conteneurs, vous pouvez sélectionner les versions exactes des systèmes d’exploitation, des outils et des dépendances dont votre build a besoin.

Les agents Linux et Windows peuvent exécuter des travaux de pipeline directement sur l’hôte ou dans les conteneurs. Les travaux de conteneur ne sont pas disponibles sur macOS.

Pour un travail de conteneur, l’agent récupère d’abord et démarre le conteneur. Ensuite, chaque étape du travail s’exécute à l’intérieur du conteneur.

Si vous avez besoin d’un contrôle précis au niveau de l’étape de génération individuelle, les cibles d’étape vous permettent de choisir un conteneur ou un hôte pour chaque étape.

Exigences et limitations

Les exigences et limitations suivantes s’appliquent aux hôtes ou conteneurs de l’agent Azure Pipelines.

Hôtes de l’agent

  • Seules les images windows-* et ubuntu-* prennent en charge l’exécution de conteneurs. Les macos-* images ne prennent pas en charge l’exécution de conteneurs.
  • Pour exécuter des conteneurs, les hôtes de l’agent Windows et Linux doivent disposer de Docker installés et doivent avoir l’autorisation d’accéder au démon Docker.
  • Les conteneurs ne sont pas pris en charge lorsque l’agent est déjà en cours d’exécution à l’intérieur d’un conteneur. Vous ne pouvez pas avoir de conteneurs imbriqués.

conteneurs

Les conteneurs Linux ont les exigences suivantes. Pour obtenir des solutions de contournement, consultez conteneurs non basés sur Nonglibc.

  • Bash installé
  • Bibliothèque GNU C (glibc) basée sur
  • Aucune ENTRYPOINT
  • Fournir USER un accès à et d’autres groupadd commandes privilégiées sans utiliser sudo
  • Peut exécuter Node.js, que l’agent fournit

    Remarque

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

Certains conteneurs supprimés disponibles sur Docker Hub, en particulier les conteneurs basés sur Alpine Linux, ne répondent pas à ces exigences. Les conteneurs avec un risque de ENTRYPOINT ne pas fonctionner, car Azure Pipelines docker create et docker exec s’attendent à ce que le conteneur soit toujours opérationnel.

Exemples de travaux uniques

Les exemples suivants définissent un conteneur Windows ou Linux pour un seul travail.

L’exemple simple suivant définit un conteneur Linux :

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

L’exemple précédent indique au système d’extraire l’image ubuntu marquée 18.04 à partir de Docker Hub, puis de démarrer le conteneur. La printenv commande s’exécute à l’intérieur du ubuntu:18.04 conteneur.

Plusieurs travaux

Vous pouvez utiliser des conteneurs pour exécuter la même étape dans plusieurs travaux. L’exemple suivant exécute la même étape dans plusieurs versions d’Ubuntu Linux. Vous n’avez pas à mentionner 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 travaux avec des pools d’agents sur un hôte d’agent unique

Un travail 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 extractions d’images de Registre pour les travaux de conteneur suivants peuvent être refusées car unauthorized authentication un autre travail s’exécutant en parallèle a déjà déconnecté le fichier de configuration Docker.

La solution consiste à définir une variable DOCKER_CONFIG d’environnement Docker spécifique à chaque pool d’agents s’exécutant sur l’agent hébergé. Exportez le DOCKER_CONFIG script runsvc.sh de chaque pool d’agents comme suit :

export DOCKER_CONFIG=./.docker

Options de démarrage

Vous pouvez spécifier options pour contrôler le démarrage du conteneur, comme dans l’exemple suivant :

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

steps:
- script: echo hello

L’exécution docker create --help vous donne la liste des options que vous pouvez passer à l’appel Docker. Toutes ces options ne fonctionnent pas forcément avec Azure DevOps. Vérifiez d’abord si vous pouvez utiliser une container propriété pour atteindre le même objectif.

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

Définition de conteneur réutilisable

L’exemple suivant définit les conteneurs dans la resources section, puis les référence par leurs alias attribués. Le jobs mot clé est explicitement répertorié pour plus de 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 d’autres registres 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 ensuite référencer le point de terminaison dans la définition du conteneur.

Connexion Docker Hub privée :

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 JSON nécessite d’autres outils clients pour convertir les informations d’identification AWS en un élément que Docker peut utiliser pour s’authentifier.

Conteneurs non basés surglibc

L’agent Azure Pipelines fournit une copie de Node.js, qui est nécessaire pour exécuter des tâches et des scripts. Pour identifier la version de Node.js pour un agent hébergé, consultez Agents hébergés par Microsoft.

La version de Node.js se compile sur le runtime C utilisé dans le cloud hébergé, généralement glibc. Certaines variantes Linux utilisent d’autres runtimes C. Par exemple, Alpine Linux utilise musl.

Si vous souhaitez utiliser un conteneur non basé surglibc, vous devez :

  • Fournissez votre propre copie de Node.js.
  • Ajoutez une étiquette à votre image indiquant à l’agent où trouver le Node.js binaire.
  • Fournissez d’autres dépendances dont Dépend Azure Pipelines : bash, , sudowhich, et groupadd.

Fournissez votre propre Node.js

Si vous utilisez un conteneur non basé surglibc, vous êtes responsable de l’ajout d’un fichier binaire Node à votre conteneur. Node.js 18 est un choix sûr. Commencez à partir de l’image node:18-alpine .

Informer l’agent concernant Node.js

L’agent lit l’étiquette "com.azure.dev.pipelines.handler.node.path"du conteneur . 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 fichier Dockerfile :

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

Ajouter les packages nécessaires

Azure Pipelines suppose qu’un système Bash avec des packages d’administration courants est installé. Alpine Linux en particulier n’est pas équipé de plusieurs packages nécessaires. Installez bash, sudoet shadow pour couvrir les besoins de base.

RUN apk add bash sudo shadow

Si vous dépendez d’une tâche dans la zone ou de la Place de marché, fournissez également les fichiers binaires dont ils ont besoin.

Exemple de fichier Dockerfile 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" ]