This page looks best with JavaScript enabled

Building Multi-Arch Images with Nerdctl

1. Installing Nerdctl

  • Install Opscli
1
curl -sfL https://raw.githubusercontent.com/shaowenchen/ops/main/getcli.sh |VERSION=latest sh -
  • Install Nerdctl
1
opscli task -f install-nerdctl --arch amd64

2. BuildKit

  • Download Buildkit
1
wget https://github.com/moby/buildkit/releases/download/v0.19.0-rc2/buildkit-v0.19.0-rc2.linux-amd64.tar.gz
  • Install Buildkit
1
2
tar xvf buildkit-*.tar.gz
mv bin/* /usr/local/bin/
  • Configure Buildkitd
1
mkdir -p /etc/buildkit /data/buildkit
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
cat > /etc/buildkit/buildkitd.toml <<EOF
debug = true
root = "/data/buildkit"
[worker.oci]
  enabled = false

[worker.containerd]
  address = "/run/containerd/containerd.sock"
  enabled = true
  platforms = [ "linux/amd64", "linux/arm64" ]
  namespace = "buildkit"
  gc = true
  gckeepstorage = 9000
  cniPoolSize = 16
EOF
  • Generate the Systemd unit file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
cat > /etc/systemd/system/buildkitd.service << EOF
[Unit]
Description=buildkitd service
Documentation=https://github.com/moby/buildkit

[Service]
Environment="NYDUS_BUILDER=/usr/local/bin/nydus-image"
ExecStart=/usr/local/bin/buildkitd --config /etc/buildkit/buildkitd.toml

[Install]
WantedBy=multi-user.target
EOF
  • Start the Buildkitd service
1
2
3
systemctl enable buildkitd
systemctl start buildkitd
systemctl status buildkitd

3. Multi-Arch Configuration

  • Install Qemu
1
nerdctl run --privileged --rm tonistiigi/binfmt:master --install all
  • Inspect the Qemu configuration
1
ls -1 /proc/sys/fs/binfmt_misc/qemu*
  • Pull an image for a specific architecture
1
nerdctl pull --platform=linux/arm64 ubuntu:20.04

--all-platforms pulls images for all architectures.

  • Run a container for a specific architecture
1
nerdctl run --rm --platform=linux/arm64 ubuntu:20.04 uname -m

4. Building Images

  • Create a test Dockerfile
1
2
3
4
cat << EOF >Dockerfile
FROM ubuntu:20.04
RUN touch 123
EOF
  • Build the multi-arch image
1
nerdctl build --platform=amd64,arm64 -t registry-1.docker.io/shaowenchen/nerdctl-build:latest .
  • Inspect the image information
1
2
3
4
nerdctl images | grep nerdctl

registry-1.docker.io/shaowenchen/nerdctl-build                  latest                                                              3f2f8f7a36bd    About a minute ago    linux/amd64    77.9 MiB     26.2 MiB
registry-1.docker.io/shaowenchen/nerdctl-build                  latest                                                              3f2f8f7a36bd    About a minute ago    linux/arm64    0.0 B        24.8 MiB
  • Push the multi-arch image
1
nerdctl push --all-platforms registry-1.docker.io/shaowenchen/nerdctl-build:latest

5. Multi-Arch Variables in the Dockerfile

With the following variables you can download binaries for different architectures, avoiding the exec format error that leaves the image unable to run.

  • TARGETPLATFORM

The target platform for building the image, for example linux/amd64, linux/arm/v7, windows/amd64.

  • TARGETOS

The OS type of TARGETPLATFORM, for example linux, windows

  • TARGETARCH

The architecture type of TARGETPLATFORM, for example amd64, arm

  • TARGETVARIANT

The variant of TARGETPLATFORM; this variable may be empty, for example v7

  • BUILDPLATFORM

The host platform for building the image, for example linux/amd64

  • BUILDOS

The OS type of BUILDPLATFORM, for example linux

  • BUILDARCH

The architecture type of BUILDPLATFORM, for example amd64

  • BUILDVARIANT

The variant of BUILDPLATFORM; this variable may be empty, for example v7

How to use:

  1. Declare the ARG variables you need in the Dockerfile
  2. Reference the variables with ${TARGETARCH}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
FROM alpine:latest as builder
ARG TARGETARCH
WORKDIR /data
RUN wget https://github.com/git-lfs/git-lfs/releases/download/v3.4.0/git-lfs-linux-${TARGETARCH}-v3.4.0.tar.gz && \
    tar xvfz git-lfs-linux-${TARGETARCH}-v3.4.0.tar.gz

FROM alpine:latest
RUN apk update && \
    apk upgrade && \
    apk add --update alpine-sdk && \
    apk add --no-cache \
    git \
    openssh

COPY --from=builder /data/git-lfs-3.4.0/git-lfs /usr/local/bin/git-lfs
RUN git lfs install
WORKDIR /runtime
ENTRYPOINT ["git"]

微信公众号
WRITTEN BY
微信公众号