Cómo crear imágenes Docker en una canalización GitLab CI

Un caso de uso común para las canalizaciones de CI es crear las imágenes de Docker que usará para implementar la aplicación. GitLab CI es una excelente opción para esto, ya que admite un servicio de proxy de extracción integrado, lo que significa canalizaciones más rápidas y un registro integrado para almacenar las imágenes que crea.

En esta guía, le mostraremos cómo configurar compilaciones de Docker que usan las dos funciones anteriores. Los pasos que debe seguir varían ligeramente según el tipo de ejecutor de GitLab Runner que usará para la canalización. Cubriremos los artistas de Shell y Docker a continuación.

Construyendo con el ejecutor de shell

Si está utilizando el ejecutor de Shell, asegúrese de tener Docker instalado en la computadora que aloja su ejecutor. El ejecutor funciona ejecutando comandos de shell normales usando el archivo docker binario en el host Runner.

Vaya al repositorio de Git para el proyecto para el que desea crear imágenes. Crear un .gitlab-ci.yml archivo en la raíz del repositorio. Este archivo define la canalización de GitLab CI que se ejecutará cuando envíe cambios a su proyecto.

Agregue el siguiente contenido al archivo:

stages:
  - build

docker_build:
  stage: build
  script:
    - docker build -t example.com/example-image:latest .
    - docker push example.com/example-image:latest

Esta configuración simplista es suficiente para demostrar los conceptos básicos de las compilaciones de imágenes basadas en canalización. GitLab clona automáticamente su repositorio Git en el entorno de compilación que está ejecutando docker build usará tu proyecto Dockerfile y hacer que el contenido del repositorio esté disponible como un contexto de compilación.

Una vez completada la compilación, puede docker push la imagen en el registro. De lo contrario, solo estaría disponible para la instalación local de Docker que realizó la compilación. Si está utilizando un registro privado, ejecute docker login antes de proporcionar los detalles de autenticación correctos:

script:
  - docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD

Defina los valores de las dos variables de credenciales yendo a Configuración> CI/CD> Variables en la interfaz de usuario web de GitLab. Haga clic en el botón azul "Agregar variable" para crear una nueva variable y asignarle un valor. GitLab hará que estas variables estén disponibles en el entorno de shell utilizado para ejecutar el trabajo.

Construyendo con Docker Executor

Docker Executor de GitLab Runner se usa comúnmente para proporcionar un entorno completamente limpio para cada trabajo. El trabajo se ejecutará en un contenedor aislado, por lo que el docker binario en host Runner será inaccesible.

Docker Executor ofrece dos posibles estrategias para crear la imagen: usar Docker-in-Docker o conectar el socket Docker del host al entorno de compilación de Runner. A continuación, utiliza la imagen oficial del contenedor de Docker como su imagen de trabajo, creando el docker comando disponible en el script de CI.

Docker en Docker

El uso de Docker-in-Docker (DinD) para crear sus imágenes le brinda un entorno completamente aislado para cada trabajo. El proceso de Docker que compila será un elemento secundario del contenedor que GitLab Runner crea en el host para ejecutar el proceso de CI.

Debe registrar su ejecutante GitLab Runner Docker con el modo privilegiado habilitado para usar DinD. Añade el --docker-privileged marca cuando registras a tu corredor:

sudo gitlab-runner register -n 
  --url https://example.com 
  --registration-token $GITLAB_REGISTRATION_TOKEN 
  --executor docker 
  --description "Docker Runner" 
  --docker-image "docker:20.10" 
  --docker-volumes "/certs/client" 
  --docker-privileged

Dentro de la canalización de CI, agregue el archivo docker:dind imagen como servicio. Esto hace que Docker esté disponible como una imagen independiente vinculada a la imagen del trabajo. Podrá utilizar el docker comando para crear imágenes usando la instancia de Docker en docker:dind envase.

services:
  - docker:dind

