Compartilhar via


Trabalhos de contêiner em pipelines YAML

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

Este artigo explica os trabalhos de contêiner no Azure Pipelines. Os contêineres são abstrações leves do sistema operacional host que fornecem todos os elementos necessários para executar um trabalho em um ambiente específico.

Por padrão, os trabalhos do Azure Pipelines são executados diretamente em agentes instalados em computadores host. Os trabalhos do agente hospedado são convenientes, exigem pouca configuração inicial ou manutenção de infraestrutura e são adequados para projetos básicos. Para obter mais controle sobre o contexto da tarefa, você pode definir e executar trabalhos de pipeline em contêineres para obter as versões exatas de sistemas operacionais, ferramentas e dependências desejadas.

Para um trabalho de contêiner, o agente primeiro busca e inicia o contêiner e executa cada etapa do trabalho dentro do contêiner. Se você precisar de um controle mais refinado das etapas de build individuais, poderá usar destinos de etapa para escolher um contêiner ou host para cada etapa.

Requisitos para trabalhos de contêiner

  • Um pipeline baseado em YAML. Pipelines clássicos não dão suporte a trabalhos de contêiner.
  • Um agente hospedado pelo Windows ou Ubuntu. Os agentes do MacOS não dão suporte a contêineres. Para usar agentes linux não Ubuntu, consulte contêineres baseados em Nãoglibc.
  • Docker instalado no agente, com permissão para acessar o daemon do Docker.
  • Agente em execução diretamente no host, ainda não dentro de um contêiner. Não há suporte para contêineres aninhados.

Os contêineres baseados em Linux também têm os seguintes requisitos:

  • Bash instalado.
  • Biblioteca C GNU (glibc)baseada. Contêineres não glibc exigem configuração adicional. Para obter mais informações, consulte contêineres baseados em nãoglibc.
  • Não ENTRYPOINT. Contêineres com um ENTRYPOINT pode não funcionar, pois o Docker Exec espera que o contêiner esteja sempre em execução.
  • USER fornecido com acesso a groupadd e outros comandos privilegiados sem usar sudo.
  • Capacidade de executar Node.js, que o agente fornece.

    Observação

    Node.js deve ser pré-instalado para contêineres do Linux em hosts do Windows.

Alguns dos contêineres despojados disponíveis no Docker Hub, especialmente os contêineres baseados no Alpine Linux, não atendem a esses requisitos. Para obter mais informações, consulte contêineres baseados em nãoglibc.

Trabalho único

O exemplo a seguir define um contêiner de trabalho único do Windows ou linux.

Este exemplo informa ao sistema para buscar a ubuntu imagem marcada 18.04 no Hub do Docker e, em seguida, iniciar o contêiner. O comando printenv é executado dentro do contêiner ubuntu:18.04.

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

Vários trabalhos

Você pode usar contêineres para executar a mesma etapa em vários trabalhos. O exemplo a seguir executa a mesma etapa em diversas versões do Ubuntu Linux. Você não precisa usar a jobs palavra-chave, pois apenas um único trabalho está definido.

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ários trabalhos em um único host de agente

Um trabalho de contêiner usa o arquivo de configuração do Docker do agente de host subjacente para autorização do registro de imagem. Esse arquivo é desconectado no final da inicialização do contêiner de registro do Docker.

Os pulls de imagem do Registro para trabalhos de contêiner podem ser negados para autenticação não autorizada se outro trabalho em execução em paralelo no agente já tiver assinado o arquivo de configuração do Docker. A solução é definir uma variável de ambiente do Docker chamada DOCKER_CONFIG para cada pool de agentes em execução no agente hospedado.

Exporte o DOCKER_CONFIG no script runsvc.sh de cada pool de agentes:

export DOCKER_CONFIG=./.docker

Opções de inicialização

Você pode usar a options propriedade para especificar opções de inicialização de contêiner.

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

steps:
- script: echo hello

Execute docker create --help para obter a lista de opções que você pode passar para a invocação do Docker. Nem todas essas opções têm a garantia de trabalhar com o Azure Pipelines. Verifique primeiro se você pode usar uma container propriedade para a mesma finalidade.

Para obter mais informações, consulte a referência de comando de criação de contêiner do docker e a definição resources.containers.container na referência de esquema YAML para Azure Pipelines.

Definição de contêiner reutilizável

O exemplo yaml a seguir define os contêineres na seção e, em resources seguida, faz referência a eles por seus aliases atribuídos. A jobs palavra-chave é usada para clareza.

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

Pontos de extremidade de serviço

Você pode hospedar contêineres em registros diferentes do Hub do Docker público. Para hospedar uma imagem no Registro de Contêiner do Azure ou em outro registro de contêiner privado (incluindo um registro privado do Docker Hub), adicione uma conexão de serviço para acessar o registro. Em seguida, você poderá fazer referência ao ponto de extremidade na definição do contêiner.

Conexão privada do Docker Hub:

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

Conexão do Registro de Contêiner do Azure:

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

Observação

O Azure Pipelines não pode configurar uma conexão de serviço para o Registro de Contêiner Elástico da Amazon (ECR), pois o Amazon ECR exige que outras ferramentas de cliente convertam credenciais do Amazon Web Services (AWS) para serem utilizáveis para autenticação do Docker.

Contêineres não baseados em glibc

Os agentes hospedados do Azure Pipelines fornecem Node.js, o que é necessário para executar tarefas e scripts. A versão Node.js é compilada no runtime C usado na nuvem hospedada, normalmente glibc. Algumas variantes do Linux usam outros runtimes C. Por exemplo, o Alpine Linux usa musl. Para obter mais informações, consulte agentes hospedados pela Microsoft.

Se você quiser usar um contêiner não baseado emglibc em um pipeline, deverá:

  • Forneça sua própria cópia do Node.js.
  • Adicione um rótulo à imagem apontando para o local do binário Node.js.
  • Forneça as bashdependências do sudowhichAzure Pipelines e groupadd do Azure.

Forneça seu próprio Node.js

Se você usar um contêiner não baseado emglibc, deverá adicionar um binário de Nó ao seu contêiner. O Node.js 18 é uma opção segura. Comece pela imagem node:18-alpine.

Direcionar o agente para Node.js

O agente lê o rótulo do contêiner "com.azure.dev.pipelines.handler.node.path". Se esse rótulo existir, ele deverá ser o caminho para o binário do Node.js.

Por exemplo, em uma imagem com base em node:18-alpine, adicione a seguinte linha ao Dockerfile:

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

Adicionar os pacotes necessários

O Azure Pipelines requer que um sistema baseado em Bash tenha pacotes administrativos comuns instalados. O Alpine Linux não tem vários dos pacotes necessários. Instale bashe sudoshadow cubra as necessidades básicas.

RUN apk add bash sudo shadow

Se você depender de tarefas internas ou do Marketplace, forneça também os binários necessários.

Exemplo completo de 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" ]