Architectural Optimization of GitLab Runner for ARM64 Environments

The shift toward heterogeneous computing environments has fundamentally altered the landscape of Continuous Integration and Continuous Deployment (CI/CD). As organizations move away from purely x8664-centric infrastructures toward ARM64 architectures—driven by the efficiency of AWS Graviton, Oracle Cloud Ampere instances, and Apple Silicon—the necessity for native ARM64 GitLab Runners becomes paramount. Traditionally, developers relied on emulation-based workflows, such as using Docker Buildx paired with QEMU to simulate ARM64 environments on x8664 hardware. While functional, this approach introduces significant latency, often slowing build pipelines by an order of magnitude due to the overhead of instruction set translation. Native execution on ARM64 runners mitigates these performance bottlenecks, providing a direct path to high-speed, efficient, and cost-effective multi-platform container orchestration.

The Technical Impetus for Native ARM64 Execution

The decision to implement a native ARM64 runner is rarely about simple preference; it is a strategic response to the limitations of software emulation. When a CI/CD pipeline attempts to build an ARM64 image on an x86_64 host using QEMU, every CPU instruction must be translated. This translation layer consumes massive amounts of compute cycles, leading to extremely slow build times.

For engineers utilizing modern hardware like the M1 Max 14” MacBook Pro or scaling workloads on cloud providers, the transition to native ARM64 execution offers a massive productivity gain. Cloud providers like Oracle Cloud provide competitive "Always Free" tiers, such as the Ampere A1 Compute instances, which offer up to 24GB of RAM and up to 4 VCPUs. Utilizing these resources to host a dedicated ARM64 GitLab Runner allows for native speed during the docker build phase, effectively removing the emulation tax.

Provisioning and Configuration of ARM64 Runner Nodes

Establishing a reliable ARM64 runner requires a systematic approach to host OS selection, Docker installation, and GitLab Runner registration. The environmental requirements differ based on whether the host is a local machine, a virtual machine, or a cloud-based instance.

Host Environment and OS Selection

The underlying operating system serves as the foundation for the runner's stability. For ARM64 deployments, Ubuntu and Oracle Linux are frequently utilized due to their robust support for ARM architecture in cloud environments like Oracle Cloud.

  • Operating System Choice: For ARM64 runners on Oracle Cloud, Ubuntu is a primary candidate.
  • Operating System Choice: Oracle Linux is another supported option within the Oracle Cloud ecosystem.
  • Architecture Requirements: The host must be an ARM64 (aarch64) capable machine to run the runner natively.

Installation of the GitLab Runner Binary

The installation process depends heavily on the Linux distribution being utilized. GitLab provides various package formats, including .deb for Debian-based systems (like Ubuntu) and .rpm for Red Hat-based systems (like CentOS or RHEL).

For users on Debian or Ubuntu-based systems:

  1. Download the helper images: curl -LJO "https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/deb/gitlab-runner-helper-images.deb"
  2. Download the specific architecture package: curl -LJO "https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/deb/gitlab-runner_${arch}.deb
  3. Install the packages: dpkg -i gitlab-runner-helper-images.deb gitlab-runner_<arch>.deb

For users on CentOS or Red Hat Enterprise Linux (RHEL):

  1. Download the helper images: curl -LJO "https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/rpm/gitlab-runner-helper-images.rpm"
  2. Download the specific architecture package: curl -LJO "https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/rpm/gitlab-runner_${arch}.rpm"
  3. Install the packages: dnf install -y gitlab-runner-helper-images.rpm gitlab-runner_<arch>.rpm

Special considerations exist for FIPS-compliant environments on RHEL, where currently only the x86_64 architecture is supported for specific FIPS-compliant versions, though the runner continues to include necessary helper images in the package.

Configuring the Runner via config.toml

Once the runner is installed and registered with a unique tag (such as arm64), the configuration must be tuned to handle Docker-in-Docker (DinD) workloads. This is primarily managed through the /etc/gitlab-runner/config.toml file. A robust configuration for an ARM64 OCI runner using the Docker executor includes specific parameters for concurrency, session timeouts, and volume mounting.

A representative config.toml structure is detailed below:

```toml
concurrent = 1
checkinterval = 0
shutdown
timeout = 0

[sessionserver]
session
timeout = 1800

[[runners]]
name = "ARM64 OCI runner"
url = snip
id = snip
token = snip
tokenobtainedat = snip
tokenexpiresat = snip
executor = "docker"

[runners.cache]
MaxUploadedArchiveSize = 0

[runners.docker]
tlsverify = false
image = "docker:stable"
privileged = true
disable
entrypointoverwrite = false
oom
killdisable = false
disable
cache = false
volumes = ["/certs/client", "/cache"]
shm_size = 0
```

After modifying this configuration, the runner must be restarted to apply the changes:

bash systemctl restart gitlab-runner

Orchestrating Multi-Platform Builds

The ultimate goal of deploying an ARM64 runner is to facilitate multi-platform container images. This is achieved by using GitLab CI/CD pipelines that leverage specific tags to route jobs to the appropriate hardware (amd64 vs. arm64).

The Multi-Platform CI/CD Pipeline Template

To build images for both architectures, a single pipeline must contain distinct stages for building the individual architecture images and a final stage for creating the multi-platform manifest.

