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 eres nuevo en Cloud Build, lee el las guías de inicio rápido y la configuración de compilación a la descripción general.

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 Cloud admite y mantiene estas imágenes. Puedes usar la imagen de Docker precompilada 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 un repositorio nuevo
  • Si deseas usar los comandos de gcloud en 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 Cómo autorizar 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.

Cómo compilar 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. El precompilada se almacena en gcr.io/cloud-builders/docker. En el siguiente archivo de configuración de ejemplo, en el campo name se especifica que Cloud Build usa la imagen ya compilada de Docker 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",
              "."
             ]
         }
         ]
       }
      

      Reemplaza los valores de marcador de posición en la configuración de compilación anterior por lo siguiente:

    • LOCATION: Es la ubicación regional o multirregional de tu repositorio de Docker en Artifact Registry.

    • PROJECT_ID: Es el ID de tu 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', "."
             ]
         }
         ]
       }
      

      Reemplaza los valores de marcador de posición en la configuración de compilación anterior por lo siguiente:

      • 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.
      • 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
    

    Reemplaza los valores de marcador de posición en el comando anterior por los siguientes:

    • 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

Reemplaza los valores de marcador de posición en el comando anterior por los siguientes:

  • 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.
  • 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

Reemplaza los valores de marcador de posición en los comandos anteriores por la siguiente información:

  • 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: 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'
    

Configurar 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 tu imagen compilada de una de las siguientes maneras:

  • Mediante el campo images, que almacena la imagen en Artifact Registry después de que se completa la compilación.
  • Mediante el comando docker push, que almacena la imagen en Artifact Registry como parte del 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 de Google 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, la imagen 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.

Para almacenar una imagen de contenedor en Artifact Registry después de la compilación, sigue estos pasos: completa:

  1. Si el repositorio de destino no existe, crea un repositorio 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 de tu 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.

Para almacenar la imagen en Artifact Registry como parte de tu flujo de compilación, haz lo siguiente:

  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 de tu 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.

Para almacenar una imagen como parte de tu flujo de compilación y mostrarla en los resultados de compilación, haz lo siguiente:

  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 de tu 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.

Firma las imágenes del 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 de 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 región o multirregional la ubicación de la repositorio en el que se almacena la imagen, por ejemplo us-east1 o us.

  • PROJECT_ID: Es el ID de tu 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 que deseas ejecutar en tu compilación. Por ejemplo, un la dirección de correo electrónico de la cuenta de servicio se parece a: 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 de confianza que esperas que se usen para crear la imagen de 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 que use tus credenciales de Artifact Registry cuando interactúe. con Artifact Registry. (Solo debes hacerlo una vez). Usa el siguiente comando para autenticar con el ayudante de credenciales de gcloud.

    gcloud auth configure-docker HOSTNAME-LIST
    

    Donde HOSTNAME-LIST es una lista separada por comas de nombres de host de repositorio para 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 compilaste 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 de tu 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?