The container startup agent in Compute Engine is deprecated. This agent lets you deploy containers on Compute Engine instances when you create VMs.
This document describes how to migrate existing containers that the startup agent created on your VMs or managed instance groups (MIGs) to other Google Cloud services.
Based on your requirements, choose one of the following options to migrate the containers that were deployed on VMs using the deprecated method:
- If you want to continue running containers on individual VMs and MIGs, use startup scripts or cloud-init.
- If you have stateless container applications and small to medium jobs, use Cloud Run.
- If your container is a batch job that has a definite end state and requires additional computing resources, use Batch.
- If you need advanced control and scalability or if you can't meet your requirements with the other options, use GKE on Google Cloud.
For more use cases and alternative solutions, see Compare the container deployment options.
Deprecated options for configuring containers on VMs
When you configure a container on a VM during VM creation,
Compute Engine uses the container startup agent to generate the
gce-container-declaration
metadata key for the instance. This key stores the
container information. Because the container startup agent is deprecated, you
can no longer store container information in the gce-container-declaration
metadata key.
The following options for deploying containers on a VM or MIG use the container startup agent to configure containers on the VM.
Console
The Deploy container option on the Create an instance page is deprecated:
gcloud
The following gcloud
commands that configure a container on a VM or an instance template are deprecated:
- gcloud compute instances create-with-container
- gcloud compute instances update-container
- gcloud compute instance-templates create-with-container
- gcloud compute instances create command that uses the
--metadata
flag to set thegce-container-declaration
metadata key - gcloud compute instance-templates create command that uses the
--metadata
flag to set thegce-container-declaration
metadata key
Terraform
The Terraform module gce-container
and the gce-container-declaration
metadata key to configure containers are deprecated.
Identify instances that use the deprecated container metadata
To determine whether any instances in your project use the deprecated container
metadata, run the following Google Cloud CLI command that lists instances
with the gce-container-declaration
metadata key and value:
gcloud compute instances list --filter="metadata.items.key:gce-container-declaration"
This command provides a list of all VM instances in your configured project that
contain the gce-container-declaration
metadata key. The metadata key uniquely
identifies VMs that are in scope of the deprecation. If you are using multiple
projects, run this command across all of the active projects.
If you have a specific instance that you want to validate, run the following Google Cloud CLI command:
gcloud compute instances describe VM_NAME --format="(metadata.items)"
Replace VM_NAME with the name of the VM instance that you want to validate.
For more information about viewing metadata, see View and query metadata.
Compare the container deployment options
The following table summarizes the use cases for running containers on VMs and recommends alternative container solutions for migrating your workloads:
Use cases | Replacement type | Cost | Recommended solution |
---|---|---|---|
|
Direct replacement | No additional cost | Use startup scripts to create the VMs. |
For example, create users, import files, mount disks, or use privileged mode. |
Direct replacement | No additional cost | Use cloud-init to run tasks during the VM lifecycle. |
Run a batch job that has a definite end state and requires additional computing resources. | Managed service | Depends on your workload characteristics and complexity of the container configuration. | Batch |
|
Managed service | No to low cost solution for smaller workloads. | Cloud Run |
|
Managed service | Depends on workload characteristics and complexity of the container configuration. | Google Kubernetes Engine |
When you transition from the Compute Engine container startup agent to an alternative solution, consider the following required changes and the potential effort of implementing them:
- VMs running Container-Optimized OS: Take full ownership of VM and container
runtime setup, configuration, security, and maintenance, which often
involves scripting with startup scripts or
cloud-init
. - Cloud Run or Batch: Ensure that your applications are stateless and fit the request-driven or job-based execution model. This approach might involve adapting applications to work with external state management services.
- GKE: Adopt Kubernetes principles, define workloads by using Kubernetes manifest files, and manage cluster resources.
Use startup scripts to deploy containers on VMs
You can run a basic container on a VM using a startup script.
Consider the following points when you use a startup script to configure containers:
- You can use a startup script for basic scenarios. For advanced configuration,
consider using
cloud-init
. - Because you are creating a new VM with a container configured using the startup script, you must plan for the transition of any workloads deployed on the existing VMs.
- Test and ensure that everything works as expected before you route traffic to your newly created VM with a container.
To create a VM and to deploy a container on a VM or a MIG, do the following:
- Map current container on VM metadata to startup script command
- Create a startup script based on the existing metadata configuration
- Create a VM by using the startup script or Create a MIG by using the startup script.
Map your container metadata to docker run
command
You can map the VM metadata or gcloud
flags
to docker run
arguments and include this in your startup script for creating VMs.
Some gcloud
flags translate directly to VM metadata. These flags also
translate directly to docker run
flags.
If you have an existing container on a VM, you can read the VM metadata
configuration and build a startup script using the equivalent docker run
commands.
# Get your existing VM instance configuration in yaml format
gcloud compute instances describe VM_NAME --format="(metadata.items)"
The output is similar to the following:
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 the following table to map existing specification to docker run
commands:
Google Cloud CLI flag | VM metadata key | Docker run command |
---|---|---|
--container-image |
containers.image |
Specify as an argument without any flag. For example: docker run gcr.io/google-containers/busybox |
--container-command |
command |
Specify as an argument without any flag, after the container
image name. For example: docker run gcr.io/google-containers/busybox echo "hello world" |
--container-arg |
args |
Specify as an argument without any flag, after the command. For example: 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 Possible values are no , on-failure , and always . Default is no . |
--container-stdin |
containers.stdin |
-i Boolean flag, true if present, false by default. |
--container-tty |
containers.tty |
-t Boolean flag, true if present, false by default. |
--container-privileged |
containers.securityContext.privileged |
--privileged Boolean flag, true if present, false by default. |
--container-mount-disk |
- | No equivalent docker run command.You can mount the disk separately. |
Example startup scripts
The following examples show how to include the docker
commands in your startup
script:
- Example 1: runs a standalone container in a VM based on Container-Optimized OS.
Example 2: runs a web server container in a VM based on Container-Optimized OS.
Example 1
Run a standalone container in a VM based on 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
# Run docker container from image in docker hub
docker run \
docker.io/library/busybox \
echo "hello world!"
Example 2
Run a web server container in a VM based on Container-Optimized OS:
#!/bin/bash
# Enable incoming traffic for TCP protocol
sudo iptables -A "INPUT" -p "tcp" -j "ACCEPT"
sudo iptables -A "FORWARD" -p "tcp" -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
# Run docker container from image in docker hub
docker run \
--name=$CONTAINER_NAME \
--privileged \
--restart=always \
--tty \
--detached \
--network="host" \
nginx:1.29.0
Additional configuration options for container deployment
This section describes the additional configuration parameters for deploying containers on your VMs.
For more information about these options, see Configure options to run a container.
Access to Artifact Registry images
If you need access to container images from gcr.io or pkg.dev,
use the docker-credential-gcr
tool, which is preinstalled in Container-Optimized OS,
and configure authentication to Artifact Registry for Docker.
Run the following command before you run the container:
# Set home directory to save docker credentials
HOME=/home/appuser
# Configure docker with credentials for gcr.io and pkg.dev
docker-credential-gcr configure-docker
For more information, see Configure authentication to Artifact Registry for Docker.
Configure logging
We recommend using Cloud Logging by enabling a logging agent on a VM.
Alternatively, if you want to change the logging driver, you can include
the --log-driver
parameter with your docker run
command:
# Enable Cloud Logging
--log-driver=gcplogs
For more information, see Using Cloud Logging with Container-Optimized OS
Configure internal firewall
Container-Optimized OS denies incoming traffic by default, so you must add
iptables
rules to allow that traffic. Note that these commands configure the
host operating system's internal firewall. Additionally, you must configure your
Virtual Private Cloud firewall to allow that traffic to the new VM
For more information, see Use VPC firewall rules.
# Enable all incoming traffic for TCP protocol
iptables -A "INPUT" -p "tcp" -j "ACCEPT"
iptables -A "FORWARD" -p "tcp" -j "ACCEPT"
# Enable all incoming traffic for UDP protocol
iptables -A "INPUT" -p "udp" -j "ACCEPT"
iptables -A "FORWARD" -p "udp" -j "ACCEPT"
# Enable all incoming traffic for ICMP protocol
iptables -A "INPUT" -p "icmp" -j "ACCEPT"
iptables -A "FORWARD" -p "icmp" -j "ACCEPT"
For more information, see Configuring the host firewall.
Attach volumes to the container
If volumes are attached to the container, the container metadata includes the
volumes
entry and a volumeMounts
array. The name
of an entry in volumes
corresponds to the name of an entry in volumeMounts
, and the other way around.
For each volume that you collect, gather the required information either from
the volumes
or from the volumeMounts
entry.
If no volumes are attached to the container, you can skip this section and directly create a VM by using the startup script.
Mount tmpfs file system
# generic command
--tmpfs <mount-path>[:opts]
# for our example
--tmpfs tmpfs-mount-path
Directory or host-path mounts
# generic command
--mount type=bind,source=HOSTPATH,target=MOUNTPATH[,readonly]
# for our example
--mount type=bind,source=directory-host-path,target=directory-mount-path,readonly
Mount a persistent disk to the container
Mounting a disk to the container requires additional steps. To mount a disk, first mount it on the VM, and then mount that disk to the container:
To mount the disk to the VM, run the following command:
#!/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-data" # This is where the disk will be mounted on the VM # 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}"
After you mount the disk to the VM, add the
--mount
flag with thedocker run
command to mount the disk to the container:--mount type=bind,source="${HOST_MOUNT_POINT}",target=/disk,readonly
Create a VM by using the startup script
After creating a startup script with your container configuration, use this startup script to create a VM.
For more information about using startup scripts, see Using startup scripts on Linux VMs.
Console
In the Google Cloud console, go to the Create an instance page.
If prompted, select your project and click Continue. The Create an instance page appears and displays the Machine configuration pane.
In the Machine configuration pane, select the machine family and machine type for your VM.
In the navigation menu, click OS and storage. In the Operating system and storage pane that appears, configure your boot disk by doing the following:
- Click Change. The Boot disk pane appears and displays the Public images tab.
- In the Operating system list, select Container Optimized OS.
- In the Version list, select the OS version.
- In the Boot disk type list, select the type of the boot disk.
- (Optional) If you need additional disks, add disks in the Additional disks section.
- Click Select.
In the navigation menu, click Advanced.
- In the Automation section, paste the startup script that you created for your container deployment.
To create and start the VM, click Create.
gcloud
When using Google Cloud CLI, store a startup script in a separate file. For more information, see Using startup scripts on Linux VMs and Create an instance from a public image.
- To create a VM from a startup script called
startup.sh
, run the following command:
gcloud compute instances create VM_NAME \ --zone=ZONE \ [--image=IMAGE | --image-family=IMAGE_FAMILY] \ --image-project=IMAGE_PROJECT \ IMAGE_FLAG \ --machine-type=MACHINE_TYPE \ --metadata-from-file=startup-script=STARTUP_SCRIPT_FILE
Replace the following:
VM_NAME
: name of the new VMZONE
: zone to create the instance inIMAGE_PROJECT
: the Container-Optimized OS image project that contains the imageIMAGE_FLAG
: the Container-Optimized OS image or image familyMACHINE_TYPE
: machine type for the new VM, which can be a predefined machine type or a custom machine type.STARTUP_SCRIPT_FILE
: the relative path to the startup script file that contains thedocker run
command for configuring and running your container.
Example:
# Configuration Variables PROJECT_ID="my_project_id" REGION="us-central1" ZONE="us-central1-c" INSTANCE_NAME="instance-startup-script" STARTUP_SCRIPT_PATH="./startup.sh" # Disk and Policy Configuration RESOURCE_POLICY_NAME="disk-resource-policy" DISK_DEVICE_NAME="my-persistent-disk" # Derived Variables (do not change) RESOURCE_POLICY_PATH="projects/${PROJECT_ID}/regions/${REGION}/resourcePolicies/${RESOURCE_POLICY_NAME}" # Create the VM instance, attach the boot disk with a resource policy, # Attach a secondary read-only disk, and runs a startup script. gcloud compute instances create "${INSTANCE_NAME}" \ --project="${PROJECT_ID}" \ --zone="${ZONE}" \ --machine-type="e2-medium" \ --scopes=devstorage.read_only,logging.write,monitoring.write,servicecontrol \ --image-family="cos-stable" \ --image-project="cos-cloud" \ --metadata-from-file=startup-script="${STARTUP_SCRIPT_PATH}" \ --create-disk=boot=yes,disk-resource-policy="${RESOURCE_POLICY_PATH}" \ --disk=name="${DISK_DEVICE_NAME}",mode=ro
Verify that Compute Engine created the VM by running the following command:
gcloud compute instances describe VM_NAME
Replace
VM_NAME
with the name of the VM you created.
Terraform
To create a VM, you can use the google_compute_instance
resource
The following example shows how to use a startup script to configure and run a container:
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" } } attached_disk { device_name = "my-persistent-disk" mode = "READ_WRITE" } network_interface { network = "default" } metadata_startup_script = <<EOF #!/bin/bash docker pull docker.io/nginx:latest docker rm -f my-nginx || true docker run -d -p 80:80 --name my-nginx docker.io/nginx:latest EOF }
Create a MIG by using the startup script
After creating an instance template using the startup script, use one of the following methods to create a MIG.
For more information about creating MIGs, see Create a managed instance group.
Console
Create an instance template that is based on the startup script you created in the previous section.
- In the Operating system section, select a Container Optimized OS and version.
- In the Automation section, paste the startup script that you created for the container deployment.
Create a MIG by using the instance template created in the previous step.
gcloud
Create an instance template by using the
instance-templates create
command.You must use a Container-Optimized OS image for the VM. You can specify the relative path to the startup script file in the
--metadata-from-file
flag.Create a MIG by using the instance template created in the previous step.
Example:
# Create the persistent disk gcloud compute disks create my-persistent-disk \ --region=us-central1 \ --replica-zones=us-central1-a,us-central1-b \ --size=20GB # 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 \ --disk=name=my-persistent-disk,device-name=my-persistent-disk,mode=rw,boot=no \ --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 the google_compute_instance_template
and google_compute_instance_group_manager
resources to
create an instance template and a MIG, as shown in the following example:
Example:
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 } disk { source_image = "" auto_delete = false boot = false device_name = "my-persistent-disk" disk_size_gb = 20 } network_interface { network = "default" } metadata_startup_script = <<EOF #!/bin/bash docker pull docker.io/nginx:latest docker rm -f my-nginx || true docker run -d -p 80:80 --name my-nginx docker.io/nginx:latest EOF lifecycle { create_before_destroy = true } } resource "google_compute_region_disk" "my_persistent_disk" { name = "my-persistent-disk" region = "us-central1" replica_zones = ["us-central1-a", "us-central1-b"] size = 20 } 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 }
Shut down a container VM by using a shutdown script
You can set up a shutdown script to gracefully shut down the container. For example, to stop a Docker container, add a shutdown script similar to the following:
#!/bin/sh docker stop my_container
Test and clean up
After successful creation of a VM or a MIG, validate that your application is running on the container and working as expected. To fix any issues, see Troubleshooting.
If the application is running successfully on your new VMs created using the startup script, you can delete the VMs and MIGs that use the deprecated method of deploying containers.
Troubleshooting
For troubleshooting issues that might occur during migration of containers, see the following documents:
- Cloud Logging overview
- Using Cloud Logging with Container-Optimized OS
- Troubleshooting the Docker daemon
- Troubleshoot and diagnose
- Troubleshoot Terraform
- Troubleshooting when running a basic web server
- Building internet connectivity for private VMs
Use cloud-init
with Container-Optimized OS
You can use cloud-init
,
an industry-standard and cross-platform solution, to deploy containers on VMs
running Container-Optimized OS.
This tool lets you run custom configuration during the VM creation or startup.
For more information, see
Using cloud-init
with the Cloud config format.
Use managed services for container deployment
This section describes the managed services provided by Google Cloud that you can use to deploy containers.
Cloud Run
Cloud Run is a good option for stateless container applications and small to medium jobs.
Key features of Cloud Run include the following:
- You can choose to only allocate CPUs during request processing, or always allocate CPUs.
- You can run a stateless container application or execute a job as one-off, on a schedule, or as part of a workflow.
- You can configure timeouts for each request or task.
- It's highly scalable and secure.
- It has integrated load balancing and autoscaling.
For more information about deploying containers on Cloud Run, see Deploying container images to Cloud Run
Batch
Batch is a fully managed service that lets you schedule, queue, and execute batch processing workloads on Google Cloud resources. It's designed for running batch-style, parallelizable workloads, including those packaged in containers.
For more information about deploying containers on Batch, see the following documents:
Google Kubernetes Engine
If you are running complex applications, microservices, continuous operation and need fine-grained control and scalability, Google Kubernetes Engine (GKE) is the offering that is best suited. For more information about deploying containers on GKE. see the following documents:
Get support
If you have any questions about the migration process or if you need assistance, review the FAQ or contact Google Cloud Support.