Crear imágenes de contenedor

En esta página se describe cómo configurar Cloud Build para compilar y almacenar imágenes de Docker. Si es la primera vez que usas Cloud Build, consulta 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 que puedes consultar en un archivo de configuración de Cloud Build para ejecutar tus tareas. Estas imágenes son compatibles y las mantiene Google Cloud. Puedes usar la imagen Docker prediseñada compatible para ejecutar comandos de Docker y compilar imágenes Docker.

Antes de empezar

En las instrucciones de esta página se da por hecho que conoces Docker. Además:

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

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

Para compilar tu imagen 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:

    • Añade un campo name y especifica la imagen de Docker prediseñada. La imagen prediseñada se almacena en gcr.io/cloud-builders/docker. En el archivo de configuración de ejemplo que se muestra a continuación, el campo name especifica que Cloud Build usa la imagen de Docker precompilada para ejecutar la tarea indicada en el campo args.
    • En el campo args, añade los argumentos para crear 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",
              "."
             ]
         }
         ]
       }
      

      Sustituye los valores de marcador de posición de la configuración de compilación anterior por los siguientes:

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

    • PROJECT_ID: tu ID de proyecto Google Cloud .

    • REPOSITORY: el nombre de tu repositorio de Docker en Artifact Registry.

    • IMAGE_NAME: el nombre de la imagen de tu contenedor.

      Si Dockerfile y el código fuente están en directorios diferentes, añade -f y la ruta a Dockerfile a la lista de argumentos del 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', "."
             ]
         }
         ]
       }
      

      Sustituye los valores de marcador de posición de la configuración de compilación anterior por los siguientes:

      • LOCATION: la ubicación regional o multirregional de tu repositorio.
      • PROJECT_ID: tu ID de proyecto Google Cloud .
      • REPOSITORY: el nombre de tu repositorio de Artifact Registry.
      • IMAGE_NAME: el nombre de la imagen de tu contenedor.
      • DOCKERFILE_PATH: ruta a tu Dockerfile.
  3. Inicia la compilación con el archivo de configuración de compilación:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Sustituye los valores de los marcadores de posición del comando anterior por los siguientes:

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

    Si no especificas CONFIG_FILE_PATH y SOURCE_DIRECTORY en el comando gcloud builds submit, Cloud Build asume que el archivo de configuración y el código fuente se encuentran en el directorio de trabajo actual.

Compilar con un Dockerfile

Con Cloud Build puedes crear una imagen Docker con solo un Dockerfile. No necesitas un archivo de configuración de compilación independiente.

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

Sustituye los valores de los marcadores de posición del comando anterior por los siguientes:

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

Crear con los buildpacks de Google Cloud

Cloud Build te permite crear una imagen sin un Dockerfile o un archivo de configuración de compilación. Para ello, puedes usar los buildpacks de Google Cloud.

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

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

Sustituye los valores de los marcadores de posición de los comandos anteriores por los siguientes:

  • BUILDPACK_BUILDER: el compilador de paquetes de compilación que se va a usar. Si no especificas ningún compilador, Cloud Build usará gcr.io/buildpacks/builder de forma predeterminada.
  • ENVIRONMENT_VARIABLE: cualquier variable de entorno de tu compilación.
  • IMAGE: 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:

  • Ejecutar una compilación con 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
    
  • Transfiere varias variables de entorno a tu compilación usando ^--^ como separador. Para obtener más información sobre cómo escapar 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 mediante la línea de comandos, puedes configurar activadores para usar buildpacks y compilar tu imagen automáticamente. Para obtener más información, consulta Crear y gestionar activadores de compilación.

Diferentes formas de almacenar imágenes en Artifact Registry

