Build multi-architecture images for Arm workloads


This page explains what multi-architecture (multi-arch) images are, why the architectures of nodes and container images are important, and why multi-arch images make deploying workloads to GKE clusters easier. This page also provides guidance about how you can check if your workloads are ready to run on Arm, and how you can build multi-arch images.

For a tutorial about deploying across architectures with multi-arch images, see Migrate x86 application on GKE to multi-arch with Arm.

What is a multi-arch image?

A multi-arch image is an image that can support multiple architectures. It looks like a single image with a single tag, but it is a list of images targeting multiple architectures organized by a manifest list. Multi-arch images are compatible with the Docker Image Manifest V2 Scheme 2 or OCI Image Index Specifications. When you deploy a multi-arch image to a cluster, GKE automatically chooses the right image that is compatible with the architecture of the node to which it is being deployed. Once you have a multi-arch image for a workload, you can seamlessly deploy this workload across multiple architectures.

Multi-arch images are most useful when you want to use the same workload across architectures. Alternatively, you can use container images with a single architecture with any types of GKE nodes. If you are only using a workload on one architecture and you already have a compatible image, you do not need to build a multi-arch image.

If you are using a single-arch image or multi-arch image that is Arm-compatible and you want to deploy it to an Arm node, you must follow the instructions to include the necessary fields so that GKE schedules the workload as expected. To learn more, see Prepare an Arm workload for deployment. You do not need to add these fields to schedule workloads if the workloads are only going to be scheduled to x86-based nodes.

Why is the architecture of a GKE node important for workloads?

GKE nodes are individual Compute Engine VM instances which GKE creates and manages on your behalf. Each node is of a standard machine type (for example, t2a-standard-1) which uses either x86 (Intel or AMD) or Arm processors. To learn more see, CPU platforms.

You must use container images that are compatible with the architecture of the node where you intend to run the workloads. For example, if you want to run a container image with the arm64 architecture, you must a machine type that supports Arm workloads, such as t2a-standard-1 from the Tau T2A machine series. You can use nodes with multiple architecture types in one GKE cluster. If you want to use one workload across multiple architecture types, you must keep all of the container images and deployment files for the architecture-specific images organized. Multi-arch images make the process of deploying across architecture types simpler.

Build multi-arch image to deploy across x86 and Arm nodes

The following instructions are for App Developers who already have:

  • a build environment with a downloaded container tool (for example, Docker).
  • an existing container image.

The following commands use Docker, but you might be able to use other container tools to accomplish the same tasks.

Is my workload ready for Arm?

If you have an existing container image, you can check if this workload is ready to run on an Arm node. The following sections explain how to do this by using docker run to attempt to run the container with the Arm architecture.

Prepare Docker in your x86 environment to check a container image

If you are running Docker in an x86 environment, you must download additional packages to run an arm64 container image. These instructions use apt for package management, but you can use your environment's package manager to download the required packages.

If you are running Docker in an Arm environment, you can skip this section.

The following commands download packages and register QEMU as the binfmt interpreter for architectures that your machine does not support:

sudo apt-get install qemu binfmt-support qemu-user-static
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

After setting your binfmt interpreters, you can run the arm64 image in your x86 environment.

Check the workload for Arm readiness

If you are running Docker in an Arm environment, or have prepared your x86 environment for running Arm images, run the following command:

docker run --platform linux/arm64 IMAGE_NAME

Replace IMAGE_NAME with the name of the container image.

The following output indicates that your container image is ready to run on Arm nodes with your GKE cluster:

Hello from Docker!
This message shows that your installation appears to be working correctly.

If your workload is ready to run on Arm, you can proceed to Prepare an Arm workload for deployment.

The following output indicates that your image is not ready to run on Arm:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
93288797bd35: Pull complete
Digest: sha256:507ecde44b8eb741278274653120c2bf793b174c06ff4eaa672b713b3263477b
Status: Downloaded newer image for hello-world:latest
standard_init_linux.go:219: exec user process caused: exec format error

This output indicates that this is an x86_64 or amd64 image and you must build an arm64 image. Proceed to the next section, Build a multi-arch image, where you can use a non-Arm-compatible container image, a Dockerfile, and build a multi-arch image that can run across architecture types.

Build a multi-arch image

If you have a Dockerfile, you can use it to build an Arm-compatible and x86-compatible multi-arch image that you can deploy across nodes with different architecture types.

You must download Docker Buildx to complete the following steps. You must also have an existing Dockerfile.

Prepare your environment if you have an x86 VM and Arm VM

The following commands assume that you have both an Arm build VM and an x86 build VM in your build environment, and your x86 VM can SSH as root into your Arm VM. If you only have an x86 VM in your build environment, follow the instructions in the next section, Prepare your environment if you only have an x86 VM.

Prepare your environment to build multi-arch images:

  1. Create a context for the x86 node using the local socket, and a context for the Arm node using SSH:

     docker context create amd_node --docker "host=unix:///var/run/docker.sock"
     docker context create arm_node --docker "host=ssh://root@NODE_IP"
    

    Replace NODE_IP with the IP address of the Arm node.

  2. Create a builder using the x86 node:

    docker buildx create --use --name BUILDER_NAME --platform linux/amd64 amd_node
    docker buildx create --append --name BUILDER_NAME --platform linux/arm64 arm_node
    

    Replace BUILDER_NAME with a name that you choose for the Buildx builder.

Prepare your environment if you only have an x86 VM

If you only have an x86 VM in your build environment, you can follow these steps to prepare your environment to build multi-arch images. With this option, the build step might take longer.

  1. Install QEMU packages:

    docker run --rm --privileged multiarch/qemu-user-static
    
  2. Create a multi-arch builder (the default builder does not support multi-arch):

    docker buildx create --name BUILDER_NAME --use
    

    Replace BUILDER_NAME with a name that you choose for the Buildx builder.

Build the image

Now that your environment is ready, run the following command to build a multi-arch image:

docker buildx build . -t PATH_TO_REGISTRY  --platform linux/amd64,linux/arm64 --push

Replace PATH_TO_REGISTRY with the path to your registry, ending with the name of your container image and a tag (for example, gcr.io/myproject/myimage:latest).

If you get an error message at this step, refer to the Docker guide and associated documentation to troubleshoot further.

Once you have built a multi-arch image, your workload is ready to run on Arm. Proceed to Prepare an Arm workload for deployment.

What's next