Compilar imágenes de contenedores

En esta página, se describe cómo configurar Cloud Build para compilar y almacenar imágenes de Docker. Si estás dando los primeros pasos en Cloud Build, lee primero las guías de inicio rápido y la descripción general de la configuración de compilación.

Cloud Build proporciona imágenes prediseñadas a las que puedes hacer referencia en un archivo de configuración de Cloud Build para ejecutar tus tareas. Google Cloudadmite y mantiene estas imágenes. Puedes usar la imagen de Docker preconfigurada y compatible para ejecutar los comandos de Docker y compilar imágenes de Docker.

Antes de comenzar

En las instrucciones de esta página se supone que estás familiarizado con Docker. Además, debes hacer lo siguiente:

  • Ten a mano el código fuente de la aplicación junto con Dockerfile.
  • Tener un repositorio de Docker para almacenar imágenes en Artifact Registry o crear uno nuevo
  • Si deseas usar los comandos de gcloud de esta página, instala Google Cloud CLI.
  • Si deseas ejecutar las imágenes, instala Docker.
  • Si deseas firmar las imágenes con cosign, sigue las instrucciones en Autoriza el acceso de servicio a servicio para crear una cuenta de servicio especificada por el usuario y otorgar los permisos necesarios para generar tokens de ID.

Compila con un archivo de configuración de compilación

Para compilar tu imagen de Docker con un archivo de configuración de compilación, sigue estos pasos:

  1. En el mismo directorio que contiene el código fuente de tu aplicación, crea un archivo llamado cloudbuild.yaml o cloudbuild.json.
  2. En el archivo de configuración de compilación:

    • Agrega un campo name y especifica la imagen prediseñada de Docker. La imagen compilada previamente se almacena en gcr.io/cloud-builders/docker. En el siguiente archivo de configuración de ejemplo, el campo name especifica que Cloud Build usa la imagen de Docker compilada previamente para ejecutar la tarea indicada por el campo args.
    • En el campo args, agrega los argumentos para compilar la imagen.

      YAML

      steps:
      - name: 'gcr.io/cloud-builders/docker'
        args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.' ]
      

      JSON

      {
       "steps": [
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
              "build",
              "-t",
              "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
              "."
             ]
         }
         ]
       }
      

    Aquí:

    • LOCATION: Es la ubicación regional o multirregional de tu repositorio de Docker en Artifact Registry.
    • PROJECT_ID: Es el ID del proyecto de Google Cloud .
    • REPOSITORY: Es el nombre de tu repositorio de Docker en Artifact Registry.
    • IMAGE_NAME: El nombre de tu imagen de contenedor

      Si tu Dockerfile y tu código fuente están en directorios diferentes, agrega -f y la ruta al Dockerfile a la lista de argumentos en el campo args:

      YAML

      steps:
      - name: 'gcr.io/cloud-builders/docker'
        args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '-f', 'DOCKERFILE_PATH', '.' ]
      

      JSON

      {
       "steps": [
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
              "build",
              "-t",
              "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME", '-f', 'DOCKERFILE_PATH', "."
             ]
         }
         ]
       }
      

      Aquí:

      • LOCATION: Es la ubicación regional o multirregional de tu repositorio.
      • PROJECT_ID: Es el ID del proyecto de Google Cloud .
      • REPOSITORY: Es el nombre de tu repositorio de Artifact Registry.
      • IMAGE_NAME: El nombre de tu imagen de contenedor
      • DOCKERFILE_PATH: Es la ruta de acceso a tu Dockerfile.
  3. Usa este comando para comenzar a compilar con el archivo de configuración de compilación:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Aquí:

    • CONFIG_FILE_PATH: La ruta de acceso al archivo de configuración de compilación.
    • SOURCE_DIRECTORY: La ruta de acceso o la URL al código fuente.

    Si se no especifica CONFIG_FILE_PATH ni SOURCE_DIRECTORY en el comando gcloud builds submit, Cloud Build da por hecho que el archivo de configuración y el código fuente están en el directorio de trabajo actual.