docker_build:
  stage: build
  image: docker:latest
  script:
    - docker build -t example-image:latest .

El uso de DinD le brinda compilaciones completamente aisladas que no pueden afectarse entre sí ni a su host. El principal inconveniente es un comportamiento de almacenamiento en caché más complicado: cada trabajo obtiene un nuevo entorno en el que no se podrá acceder a las capas creadas previamente. Puede arreglar esto parcialmente tratando de extraer la versión anterior de su imagen antes de crearla, luego usando el --cache-from build flag para hacer que las capas de la imagen extraída estén disponibles como fuente de caché:

docker_build:
  stage: build
  image: docker:latest
  script:
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    - docker build --cache-from $CI_REGISTRY_IMAGE:latest -t $CI_REGISTRY_IMAGE:latest .

Soportes para accesorios de enchufe

Montar el socket Docker del host en el entorno de trabajo es una opción alternativa cuando se usa el ejecutor Docker. Esto le brinda un almacenamiento en caché sin problemas y elimina la necesidad de agregar el archivo docker:dind servicio a su configuración de CI.

Para configurarlo, registre su Runner con un docker-volumes indicador que vincula el socket Docker del host a /var/run/docker.sock dentro de los contenedores de trabajo:

sudo gitlab-runner register -n 
  --url https://example.com 
  --registration-token $GITLAB_REGISTRATION_TOKEN 
  --executor docker 
  --description "Docker Runner" 
  --docker-image "docker:20.10" 
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

Ahora las obras realizadas con docker la imagen podrá usar el docker binario como siempre. Las operaciones en realidad se llevarán a cabo en la computadora host, convirtiéndose en hermanos del contenedor de trabajos en lugar de hijos.

En realidad, esto es similar a usar el ejecutor de shell con la instalación de Docker del host. Las imágenes residirán en el host, lo que facilita su uso sin interrupciones normales docker build almacenamiento en caché de capas.

Si bien este enfoque puede conducir a un mayor rendimiento, menos configuración y ninguna de las limitaciones de DinD, tiene sus propios problemas únicos. Las más importantes son las implicaciones de seguridad: los trabajos podrían ejecutar comandos Docker arbitrarios en su host Runner, por lo que podría ejecutarse un proyecto malicioso en su instancia de GitLab. docker run -it malicious-image:latest o docker rm -f $(docker ps -a) con consecuencias devastadoras.

GitLab también advierte que la vinculación de sockets puede causar problemas cuando los trabajos se ejecutan simultáneamente. Esto ocurre cuando se confía en la creación de contenedores con nombres específicos. Si dos instancias de un trabajo se ejecutan en paralelo, la segunda fallará porque el nombre del contenedor ya existe en el host.

Debería considerar usar DinD en su lugar si espera que alguno de estos problemas sea problemático. Si bien DinD ya no se recomienda en general, puede tener más sentido para las instancias públicas de GitLab que ejecutan trabajos de CI simultáneos.

Envío de imágenes al registro de GitLab

Los proyectos de GitLab tienen la opción de un registro incorporado que puede usar para archivar sus imágenes. Puede ver el contenido del registro yendo a Paquetes y registros> Registro de contenedor en la barra lateral de su proyecto. Si no ve este enlace, habilite el registro yendo a Configuración> General> Visibilidad, Proyecto, Funciones y Permisos y activando el interruptor "Registro de contenedor".

GitLab establece automáticamente variables de entorno en sus trabajos de CI que le permiten hacer referencia al registro de contenedores de su proyecto. Arregla el script sección para acceder al registro y enviar su imagen:

script:
  - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
  - docker build -t $CI_REGISTRY_IMAGE:latest .
  - docker push $CI_REGISTRY_IMAGE:latest

GitLab genera un conjunto seguro de credenciales para cada uno de sus trabajos de CI. El $CI_JOB_TOKEN La variable de entorno contendrá un token de acceso que el trabajo puede usar para conectarse al registro como gitlab-ci-token usuario. La URL del servidor de registro está disponible como $CI_REGISTRY.

