Definición de trabajos de contenedor (YAML)
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
De forma predeterminada, los trabajos se ejecutan en la máquina host donde está instalado el agente. Este sistema resulta práctico y es adecuado normalmente para los proyectos que están empezando a adoptar Azure Pipelines. Con el tiempo, es posible que desee un mayor control sobre el contexto donde se ejecutan las tareas. Las canalizaciones de YAML ofrecen trabajos de contenedor para este nivel de control.
En los agentes de Linux y Windows, los trabajos se pueden ejecutar en el host o en un contenedor. (En macOS y Red Hat Enterprise Linux 6, los trabajos de contenedor no están disponibles). Los contenedores proporcionan aislamiento del host y permiten anclar versiones específicas de herramientas y dependencias. Los trabajos de host no necesitan tanto mantenimiento de la instalación y la infraestructura.
Los contenedores ofrecen una abstracción ligera sobre el sistema operativo host. Puede seleccionar las versiones exactas de los sistemas operativos, las herramientas y las dependencias que requiere la compilación. Al especificar un contenedor en la canalización, el agente primero lo capturará e iniciará. A continuación, cada paso del trabajo se ejecutará dentro del contenedor. No se pueden tener contenedores anidados. No se admiten contenedores cuando un agente ya se ejecuta dentro de un contenedor.
Si necesita un control específico a nivel de paso individual, los destinos de paso le permiten elegir el contenedor o el host de cada paso.
Requisitos
Contenedores basados en Linux
El sistema de Azure Pipelines necesita algunos elementos en contenedores basados en Linux:
- Bash
- Basado en glibc
- Puede ejecutar Node.js (que proporciona el agente).
- No define un objeto
ENTRYPOINT
. USER
tiene acceso agroupadd
y otros comandos de privilegios sinsudo
.
Y en el host del agente:
- Asegúrese de que Docker está instalado.
- El agente debe tener permiso para acceder al demonio de Docker.
Asegúrese de que el contenedor tiene cada una de estas herramientas disponibles. Algunos de los contenedores eliminados disponibles en Docker Hub, especialmente aquellos basados en Alpine Linux, no cumplen estos requisitos mínimos. Es posible que los contenedores con un objeto ENTRYPOINT
no funcionen, ya que Azure Pipelines aplicará docker create
al contenedor en espera y docker exec
a una serie de comandos, que esperan que el contenedor esté siempre en funcionamiento.
Nota:
En el caso de los contenedores de Linux basados en Windows, Node.js debe estar preinstalado.
Contenedores de Windows
Azure Pipelines también puede ejecutar contenedores de Windows. Se requiere Windows Server versión 1803 o posterior. Docker debe estar instalado. Asegúrese de que el agente de canalizaciones tiene permiso para acceder al demonio de Docker.
El contenedor de Windows debe admitir la ejecución de Node.js. A un contenedor base Windows Nano Server le faltan dependencias necesarias para ejecutar Node.
Agentes hospedados
Solo las imágenes de windows-2019
y ubuntu-*
admiten la ejecución de contenedores.
La imagen de macOS no admite la ejecución de contenedores.
Trabajo único
Un ejemplo sencillo:
pool:
vmImage: 'ubuntu-latest'
container: ubuntu:18.04
steps:
- script: printenv
Esto indica al sistema que capture la imagen de ubuntu
etiquetada como 18.04
de Docker Hub y, que, luego, inicie el contenedor. Cuando se ejecute el comando printenv
, sucederá dentro del contenedor ubuntu:18.04
.
Ejemplo de Windows:
pool:
vmImage: 'windows-2019'
container: mcr.microsoft.com/windows/servercore:ltsc2019
steps:
- script: set
Nota:
Windows requiere que la versión del kernel del host y el contenedor coincidan.
Dado que en este ejemplo se usa la imagen de Windows 2019, se utilizará la etiqueta 2019
para el contenedor.
Varios trabajos
Los contenedores también son útiles para ejecutar los mismos pasos en varios trabajos.
En el ejemplo siguiente, los mismos pasos se ejecutan en varias versiones de Ubuntu Linux.
(Y no tenemos que mencionar la palabra clave jobs
, ya que solo hay un único trabajo 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
Puntos de conexión
Los contenedores se pueden hospedar en registros distintos de los registros de Docker Hub públicos. Para hospedar una imagen en Azure Container Registry u otro registro de contenedor privado (incluido un registro de Docker Hub privado), agregue una conexión de servicio al registro privado. A continuación, puede hacer referencia a ella en una especificación de contenedor:
container:
image: registry:ubuntu1804
endpoint: private_dockerhub_connection
steps:
- script: echo hello
o
container:
image: myprivate.azurecr.io/windowsservercore:1803
endpoint: my_acr_connection
steps:
- script: echo hello
Otros registros de contenedor también pueden funcionar. Amazon ECR no funciona actualmente, ya que hay otras herramientas de cliente necesarias para convertir las credenciales de AWS en algo que Docker puede usar para autenticarse.
Nota:
La compilación de Red Hat Enterprise Linux 6 del agente no ejecutará el trabajo de contenedor. Elija otra versión de Linux, como Red Hat Enterprise Linux 7 o superior.
Opciones
Si necesita controlar el inicio del contenedor, puede especificar options
.
container:
image: ubuntu:18.04
options: --hostname container-test --ip 192.168.0.1
steps:
- script: echo hello
La ejecución de docker create --help
le proporcionará la lista de opciones que se pueden pasar a la invocación de Docker. No todas estas opciones están garantizadas para trabajar con Azure DevOps. Compruebe primero si puede usar una propiedad de contenedor para lograr el mismo objetivo. Para obtener más información, consulte resources.containers.container
en el esquema YAML y la referencia de comandos docker create
.
Definición de contenedor reutilizable
En el ejemplo siguiente, los contenedores se definen en la sección de recursos.
Luego, se hace referencia a cada contenedor más adelante, con una referencia a su alias asignado.
(Por claridad, aquí se muestra explícitamente la palabra clave jobs
).
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
Contenedores no basados en glibc
El agente de Azure Pipelines proporciona una copia de Node.js, que es necesaria para ejecutar tareas y scripts. Para averiguar la versión de Node.js de un agente hospedado, consulte Agentes hospedados por Microsoft. La versión de Node.js se compila en el tiempo de ejecución de C que usamos en la nube hospedada, normalmente glibc. Algunas variantes de Linux usan otros entornos de ejecución de C. Por ejemplo, Alpine Linux usa musl.
Si quiere usar un contenedor no basado en glibc como contenedor de trabajos, deberá organizar algunas cosas por su cuenta. En primer lugar, debe proporcionar su propia copia de Node.js. En segundo lugar, debe agregar una etiqueta a la imagen que indique al agente dónde encontrar el archivo binario Node.js. Por último, Stock Alpine no viene con otras dependencias de las que Azure Pipelines depende: bash, sudo, which y groupadd.
Traiga su propio archivo de Node.js
Es responsable de agregar un archivo binario de Node al contenedor.
Node 14 es una opción segura.
Puede empezar a partir de la imagen de node:14-alpine
.
Informar al agente sobre Node.js
El agente leerá la etiqueta de contenedor "com.azure.dev.pipelines.handler.node.path".
Si esta etiqueta existe, debe ser la ruta de acceso al archivo binario de Node.js.
Por ejemplo, en una imagen basada en node:10-alpine
, agregue esta línea al Dockerfile:
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"
Agregar requisitos
Azure Pipelines da por hecho un sistema basado en Bash con paquetes de administración comunes instalados.
Alpine Linux en particular no incluye varios de los paquetes necesarios.
La instalación de bash
, sudo
y shadow
cubre las necesidades básicas.
RUN apk add bash sudo shadow
Si depende de cualquier tarea integrada o de Marketplace, también deberá proporcionar los archivos binarios que estos requieran.
Ejemplo completo de un 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" ]
Varios trabajos con grupos de agentes en un único agente hospedado
El trabajo de contenedor usa el archivo config.json de Docker del agente host subyacente para la autorización del registro de imágenes, que cierra la sesión al final de la inicialización del contenedor de registro de Docker. La autorización de las extracciones de imágenes del registro subsiguientes podría denegarse por "autenticación no autorizada" porque uno de los otros trabajos de contenedor que se ejecutan en paralelo ya ha cerrado la sesión del archivo config.json de Docker registrado en el sistema para la autenticación.
La solución consiste en establecer la variable de entorno DOCKER_CONFIG
de Docker específica de cada servicio de grupo de agentes que se ejecuta en el agente hospedado. Exporte DOCKER_CONFIG
en cada script de runsvc.sh de cada grupo de agentes:
#insert anything to set up env when running as a service
export DOCKER_CONFIG=./.docker
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de