Compila con un Dockerfile

Cloud Build te permite compilar una imagen de Docker con solo un Dockerfile. No necesitas un archivo de configuración de compilación diferente.

Para compilar con un Dockerfile, ejecuta el siguiente comando desde el directorio que contiene el código fuente y el Dockerfile:

    gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME

Aquí:

  • LOCATION: Es la ubicación regional o multirregional de tu repositorio.
  • PROJECT_ID: Es el ID del proyecto de Google Cloud .
  • REPOSITORY: Es el nombre de tu repositorio de Artifact Registry.
  • IMAGE_NAME: El nombre de tu imagen de contenedor

Compila con los paquetes de compilación de Google Cloud

Cloud Build te permite compilar una imagen sin un Dockerfile o un archivo de configuración de compilación. Puedes hacerlo con los paquetes de compilación de Google Cloud.

Para compilar mediante paquetes de compilación, ejecuta el siguiente comando desde el directorio que contiene el código fuente:

    gcloud builds submit --pack builder=BUILDPACK_BUILDER, \
        env=ENVIRONMENT_VARIABLE, \
        image=IMAGE_NAME

Aquí:

  • BUILDPACK_BUILDER: El compilador de paquetes de compilación que se usará Si no especificas un compilador, Cloud Build usa gcr.io/buildpacks/builder de forma predeterminada.
  • ENVIRONMENT_VARIABLE: Cualquier variable de entorno para la compilación.
  • IMAGE: Es la URL de la imagen en Artifact Registry. La URL de la imagen debe tener el formato LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME.

Estos son algunos ejemplos de comandos:

  • Ejecuta una compilación mediante el gcr.io/buildpacks/builder predeterminado para crear la imagen us-docker.pkg.dev/gcb-docs-project/containers/gke/hello-app:

      gcloud builds submit --pack image=us-docker.pkg.dev/gcb-docs-project/containers/gke/hello-app
    
  • Pasa múltiples variables de entorno a tu compilación mediante ^--^ como separador. Para obtener más información sobre el escape de argumentos, consulta gcloud topic escaping.

      gcloud builds submit --pack \
          ^--^image=gcr.io/my-project/myimage--env=GOOGLE_ENTRYPOINT='java -jar target/myjar.jar',GOOGLE_RUNTIME_VERSION='3.1.301'
    

Configura activadores para usar buildpacks: Además de compilar con la línea de comandos, puedes configurar activadores para usar buildpacks y compilar tu imagen automáticamente. Para obtener más información, consulta Crea y administra activadores de compilación.

Diferentes formas de almacenar imágenes en Artifact Registry

Puedes configurar Cloud Build para almacenar una imagen compilada de una de las siguientes maneras:

  • Usa el campo images para almacenar una imagen de Docker en Artifact Registry después de que se complete la compilación.
  • Usa el campo artifacts.oci para almacenar una imagen de OCI en Artifact Registry después de que se complete la compilación.
  • Usa el comando docker push para almacenar una imagen de contenedor en Artifact Registry como parte de tu flujo de compilación.

La diferencia entre usar el campo images y el comando push de Docker es que si se usa el campo images, la imagen almacenada se mostrará en los resultados de compilación. Esto incluye la página Descripción de compilación de una compilación en la consola deGoogle Cloud , los resultados de Build.get() y los resultados de gcloud builds list. Sin embargo, si usas el comando push de Docker para almacenar la imagen compilada, esta no se mostrará en los resultados de compilación.

Si quieres almacenar la imagen como parte del flujo de compilación y deseas mostrarla en los resultados de compilación, usa el comando push de Docker y el campo images del archivo de configuración de compilación.

