Migrar contêineres implantados em VMs durante a criação delas

O agente de inicialização de contêineres no Compute Engine foi descontinuado. Com ele, é possível implantar contêineres em instâncias do Compute Engine ao criar VMs.

Neste documento, descrevemos como migrar contêineres criados pelo agente de inicialização nas suas VMs ou grupos gerenciados de instâncias (MIGs) para outros serviços doCloud de Confiance by S3NS .

Com base nos seus requisitos, escolha uma das seguintes opções para migrar os contêineres implantados em VMs usando o método descontinuado:

  • Se você quiser continuar executando contêineres em VMs e MIGs individuais, use scripts de inicialização ou cloud-init.
  • Se você tiver aplicativos de contêiner sem estado e jobs de pequeno a médio porte, use o Cloud Run.
  • Se o contêiner for um job em lote com um estado final definido e exigir mais recursos de computação, use o Batch.
  • Se você precisar de controle e escalonabilidade avançados ou não conseguir atender aos seus requisitos com as outras opções, use o GKE no Google Cloud.

Para mais casos de uso e soluções alternativas, consulte Comparar as opções de implantação de contêineres.

Impedir a criação de novas VMs que usam o agente de inicialização de contêiner

Para impedir a criação de novas VMs que usam o agente de inicialização de contêineres descontinuado, os administradores da organização podem aplicar uma política da organização. Para mais informações, consulte Impedir a criação de VMs que usam os metadados de contêineres descontinuados.

Opções descontinuadas para configurar contêineres em VMs

Quando você configura um contêiner durante a criação da VM, o Compute Engine usa o agente de inicialização do contêiner para ler os metadados gce-container-declaration que armazenam as informações do contêiner e para implantar o contêiner na VM.

As seguintes opções para implantar contêineres diretamente em uma VM ou MIG que usam o agente de inicialização de contêiner e o gce-container-metadata foram descontinuadas.

Console

A opção Implantar contêiner na página Criar uma instância foi descontinuada:

A opção "Implantar contêiner".

gcloud

Os seguintes comandos gcloud que configuram um contêiner em uma VM ou um modelo de instância estão descontinuados:

Terraform

O módulo do Terraform gce-container e a chave de metadados gce-container-declaration para configurar contêineres foram descontinuados.

Impedir a criação de VMs que usam o agente de inicialização de contêiner

Para impedir a criação de novas VMs que usam o agente de inicialização de contêineres descontinuado com uma política da organização, consulte Impedir a criação de VMs que usam os metadados de contêineres descontinuados.

Identificar instâncias que usam os metadados de contêiner obsoletos

Para identificar instâncias no seu projeto que usam os metadados de contêiner descontinuados, siga estas etapas para verificar a chave de metadados gce-container-declaration:

  1. Execute um dos seguintes comandos:

    • Para listar todas as instâncias do projeto que usam a chave e o valor de metadados gce-container-declaration, execute o seguinte comando da CLI gcloud:

      gcloud compute instances list --filter="metadata.items.key:gce-container-declaration"
      

      Esse comando fornece uma lista de todas as instâncias de VM no projeto configurado que contêm a chave de metadados gce-container-declaration. A chave de metadados identifica exclusivamente as VMs que estão no escopo da descontinuação. Se você estiver usando vários projetos, execute esse comando em todos os projetos ativos.

    • Para validar uma instância específica, execute o seguinte comando da CLI gcloud:

      gcloud compute instances describe VM_NAME --format="(metadata.items)"
      

      Substitua VM_NAME pelo nome da instância de VM que você quer validar.

  2. Se a saída do comando da etapa anterior listar instâncias que usam a chave de metadados gce-container-declaration, execute o seguinte comando para mais detalhes sobre a declaração de contêiner nas suas VMs:

    gcloud compute instances list \
      --filter='metadata.items.key:gce-container-declaration AND (metadata.items.value~"image:")' \
      --format="table(name, zone, metadata.items.filter(key='gce-container-declaration').extract(value).slice(0):label=CONTAINER_DECLARATION)"
    
  3. Com base na saída do comando, considere o seguinte:

    • Se os metadados contiverem a definição do agente de inicialização do contêiner descontinuado, migre a implantação do contêiner para uma solução alternativa, conforme descrito neste documento.

    • Se a chave de metadados gce-container-declaration estiver presente, mas você não a estiver usando para o agente de inicialização do contêiner, faça o seguinte:

      • Verifique se você está reutilizando essa chave de metadados para outras configurações.
      • Se você estiver reutilizando a chave, use uma chave de metadados diferente para outras configurações.

Para mais informações sobre como acessar metadados, consulte Acessar e consultar metadados.

Comparar as opções de implantação de contêineres

A tabela a seguir resume os casos de uso para execução de contêineres em VMs e recomenda soluções alternativas de contêineres para migrar suas cargas de trabalho:

