Criar imagens de contêiner

Nesta página, descrevemos como configurar o Cloud Build para criar e armazenar imagens do Docker. Se você não conhece o Cloud Build, leia os guias de início rápido e a visão geral da configuração do build primeiro.

O Cloud Build fornece imagens pré-criadas que podem ser referenciadas em um arquivo de configuração do Cloud Build para executar suas tarefas. Essas imagens são compatíveis e mantidas pelo Google Cloud. Use a imagem compatível e pré-criada do Docker para executar comandos e criar imagens do Docker.

Antes de começar

As instruções nesta página presumem que você tenha familiaridade com o Docker. Além disso:

  • Tenha o código-fonte do aplicativo e o Dockerfile.
  • Tenha um repositório do Docker para armazenar imagens no Artifact Registry ou crie um repositório novo.
  • Se você quiser usar os comandos gcloud desta página, instale a Google Cloud CLI.
  • Para executar as imagens, instale o Docker.
  • Se você quiser assinar as imagens com cosign, siga as instruções em Autorizar acesso de serviço a serviço para criar uma conta de serviço especificada pelo usuário e conceder as permissões necessárias para gerar tokens de ID.

Criar com um arquivo de configuração de build

Para criar sua imagem do Docker usando um arquivo de configuração de build:

  1. no mesmo diretório que contém o código-fonte do aplicativo, crie um arquivo chamado cloudbuild.yaml ou cloudbuild.json;
  2. No arquivo de configuração de build:

    • Adicione um campo name e especifique a imagem do Docker pré-criada. A imagem pré-criada é armazenada em gcr.io/cloud-builders/docker. No exemplo de arquivo de configuração abaixo, o campo name especifica que a imagem do Docker pré-criada é usada pelo Cloud Build para executar a tarefa indicada pelo campo args.
    • No campo args, adicione os argumentos para criar a imagem.

      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",
              "."
             ]
         }
         ]
       }
      

      Substitua os valores de marcador na configuração da versão acima pelo seguinte:

    • LOCATION: o local regional ou multirregional do repositório do Docker no Artifact Registry.

    • PROJECT_ID: é seu ID do projeto no Google Cloud.

    • REPOSITORY: o nome do repositório do Docker no Artifact Registry.

    • IMAGE_NAME: o nome da imagem do contêiner.

      Se Dockerfile e o código-fonte estiverem em diretórios diferentes, adicione -f e o caminho para Dockerfile à lista de argumentos no 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', "."
             ]
         }
         ]
       }
      

      Substitua os valores de marcador na configuração da versão acima pelo seguinte:

      • LOCATION: o local regional ou multirregional do seu repositório.
      • PROJECT_ID: é seu ID do projeto no Google Cloud.
      • REPOSITORY: o nome do repositório do Artifact Registry.
      • IMAGE_NAME: o nome da imagem do contêiner.
      • DOCKERFILE_PATH: caminho para Dockerfile.
  3. Inicie a compilação usando o arquivo de configuração da compilação:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Substitua os valores de marcador no comando acima pelo seguinte:

    • CONFIG_FILE_PATH: o caminho para o arquivo de configuração do build.
    • SOURCE_DIRECTORY: o caminho ou URL do código-fonte.

    Se você não especificar CONFIG_FILE_PATH e SOURCE_DIRECTORY no comando gcloud builds submit, o Cloud Build presumirá que o arquivo de configuração e o código-fonte estão no diretório de trabalho atual.

Criar com um Dockerfile

O Cloud Build permite que você crie uma imagem do Docker usando apenas um Dockerfile. Você não precisa de um arquivo de configuração de build à parte.

Para criar usando um Dockerfile, execute o seguinte comando no diretório que contém seu código-fonte e o Dockerfile:

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

Substitua os valores de marcador no comando acima pelo seguinte:

  • LOCATION: o local regional ou multirregional do seu repositório.
  • PROJECT_ID: é seu ID do projeto no Google Cloud.
  • REPOSITORY: o nome do repositório do Artifact Registry.
  • IMAGE_NAME: o nome da imagem do contêiner.

Crie com os buildpacks do Google Cloud

O Cloud Build permite que você crie uma imagem sem um Dockerfile ou um arquivo de configuração da versão. É possível fazer isso usando os buildpacks do Google Cloud.

