Usa la caché de Kaniko

Descripción general

Kaniko almacena en caché los artefactos de compilación de contenedores mediante el almacenamiento y la indexación de capas intermedias dentro de un registro de imágenes de contenedor, como Artifact Registry de Google. Para obtener información sobre casos de uso adicionales, consulta el repositorio de Kaniko en GitHub.

La caché de Kaniko funciona de la siguiente manera:

  • Cloud Build sube las capas de imagen del contenedor directamente en el registro a medida que se crean, por lo que no hay un paso explícito. Si todas las capas se crean correctamente, un manifiesto de imagen que contiene esas capas se escribe en el registro.

  • Kaniko almacena en caché cada capa de acuerdo con el contenido de la directiva del Dockerfile que la creó, además de todas las directivas que la precedieron, hasta el resumen de la imagen en la línea FROM.

Habilita la caché de Kaniko en tus compilaciones

Puedes habilitar la caché de Kaniko en una compilación de Docker si reemplazas los trabajadores cloud-builders/docker por trabajadores kaniko-project/executor en tu archivo cloudbuild.yaml de la siguiente manera:

Compilación de Kaniko

steps:
- name: 'gcr.io/kaniko-project/executor:latest'
  args:
  - --destination=${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}
  - --cache=true
  - --cache-ttl=XXh

Compilación de Docker

steps:
- name: gcr.io/cloud-builders/docker
  args: ['build', '-t', '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}', '.']
images:
- '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}'

Donde:

  • --destination=${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE} es la imagen del contenedor de destino. Cloud Build sustituye de forma automática el PROJECT_ID del proyecto que contiene el Dockerfile. LOCATION, REPOSITORY y IMAGE son sustituciones definidas por el usuario.
  • LOCATION es la ubicación regional o multirregional del repositorio en el que se almacena la imagen, por ejemplo, us-east1.
  • REPOSITORY es el nombre del repositorio en el que se almacena la imagen.
  • IMAGE es el nombre de la imagen.
  • --cache=true habilita la caché de Kaniko.
  • --cache-ttl=XXh establece el tiempo de caducidad de la caché, en la que XX es la cantidad de horas que pasarán hasta que la caché caduque. Consulta Configura el tiempo de caducidad de la caché.

Si ejecutas compilaciones con mediante el comando gcloud builds submit --tag [IMAGE], puedes habilitar la caché de Kaniko mediante la configuración de la propiedad builds/use_kaniko en True como se muestra a continuación:

gcloud config set builds/use_kaniko True

Ejemplo: Usa la caché de Kaniko en una compilación de Node.js

En este ejemplo, se muestra cómo ejecutar compilaciones incrementales para aplicaciones de Node.js mediante las prácticas recomendadas generales del Dockerfile. Estas prácticas se aplican a las compilaciones de todos los demás idiomas admitidos.

Aquí, mueves directivas que es poco probable que cambien entre compilaciones a la parte superior de tu Dockerfile, y mueves directivas que es probable que cambien a la parte inferior. Esto hace que el proceso de compilación sea más gradual y pueda aumentar la velocidad de compilación.

Considera el siguiente Dockerfile:

FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "npm", "start" ]

Este Dockerfile hace lo siguiente:

Cloud Build debe completar el paso correspondiente cada vez que se ejecuta la compilación, ya que no hay caché de capa de imagen de compilación cruzada en Cloud Build. Sin embargo, cuando ejecutas esta compilación con la caché de Kaniko habilitada, sucede lo siguiente:

  1. Durante la primera ejecución, Cloud Build completa los pasos uno a uno, y cada directiva escribe una capa en el registro de imágenes del contenedor.

  2. Kaniko etiqueta cada capa con una clave de caché que deriva del contenido de la directiva que produjo esa capa más todas las directivas anteriores.

  3. La próxima vez que Cloud Build ejecuta la compilación desde el mismo Dockerfile, verificará si el archivo ha cambiado. Si este no se ha modificado, Cloud Build usa las capas en caché almacenadas en el registro para completar la compilación, lo que permite que la compilación finalice más rápido. Consulta la información a continuación.

FROM node:8                # no change -> cached!
COPY package*.json ./      # no change -> cached!
RUN npm install            # no change -> cached!
COPY . .                   # no change -> cached!
CMD [ "npm", "start" ]     # metadata, nothing to do

Si modificas tu archivo package.json, Cloud Build no necesita ejecutar directivas antes del paso COPY porque su contenido no ha cambiado. Sin embargo, como la modificación del archivo package.json modifica el paso COPY, Cloud Build debe volver a ejecutar todos los pasos posteriores al COPY. Consulta la información a continuación.

FROM node:8                # no change -> cached!
COPY package*.json ./      # changed, must re-run
RUN npm install            # preceding layer changed
COPY . .                   # preceding layer changed
CMD [ "npm", "start" ]     # metadata, nothing to do

Si solo cambia el contenido de la app, pero no sus dependencias (la situación más común), el archivo package.json no se modifica y Cloud Build solo debe volver a ejecutar el paso final COPY . .. Esto da como resultado una mayor velocidad de compilación, ya que el paso simplemente copia el contenido fuente a una capa en el registro de imágenes del contenedor.

FROM node:8                # no change -> cached!
COPY package*.json ./      # no change -> cached!
RUN npm install            # no change -> cached!
COPY . .                   # changed, must re-run
CMD [ "npm", "start" ]     # metadata, nothing to do

Configura el tiempo de caducidad de la memoria caché

La marca --cache-ttl indica a Kaniko que ignore las capas de la caché que no se hayan enviado dentro de un tiempo de caducidad determinado.

La sintaxis es --cache-ttl=XXh, en la que XX es el tiempo en horas. Por ejemplo, --cache-ttl=6h establece la caducidad de la caché en 6 horas. Si ejecutas compilaciones mediante el comando gcloud builds submit --tag [IMAGE], el valor predeterminado de la marca --cache-ttl es de 6 horas. Si usas la imagen del ejecutor de Kaniko directamente, el valor predeterminado es 2 semanas.

Un tiempo de vencimiento más prolongado garantiza compilaciones más rápidas cuando no esperas que las dependencias cambien con frecuencia, mientras que un tiempo de vencimiento más corto asegura que tu compilación recoja dependencias actualizadas (como paquetes Maven o módulos Node.js) más rápidamente a expensas del uso disminuido de las capas en caché.

Para configurar el tiempo de caducidad de la caché desde la línea de comandos, ejecuta el comando siguiente:

gcloud config set builds/kaniko_cache_ttl XX

en el que XX es el tiempo de caducidad de la caché en horas.

En nuestro ejemplo de Node.js, dado que el resultado de la directiva RUN npm install no ha cambiado, debemos volver a ejecutarlo con regularidad, incluso si se almacenó en caché. Establecer el parámetro --cache-ttl en 6 horas es una buena solución, ya que garantiza que Cloud Build ejecute la directiva al menos una vez por cada día laboral, pero no cada vez que la compilación se ejecute, sin importar si el contenido de esa directiva cambió.