Casos de uso Tipo de substituição Custo Solução recomendada
  • Continue executando o contêiner em uma VM ou um MIG.
  • Menos familiarizado com soluções gerenciadas ou sem servidor.
  • Executar contêiner para teste e desenvolvimento.
  • Sua carga de trabalho consiste em uma única VM.
  • Execute o contêiner no modo privilegiado.
  • Substituição direta Sem custo extra Usar scripts de inicialização para implantar contêineres em VMs.
  • Continue executando o contêiner em uma VM ou um MIG.
  • Executar vários contêineres em uma única VM.
  • Configure cenários avançados em contêineres ou VMs.
    Por exemplo, crie usuários, importe arquivos, monte discos ou use o modo privilegiado.
  • Sua carga de trabalho consiste em várias VMs ou MIGs.
  • Substituição direta Sem custo extra Use cloud-init para executar tarefas durante o ciclo de vida da VM.
    Execute um job em lote com um estado final definido e que exija recursos de computação adicionais. Serviço gerenciado Depende das características da carga de trabalho e da complexidade da configuração do contêiner. Batch
  • Executar aplicativos sem estado.
  • Execute trabalhos de pequeno a médio porte.
  • Serviço gerenciado Não ou solução de baixo custo para cargas de trabalho menores. Cloud Run
  • Você já tem um cluster do GKE.
  • Você precisa de controle e escalonabilidade avançados.
  • Serviço gerenciado Depende das características da carga de trabalho e da complexidade da configuração do contêiner. Google Kubernetes Engine

    Ao fazer a transição do agente de inicialização de contêiner do Compute Engine para uma solução alternativa, considere as seguintes mudanças necessárias e o possível esforço de implementação:

    • VMs que executam o Container-Optimized OS: assuma total responsabilidade pela configuração, segurança e manutenção da VM e do ambiente de execução de contêineres, o que geralmente envolve scripts com scripts de inicialização ou cloud-init.
    • Cloud Run ou Batch: verifique se os aplicativos são sem estado e se adequam ao modelo de execução orientado por solicitações ou baseado em jobs. Essa abordagem pode envolver a adaptação de aplicativos para trabalhar com serviços externos de gerenciamento de estado.
    • GKE: adote os princípios do Kubernetes, defina cargas de trabalho usando arquivos de manifesto do Kubernetes e gerencie recursos do cluster.

    Usar scripts de inicialização para implantar contêineres em VMs

    É possível executar um contêiner básico em uma VM usando um script de inicialização.

    Considere os seguintes pontos ao usar um script de inicialização para configurar contêineres:

    • É possível usar um script de inicialização para cenários básicos. Para configurações avançadas, considere usar cloud-init.
    • Como você está criando uma nova VM com um contêiner configurado usando o script de inicialização, é necessário planejar a transição de todas as cargas de trabalho implantadas nas VMs atuais.
    • Teste e garanta que tudo funcione conforme o esperado antes de rotear o tráfego para a VM recém-criada com um contêiner.

    Para criar uma VM e implantar um contêiner em uma VM ou um MIG, faça o seguinte:

    1. Mapear o contêiner atual nos metadados da VM para o comando do script de inicialização
    2. Criar um script de inicialização com base na configuração de metadados atual
    3. Criar uma VM usando o script de inicialização ou Criar um MIG usando o script de inicialização.

    Mapear os metadados do contêiner para o comando docker run

    É possível mapear os metadados da VM ou as flags gcloud para argumentos docker run e incluir isso no script de inicialização para criar VMs.

    Algumas flags gcloud são traduzidas diretamente para metadados de VM, assim como para flags docker run. Se você tiver um contêiner em uma VM, leia a configuração de metadados da VM e crie um script de inicialização usando os comandos docker run equivalentes.

      # Get your existing VM instance configuration in yaml format
      gcloud compute instances describe VM_NAME --format="(metadata.items)"
    

    O resultado será o seguinte:

      metadata:
        items:
        - key: gce-container-declaration
          value: |
            spec:
              containers:
              - args:
                - '"hello world!"'
                command:
                - echo
                env:
                - name: ONE
                  value: '1'
                image: docker.io/library/busybox
                name: my-instance
                securityContext:
                  privileged: true
                stdin: true
                tty: true
              restartPolicy: Always
        - key: google-logging-enabled
          value: 'true'
    

    Use a tabela a seguir para mapear a especificação atual para comandos docker run:

    Flag da CLI gcloud Chave de metadados da VM Comando "docker run"
    --container-image containers.image Especifique como um argumento sem nenhuma flag.
    Por exemplo:
    docker run gcr.io/google-containers/busybox
    --container-command command Especifique como um argumento sem flag, depois do nome da imagem do contêiner.
    Por exemplo:
    docker run gcr.io/google-containers/busybox echo "hello world"
    --container-arg args Especifique como um argumento sem nenhuma flag, depois do comando.
    Por exemplo:
    docker run gcr.io/google-containers/busybox echo "hello world"
    --container-env containers.env array --env KEY=VALUE [--env KEY=VALUE ...]
    --container-restart-policy restartPolicy --restart
    Os valores possíveis são no, on-failure e always. O padrão é no.
    --container-stdin containers.stdin -i
    Flag booleana, verdadeira se estiver presente, falsa por padrão.
    --container-tty containers.tty -t
    Flag booleana, verdadeira se estiver presente, falsa por padrão.
    --container-privileged containers.securityContext.privileged --privileged
    Flag booleana, verdadeira se estiver presente, falsa por padrão.
    --container-mount-disk - Não há um comando docker run equivalente.
    É possível montar o disco separadamente.

    Exemplos de scripts de inicialização

    Os exemplos a seguir mostram como incluir os comandos docker no script de inicialização:

    • Exemplo 1: executa um contêiner independente em uma VM baseada no Container-Optimized OS.
    • Exemplo 2: executa um contêiner do servidor da Web em uma VM baseada no Container-Optimized OS.

    Exemplo 1

    Execute um contêiner independente em uma VM baseada no Container-Optimized OS:

    #!/bin/bash
    
    # A name for the container
    CONTAINER_NAME="my-app-container"
    
    # Stop and remove the container if it exists
    docker stop $CONTAINER_NAME || true
    docker rm $CONTAINER_NAME || true
    
    # Pull the latest version of the container image from Docker Hub
    docker pull busybox:latest
    
    # Run docker container from image in docker hub
    docker run busybox:latest \
      echo "hello world!"
    

    Exemplo 2

    Execute um contêiner de servidor da Web em uma VM baseada no Container-Optimized OS:

    #!/bin/bash
    
    # Enable incoming traffic
    iptables -A INPUT -j ACCEPT
    
    # A name for the container
    CONTAINER_NAME="my-app-container"
    
    # Stop and remove the container if it exists
    docker stop $CONTAINER_NAME || true
    docker rm $CONTAINER_NAME || true
    
    # Pull the latest version of the container image from Docker Hub
    docker pull nginx:latest
    
    # Run docker container from image in docker hub
    docker run \
      --name=$CONTAINER_NAME \
      --privileged \
      --restart=always \
      --tty \
      --detach \
      --network="host" \
      nginx:latest
    

    Outras opções de configuração para implantação de contêineres

    Nesta seção, descrevemos os parâmetros de configuração adicionais para implantar contêineres nas suas VMs.

    Para mais informações sobre essas opções, consulte Configurar opções para executar um contêiner.

    Acesso a imagens do Artifact Registry

    Se você precisar acessar imagens de contêiner de gcr.io ou pkg.dev, use a ferramenta docker-credential-gcr, que já vem instalada no Container-Optimized OS, e configure a autenticação no Artifact Registry para o Docker. Execute o comando a seguir antes de executar o contêiner:

      # Set home directory to save docker credentials
      export HOME=/home/appuser
    
      # Configure docker with credentials for gcr.io and pkg.dev
      docker-credential-gcr configure-docker --registries LOCATION-docker.pkg.dev
    

    Substitua LOCATION pelo local do seu repositório.

    Para mais informações, consulte Configurar a autenticação do Docker no Artifact Registry.

    Configurar a geração de registros

    Recomendamos usar o Cloud Logging ativando um agente de geração de registros em uma VM.

    Como alternativa, se você quiser mudar o driver de geração de registros, inclua o parâmetro --log-driver com o comando docker run:

      # Use Cloud Logging logging driver
      docker run --log-driver=gcplogs nginx:latest
    

    Para mais informações, consulte Como usar o Cloud Logging com o Container-Optimized OS.

    Configurar o firewall interno

    O Container-Optimized OS nega o tráfego de entrada por padrão. Portanto, é necessário adicionar regras iptables para permitir esse tráfego. Esses comandos configuram o firewall interno do sistema operacional host. Além disso, configure o firewall da nuvem privada virtual (VPC) para permitir esse tráfego na nova VM.

    Para mais informações, consulte Usar regras de firewall da VPC.

      # Enable all incoming and routed traffic
      iptables -A INPUT -j ACCEPT
      iptables -A FORWARD -j ACCEPT
    

    Para mais informações, consulte Como configurar o firewall do host.

    Anexar volumes ao contêiner

    Se os volumes estiverem anexados ao contêiner, os metadados dele vão incluir a entrada volumes e uma matriz volumeMounts. O name de uma entrada em volumes corresponde ao nome de uma entrada em volumeMounts e vice-versa. Para cada volume coletado, reúna as informações necessárias na entrada volumes ou volumeMounts.

    Se nenhum volume estiver anexado ao contêiner, pule esta seção e crie uma VM usando o script de inicialização.

    Para mais informações sobre discos e sistema de arquivos no Container-Optimized OS, consulte Visão geral de discos e sistema de arquivos.

    Montar o sistema de arquivos tmpfs

    Para montar um sistema de arquivos tmpfs vazio em um contêiner, especifique o argumento --tmpfs com o comando docker run. Por exemplo, para montar um sistema de arquivos de cache no contêiner nginx, execute o seguinte comando:

      # mount a cache file system to the nginx container
      docker run -d --name=$CONTAINER_NAME --tmpfs /var/cache/nginx:rw,size=512m,noexec,nosuid,nodev --network="host" nginx:latest
    

    Para mais informações sobre como montar sistemas de arquivos tmpfs, consulte Montagens tmpfs.

    Montar um diretório de host

    Para ativar um diretório de uma VM de host em um contêiner, especifique o argumento --mount com o comando docker run:

      # mount a read-only directory to the nginx container
      docker run -d --name=$CONTAINER_NAME --mount type=bind,source=/var/www/html,target=/usr/share/nginx/html,ro nginx:latest
    

    Para mais informações, consulte Montagens de vinculação.

    Ativar um disco permanente no contêiner

    A montagem de um disco no contêiner exige etapas adicionais. Para montar um disco, primeiro monte-o na VM e depois no contêiner:

    1. Para ativar o disco na VM, execute o seguinte comando:

      #!/bin/bash
      
      DISK_DEVICE_NAME="my-persistent-disk" # This name MUST match the 'device-name' in the gcloud --disk flag
      DISK_BY_ID_PATH="/dev/disk/by-id/google-${DISK_DEVICE_NAME}"
      HOST_MOUNT_POINT="/mnt/disks/my-persistent-disk" # This is the path where the disk will be mounted on the VM
      CONTAINER_MOUNT_PATH="/usr/share/my-persistent-disk" # This is the path where the disk will be mounted in the container
      
      # format a disk as an ext4 filesystem, if it doesn't already contain one
      file -sL $DISK_BY_ID_PATH | grep -q filesystem || \
              mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard $DISK_BY_ID_PATH
      
      # create a directory for mounting point
      sudo mkdir -p "${HOST_MOUNT_POINT}"
      
      # mount a disk to the VM
      sudo mount -o defaults,discard "${DISK_BY_ID_PATH}" "${HOST_MOUNT_POINT}"
      
    2. Depois de montar o disco na VM, adicione a flag --mount com o comando docker run para montar o disco no contêiner:

      docker run -d --name=$CONTAINER_NAME --mount type=bind,source="${HOST_MOUNT_POINT}",target="${CONTAINER_MOUNT_PATH}",readonly nginx:latest
      

    Gerar um script de inicialização com a ajuda do Gemini

    Você pode usar o Gemini para gerar um script de inicialização com base na declaração de contêiner atual.

    Para usar o Gemini Cloud Assist e gerar um script de inicialização, siga estas etapas:

    1. Acessar a página do Compute Engine.

      Acessar o Compute Engine

    2. Na barra de ferramentas Cloud de Confiance , clique em spark Abrir ou fechar o chat com IA do Gemini para abrir o chat do Gemini Cloud Assist.

      Botão do Gemini Cloud Assist na barra de ferramentas do Compute Engine.

    3. No campo Insira um comando, digite o comando de exemplo fornecido nesta seção. Substitua os marcadores de posição do script e do YAML do contêiner por um script de inicialização e sua configuração de contêiner atual.

    4. Clique em Enviar solicitação.

    Para mais informações sobre como configurar e usar o Gemini Cloud Assist, consulte Configurar o Gemini Cloud Assist.

    Exemplo de comando para gerar um script de inicialização com base na configuração de contêiner atual

          <OBJECTIVE_AND_PERSONA>
          You are a senior systems architect migrating container deployments on Compute Engine. The legacy container startup agent, Konlet, is deprecated, which is the reason for this migration. Your task is to process the input YAML specification, which is the existing container declaration being migrated, and translate it into a robust Bash startup script for Container-Optimized OS on Compute Engine. You must ensure complete functional equivalence with 1:1 Konlet parity by following the `<INSTRUCTIONS>` and referring to the `<CONTEXT>` element below.
          </OBJECTIVE_AND_PERSONA>
    
          <INSTRUCTIONS>
          To complete this task, follow these instructions in sequence:
          1. Initialize the script with the shebang `#!/bin/bash` and options `set -euo pipefail`.
          2. Integrate the "Existing Script" input verbatim immediately after the initialization.
          3. Add a blank line, then define a function wrapper: `start_gce_container() { ... }`.
          4. Inside the function, include the mandatory logic blocks for Firewall, Cleanup, and Authentication provided in the `<CONTEXT>`.
          5. Translate the provided YAML "Container Declaration" using the mapping rules in the `<CONTEXT>`.
          6. Generate HostPath, EmptyDir, or Persistent Disk volume preparation steps using the patterns provided in the `<CONTEXT>`.
          7. Finalize the function, add a blank line, and provide the invocation and completion echo statements as specified in the `<OUTPUT_FORMAT>`.
          </INSTRUCTIONS>
    
          <CONSTRAINTS>
          1. Do not simplify: Ensure all logic steps and verbatim blocks are included. Omitting any block constitutes a functional failure.
          2. UI link protection: Define all URLs using split-string variables to prevent the UI from breaking the script with Markdown links:
             `KLT_URL="http""://metadata.google.internal/..."`
          3. Nsenter prefix: You must prefix every `mkdir`, `mount`, `umount`, `blkid`, `mkfs`, and `grep` (when checking `/proc/mounts`) with: `nsenter -t 1 -m --`.
          4. One command per line: Every single Bash command must be on its own separate line. Do not split a single command's arguments across multiple lines (e.g. keep `docker run` and its flags on one line, or use backslash `\` line continuations if you split the command).
          5. Comment style: Include headers and comments using the `#` symbol for clarity.
          6. Docker execution rules: Always run containers in detached mode using `docker run -d`. Never use the `--rm` flag. Never use the shell background operator (`&`) at the end of the `docker run` command.
          </CONSTRAINTS>
    
          <CONTEXT>
    
          ## Translation dictionary (1:1 Konlet parity)
          1. Restart policy:
             - Always: `--restart always`
             - OnFailure: `--restart on-failure`
             - Never: `--restart no`
          2. Security context:
             - privileged: true -> Add `--privileged` flag.
             - If disk name contains 'local-ssd', use dev path: `/dev/disk/by-id/google-local-nvme-ssd-0`
          3. Multi-container support:
             - If `spec.containers` has multiple entries, generate a separate `docker run` command for EACH container.
          4. Background execution:
             - To run containers in the background, you must use the `docker run -d` (detached) flag. Do not use `--rm` or `&`.
    
          ## Verbatim logic blocks (Use as-is inside function)
          Firewall:
          /sbin/iptables -C INPUT -j ACCEPT 2>/dev/null || /sbin/iptables -A INPUT -j ACCEPT
          /sbin/iptables -C FORWARD -j ACCEPT 2>/dev/null || /sbin/iptables -A FORWARD -j ACCEPT
    
          Cleanup:
          /usr/bin/docker ps -a --filter "name=klt-" -q | xargs -r /usr/bin/docker rm -f
          nsenter -t 1 -m -- /bin/sh -c 'for m in $(/bin/grep "/mnt/disks/gce-containers-mounts/" /proc/mounts | /usr/bin/awk '\''{print $2}'\'' | /bin/sort -r); do /bin/umount "$m" || true; done'
    
          Authentication (Hardened for boot-time race conditions):
          export DOCKER_CONFIG="/var/lib/docker-config"
          /bin/mkdir -p "$DOCKER_CONFIG"
          KLT_URL_TOKEN="http""://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
          KLT_URL_REG="https""://gcr.io"
          /bin/sleep 2
          KLT_TOKEN=$(/usr/bin/curl -s -H "Metadata-Flavor: Google" "$KLT_URL_TOKEN" | /bin/grep -o '"access_token":"[^"]*' | /bin/grep -o '[^"]*$')
          if [ -n "$KLT_TOKEN" ]; then
            echo "$KLT_TOKEN" | /usr/bin/docker login -u oauth2accesstoken --password-stdin "$KLT_URL_REG"
          fi
    
          ## Volume preparation patterns
          Pattern A (GcePersistentDisk):
          nsenter -t 1 -m -- /bin/mkdir -p [MNT_PATH]
          nsenter -t 1 -m -- /sbin/blkid [DEV_PATH] || nsenter -t 1 -m -- /sbin/mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard [DEV_PATH]
          nsenter -t 1 -m -- /bin/mount -t ext4 -o discard,defaults [DEV_PATH] [MNT_PATH]
          nsenter -t 1 -m -- /bin/grep -q " [MNT_PATH] " /proc/mounts || exit 1
    
          Pattern B (EmptyDir Memory):
          nsenter -t 1 -m -- /bin/mkdir -p [MNT_PATH]
          nsenter -t 1 -m -- /bin/mount -t tmpfs tmpfs [MNT_PATH]
          nsenter -t 1 -m -- /bin/grep -q " [MNT_PATH] " /proc/mounts || exit 1
    
          Pattern C (HostPath):
          nsenter -t 1 -m -- /bin/mkdir -p [HOST_PATH]
          </CONTEXT>
    
          <OUTPUT_FORMAT>
          1. Shebang & Opts: `#!/bin/bash` and `set -euo pipefail`.
          2. Existing Script: Integrated verbatim.
          3. [BLANK LINE]
          4. Function Wrapper: `start_gce_container() { ... }`
          5. [BLANK LINE]
          6. Invocation: `start_gce_container || echo "Error: Container failed to start..."`
          7. Completion: `echo "Startup script finished."`
          </OUTPUT_FORMAT>
    
          <FEW_SHOT_EXAMPLES>
          <INPUT_YAML>
          ```yaml
          spec: \
            containers: \
            - name: klt-main \
              image: gcr.io/my-proj/app:v1 \
              volumeMounts: \
              - name: data \
                mountPath: /data \
            volumes: \
            - name: data \
              gcePersistentDisk: \
                pdName: data-disk \
                fsType: ext4
          ```
          </INPUT_YAML>
    
          <OUTPUT_THOUGHTS>
          The model should identify Pattern A for GcePersistentDisk and use the `nsenter` prefix for mounts.
          </OUTPUT_THOUGHTS>
    
          <OUTPUT_SNIPPETS>
          <SAMPLE_STARTUP_SCRIPT>
          #!/bin/bash \
          set -euo pipefail \
          echo "=== STARTING CUSTOM PRE-STARTUP ===" \
          mkdir -p /tmp/test-marker \
          echo "marker-content" > /tmp/test-marker/ok.txt \
          echo "=== FINISHED CUSTOM PRE-STARTUP ==="
    
          start_gce_container() {
          # Firewall:
          /sbin/iptables -C INPUT -j ACCEPT 2>/dev/null || /sbin/iptables -A INPUT -j ACCEPT
          /sbin/iptables -C FORWARD -j ACCEPT 2>/dev/null || /sbin/iptables -A FORWARD -j ACCEPT
    
          # Cleanup:
          /usr/bin/docker ps -a --filter "name=klt-" -q | xargs -r /usr/bin/docker rm -f
          nsenter -t 1 -m -- /bin/sh -c 'for m in $(/bin/grep "/mnt/disks/gce-containers-mounts/" /proc/mounts | /usr/bin/awk '\''{print $2}'\'' | /bin/sort -r); do /bin/umount "$m" || true; done'
    
          # Authentication (Hardened for boot-time race conditions):
          export DOCKER_CONFIG="/var/lib/docker-config"
          /bin/mkdir -p "$DOCKER_CONFIG"
          KLT_URL_TOKEN="http""://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
          KLT_URL_REG="https""://gcr.io"
          /bin/sleep 2
          KLT_TOKEN=$(/usr/bin/curl -s -H "Metadata-Flavor: Google" "$KLT_URL_TOKEN" | /bin/grep -o '"access_token":"[^"]*' | /bin/grep -o '[^"]*$')
          if [ -n "$KLT_TOKEN" ]; then
            echo "$KLT_TOKEN" | /usr/bin/docker login -u oauth2accesstoken --password-stdin "$KLT_URL_REG"
          fi
    
          </SAMPLE_STARTUP_SCRIPT>
          </OUTPUT_SNIPPETS>
          </FEW_SHOT_EXAMPLES>
    
          <RECAP>
          As the systems architect leading this migration on Compute Engine, you must ensure that the final script retains full functional equivalence with the deprecated Konlet agent. This requires applying the host-level execution constraints using `nsenter` specified in the `<CONTEXT>` element, protecting URLs with string splitting, and strictly conforming to the `<OUTPUT_FORMAT>` without skipping any logic blocks.
          </RECAP>
    
          # Input
          1. Existing script: EXISTING_SCRIPT
          2. Container declaration (YAML): CONTAINER_YAML
      

    Substitua:

    • EXISTING_SCRIPT: o conteúdo do seu script de inicialização atual. Adicione uma barra invertida (\) no final de cada linha em vez de uma quebra de linha.
    • CONTAINER_YAML: a especificação YAML da implantação do contêiner da chave de metadados gce-container-declaration. Adicione uma barra invertida (\) no final de cada linha em vez de uma quebra de linha.

    Criar uma VM usando o script de inicialização

    Depois de criar um script de inicialização com a configuração do contêiner, use esse script para criar uma VM com base no Container-Optimized OS. Para mais informações sobre como criar uma VM com base no Container-Optimized OS, consulte Criar uma instância com base em uma imagem pública.

    Para mais informações sobre como usar scripts de inicialização, consulte Como usar scripts de inicialização em VMs do Linux.

    Console

    1. No console do Cloud de Confiance , acesse a página Criar uma instância.

      Acesse "Criar uma instância"

      Se solicitado, selecione o projeto e clique em Continuar. A página Criar instância aparece e mostra o painel Configuração da máquina.

    2. No painel Configuração da máquina, selecione a família e o tipo de máquina para sua VM.

    3. No menu de navegação, clique em SO e armazenamento. No painel Sistema operacional e armazenamento, configure o disco de inicialização fazendo o seguinte:

      1. Clique em Alterar. O painel Disco de inicialização aparece e mostra a guia Imagens públicas.
      2. Na lista Sistema operacional, selecione Container-Optimized OS.
      3. Na lista Versão, selecione a versão do SO.
      4. Na lista Tipo de disco de inicialização, selecione o tipo de disco de inicialização.
      5. (Opcional) Se você precisar de mais discos, adicione-os na seção Discos extras.
      6. Clique em Selecionar.
    4. No menu de navegação, clique em Avançado.

      1. Na seção Automação, cole o script de inicialização que você criou para a implantação do contêiner.
    5. Para criar e iniciar a VM, clique em Criar.

    gcloud

    Ao usar a CLI gcloud, armazene um script de inicialização em um arquivo separado.

    1. Para criar uma VM usando um script de inicialização, execute o seguinte comando:

      gcloud compute instances create VM_NAME \
          --zone=ZONE \
          --image-family=IMAGE_FAMILY \
          --image-project=IMAGE_PROJECT \
          --machine-type=MACHINE_TYPE \
          --metadata-from-file=startup-script=STARTUP_SCRIPT_FILE
      

      Substitua:

      • VM_NAME: nome da nova VM.
      • ZONE: a zona em que a instância será criada.
      • IMAGE_PROJECT: o projeto de imagem do Container-Optimized OS que contém a imagem, por exemplo, cos-cloud.
      • IMAGE_FAMILY: a família de imagens do Container-Optimized OS, por exemplo, cos-stable.
      • MACHINE_TYPE: tipo de máquina para a nova VM, que pode ser predefinido ou personalizado.
      • STARTUP_SCRIPT_FILE: o caminho relativo na sua máquina para o arquivo de script de inicialização, por exemplo, ./startup_script.sh.

      Exemplo:

      # Create COS-based VM by using a startup script
      gcloud compute instances create "cos-instance-with-startup-script" \
      --zone="us-central1-c" \
      --machine-type="e2-medium" \
      --image-family="cos-stable" \
      --image-project="cos-cloud" \
      --metadata-from-file=startup-script="./startup_script.sh"
      
    2. Verifique se o Compute Engine criou a VM executando o seguinte comando:

      gcloud compute instances describe VM_NAME
      

      Substitua VM_NAME pelo nome da VM criada.

    Terraform

    Para criar uma VM, use o recurso google_compute_instance.

    provider "google" {
    project = "PROJECT_ID"
    }
    
    resource "google_compute_instance" "cos_vm_instance" {
    name         = "VM_NAME"
    machine_type = "MACHINE_TYPE"
    zone         = "ZONE"
    
    # Use a Container-Optimized OS image for the boot disk
    boot_disk {
      initialize_params {
        image = "IMAGE_PROJECT/IMAGE_FAMILY"
      }
    }
    
    # Attaches the instance to the default network
    network_interface {
      network = "default"
    }
    
    # Specify the relative path to the startup script on your local machine
    metadata = {
      startup-script = file("STARTUP_SCRIPT_FILE")
    }
    }
    

    Substitua:

    • VM_NAME: nome da nova VM
    • ZONE: a zona em que a instância será criada.
    • IMAGE_PROJECT: o projeto de imagem do Container-Optimized OS que contém a imagem, por exemplo, cos-cloud.
    • IMAGE_FAMILY: a família de imagens do Container-Optimized OS. Por exemplo, cos-stable.
    • MACHINE_TYPE: tipo de máquina para a nova VM, que pode ser predefinido ou personalizado.
    • STARTUP_SCRIPT_FILE: o caminho relativo na sua máquina para o arquivo de script de inicialização, por exemplo, ./startup_script.sh.

    Exemplo:

    provider "google" {
      project = "my-project"
    }
    
    resource "google_compute_instance" "my_container_vm" {
      name = "my-container-vm-startup"
      machine_type = "e2-medium"
      zone = "us-central1-a"
    
      boot_disk {
        initialize_params {
          image = "cos-cloud/cos-stable"
        }
      }
    
      network_interface {
        network = "default"
      }
    
      metadata = {
        startup-script = file("./startup_script.sh")
      }
    }
    

    Criar um MIG usando o script de inicialização

    Depois de criar um modelo de instância usando o script de inicialização, use um dos métodos a seguir para criar um MIG.

    Para mais informações sobre como criar MIGs, consulte Criar um grupo gerenciado de instâncias.

    Console

    1. Crie um modelo de instância com base no script de inicialização criado na seção anterior.

      1. Na seção Sistema operacional, selecione um SO otimizado para contêiner e uma versão.
      2. Na seção Automação, cole o script de inicialização que você criou para a implantação do contêiner.
    2. Crie um MIG usando o modelo de instância criado na etapa anterior.

    gcloud

    1. Crie um modelo de instância usando o comando instance-templates create.

      Use uma imagem do Container-Optimized OS para a VM. É possível especificar o caminho relativo para o arquivo de script de inicialização na flag --metadata-from-file.

    2. Crie um MIG usando o modelo de instância criado na etapa anterior.

    Exemplo:

      # Create the instance template that uses a startup script
      gcloud compute instance-templates create startup-template \
          --machine-type=e2-medium \
          --image-family=cos-stable \
          --image-project=cos-cloud \
          --metadata-from-file=startup-script=./startup_script.sh
    
      # Create the managed instance group
        gcloud compute instance-groups managed create startup-mig \
          --template=startup-template \
          --size=2 \
          --zone=us-central1-a
    

    Terraform

    Use os recursos google_compute_instance_template e google_compute_instance_group_manager para criar um modelo de instância e um MIG, conforme mostrado no exemplo a seguir:

    Exemplo:

    resource "google_compute_instance_template" "startup_template" {
      name_prefix = "startup-template-"
      machine_type = "e2-medium"
      disk {
        source_image = "cos-cloud/cos-stable"
        auto_delete  = true
        boot         = true
      }
    
      network_interface {
        network = "default"
      }
      metadata = {
        startup-script = file("./startup_script.sh")
    }
    }
    
    resource "google_compute_instance_group_manager" "startup_mig" {
      name               = "startup-mig"
      base_instance_name = "startup-vm"
      zone               = "us-central1-a"
      version {
        instance_template = google_compute_instance_template.startup_template.id
      }
      target_size = 2
    }
    

    Testar e limpar

    Depois de criar uma VM ou um MIG, valide se o aplicativo está sendo executado no contêiner e funcionando conforme o esperado. Para corrigir problemas, consulte Solução de problemas.

    Se o aplicativo estiver sendo executado corretamente nas novas VMs criadas com o script de inicialização, exclua as VMs e os MIGs que usam o método descontinuado de implantação de contêineres.

    Solução de problemas com script de inicialização

    Nesta seção, você encontra informações para solucionar problemas que podem ocorrer ao usar scripts de inicialização.

    Não foi possível salvar a configuração do Docker

    Ao executar o comando docker-credential-gcr configure-docker em um script de inicialização, você pode receber a seguinte mensagem de erro:

    ERROR: Unable to save docker config: mkdir /root/.docker: read-only file system

    Esse erro ocorre porque o docker-credential-gcr tenta gravar credenciais no arquivo /root/.docker/config.json. O sistema de arquivos root no Container-Optimized OS é somente leitura, então não é possível gravar nele.

    Para resolver esse problema, defina a variável de ambiente $HOME para apontar para um diretório inicial personalizado antes de executar os comandos docker.

    Exemplo:

      export HOME=/home/appuser
      docker-credential-gcr configure-docker
      

    Ver registros para depurar problemas

    Para resolver problemas que podem ocorrer ao configurar contêineres em VMs usando um script de inicialização, consulte os registros do script de inicialização e do contêiner.

    • Para ver os registros do script de inicialização na instância de VM, execute o seguinte comando:

      sudo journalctl | grep "startup-script"
      
    • Para ver os registros do contêiner do Docker, execute o comando docker logs:

      docker logs CONTAINER_NAME
      

      Substitua CONTAINER_NAME pelo nome do contêiner.

    Para resolver outros problemas, consulte os seguintes documentos:

    Usar cloud-init com o Container-Optimized OS

    É possível usar o cloud-init, uma solução multiplataforma e padrão do setor, para implantar contêineres em VMs que executam o Container-Optimized OS. Com essa ferramenta, é possível executar uma configuração personalizada durante a criação ou inicialização da VM. Para mais informações, consulte Como usar cloud-init com o formato de configuração do Cloud.

    Usar serviços gerenciados para implantação de contêineres

    Esta seção descreve os serviços gerenciados fornecidos pelo Cloud de Confiance que você pode usar para implantar contêineres.

    Cloud Run

    O Cloud Run é uma boa opção para aplicativos de contêiner sem estado e jobs de pequeno a médio porte.

    Os principais recursos do Cloud Run incluem:

    • Você pode escolher alocar CPUs apenas durante o processamento de solicitações ou alocar sempre.
    • É possível executar um aplicativo de contêiner sem estado ou um job único, de acordo com uma programação ou como parte de um fluxo de trabalho.
    • É possível configurar tempos limite para cada solicitação ou tarefa.
    • É altamente escalonável e seguro.
    • Ele tem balanceamento de carga e escalonamento automático integrados.

    Para mais informações sobre como implantar contêineres no Cloud Run, consulte Como implantar imagens de contêiner no Cloud Run

    Lote

    O Batch é um serviço totalmente gerenciado que permite programar, enfileirar e executar cargas de trabalho de processamento em lote em recursos do Cloud de Confiance . Ele foi projetado para executar cargas de trabalho em lote e paralelizadas, incluindo aquelas empacotadas em contêineres.

    Para mais informações sobre como implantar contêineres no Batch, consulte os seguintes documentos:

    GKE

    Se você estiver executando aplicativos complexos, microsserviços, operação contínua e precisar de controle e escalonabilidade refinados, o Google Kubernetes Engine (GKE) será a oferta mais adequada. Para mais informações sobre como implantar contêineres no GKE, consulte os seguintes documentos:

    Receber suporte

    Se você tiver dúvidas sobre o processo de migração ou precisar de ajuda, consulte as perguntas frequentes ou entre em contato com o suporte doCloud de Confiance .