Partilhar via


Trabalhos de contêiner em dutos YAML

Serviços de DevOps do Azure | 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 máquinas host. Os trabalhos de 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, em seguida, executa cada etapa do trabalho dentro do contêiner. Se você precisar de um controle mais refinado de etapas de compilação 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. Os pipelines clássicos não suportam trabalhos de contêiner.
  • Um agente hospedado no Windows ou Ubuntu. Os agentes do MacOS não suportam contêineres. Para usar agentes Linux que não sejam do Ubuntu, consulte Contêineres baseados em Nonglibc.
  • 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.
  • Baseado na Biblioteca GNU C (glibc). Os contêineres não glibc exigem configuração adicional. Para obter mais informações, consulte Contêineres não baseados em glibc.
  • Não ENTRYPOINT. Contêineres com um ENTRYPOINT podem não funcionar, porque 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 sudoo .
  • Capacidade de executar Node.js, que o agente fornece.

    Nota

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

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

Emprego único

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

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

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 várias versões do Ubuntu Linux. Você não precisa usar 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 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 de registro de imagem. Este ficheiro termina a execução no final da inicialização do contentor do Registo do Docker.

A imagem do Registro obtida para trabalhos de contêiner pode ser negada 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 script runsvc.sh de cada pool de agentes da seguinte maneira:

export DOCKER_CONFIG=./.docker

Opções de inicialização

Você pode usar a propriedade para especificar opções para inicialização do options 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 chamada do Docker. Nem todas essas opções têm garantia de funcionar com o Azure Pipelines. Verifique primeiro se pode usar um container imóvel para o mesmo fim.

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

Definição de recipiente reutilizável

O exemplo YAML a seguir define os contêineres na seção e, em seguida, faz referência a resources eles por seus aliases atribuídos. A jobs palavra-chave é usada 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 finais de serviço

Você pode hospedar contêineres em registros diferentes do Docker Hub público. Para hospedar uma imagem no Registro de Contêiner do Azure ou 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 de 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

Nota

O Azure Pipelines não pode configurar uma conexão de serviço para o Amazon Elastic Container Registry (ECR), porque o Amazon ECR requer outras ferramentas de cliente para converter credenciais da Amazon Web Services (AWS) para ser utilizável para autenticação do Docker.

Contentores não baseados em glibc

Os agentes hospedados do Azure Pipelines fornecem Node.js, que é necessário para executar tarefas e scripts. A versão Node.js compila em relação ao 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. Para obter mais informações, consulte Agentes hospedados pela Microsoft.

Se você quiser usar um contêiner não baseado em glibc em um pipeline, você deve:

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

Forneça o seu próprio Node.js

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

Direcione o agente para Node.js

O agente lê o rótulo "com.azure.dev.pipelines.handler.node.path"do contêiner. Se esse rótulo existir, ele deve ser o caminho para o binário 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 pacotes necessários

O Azure Pipelines requer um sistema baseado em Bash para ter pacotes administrativos comuns instalados. O Alpine Linux não tem vários dos pacotes necessários. Instalar bash, sudoe shadow para cobrir necessidades básicas.

RUN apk add bash sudo shadow

Se depender de tarefas incorporadas 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" ]