Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
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 umENTRYPOINTpodem não funcionar, porque o docker exec espera que o contêiner esteja sempre em execução. -
USERfornecido com acesso agroupadde outros comandos privilegiados sem usarsudoo . - 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,whichegroupaddAzure 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" ]