Almacena una imagen de contenedor en Artifact Registry después de que se complete la compilación

  1. Si el repositorio de destino no existe, crea uno nuevo.
  2. En el mismo directorio que contiene el código fuente de tu aplicación y Dockerfile, crea un archivo llamado cloudbuild.yaml o cloudbuild.json.
  3. En el archivo de configuración de compilación, agrega un paso de compilación para compilar una imagen y, luego, agrega un campo images que especifique la imagen compilada. Esto almacena la imagen en Artifact Registry. En el siguiente fragmento, se muestra una configuración de compilación para compilar una imagen y almacenarla en Artifact Registry:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.' ]
    images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']
    

    JSON

    {
    "steps": [
    {
        "name": "gcr.io/cloud-builders/docker",
        "args": [
            "build",
            "-t",
            "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
            "."
        ]
    }
    ],
    "images": [
        "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"
    ]
    }
    

    Aquí:

    • LOCATION: Es la ubicación regional o multirregional de tu repositorio.
    • PROJECT_ID: Es el ID del proyecto de Google Cloud .
    • REPOSITORY: Es el nombre de tu repositorio de Artifact Registry.
    • IMAGE_NAME: El nombre de tu imagen de contenedor
  4. Usa este comando para comenzar a compilar con el archivo de configuración de compilación:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    En el ejemplo anterior, se ilustra lo siguiente:

    • CONFIG_FILE_PATH es la ruta de acceso al archivo de configuración de compilación.
    • SOURCE_DIRECTORY es la ruta o la URL del código fuente.