Puedes configurar Cloud Build para que almacene la imagen compilada de una de las siguientes formas:

  • con el campo images, que almacena la imagen en Artifact Registry una vez que se completa la compilación.
  • con 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 usas el campo images, la imagen almacenada se mostrará en los resultados de la compilación. Esto incluye la página Descripción de la compilación de una compilación en la consolaGoogle Cloud , los resultados de Build.get() y los resultados de gcloud builds list. Sin embargo, si usas el comando de Docker push para almacenar la imagen compilada, esta no se mostrará en los resultados de la compilación.

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

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

  1. Si el repositorio de destino no existe, crea uno.
  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, añade un paso de compilación para compilar una imagen y, a continuación, añade un campo images que especifique la imagen compilada. De esta forma, la imagen se almacena en Artifact Registry. El siguiente fragmento muestra una configuración de compilación para crear 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"
    ]
    }
    

    Donde:

    • LOCATION: la ubicación regional o multirregional de tu repositorio.
    • PROJECT_ID: tu ID de proyecto Google Cloud .
    • REPOSITORY: el nombre de tu repositorio de Artifact Registry.
    • IMAGE_NAME: el nombre de la imagen de tu contenedor.
  4. Inicia la compilación con el archivo de configuración de compilación:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Donde:

    • CONFIG_FILE_PATH es la ruta 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, añade un paso de compilación docker para compilar una imagen y, a continuación, añade otro paso de compilación docker y pasa argumentos para 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"
            ]
       }
      ]
    }
    

    Donde:

    • LOCATION: la ubicación regional o multirregional de tu repositorio.
    • PROJECT_ID: tu ID de proyecto Google Cloud .
    • REPOSITORY: el nombre de tu repositorio de Artifact Registry.
    • IMAGE_NAME: el nombre de la imagen de tu contenedor.
  3. Inicia la compilación con el archivo de configuración de compilación:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Donde:

    • CONFIG_FILE_PATH es la ruta 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 la 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, añade un paso para invocar el comando Docker push y, a continuación, añade 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"
        ]
    }
    

    Donde:

    • LOCATION: la ubicación regional o multirregional de tu repositorio.
    • PROJECT_ID: tu ID de proyecto Google Cloud .
    • REPOSITORY: el nombre de tu repositorio de Artifact Registry.
    • IMAGE_NAME: el nombre de la imagen de tu contenedor.
  3. Inicia la compilación con el archivo de configuración de compilación:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Donde:

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

Firmar imágenes de contenedor con cosign

Si almacenas imágenes en Artifact Registry, puedes añadir 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. Basado en el estándar OpenID Connect (OIDC), los auditores pueden usar ese registro para verificar que una imagen se ha creado con una cuenta de servicio de confianza.

En los pasos siguientes se muestra cómo usar el archivo de configuración cloudbuild.yaml para obtener un token de identidad y firmar la imagen de tu 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"
        }
    }

Donde:

  • 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: tu ID de proyecto 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 de la cuenta de servicio especificada por el usuario con la que quieres ejecutar la compilación. Por ejemplo, una dirección de correo de una cuenta de servicio tiene este aspecto: service-account-name@project-id.iam.gserviceaccount.com.

Para verificar la firma, instala cosign en tu máquina local y, a continuación, ejecuta el comando cosign verify:

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

Donde:

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

Ejecutar la imagen Docker

Para verificar que la imagen que has creado funciona correctamente, puedes ejecutarla con Docker.

  1. Configura Docker para que use tus credenciales de Artifact Registry al interactuar con Artifact Registry. Solo tienes que hacerlo una vez. Usa el siguiente comando para autenticarte con el asistente de credenciales de gcloud.

    gcloud auth configure-docker HOSTNAME-LIST
    

    Donde LISTA-DE-NOMBRES-DE-HOST es una lista de nombres de host de repositorios separados por comas que se van a añadir a la configuración del asistente de credenciales.

    Por ejemplo, para añadir 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 Docker que has creado antes:

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

    Donde:

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

    Verá un resultado similar al siguiente:

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

Siguientes pasos