Para criar usando pacotes de criação, execute o seguinte comando no diretório que contém seu código-fonte:

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

Substitua os valores dos marcadores nos comandos acima pelo seguinte:

  • BUILDPACK_BUILDER: o builder do pacote de criação a ser usado. Se você não especificar um builder, o Cloud Build usará gcr.io/buildpacks/builder por padrão.
  • ENVIRONMENT_VARIABLE: qualquer variável de ambiente para a versão.
  • IMAGE: o URL da imagem no Artifact Registry. O URL da imagem precisa estar no formato LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME.

Veja alguns comandos de exemplo:

  • Como executar uma versão usando o gcr.io/buildpacks/builder padrão para criar a imagem 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
    
  • Como transmitir várias variáveis de ambiente para sua versão usando ^--^ como um separador. Para mais informações sobre como usar argumentos de escape, consulte 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ção de gatilhos para usar o buildpacks: além de criar usando a linha de comando, é possível configurar os gatilhos para usar buildpacks para criar a imagem automaticamente. Para saber mais, consulte Como criar e gerenciar gatilhos de compilação.

Diferentes maneiras de armazenar imagens no Artifact Registry

Configure o Cloud Build para armazenar sua imagem criada de uma das seguintes maneiras:

  • usando o campo images, que armazena a imagem no Artifact Registry após a conclusão do build.
  • usando o comando docker push, que armazena a imagem no Artifact Registry como parte do fluxo de build.

A diferença entre o uso do campo images e do comando push do Docker é que, se você usar o campo images, a imagem armazenada será exibida nos resultados da versão. Isso inclui a página Descrição do build para um build no Console do Google Cloud, os resultados de Build.get() e de gcloud builds list. No entanto, se você usar o comando push do Docker para armazenar a imagem criada, ela não será exibida nos resultados da versão.

Se quiser armazenar a imagem como parte de seu fluxo de build e exibir a imagem nos resultados do build, use o comando push do Docker e o campo images em seu arquivo de configuração de build.

Para armazenar uma imagem de contêiner no Artifact Registry após a conclusão do build:

  1. Se o repositório de destino não existir, crie um novo repositório.
  2. no mesmo diretório que contém o código-fonte do aplicativo e Dockerfile, crie um arquivo chamado cloudbuild.yaml ou cloudbuild.json;
  3. no seu arquivo de configuração de build, adicione uma etapa da criação para criar uma imagem e, em seguida, adicione um campo images especificando a imagem criada. Isso armazena a imagem no Artifact Registry. O snippet a seguir mostra uma configuração de build para criar uma imagem e armazená-la no 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"
    ]
    }
    

    Em que:

    • LOCATION: o local regional ou multirregional do seu repositório.
    • PROJECT_ID: é seu ID do projeto no Google Cloud.
    • REPOSITORY: o nome do repositório do Artifact Registry.
    • IMAGE_NAME: o nome da imagem do contêiner.
  4. Inicie o build usando o arquivo de configuração do build:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Em que:

    • CONFIG_FILE_PATH é o caminho para o arquivo de configuração da compilação;
    • SOURCE_DIRECTORY é o caminho ou o URL do código-fonte.

Para armazenar a imagem no Artifact Registry como parte do fluxo de build:

  1. no mesmo diretório que contém o código-fonte do aplicativo e Dockerfile, crie um arquivo chamado cloudbuild.yaml ou cloudbuild.json;

  2. no seu arquivo de configuração de build, adicione uma etapa de build docker para criar uma imagem, adicione outra etapa de build docker e transmita argumentos para invocar o 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"
            ]
       }
      ]
    }
    

    Em que:

    • LOCATION: o local regional ou multirregional do seu repositório.
    • PROJECT_ID: é seu ID do projeto no Google Cloud.
    • REPOSITORY: o nome do repositório do Artifact Registry.
    • IMAGE_NAME: o nome da imagem do contêiner.
  3. Inicie o build usando o arquivo de configuração do build:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Em que:

    • CONFIG_FILE_PATH é o caminho para o arquivo de configuração da compilação;
    • SOURCE_DIRECTORY é o caminho ou o URL do código-fonte.

