Migrar contenedores desde un registro de terceros

Si extraes algunas imágenes de contenedor directamente de registros de terceros para desplegarlas en entornos como Google Kubernetes Engine o Cloud Run, los límites de frecuencia de las extracciones de imágenes o las interrupciones de terceros pueden afectar a tus compilaciones y despliegues. Google Cloud En esta página se describe cómo identificar y copiar esas imágenes en un registro de Google Cloud para gestionar las imágenes de contenedor de forma consolidada y coherente.

Además, puedes aprovechar otras funciones, como proteger tu cadena de suministro de software con análisis de vulnerabilidades y aplicar políticas de despliegue con Autorización binaria.

Elegir un registro

Artifact Registry es el servicio recomendado para almacenar y gestionar imágenes de contenedor y otros artefactos de compilación en Google Cloud.

  • Si no usas Container Registry, migra las imágenes a Artifact Registry. Artifact Registry ofrece mayor flexibilidad y control, como la posibilidad de almacenar imágenes en una región en lugar de en varias, un control de acceso más detallado y compatibilidad con otros formatos de artefactos.
  • Si usas Container Registry, puedes migrar a Artifact Registry.

Información general sobre la migración

La migración de tus imágenes de contenedor incluye los siguientes pasos:

  1. Configura los requisitos previos.
  2. Identifica las imágenes que quieras migrar.
    • Busca en tus archivos Dockerfile y manifiestos de implementación referencias a registros de terceros.
    • Determina la frecuencia de extracción de imágenes de registros de terceros mediante Cloud Logging y BigQuery.
  3. Copia las imágenes identificadas en Container Registry.
  4. Comprueba que los permisos del registro estén configurados correctamente, sobre todo si Container Registry y tu entorno de implementación de Google Cloudestán en proyectos diferentes.
  5. Actualiza los manifiestos de tus implementaciones.
  6. Vuelve a desplegar tus cargas de trabajo.
  7. (Opcional) Bloquea las implementaciones de imágenes de fuentes de terceros.

Container Registry no monitoriza los registros de terceros para detectar actualizaciones de las imágenes que copies en Container Registry. Si quieres incorporar una versión más reciente de una imagen a tu canalización, debes enviarla a Container Registry.

Antes de empezar

  1. Verifica tus permisos. Debes tener el rol de gestión de identidades y accesos Propietario o Editor en los proyectos a los que vas a migrar imágenes a Container Registry.
  2. Ir a la página del selector de proyectos

    1. Selecciona el Google Cloud proyecto en el que quieras usar Container Registry.
    2. En la Google Cloud consola, ve a Cloud Shell
    3. Busca el ID de tu proyecto y configúralo en Cloud Shell. Sustituye YOUR_PROJECT_ID por el ID de tu proyecto.

      gcloud config set project YOUR_PROJECT_ID
      
  3. Exporta las siguientes variables de entorno:

      export PROJECT=$(gcloud config get-value project)
    
  4. Habilita las APIs BigQuery, Container Registry y Cloud Monitoring con el siguiente comando:

    gcloud services enable \
    containerregistry.googleapis.com \
    stackdriver.googleapis.com \
    logging.googleapis.com \
    monitoring.googleapis.com
    
  5. Comprueba que tienes instalada la versión 1.13 de Go o una posterior.

    • Comprueba la versión de una instalación de Go con el comando:

      go version
      
    • Si necesitas instalar o actualizar Go, consulta la documentación de instalación de Go.

Costes

En esta guía se usan los siguientes componentes facturables de Google Cloud:

Identificar las imágenes que se van a migrar

Busca en los archivos que usas para compilar e implementar tus imágenes de contenedor referencias a registros de terceros y, a continuación, comprueba con qué frecuencia extraes las imágenes.

Identificar referencias en Dockerfiles

Realiza este paso en una ubicación donde se almacenen tus Dockerfiles. Puede que sea donde se haya extraído tu código de forma local o en Cloud Shell si los archivos están disponibles en una VM.

En el directorio que contiene tus Dockerfiles, ejecuta el siguiente comando:

grep -inr -H --include Dockerfile\* "FROM" . | grep -i -v -E 'docker.pkg.dev|gcr.io'

La salida tiene el siguiente aspecto:

./code/build/baseimage/Dockerfile:1:FROM debian:stretch
./code/build/ubuntubase/Dockerfile:1:FROM ubuntu:latest
./code/build/pythonbase/Dockerfile:1:FROM python:3.5-buster

Este comando busca todos los Dockerfiles de tu directorio e identifica la línea "FROM". Ajusta el comando según sea necesario para que coincida con la forma en que almacenas tus archivos Dockerfile.

Identificar referencias en manifiestos

