GNU/Linux >> Tutoriales Linux >  >> Panels >> Docker

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

Un caso de uso común para las canalizaciones de CI es la creación de las imágenes de Docker que usará para implementar su 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 sus imágenes creadas.

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 su canalización. Cubriremos los ejecutores de Shell y Docker a continuación.

Crear con el ejecutor de shell

Si está utilizando el ejecutor de Shell, asegúrese de tener Docker instalado en la máquina que aloja su ejecutor. El ejecutor funciona mediante la ejecución de comandos regulares de shell utilizando docker binario en el host de Runner.

Dirígete al repositorio de Git para el proyecto para el que deseas crear imágenes. Crea 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 impulsadas por canalización. GitLab clona automáticamente su repositorio Git en el entorno de compilación, por lo que ejecuta docker build utilizará el Dockerfile de su proyecto y hacer que el contenido del repositorio esté disponible como contexto de compilación.

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

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

Defina los valores de las dos variables de credenciales dirigiéndose 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 su trabajo.

Crear con el ejecutor Docker

El ejecutor Docker 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 docker el binario en el host de Runner será inaccesible.

El ejecutor de Docker le brinda dos estrategias posibles para construir su imagen:usar Docker-in-Docker o vincular el socket de Docker del host al entorno de construcción de Runner. Luego usa la imagen oficial del contenedor de Docker como la imagen de su trabajo, haciendo que docker comando disponible en su secuencia de comandos 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 realiza la compilación será un elemento secundario del contenedor que GitLab Runner crea en el host para ejecutar el trabajo de CI.

Debe registrar su ejecutor Docker de GitLab Runner con el modo privilegiado habilitado para usar DinD. Agregue 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 su canalización de CI, agregue el docker:dind imagen como servicio. Esto hace que Docker esté disponible como una imagen separada que está vinculada a la imagen del trabajo. Podrás usar el docker comando para crear imágenes utilizando la instancia de Docker en docker:dind contenedor.

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 abordar esto parcialmente al intentar extraer la versión anterior de su imagen antes de compilarla y luego usar --cache-from marca de compilación para 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 .

Monturas de enlace de socket

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

Para configurar esto, registre su Runner con un docker-volumes bandera que une el socket Docker del host a /var/run/docker.sock dentro de 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 los trabajos que se ejecutan con docker la imagen podrá usar el docker binario como normal. Las operaciones en realidad ocurrirán en su máquina host, convirtiéndose en hermanos del contenedor del trabajo en lugar de hijos.

Esto es efectivamente similar a usar el ejecutor de shell con la instalación de Docker de su host. Las imágenes residirán en el host, lo que facilitará el uso continuo de docker build normal. 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 destacadas son las implicaciones de seguridad:los trabajos podrían ejecutar comandos Docker arbitrarios en su host Runner, por lo que un proyecto malicioso en su instancia de GitLab podría ejecutar 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 confía en que se crean contenedores con nombres específicos. Si dos instancias de un trabajo se ejecutan en paralelo, la segunda fallará porque el nombre del contenedor ya existirá en su host.

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

Enviar imágenes al registro de GitLab

Los proyectos de GitLab tienen la opción de un registro integrado que puede usar para almacenar sus imágenes. Puede ver el contenido del registro navegando a Paquetes y registros> Registro de contenedores 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 la opción "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. Ajustar el script sección para iniciar sesión en el 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 variable final, $CI_REGISTRY_IMAGE , proporciona la ruta completa al registro de contenedores de su 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 mediante un token de acceso. Puede generarlos en la pantalla Configuración> Tokens de acceso de su proyecto. Agregue el read_registry alcance, luego use las credenciales mostradas para docker login al registro de su proyecto.

Uso del proxy de dependencia de GitLab

Dependency Proxy de GitLab proporciona una capa de almacenamiento en caché para las imágenes ascendentes que extrae de Docker Hub. Le ayuda a mantenerse dentro de los límites de velocidad de Docker Hub extrayendo solo el contenido de las imágenes cuando realmente han cambiado. Esto también mejorará el rendimiento de tus compilaciones.

El proxy de dependencia se activa en el nivel de grupo de GitLab dirigiéndose a Configuración> Paquetes y registros> Proxy de dependencia. Una vez que esté habilitado, prefije las referencias de imágenes en su .gitlab-ci.yml archivo con $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX para pasarlos 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 inicia sesión automáticamente en el registro de proxy de dependencia, por lo que no es necesario que proporcione manualmente sus credenciales.

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

Si bien ya hemos configurado el proxy para imágenes utilizadas directamente por nuestras etapas 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 pieza final, use los argumentos de compilación de Docker para que la URL del proxy de dependencia esté disponible al recorrer el Dockerfile:

ARG GITLAB_DEPENDENCY_PROXY
FROM ${GITLAB_DEPENDENCY_PROXY}/ubuntu:latest

Luego modifique su 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 extraerá a través del proxy de dependencia.

Resumen

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

Más allá 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 su método seleccionado permite que proyectos que no sean de confianza ejecuten comandos en su host Runner. Aunque conlleva sus propios problemas, Docker-in-Docker es el enfoque más seguro cuando su instancia de GitLab es de acceso público o una gran base de usuarios accede a ella.


Docker
  1. Cómo mover imágenes de Docker entre hosts

  2. Cómo buscar, extraer, enumerar y eliminar imágenes de Docker en Linux

  3. Cómo construir el contenedor Docker Anaconda Python Data Science

  4. Cómo usar un Dockerfile para crear una imagen de Docker

  5. Cómo modificar imágenes de Docker

Cómo usar Rsync y SSH en una canalización GitLab CI dockerizada

Cómo limpiar y eliminar imágenes de Docker

Cómo crear una canalización de CI/CD para imágenes de CircleCI Docker

Cómo actualizar las imágenes de Docker a la última versión

Cómo usar Docker Commit para cambiar imágenes de contenedores

Cómo listar/buscar/extraer imágenes de la ventana acoplable en Linux