Acelera tus compilaciones

En esta página, se explican algunas de las formas en que puedes acelerar tus compilaciones con Cloud Build.

Mediante una imagen de Docker almacenada en caché

La forma más sencilla de aumentar la velocidad de compilación de tu imagen de Docker es con la especificación de una imagen en caché que se puede usar para compilaciones posteriores. Puedes especificar la imagen en caché si agregas el argumento --cache-from en tu archivo de configuración de compilación que instruirá a Docker a que compile con esa imagen como una fuente en caché.

Cada imagen de Docker está compuesta por capas apiladas. Con el uso de --cache-from, se vuelven a compilar todas las capas desde la capa modificada hasta el final de la compilación; por eso, no es beneficioso usar --cache-from si cambias una capa en las etapas iniciales de tu compilación de Docker.

Se recomienda que siempre uses --cache-from para tus compilaciones, pero ten en cuenta las advertencias siguientes:

  • Necesitas una imagen de Docker compilada con anterioridad desde la que se pueda acceder al almacenamiento en caché.
  • Puedes usar --cache-from solo para compilaciones de Docker; no con compilaciones que crean otros tipos de artefactos.
  • Se debe recuperar la imagen en caché desde un registro que pueda aumentar el tiempo de compilación.

En los pasos siguientes, se explica cómo compilar con una imagen almacenada en caché con anterioridad:

YAML

  1. En tu configuración de compilación, agrega instrucciones para realizar lo siguiente:

    • Extraer la imagen en caché desde Container Registry. Ten en cuenta que el paso de compilación docker pull debajo establece entrypoint en bash, lo que te permite ejecutar el comando y, además, ignorar el error mostrado. Esto es necesario cuando compilas una imagen por primera vez y docker pull no tiene una imagen existente para extraer.
    • Agrega un argumento --cache-from para usar esa imagen a fin de volver a compilar.

      steps:
       - name: 'gcr.io/cloud-builders/docker'
         entrypoint: 'bash'
         args:
         - '-c'
         - |
           docker pull gcr.io/$PROJECT_ID/[IMAGE_NAME]:latest || exit 0
      - name: 'gcr.io/cloud-builders/docker'
        args: [
                  'build',
                  '-t', 'gcr.io/$PROJECT_ID/[IMAGE_NAME]:latest',
                  '--cache-from', 'gcr.io/$PROJECT_ID/[IMAGE_NAME]:latest',
                  '.'
              ]
      images: ['gcr.io/$PROJECT_ID/[IMAGE_NAME]:latest']
      

      donde [IMAGE_NAME] es el nombre de tu imagen.

  2. Compila tu imagen con la configuración de compilación anterior:

    gcloud builds submit --config cloudbuild.yaml .
    

JSON

  1. En tu configuración de compilación, agrega instrucciones para realizar lo siguiente:

    • Extraer la imagen en caché desde Container Registry. Ten en cuenta que el paso de compilación docker pull debajo establece entrypoint en bash, lo que te permite ejecutar el comando y, además, ignorar los errores mostrados. Esto es necesario cuando compilas una imagen por primera vez y docker pull no tiene una imagen existente para extraer.
    • Agrega un argumento --cache-from para usar esa imagen a fin de volver a compilar.

      {
          "steps": [
          {
              "name": "gcr.io/cloud-builders/docker",
              "entrypoint": "bash",
              "args": ["-c", "docker pull gcr.io/$PROJECT_ID/quickstart-image:latest || exit 0"]
          },
          {
              "name": "gcr.io/cloud-builders/docker",
              "args": [
                  "build",
                  "-t",
                  "gcr.io/$PROJECT_ID/[IMAGE_NAME]:latest",
                  "--cache-from",
                  "gcr.io/$PROJECT_ID/[IMAGE_NAME]:latest",
                  "."
              ]
          }
          ],
          "images": ["gcr.io/$PROJECT_ID/[IMAGE_NAME]:latest"]
      }
      

      donde [IMAGE_NAME] es el nombre de tu imagen.

  2. Compila tu imagen con la configuración de compilación anterior:

    gcloud builds submit --config cloudbuild.json .
    

Almacena directorios en caché con Google Cloud Storage

Con el fin de aumentar la velocidad de una compilación, vuelve a usar los resultados de una compilación anterior. Puedes copiar los resultados de una compilación previa en un depósito de Google Cloud Storage, usar los resultados para hacer cálculos más rápido y, luego, copiar los resultados nuevos otra vez en el depósito. Usa este método si tu compilación tarda mucho y produce pocos archivos que no demoran mucho en copiarse desde y hacia Google Cloud Storage.

A diferencia de --cache-from, que es solo para compilaciones de Docker, el almacenamiento en caché de Google Cloud Storage se puede usar con cualquier compilador compatible con Cloud Build.

Usa los pasos a continuación para almacenar en caché los directorios que usan Google Cloud Storage:

YAML

  1. En tu archivo de configuración de compilación, agrega instrucciones para realizar lo siguiente:

    • Copia los resultados de una compilación previa desde el depósito de Google Cloud Storage.
    • Usa los resultados para la compilación actual.
    • Vuelve a copiar los resultados nuevos en el depósito.

      steps:
      - name: gcr.io/cloud-builders/gsutil
        args: ['cp', 'gs://mybucket/results.zip', 'previous_results.zip']
      # operations that use previous_results.zip and produce new_results.zip
      - name: gcr.io/cloud-builders/gsutil
        args: ['cp', 'new_results.zip', 'gs://mybucket/results.zip']
      
  2. Compila tu código con la configuración de compilación anterior:

    gcloud builds submit --config cloudbuild.yaml .
    

JSON

  1. En tu archivo de configuración de compilación, agrega instrucciones para realizar lo siguiente:

    • Copia los resultados de una compilación previa desde el depósito de Google Cloud Storage.
    • Usa los resultados para la compilación actual.
    • Vuelve a copiar los resultados nuevos en el depósito.

      {
          "steps": [
          {
              "name": "gcr.io/cloud-builders/gsutil",
              "args": ["cp", "gs://mybucket/results.zip", "previous_results.zip"]
          },
          {
              // operations that use previous_results.zip and produce new_results.zip
          },
          {
              "name": "gcr.io/cloud-builders/gsutil",
              "args": ["cp", "new_results.zip", "gs://mybucket/results.zip"]
          }
          ]
      }
      
  2. Compila tu código con la configuración de compilación anterior:

    gcloud builds submit --config cloudbuild.json .
    

Usa tamaños personalizados de máquinas virtuales

Además del tipo de máquina estándar, Cloud Build proporciona dos tipos de máquina virtual con capacidad alta de CPU para ejecutar tus compilaciones. A fin de aumentar la velocidad de tu compilación, selecciona una máquina virtual con una capacidad alta de CPU. Solicitar una máquina con capacidad alta de CPU puede incrementar el tiempo de inicio de tu compilación, ya que Cloud Build solo inicia estas máquinas a la demanda.

Para obtener información sobre la selección de tamaños personalizados del disco, consulta diskSize.

En los pasos a continuación, se explica cómo especificar un tamaño personalizado de una VM para una compilación:

gcloud

Para especificar un tamaño de VM personalizado, usa el argumento --machine-type:

gcloud builds submit --config=cloudbuild.yaml \
    --machine-type=n1-highcpu-8 .

YAML

  1. Especifica el tamaño de la VM en tu archivo de configuración de compilación:

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', 'gcr.io/my-project/image1', '.']
      # operations that take a long time to build
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', 'gcr.io/my-project/image2', '.']
    options:
      machineType: 'N1_HIGHCPU_8'
    
  2. Compila con la configuración de compilación anterior:

    gcloud builds submit --config cloudbuild.yaml .
    

JSON

  1. Especifica el tamaño de la VM en tu archivo de configuración de compilación:

    {
        "steps": [
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": ["build", "-t", "gcr.io/my-project/image1", "."]
        },
        // operations that take a long time to build
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": ["build", "-t", "gcr.io/my-project/image2", "."]
        }
        ],
        "options": {
            "machineType": "N1_HIGHCPU_8"
        }
    }
    
  2. Compila con la configuración de compilación anterior:

    gcloud builds submit --config cloudbuild.json .
    

Compila contenedores más eficientes

Muchas veces, compilar una aplicación requiere una gran cantidad de archivos como dependencias de tiempo de compilación y archivos intermedios, que no son necesarios en el entorno de ejecución. Pero, cuando organizas la aplicación en contenedores, estos archivos se incluyen en el contenedor y producen un sobredimensionamiento innecesario. Con el tiempo, este sobredimensionamiento te cuesta tiempo y dinero debido al almacenamiento y movimiento de bits entre tu registro de Docker y el contenedor de tu entorno de ejecución.

A fin de asegurarte de que tu contenedor sea lo más pequeño posible, separa la compilación de la aplicación (y las herramientas necesarias para hacerlo) del ensamblaje del contenedor del entorno de ejecución.

Cloud Build proporciona una serie de contenedores de Docker con herramientas para desarrolladores comunes como Git, Docker y la interfaz de línea de comandos de gcloud. Usa estas herramientas a fin de definir un archivo de configuración de compilación con un paso de compilación de la aplicación y otro paso para ensamblar su entorno de ejecución final.

Por ejemplo, si compilas una aplicación Java, lo que necesita archivos como el código fuente, las bibliotecas de la aplicación, los sistemas de compilación, las dependencias del sistema de compilación y el JDK, es posible que tengas un Dockerfile similar al siguiente:

FROM java:8

COPY . workdir/

WORKDIR workdir