Realiza este paso en una ubicación donde se almacenen tus manifiestos de GKE o Cloud Run. Puede que sea donde se haya extraído tu código localmente o en Cloud Shell si los archivos están disponibles en una VM.

  1. En el directorio que contiene los manifiestos de GKE o Cloud Run, ejecuta el siguiente comando:

    grep -inr -H --include \*.yaml "image:" . | grep -i -v -E 'docker.pkg.dev|gcr.io'
    

    Ejemplo de salida:

    ./code/deploy/k8s/ubuntu16-04.yaml:63: image: busybox:1.31.1-uclibc
    ./code/deploy/k8s/master.yaml:26:      image: kubernetes/redis:v1
    

    Este comando examina todos los archivos YAML de tu directorio e identifica la línea image:. Ajusta esta línea según sea necesario para que funcione con la forma en que se almacenan los manifiestos.

  2. Para ver las imágenes que se están ejecutando en un clúster, ejecuta el siguiente comando:

      kubectl get all --all-namespaces -o yaml | grep image: | grep -i -v -E 'docker.pkg.dev|gcr.io'
    

    Este comando devuelve todos los objetos que se ejecutan en el clúster de Kubernetes seleccionado y obtiene sus nombres de imagen.

    Ejemplo de salida:

    - image: nginx
      image: nginx:latest
        - image: nginx
        - image: nginx
    

Ejecuta este comando en todos los clústeres de GKE de todos los proyectos deGoogle Cloud para obtener una cobertura total.

Identificar la frecuencia de extracción de un registro de terceros

En los proyectos que extraen datos de registros de terceros, use la información sobre la frecuencia de extracción de imágenes para determinar si su uso se acerca o supera los límites de frecuencia que aplique el registro de terceros.

Recoger datos de registro

Crea un sumidero de registros para exportar datos a BigQuery. Un sumidero de registros incluye un destino y una consulta que selecciona las entradas de registro que se van a exportar. Puedes crear un receptor consultando proyectos individuales o usar una secuencia de comandos para recoger datos de varios proyectos.

Para crear un receptor de un solo proyecto, sigue estos pasos:

Estas instrucciones son para la interfaz de vista previa de Logging.

  1. Ir al Explorador de registros

  2. Elige un Google Cloud proyecto.

  3. En la pestaña Creador de consultas, introduce la siguiente consulta:

      resource.type="k8s_pod"
      jsonPayload.reason="Pulling"
    
  4. Cambie el filtro del historial de cambios de Última hora a Últimos 7 días.

    imagen

  5. Haz clic en Ejecutar consulta.

  6. Después de verificar que los resultados se muestran correctamente, haz clic en Acciones > Crear receptor.

  7. En la lista de receptores, selecciona Conjunto de datos de BigQuery y, a continuación, haz clic en Siguiente.

  8. En el panel Editar receptor, siga estos pasos:

    • En el campo Nombre del receptor, introduce image_pull_logs.
    • En el campo Destino del receptor, crea un conjunto de datos o elige uno de destino en otro proyecto.
  9. Haz clic en Crear sumidero.

Para crear un receptor para varios proyectos, sigue estos pasos:

  1. Abre Cloud Shell.

  2. Ejecuta los siguientes comandos en Cloud Shell:

    PROJECTS="PROJECT-LIST"
    DESTINATION_PROJECT="DATASET-PROJECT"
    DATASET="DATASET-NAME"
    
    for source_project in $PROJECTS
    do
      gcloud logging --project="${source_project}" sinks create image_pull_logs bigquery.googleapis.com/projects/${DESTINATION_PROJECT}/datasets/${DATASET} --log-filter='resource.type="k8s_pod" jsonPayload.reason="Pulling"'
    done
    

    donde

    • PROJECT-LIST es una lista de IDs de proyectos Google Cloud separados por espacios. Por ejemplo, project1 project2 project3.
    • DATASET-PROJECT es el proyecto en el que quieres almacenar el conjunto de datos.
    • DATASET-NAME es el nombre del conjunto de datos, por ejemplo, image_pull_logs.

Después de crear un receptor, los datos tardan en llegar a las tablas de BigQuery, en función de la frecuencia con la que se extraigan las imágenes.

Consulta sobre la frecuencia de extracción

Una vez que tengas una muestra representativa de las extracciones de imágenes que realizan tus compilaciones, ejecuta una consulta de frecuencia de extracción.

  1. Ve a la consola de BigQuery.

  2. Ejecuta la siguiente consulta:

    SELECT
      REGEXP_EXTRACT(jsonPayload.message, r'"(.*?)"') AS imageName,
      COUNT(*) AS numberOfPulls
    FROM
          `DATASET-PROJECT.DATASET-NAME.events_*`
    GROUP BY
          imageName
    ORDER BY
          numberOfPulls DESC
    

    donde

    • DATASET-PROJECT es el proyecto que contiene el conjunto de datos.
    • DATASET-NAME es el nombre del conjunto de datos.

En el siguiente ejemplo se muestra el resultado de la consulta. En la columna imageName, puede consultar la frecuencia de extracción de las imágenes que no están almacenadas en Container Registry ni en Artifact Registry.

imagen

Copiar imágenes en Container Registry

