Definir trabalhos de contêiner (YAML)
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
Por padrão, os trabalhos são executados no computador host em que o agente está instalado. Isso é prático e normalmente adequado para projetos que estão apenas começando a adotar o Azure Pipelines. Com o passar do tempo, você poderá concluir que deseja ter mais controle sobre o contexto em que suas tarefas são executadas. Os pipelines YAML oferecem trabalhos de contêiner para esse nível de controle.
Nos agentes do Linux e do Windows, os trabalhos podem ser executados no host ou em um contêiner. (No macOS e no Red Hat Enterprise Linux 6, os trabalhos de contêiner não estão disponíveis). Os contêineres fornecem isolamento do host e permitem fixar versões específicas de ferramentas e dependências. Os trabalhos de host exigem menos configuração inicial e infraestrutura para manter.
Os contêineres oferecem uma abstração leve sobre o sistema operacional host. Você pode selecionar as versões exatas de sistemas operacionais, ferramentas e dependências que o build requer. Quando você especificar um contêiner no seu pipeline, o agente buscará primeiro e iniciará o contêiner. Em seguida, cada etapa do trabalho será executada dentro do contêiner. Você não pode ter contêineres aninhados. Não há suporte para contêineres quando um agente já está em execução dentro de um contêiner.
Se você precisar de controle refinado no nível de etapa individual, os destinos das etapas permitirão que você escolha contêiner ou host de cada etapa.
Requisitos
Contêineres baseados em Linux
O sistema do Azure Pipelines exige algumas coisas nos contêineres baseados em Linux:
- Bash
- Baseado em glibc
- Pode executar Node.js (que o agente fornece)
- Não define um
ENTRYPOINT
USER
tem acesso agroupadd
e outros comandos de privilégios semsudo
E no host do agente:
- Verifique se o Docker está instalado
- O agente deve ter permissão para acessar o daemon do Docker
Verifique se o contêiner tem cada uma dessas ferramentas disponíveis. Alguns dos contêineres despojados disponíveis no Docker Hub, especialmente os baseados no Alpine Linux, não atendem a esses requisitos mínimos. Os contêineres com um ENTRYPOINT
podem não funcionar, pois o Azure Pipelines terá docker create
um contêiner aguardando e docker exec
uma série de comandos, que esperam que o contêiner esteja sempre em funcionamento.
Observação
Para contêineres do Linux baseados no Windows, o Node.js deve ser pré-instalado.
Contêineres do Windows
O Azure Pipelines também pode executar os contêineres do Windows. Windows Server versão 1803 ou posterior é necessária. O Docker deve ser instalado. Verifique se o agente de pipelines tem permissão para acessar o daemon do Docker.
O contêiner do Windows deve dar suporte à execução do Node.js. Um contêiner base do Windows Nano Server não tem as dependências necessárias para executar o Node.
Agentes hospedados
Somente as imagens windows-2019
e ubuntu-*
dão suporte à execução de contêineres.
A imagem do macOS não dá suporte à execução de contêineres.
Trabalho único
Um exemplo simples:
pool:
vmImage: 'ubuntu-latest'
container: ubuntu:18.04
steps:
- script: printenv
Isso informa ao sistema para buscar a ubuntu
imagem marcada 18.04
do Docker Hub e, em seguida, iniciar o contêiner. Quando o comando printenv
for executado, ele ocorrerá dentro do contêiner ubuntu:18.04
.
Uma exemplo do Windows:
pool:
vmImage: 'windows-2019'
container: mcr.microsoft.com/windows/servercore:ltsc2019
steps:
- script: set
Observação
O Windows exige que a versão do kernel do host e do contêiner corresponda.
Como este exemplo usa a imagem do Windows 2019, usaremos a marca 2019
para o contêiner.
Vários trabalhos
Os contêineres também são úteis para executar as mesmas etapas em vários trabalhos.
No exemplo a seguir, as mesmas etapas são executadas em várias versões do Ubuntu Linux.
(E não precisamos mencionar a palavra-chave jobs
, pois há 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
Pontos de extremidade
Os contêineres podem ser hospedados em registros diferentes dos registros públicos do Docker Hub. 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 ao registro privado. Em seguida, você poderá referenciá-lo em uma especificação de contêiner:
container:
image: registry:ubuntu1804
endpoint: private_dockerhub_connection
steps:
- script: echo hello
ou
container:
image: myprivate.azurecr.io/windowsservercore:1803
endpoint: my_acr_connection
steps:
- script: echo hello
Outros registros de contêiner também podem funcionar. No momento, o Amazon ECR não funciona, pois há outras ferramentas de cliente necessárias para converter as credenciais do AWS em algo que o Docker pode usar para autenticar.
Observação
O build do Red Hat Enterprise Linux 6 do agente não executará o trabalho de contêiner. Escolha outro tipo do Linux, como Red Hat Enterprise Linux 7 ou superior.
Opções
Se você precisar controlar a inicialização do contêiner, poderá especificar options
.
container:
image: ubuntu:18.04
options: --hostname container-test --ip 192.168.0.1
steps:
- script: echo hello
A execução de docker create --help
fornecerá a lista de opções com suporte. Você pode usar qualquer opção disponível com o comando docker create
.
Definição de contêiner reutilizável
No exemplo a seguir, os contêineres são definidos na seção de recursos.
Cada contêiner é referenciado posteriormente, referindo-se ao alias atribuído.
(Aqui, listamos explicitamente a palavra-chave jobs
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
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. Para descobrir a versão do Node.js para um agente hospedado, confira Agentes hospedados pela Microsoft. A versão do Node.js é compilada no runtime C que usamos em nossa nuvem hospedada, normalmente o glibc. Algumas variantes do Linux usam outros runtimes C. Por exemplo, o Alpine Linux usa musl.
Se você quiser usar um contêiner não baseado em glibc como contêiner de trabalho, precisará organizar algumas coisas por conta própria. Primeiro, você deve fornecer sua própria cópia do Node.js. Segundo, você deve adicionar um rótulo à sua imagem informando ao agente onde encontrar o binário do Node.js. Por fim, o Stock Alpine não vem com outras dependências das quais o Azure Pipelines depende: bash, sudo, which e groupadd.
Traga seu próprio Node.js
Você é responsável por adicionar um binário do Node ao seu contêiner.
O Node 14 é uma opção segura.
Você pode começar com a imagem node:14-alpine
.
Conte ao agente sobre o Node.js
O agente lerá um rótulo de 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:10-alpine
, adicione esta linha ao Dockerfile:
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"
Adicionar requisitos
O Azure Pipelines pressupõe um sistema baseado em Bash com pacotes de administração comuns instalados.
O Alpine Linux, em particular, não vem com vários dos pacotes necessários.
A instalação de bash
, sudo
e shadow
abrangerá as necessidades básicas.
RUN apk add bash sudo shadow
Se você depender de tarefas internas ou do Marketplace, também precisará fornecer os binários necessários.
Exemplo completo de um Dockerfile
FROM node:10-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" ]
Vários trabalhos com pools de agentes em um único agente hospedado
O trabalho de contêiner usa o agente host subjacente Docker config.json para autorização do registro de imagem, que faz logoff no final da inicialização do contêiner do Registro do Docker. A autorização subsequente de pulls de imagem do registro pode ser negada devido a "autenticação não autorizada", pois o arquivo Docker config.json registrado no sistema para autenticação já foi registrado por um dos outros trabalhos de contêiner que estão sendo executados paralelamente.
A solução é definir a variável de ambiente do Docker DOCKER_CONFIG
específica para cada serviço de pool de agentes em execução no agente hospedado. Exporte o DOCKER_CONFIG
no script de runsvc.sh de cada pool de agentes:
#insert anything to set up env when running as a service
export DOCKER_CONFIG=./.docker