RUN GRADLE_USER_HOME=cache ./gradlew buildDeb -x test

RUN dpkg -i ./gate-web/build/distributions/*.deb

CMD ["/opt/gate/bin/gate"]

En el ejemplo anterior, Gradle, que se usa a fin de compilar el paquete, descarga muchas bibliotecas para funcionar. Estas bibliotecas son indispensables para la compilación del paquete, pero no son necesarias en el entorno de ejecución. Todas las dependencias del entorno de ejecución se juntan en el paquete.

Cada comando en el Dockerfile crea una capa nueva en el contenedor. Si se generan datos en esa capa y no se borran en el mismo comando, ese espacio no se puede recuperar. En este caso, Gradle descarga cientos de megabytes de las bibliotecas en el directorio cache a modo de realizar la compilación, pero las bibliotecas no se borran.

Una forma más eficiente de realizar la compilación es usar Cloud Build a fin de separar la compilación de la aplicación de la compilación de su capa de entorno de ejecución.

El ejemplo siguiente separa el paso de compilación de la aplicación Java del paso de ensamblaje del contenedor del entorno de ejecución:

YAML

  1. Compila la aplicación: en cloudbuild.yaml, agrega un paso para compilar la aplicación.

    El código a continuación agrega un paso llamado java:8 para compilar el código de Java.

    steps:
    
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c', './gradlew gate-web:installDist -x test']
    
    
  2. Ensambla el contenedor del entorno de ejecución: en cloudbuild.yaml, agrega un paso para ensamblar el contenedor del entorno de ejecución.

    El código a continuación agrega un paso llamado gcr.io/cloud-builders/docker que ensambla el contenedor del entorno de ejecución. Este define el contenedor del entorno de ejecución en un archivo diferente llamado Dockerfile.slim.

    El ejemplo usa la capa base openjdk:8u111-jre-alpine de Alpine Linux, que es muy eficiente. Además, incluye el JRE, en lugar del JDK más voluminoso que era necesario para compilar la aplicación.

    cloudbuild.yaml
    
    steps:
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c',
             './gradlew gate-web:installDist -x test']
    
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',
             '-f', 'Dockerfile.slim',
             '.'
      ]
    
    
    Dockerfile.slim
    
    FROM openjdk:8u111-jre-alpine
    
    COPY ./gate-web/build/install/gate /opt/gate
    
    CMD ["/opt/gate/bin/gate"]
    
  3. Crea las imágenes de Docker: en cloudbuild.yaml, agrega un paso para crear las imágenes.
    steps:
    - name: 'java:8'
      env: ['GRADLE_USER_HOME=cache']
      entrypoint: 'bash'
      args: ['-c', './gradlew gate-web:installDist -x test']
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA',
             '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',
             '-f', 'Dockerfile.slim', '.']
    images:
    - 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA'
    - 'gcr.io/$PROJECT_ID/$REPO_NAME:latest'
    

JSON

  1. Compila la aplicación: En cloudbuild.json, agrega un paso para compilar la aplicación.

    El código a continuación agrega un paso llamado java:8 para compilar el código de Java.

    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
    }
    
  2. Ensambla el contenedor del entorno de ejecución: En cloudbuild.json, agrega un paso para ensamblar el contenedor del entorno de ejecución.

    El código a continuación agrega un paso llamado gcr.io/cloud-builders/docker que ensambla el contenedor del entorno de ejecución. Este define el contenedor del entorno de ejecución en un archivo diferente llamado Dockerfile.slim.

    El ejemplo usa la capa base openjdk:8u111-jre-alpine de Alpine Linux, que es muy eficiente. Además, incluye el JRE, en lugar del JDK más voluminoso que era necesario para compilar la aplicación.

    cloudbuild.json:
    
    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
                "build",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:latest",
                "-f",
                "Dockerfile.slim",
                "."
            ]
        }
        ],
    }
    
    Dockerfile.slim:
    
    FROM openjdk:8u111-jre-alpine
    
    COPY ./gate-web/build/install/gate /opt/gate
    
    CMD ["/opt/gate/bin/gate"]
    
  3. Crea las imágenes de Docker: en cloudbuild.json, agrega un paso para crear las imágenes.
    {
        "steps": [
        {
            "name": "java:8",
            "env": [
                "GRADLE_USER_HOME=cache"
            ],
            "entrypoint": "bash",
            "args": [
                "-c",
                "./gradlew gate-web:installDist -x test"
            ]
        },
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
                "build",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
                "-t",
                "gcr.io/$PROJECT_ID/$REPO_NAME:latest",
                "-f",
                "Dockerfile.slim",
                "."
            ]
        }
        ],
        "images": [
            "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA",
            "gcr.io/$PROJECT_ID/$REPO_NAME:latest"
        ]
    }
    
¿Te sirvió esta página? Envíanos tu opinión:

Enviar comentarios sobre…