Una vez que haya identificado las imágenes de registros de terceros, podrá copiarlas en Container Registry. La herramienta gcrane te ayuda con el proceso de copia.

  1. Crea un archivo de texto images.txt en Cloud Shell con los nombres de las imágenes que has identificado. Por ejemplo:

    ubuntu:18.04
    debian:buster
    hello-world:latest
    redis:buster
    jupyter/tensorflow-notebook
    
  2. Descarga gcrane.

      GO111MODULE=on go get github.com/google/go-containerregistry/cmd/gcrane
    
  3. Crea una secuencia de comandos llamada copy_images.sh para copiar tu lista de archivos.

    #!/bin/bash
    
    images=$(cat images.txt)
    
    if [ -z "${GCR_PROJECT}" ]
    then
        echo ERROR: GCR_PROJECT must be set before running this
        exit 1
    fi
    
    for img in ${images}
    do
        gcrane cp ${img} gcr.io/${GCR_PROJECT}/${img}
    done
    

    Haz que la secuencia de comandos sea ejecutable:

      chmod +x copy_images.sh
    
  4. Ejecuta la secuencia de comandos para copiar los archivos:

    GCR_PROJECT=${PROJECT}
    ./copy_images.sh
    

Verificar permisos

De forma predeterminada, Google Cloud los servicios de CI/CD tienen acceso a Container Registry en el mismo Google Cloud proyecto.

  • Cloud Build puede insertar y extraer imágenes
  • Los entornos de ejecución, como GKE, Cloud Run, el entorno flexible de App Engine y Compute Engine, pueden extraer imágenes.

Si necesitas enviar o extraer imágenes entre proyectos, o si utilizas herramientas de terceros en tu canalización que necesitan acceder a Container Registry, asegúrate de que los permisos estén configurados correctamente antes de actualizar y volver a implementar tus cargas de trabajo.

Para obtener más información, consulta la documentación sobre el control de acceso.

Actualizar los manifiestos para que hagan referencia a Container Registry

Actualiza tus archivos Dockerfile y tus manifiestos para que hagan referencia a Container Registry en lugar del registro de terceros.

En el siguiente ejemplo se muestra un manifiesto que hace referencia a un registro de terceros:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Esta versión actualizada del manifiesto apunta a la imagen de Container Registry:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: gcr.io/<GCR_PROJECT>/nginx:1.14.2
        ports:
        - containerPort: 80

Si tiene un gran número de manifiestos, use sed u otra herramienta que pueda gestionar las actualizaciones de muchos archivos de texto.

Volver a desplegar cargas de trabajo

Vuelve a desplegar las cargas de trabajo con los manifiestos actualizados.

Para hacer un seguimiento de las nuevas extracciones de imágenes, ejecute la siguiente consulta en la consola de BigQuery:

SELECT`

FORMAT_TIMESTAMP("%D %R", timestamp) as timeOfImagePull,
REGEXP_EXTRACT(jsonPayload.message, r'"(.*?)"') AS imageName,
COUNT(*) AS numberOfPulls
FROM
  `image_pull_logs.events_*`
GROUP BY
  timeOfImagePull,
  imageName
ORDER BY
  timeOfImagePull DESC,
  numberOfPulls DESC

Todas las nuevas extracciones de imágenes deben proceder de Container Registry y contener la cadena gcr.io.

(Opcional) Bloquear las extracciones de imágenes de registros de terceros

En los clústeres de GKE que usan Autorización binaria, la política que definas bloqueará automáticamente las extracciones de fuentes no fiables. Asegúrate de que las imágenes migradas no estén bloqueadas por la política añadiéndolas a la lista de excepciones. En estas instrucciones se describe cómo especificar una exención para todas las imágenes almacenadas en Container Registry en su proyecto.

Cuando actualices la política por primera vez, te recomendamos que habilites el modo de prueba. En lugar de bloquear imágenes, la autorización binaria crea entradas de registro de auditoría para que puedas identificar las imágenes pendientes de registros de terceros que debas migrar a Container Registry.

Para obtener más información sobre cómo configurar políticas de implementación, consulta la documentación de Autorización binaria.

  1. Ir a la página Autorización binaria
  2. Haz clic en Editar política.
  3. En Regla predeterminada del proyecto, habilita Modo de prueba.
  4. En Imágenes a las que no se les aplican las reglas de despliegue, deja seleccionada la opción Confiar en todas las imágenes del sistema proporcionadas por Google.
  5. Despliega Rutas de imágenes.
  6. Añada la ruta a sus imágenes como excepción a la regla predeterminada del proyecto:
    1. En la parte inferior de la lista de imágenes, haga clic en Añadir imágenes.
    2. Introduce la ruta de la imagen de tu proyecto Google Cloud . Por ejemplo, gcr.io/my-project/* excluye todas las imágenes del proyecto my-project.
  7. Repite el paso anterior con los demás proyectos que contengan imágenes que quieras implementar.

Revisa los eventos de ejecución de prueba en Logging de tus implementaciones. Migra las imágenes que te queden y que extraigas con regularidad de registros de terceros. Cuando se hayan migrado todas las imágenes, puedes editar la política para inhabilitar el modo de prueba y bloquear las imágenes de fuentes no fiables.