The following template illustrates a complete workflow:

```yaml
image: docker:latest

services:
- docker:dind

beforescript:
- docker login -u $CI
REGISTRYUSER -p $CIREGISTRYPASSWORD $CIREGISTRY

amd64-docker-build-latest:
stage: build
tags:
- amd64
script:
- docker build -t "$CIREGISTRYIMAGE:latest-amd64" .
- docker push "$CIREGISTRYIMAGE:latest-amd64"
only:
- master
- main

arm64-docker-build-latest:
stage: build
tags:
- arm64
script:
- docker build -t "$CIREGISTRYIMAGE:latest-arm64" .
- docker push "$CIREGISTRYIMAGE:latest-arm64"
only:
- master
- main

manifest-docker-build-latest:
stage: deploy
script:
- docker manifest create "$CIREGISTRYIMAGE:latest" "$CIREGISTRYIMAGE:latest-amd64" "$CIREGISTRYIMAGE:latest-arm64"
- docker manifest push "$CIREGISTRYIMAGE:latest"
only:
- master
- main
```

Analysis of the Pipeline Workflow

The pipeline is divided into three critical logical operations:

  1. The amd64 build job is routed to the x86_64 runner via the amd64 tag, producing an image suffixed with -amd64.
  2. The arm64 build job is routed to the native ARM64 runner via the arm64 tag, producing an image suffixed with -arm64.
  3. The manifest job, which can run on any compatible runner, uses the docker manifest command to create a single, unified image tag that points to both architecture-specific images. This allows users to pull $CI_REGISTRY_IMAGE:latest and have Docker automatically select the correct version based on the client's architecture.

GitLab Hosted Runners for ARM64

For organizations that prefer not to manage their own infrastructure, GitLab provides hosted runners. These runners are provided as isolated, ephemeral virtual machines (VMs) running on the Google Container-Optimized OS (COS) using the docker+machine executor.

Hosted Runner Specifications

GitLab's hosted runners are categorized by their performance tiers. For ARM64, the availability and specifications are as follows:

Runner Tag vCPUs Memory Storage
saas-linux-small-arm64 2 8 GB 30 GB
saas-linux-medium-arm64 4 16 GB (Premium/Ultimate only) 50 GB (Premium/Ultimate only)
saas-linux-large-arm64 8 100 GB (Premium/Ultimate only) 200 GB (Premium/Ultimate only)

It is important to note that untagged jobs default to the small Linux x86-64 runner. Furthermore, users utilizing Docker-in-Docker (DinD) on hosted ARM64 runners may encounter network connectivity issues, a known characteristic of the hosted ARM architecture implementation.

Technical Component: GitLab Runner Helper Images

The GitLab Runner requires specialized helper images to perform tasks such as cloning repositories, uploading artifacts, and managing caches. These images are architecture-specific.

Available Helper Image Variants

The gitlab-runner-helper images are distributed via Docker Hub and are available for various architectures and operating systems. For instance, specific tags include:

  • gitlab/gitlab-runner-helper:alpine-latest-arm64-bleeding (linux/arm64)
  • gitlab/gitlab-runner-helper:arm64-bleeding (linux/arm64)
  • gitlab/gitlab-runner-helper:ubuntu-x86_64-bleeding-pwsh
  • gitlab/gitlab-runner-helper:alpine3.21-s390x-bleeding

The availability of these images ensures that the runner's internal processes can execute efficiently on the target hardware. For example, a runner on an ARM64 host will require an ARM64-compatible helper image to avoid the performance degradation associated with emulating the runner's own management tasks.

Comparative Analysis of Runner Architectures

Understanding the differences between the x86_64 and ARM64 runner implementations is essential for optimizing pipeline throughput and resource allocation.

Feature x86_64 (AMD64) Runner ARM64 Runner
Primary Use Case Standard x86 builds ARM-native builds (Apple Silicon, Graviton, Ampere)
Performance on x86 Host Native Slow (if using QEMU/Buildx)
Performance on ARM Host Slow (if using QEMU/Buildx) Native
Hosted Runner Availability Standard (Small, Medium, Large, XL, 2XL) Limited (Small, Medium, Large)
Infrastructure Example Debian VM on local hardware Ubuntu on Oracle Cloud Ampere

Conclusion

The deployment of a GitLab Runner for ARM64 represents a critical evolution in modern DevOps practices. By transitioning from emulation-heavy workflows to native execution, engineers can drastically reduce build durations and improve the reliability of multi-platform container deployments. Whether leveraging the "Always Free" resources of Oracle Cloud's Ampere instances or utilizing GitLab's hosted ARM64 runners, the ability to execute code natively on the target architecture is the key to scalable, high-performance CI/CD. The complexity of managing multi-platform manifests is a small price to pay for the efficiency gained by avoiding the QEMU bottleneck. As the industry continues its migration toward ARM-based silicon, the proficiency in configuring and orchestrating these runners will remain a cornerstone of advanced software engineering.

Sources

  1. Multi-platform builds with GitLab CI (Part 2)
  2. Install GitLab Runner on Linux manually
  3. GitLab Runner Helper Images on Docker Hub
  4. Hosted Runners for Linux

Related Posts