Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
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 umENTRYPOINTpode não funcionar, pois o Docker Exec espera que o contêiner esteja sempre em execução. -
USERfornecido com acesso agroupadde outros comandos privilegiados sem usarsudo. - 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 dosudowhichAzure Pipelines egroupadddo 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" ]