La última variable, $CI_REGISTRY_IMAGE, proporciona la ruta completa al registro del contenedor del proyecto. Esta es una base adecuada para sus etiquetas de imagen. Puede extender esta variable para crear sub-repositorios, como $CI_REGISTRY_IMAGE/production/api:latest.

Otros clientes de Docker pueden extraer imágenes del registro al autenticarse con un token de acceso. Puede generarlos en la pantalla Configuración> Tokens de acceso de su proyecto. Añade el read_registry alcance, luego use las credenciales que se muestran para docker login en el registro de su proyecto.

Usando el proxy de dependencia de GitLab

El proxy de dependencia de GitLab proporciona una capa de almacenamiento en caché para las imágenes ascendentes que extrae de Docker Hub. Le ayuda a permanecer dentro de los límites de velocidad de Docker Hub al extraer el contenido de la imagen solo cuando se ha editado. Esto también mejorará el rendimiento de tus compilaciones.

El proxy de dependencia se activa en el nivel de grupo de GitLab yendo a Configuración> Paquetes y registros> Proxy de dependencia. Una vez habilitado, prefije las referencias a las imágenes en el archivo .gitlab-ci.yml archivo con $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX para extraerlos a través del proxy:

docker_build:
  stage: build
  image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:latest
  services:
    - name: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:dind
      alias: docker

¡Eso es todo al respecto! GitLab Runner accede automáticamente al registro de proxy de dependencia, por lo que no es necesario que proporcione las credenciales manualmente.

GitLab ahora almacena en caché sus imágenes, lo que le brinda un mejor rendimiento y resistencia a las interrupciones de la red. Tenga en cuenta que el services la definición también tuvo que cambiarse: las variables de entorno no funcionan con el módulo en línea utilizado anteriormente, por lo que la imagen completa name debe especificarse, entonces un comando alias para hacer referencia en su script sección.

Aunque ya hemos configurado el proxy para las imágenes utilizadas directamente por nuestros pasos de trabajo, se necesita más trabajo para agregar soporte para la imagen base en el Dockerfile para construir. Una instrucción regular como esta no pasará por el proxy:

FROM ubuntu:latest

Para agregar esta última pieza, use los argumentos de compilación de Docker para que la URL del proxy de dependencia esté disponible cuando se desplace por el Dockerfile:

ARG GITLAB_DEPENDENCY_PROXY
FROM ${GITLAB_DEPENDENCY_PROXY}/ubuntu:latest

Luego edita el tuyo docker build Comando para definir el valor de la variable:

script:
  >
    - docker build 
        --build-arg GITLAB_DEPENDENCY_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX} 
        -t example-image:latest .

Ahora su imagen base también se arrastrará a través del proxy de dependencia.

Resumen

Las compilaciones de imágenes de Docker se integran fácilmente en las canalizaciones de CI de GitLab. Después de la configuración inicial del Runner, docker build Y docker push Comandos en tu trabajo script son todo lo que necesita para crear una imagen con el archivo Dockerfile en tu repositorio. El registro de contenedores incorporado de GitLab le brinda espacio de almacenamiento privado para las imágenes de su proyecto.

Además de las compilaciones básicas, vale la pena integrar el proxy de dependencia de GitLab para acelerar el rendimiento y evitar alcanzar los límites de velocidad de Docker Hub. También debe verificar la seguridad de su instalación evaluando si el método seleccionado permite que proyectos no confiables ejecuten comandos en su host Runner. Si bien tiene sus problemas, Docker-in-Docker es el enfoque más seguro cuando la instancia de GitLab es de acceso público o accesible para una gran base de usuarios.

¿Qué te ha parecido?
Subir
DiarioInforme utiliza cookies    Configurar y más información
Privacidad