Para armazenar uma imagem como parte de seu fluxo de build e para exibir a imagem nos resultados do build:

  1. no mesmo diretório que contém o código-fonte do aplicativo e Dockerfile, crie um arquivo chamado cloudbuild.yaml ou cloudbuild.json;
  2. no arquivo de configuração de build, após a etapa de criação da imagem, adicione uma etapa para invocar o comando push do Docker e, em seguida, adicione o 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"
        ]
    }
    

    Em que:

    • LOCATION: o local regional ou multirregional do seu repositório.
    • PROJECT_ID: é seu ID do projeto no Google Cloud.
    • REPOSITORY: o nome do repositório do Artifact Registry.
    • IMAGE_NAME: o nome da imagem do contêiner.
  3. Inicie o build usando o arquivo de configuração do build:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Em que:

    • CONFIG_FILE_PATH é o caminho para o arquivo de configuração da compilação;
    • SOURCE_DIRECTORY é o caminho ou o URL do código-fonte.

Assinar imagens de contêiner com a cosign

Se você estiver armazenando imagens no Artifact Registry, poderá adicionar outra camada de segurança usando a ferramenta cosign para criar um registro de qual conta de serviço é usada para iniciar uma versão. Com base no padrão OpenID Connect (OIDC), os auditores podem usar esse registro para verificar se uma imagem foi criada por uma conta de serviço confiável.

As etapas a seguir demonstram como usar o arquivo de configuração cloudbuild.yaml para receber um token de identidade e assinar a imagem do contêiner.

YAML

  steps:
  - name: 'gcr.io/cloud-builders/docker'
    id: 'tag-and-push'
    script: |
      #!/bin/sh
      set -e
      docker build -t $_IMAGE .
      docker push "$_IMAGE"
  - name: 'gcr.io/cloud-builders/gcloud'
    id: 'generate-token-and-get-digest'
    script: |
      #!/bin/sh
      set -e
      gcloud auth print-identity-token --audiences=sigstore > token
      gcloud 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

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"
        }
    }

Em que:

  • LOCATION é o local regional ou multirregional do repositório em que a imagem está armazenada, por exemplo, us-east1 ou us.

  • PROJECT_ID: é seu ID do projeto no Google Cloud.

  • REPOSITORY é o nome do repositório em que a imagem está armazenada.

  • IMAGE_NAME é o nome da imagem.

  • SERVICE_ACCOUNT_ID é o endereço de e-mail da conta de serviço especificada pelo usuário em que você quer executar o build. Por exemplo, o endereço de e-mail de uma conta de serviço tem esta aparência: service-account-name@project-id.iam.gserviceaccount.com.

Para verificar a assinatura, instale o cosign na sua máquina local e execute o comando cosign verify:

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

Em que:

  • SERVICE_ACCOUNT_ID é o endereço de e-mail da conta de serviço confiável que você espera que seja usada para criar a imagem do contêiner.
  • IMAGE é o nome completo da imagem, incluindo o resumo da imagem sha256.

Executar a imagem do Docker

Para verificar se a imagem que você criou funciona como esperado, é possível executá-la usando o Docker.

  1. Configure o Docker para usar suas credenciais do Artifact Registry ao interagir com o Artifact Registry. Você só precisa fazer isso uma vez. Use o comando a seguir para autenticar usando o auxiliar de credenciais da gcloud.

    gcloud auth configure-docker HOSTNAME-LIST
    

    Em que HOSTNAME-LIST é uma lista separada por vírgulas de nomes de host do repositório a serem adicionados à configuração do auxiliar de credenciais.

    Por exemplo, para adicionar as regiões us-central1 e asia-northeast1, execute o comando:

    gcloud auth configure-docker us-central1-docker.pkg.dev,asia-northeast1-docker.pkg.dev
    
  2. Execute a imagem do Docker que você criou antes:

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

    Em que:

    • LOCATION: o local regional ou multirregional do seu repositório.
    • PROJECT_ID: é seu ID do projeto no Google Cloud.
    • REPOSITORY: o nome do repositório do Artifact Registry.
    • IMAGE_NAME: o nome da imagem do contêiner.

    Você verá um resultado semelhante a este:

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

A seguir