Trabalhos de contêiner em dutos 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 nas máquinas host onde o agente está instalado. Os trabalhos do agente hospedado são convenientes, exigem pouca configuração inicial e infraestrutura para manutenção e são adequados para projetos básicos.
Se quiser mais controle sobre o contexto da tarefa, você pode 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 Linux e 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 um controle refinado no nível da etapa de construção individual, os destinos de etapa permitem que você escolha um contêiner ou host para cada etapa.
Pré-requisitos
- Use um pipeline YAML. Os pipelines clássicos não suportam trabalhos de contêiner.
- Use um agente Windows ou Ubuntu hospedado. Apenas
windows-*
eubuntu-*
agentes suportam a execução de contêineres. Osmacos-*
agentes não suportam a execução de contêineres. - Seu agente está configurado para trabalhos de contêiner.
- Os agentes Windows e Linux devem ter o Docker instalado e precisam de permissão para acessar o daemon do Docker.
- Os contêineres não são suportados quando o agente já está em execução dentro de um contêiner. Não é possível ter contêineres aninhados.
Requisitos adicionais do contentor
Os contêineres baseados em Linux têm os seguintes requisitos. Para obter soluções alternativas, consulte Contêineres não baseados em glibc.
- Bash instalado
- Baseado na Biblioteca GNU C (glibc)
- Não
ENTRYPOINT
- Fornecer
USER
acesso agroupadd
e outros comandos privilegiados sem usarsudo
- Pode 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. Os contêineres com um ENTRYPOINT
podem não funcionar porque o Azure Pipelines docker create
espera docker exec
que o contêiner esteja sempre ativo e em execução.
Exemplos de emprego único
Os exemplos a seguir definem um contêiner Windows ou Linux para um único trabalho.
O exemplo simples a seguir define um contêiner Linux:
pool:
vmImage: 'ubuntu-latest'
container: ubuntu:18.04
steps:
- script: printenv
O exemplo anterior 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.
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 de registro de imagem. Esse arquivo sai no final da inicialização do contêiner do Registro do Docker. As imagens 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 chamada do Docker. Nem todas essas opções têm garantia de funcionar com o Azure DevOps. Verifique primeiro se você pode usar um container
imóvel 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 recipiente reutilizável
O exemplo 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 está explicitamente listada 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 outros registros que não o 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 AWS em algo que o Docker possa usar para autenticar.
Contentores 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. Para descobrir a versão do Node.js para um agente hospedado, consulte Agentes hospedados pela Microsoft.
A versão do 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.
Se você quiser usar um contêiner não baseado em glibc, você precisa:
- Forneça 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
,which
egroupadd
.
Forneça o 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 anos é uma escolha segura. Comece pela node:18-alpine
imagem.
Informe o agente sobre 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 assume 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 bash
, sudo
e shadow
para cobrir as necessidades básicas.
RUN apk add bash sudo shadow
Se você depender de alguma tarefa da caixa de entrada 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" ]