Compartilhar via


Trabalhos de contêiner em pipelines YAML

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

Este artigo explica os trabalhos de contêiner no Azure Pipelines.

Por padrão, os trabalhos do Azure Pipelines são executados diretamente nos computadores host em que o agente está instalado. Os trabalhos de agente hospedado são convenientes, exigem pouca configuração inicial e infraestrutura para manutenção e são adequados para projetos básicos.

Se você quiser mais controle sobre o contexto da tarefa, poderá definir e executar trabalhos em contêineres. Os contêineres são uma abstração leve sobre o sistema operacional do host que fornece isolamento do host. Ao executar trabalhos em contêineres, você pode selecionar as versões exatas de sistemas operacionais, ferramentas e dependências que sua compilação exige.

Os agentes do Linux e do Windows podem executar trabalhos de pipeline diretamente no host ou em contêineres. Os trabalhos de contêiner não estão disponíveis no macOS.

Para um trabalho de contêiner, o agente primeiro busca e inicia o contêiner. Em seguida, cada etapa do trabalho é executada dentro do contêiner.

Se você precisar de controle refinado no nível da etapa de build individual, os destinos de etapa permitirão que você escolha um contêiner ou host para cada etapa.

Requisitos e limitações

Os requisitos e limitações a seguir se aplicam aos hosts ou contêineres do agente do Azure Pipelines.

Hosts do agente

  • Somente as imagens windows-* e ubuntu-* dão suporte à execução de contêineres. As macos-* imagens não dão suporte à execução de contêineres.
  • Para executar contêineres, os hosts do agente Windows e Linux devem ter o Docker instalado e devem ter permissão para acessar o daemon do Docker.
  • Não há suporte para contêineres quando o agente já está em execução dentro de um contêiner. Você não pode ter contêineres aninhados.

Contêineres

Os contêineres baseados em Linux têm os seguintes requisitos. Para soluções alternativas, consulte Contêineres baseados em Nonglibc.

  • Bash instalado
  • Baseado na Biblioteca GNU C (glibc)
  • Nenhum ENTRYPOINT
  • Fornecer USER acesso e groupadd outros comandos privilegiados sem usar sudo
  • Pode executar Node.js, que o agente fornece

    Observação

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

Alguns contêineres simplificados disponíveis no Docker Hub, especialmente contêineres baseados no Alpine Linux, não atendem a esses requisitos. Contêineres com um ENTRYPOINT podem não funcionar porque Azure Pipelines docker create e docker exec esperam que o contêiner esteja sempre em execução.

Exemplos de trabalho único

Os exemplos a seguir definem um contêiner do Windows ou Linux para um único trabalho.

O exemplo simples a seguir define um contêiner do Linux:

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

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

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 várias versões do Ubuntu Linux. Você não precisa mencionar a jobs palavra-chave porque apenas um único trabalho é 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 com pools de agentes 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. As extrações de imagem do Registro para trabalhos de contêiner subsequentes podem ser negadas porque unauthorized authentication outro trabalho em execução em paralelo já desconectou o arquivo de configuração do Docker.

A solução é definir uma variável DOCKER_CONFIG de ambiente do Docker específica para cada pool de agentes em execução no agente hospedado. Exporte o DOCKER_CONFIG script de runsvc.sh de cada pool de agentes da seguinte maneira:

export DOCKER_CONFIG=./.docker

Opções de inicialização

Você pode especificar options para controlar a inicialização do contêiner, como no exemplo a seguir:

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

steps:
- script: echo hello

A execução docker create --help fornece a lista de opções que você pode passar para a invocação do Docker. Nem todas essas opções têm garantia de funcionar com o Azure DevOps. Verifique primeiro se você pode usar uma container propriedade para atingir o mesmo objetivo.

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

Definição de contêiner reutilizável

O exemplo a resources seguir define os contêineres na seção e, em seguida, faz referência a eles por seus aliases atribuídos. A jobs palavra-chave é listada explicitamente para maior 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 outros registros que não o Docker Hub 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ê pode 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 Amazon Elastic Container Registry (ECR), pois o Amazon ECR requer outras ferramentas de cliente para converter credenciais da AWS em algo que o Docker possa usar para autenticar.

Contêineres não baseados em glibc

O agente do Azure Pipelines fornece uma cópia do Node.js, que é necessária para executar tarefas e scripts. Descubra a versão da Node.js de um agente hospedado, consulte Agentes hospedados pela Microsoft.

A versão do Node.js compila no tempo de execução C usado na nuvem hospedada, normalmente glibc. Algumas variantes do Linux usam outros tempos de execução C. Por exemplo, o Alpine Linux usa musl.

Se você quiser usar um contêiner não baseado em glibc, será necessário:

  • Forneça sua própria cópia do Node.js.
  • Adicione um rótulo à sua imagem informando ao agente onde encontrar o binário Node.js.
  • Forneça outras dependências das quais o Azure Pipelines depende: bash, sudo, whiche groupadd.

Forneça seu próprio Node.js

Se você usar um contêiner não baseado em glibc, será responsável por adicionar um binário de nó ao contêiner. Node.js 18 é uma escolha segura. Comece pela node:18-alpine imagem.

Conte ao agente sobre o Node.js

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

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

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

Adicionar os pacotes necessários

O Azure Pipelines pressupõe um sistema baseado em Bash com pacotes administrativos comuns instalados. O Alpine Linux, em particular, não vem com vários dos pacotes necessários. Instale basho , sudoe shadow para cobrir as necessidades básicas.

RUN apk add bash sudo shadow

Se você depender de qualquer tarefa in-box ou do Marketplace, forneça também os binários necessários.

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