Almacena la imagen en Artifact Registry como parte de tu flujo de compilación

  1. En el mismo directorio que contiene el código fuente de tu aplicación y Dockerfile, crea un archivo llamado cloudbuild.yaml o cloudbuild.json.

  2. En el archivo de configuración de compilación, agrega un paso de compilación de docker para compilar una imagen y, luego, agrega otro paso de compilación de docker y pasa argumentos a fin de invocar el comando push:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.']
    - name: 'gcr.io/cloud-builders/docker'
      args: ['push', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']
    

    JSON

    {
      "steps": [
       {
          "name": "gcr.io/cloud-builders/docker",
          "args": [
              "build",
              "-t",
              "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
              "."
           ]
       },
       {
           "name": "gcr.io/cloud-builders/docker",
           "args": [
              "push",
              "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"
            ]
       }
      ]
    }
    

    Aquí:

    • LOCATION: Es la ubicación regional o multirregional de tu repositorio.
    • PROJECT_ID: Es el ID del proyecto de Google Cloud .
    • REPOSITORY: Es el nombre de tu repositorio de Artifact Registry.
    • IMAGE_NAME: El nombre de tu imagen de contenedor
  3. Usa este comando para comenzar a compilar con el archivo de configuración de compilación:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    En el ejemplo anterior, se ilustra lo siguiente:

    • CONFIG_FILE_PATH es la ruta de acceso al archivo de configuración de compilación.
    • SOURCE_DIRECTORY es la ruta o la URL del código fuente.

Almacenar una imagen como parte de tu flujo de compilación y mostrarla en los resultados de compilación

  1. En el mismo directorio que contiene el código fuente de tu aplicación y Dockerfile, crea un archivo llamado cloudbuild.yaml o cloudbuild.json.
  2. En el archivo de configuración de compilación, después del paso que compila la imagen, agrega un paso para invocar el comando push de Docker y, luego, agrega el campo images:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.']
    - name: 'gcr.io/cloud-builders/docker'
      args: ['push', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']
    images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']
    

    JSON

    {
        "steps": [
       {
           "name": "gcr.io/cloud-builders/docker",
           "args": [
               "build",
               "-t",
               "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
               "."
            ]
       },
       {
           "name": "gcr.io/cloud-builders/docker",
           "args": [
               "push",
               "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"
            ]
       }
       ],
        "images": [
           "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"
        ]
    }
    

    Aquí:

    • LOCATION: Es la ubicación regional o multirregional de tu repositorio.
    • PROJECT_ID: Es el ID del proyecto de Google Cloud .
    • REPOSITORY: Es el nombre de tu repositorio de Artifact Registry.
    • IMAGE_NAME: El nombre de tu imagen de contenedor
  3. Usa este comando para comenzar a compilar con el archivo de configuración de compilación:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    En el ejemplo anterior, se ilustra lo siguiente:

    • CONFIG_FILE_PATH es la ruta de acceso al archivo de configuración de compilación.
    • SOURCE_DIRECTORY es la ruta o la URL del código fuente.

Almacena una imagen OCI en Artifact Registry después de que se complete la compilación

  1. En el mismo directorio que contiene el código fuente de tu aplicación y Dockerfile, crea un archivo llamado cloudbuild.yaml o cloudbuild.json.
  2. En el archivo de configuración de compilación, agrega un campo artifacts que especifique la imagen OCI compilada. Esta configuración almacena la imagen de OCI en Artifact Registry. En el siguiente ejemplo, se muestra una configuración de compilación que compila una imagen de OCI y la almacena en Artifact Registry:

    YAML

    artifacts:
      oci:
      - file: 'OCI_IMAGE_PATH'
        registryPath: 'https://LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY'
        tags: ["primary_image"]
    

    JSON

    {
      "artifacts": {
        "oci": [
          {
            "file": "OCI_IMAGE_PATH",
            "registryPath": "https://LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY",
            "tags": ["primary_image"]
          }
        ]
      }
    }
    

    Aquí:

    • OCI_IMAGE_PATH es la dirección del directorio local que contiene la imagen de OCI que se subirá, por ejemplo, /.pack/layout-repo/my-app.
    • LOCATION es la ubicación regional o multirregional de tu repositorio.
    • PROJECT_ID es el ID de tu proyecto de Google Cloud .
    • REPOSITORY: Es el nombre de tu repositorio de Artifact Registry.

Firma imágenes de contenedor con cosign

Si almacenas imágenes en Artifact Registry, puedes agregar otra capa de seguridad con la herramienta cosign para crear un registro de la cuenta de servicio que se usa para iniciar una compilación. Con el respaldo del estándar OpenID Connect (OIDC), los auditores pueden usar ese registro para verificar que una imagen se haya compilado con una cuenta de servicio de confianza.

En los siguientes pasos, se muestra cómo usar el archivo de configuración cloudbuild.yaml para obtener un token de identidad y firmar la imagen del contenedor.

YAML

  steps:
  - name: 'gcr.io/cloud-builders/docker'
    id: 'tag-and-push'
    script: |
      #!/bin/sh
      set -e
      docker build -t $_IMAGE .
      docker push "$_IMAGE"
      docker inspect $_IMAGE --format "$_IMAGE@{{.Id}}" >image_with_digest
  - name: 'gcr.io/cloud-builders/gcloud'
    id: 'generate-token'
    script: |
      #!/bin/sh
      set -e
      gcloud auth print-identity-token --audiences=sigstore > token
  - name: 'gcr.io/cloud-builders/docker'
    id: 'sign-image'
    script: |
      #!/bin/sh
      set -e
      docker run \
      --network=cloudbuild \
      --mount source=home-volume,target=/builder/home \
      --rm \
      -e SIGSTORE_NO_CACHE=true \
      -e HOME=/builder/home \
      gcr.io/projectsigstore/cosign \
      sign --identity-token=$(cat token) $(cat image_with_digest) -y
  service_account: '$_SERVICE_ACCOUNT'
  artifacts:
    images:
    - $_IMAGE
  substitutions:
    _IMAGE: 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'
    _SERVICE_ACCOUNT_ID: 'SERVICE_ACCOUNT_ID'
    _SERVICE_ACCOUNT: projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}
  options:
    env:
    - '_IMAGE=$_IMAGE'
    dynamic_substitutions: true
    logging: CLOUD_LOGGING_ONLY

JSON

    {
        "steps": [
            {
                "name": "gcr.io/cloud-builders/docker",
                "id": "tag-and-push",
                "script": "#!/bin/sh set -e \ndocker build -t $_IMAGE . \ndocker push \"$_IMAGE\""
            },
            {
                "name": "gcr.io/cloud-builders/gcloud",
                "id": "generate-token-and-get-digest",
                "script": "#!/bin/sh set -e \ngcloud auth print-identity-token --audiences=sigstore > token \ngcloud container images describe \"$_IMAGE\" --format=\"value(image_summary.fully_qualified_digest)\" > image_with_digest"
            },
            {
                "name": "gcr.io/projectsigstore/cosign",
                "id": "sign-image",
                "script": "#!/busybox/sh cosign sign --identity-token=$(cat token) $(cat image_with_digest) -y",
                "env": [
                    "SIGSTORE_NO_CACHE=true"
                ]
            }
        ],
        "service_account": "$_SERVICE_ACCOUNT",
        "artifacts": {
            "images": [
                "$_IMAGE"
            ]
        },
        "substitutions": {
            "_IMAGE": "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
            "_SERVICE_ACCOUNT_ID": "SERVICE_ACCOUNT_ID",
            "_SERVICE_ACCOUNT": "projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}"
        },
        "options": {
            "env": [
                "_IMAGE=$_IMAGE"
            ],
            "dynamic_substitutions": true,
            "logging": "CLOUD_LOGGING_ONLY"
        }
    }

Aquí:

  • LOCATION es la ubicación regional o multirregional del repositorio en el que se almacena la imagen, por ejemplo, us-east1 o us.

  • PROJECT_ID: Es el ID del proyecto de Google Cloud .

  • REPOSITORY es el nombre del repositorio en el que se almacena la imagen.

  • IMAGE_NAME es el nombre de la imagen.

  • SERVICE_ACCOUNT_ID es la dirección de correo electrónico de la cuenta de servicio especificada por el usuario con la que deseas ejecutar tu compilación. Por ejemplo, una dirección de correo electrónico de cuenta de servicio se ve así: service-account-name@project-id.iam.gserviceaccount.com.

Para verificar la firma, instala cosign en tu máquina local y, luego, ejecuta el comando cosign verify:

cosign verify \
--certificate-identity=SERVICE_ACCOUNT_ID \
--certificate-oidc-issuer=https://accounts.google.com \
IMAGE

Aquí:

  • SERVICE_ACCOUNT_ID es la dirección de correo electrónico de la cuenta de servicio de confianza que esperas que se haya usado para compilar la imagen del contenedor.
  • IMAGE es el nombre completo de la imagen, incluido el resumen de la imagen sha256.

Ejecuta la imagen de Docker

Para verificar que la imagen que compilaste funciona como lo esperado, puedes ejecutarla mediante Docker.

  1. Configura Docker para usar tus credenciales de Artifact Registry cuando interactúes con este. (Solo debes hacerlo una vez). Usa el siguiente comando para autenticarte con el asistente de credenciales de gcloud.

    gcloud auth configure-docker HOSTNAME-LIST
    

    En el ejemplo anterior, HOSTNAME-LIST es una lista separada por comas de nombres de host de repositorios que se agregará a la configuración del auxiliar de credenciales.

    Por ejemplo, para agregar las regiones us-central1 y asia-northeast1, ejecuta el siguiente comando:

    gcloud auth configure-docker us-central1-docker.pkg.dev,asia-northeast1-docker.pkg.dev
    
  2. Ejecuta la imagen de Docker que creaste antes:

    docker run LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME
    

    Aquí:

    • LOCATION: Es la ubicación regional o multirregional de tu repositorio.
    • PROJECT_ID: Es el ID del proyecto de Google Cloud .
    • REPOSITORY: Es el nombre de tu repositorio de Artifact Registry.
    • IMAGE_NAME: El nombre de tu imagen de contenedor

    Verás un resultado similar al siguiente:

    Hello, world! The time is Fri Feb  2 16:09:54 UTC 2018.
    

¿Qué sigue?