Skip to content

feat: build multi-arch (amd64/arm64) images and publish both tags in a single buildx#745

Open
Yetkin Timocin (ytimocin) wants to merge 1 commit into
kubefleet-dev:mainfrom
ytimocin:feat/multi-arch-images
Open

feat: build multi-arch (amd64/arm64) images and publish both tags in a single buildx#745
Yetkin Timocin (ytimocin) wants to merge 1 commit into
kubefleet-dev:mainfrom
ytimocin:feat/multi-arch-images

Conversation

@ytimocin

Copy link
Copy Markdown
Collaborator

What

Make the hub-agent, member-agent, and refresh-token images multi-arch (linux/amd64 + linux/arm64) and collapse the image publish path into a single dual-tag docker buildx build, removing the separate docker buildx imagetools create retag step.

Addresses two Phase 1 items from #693:

  • Add linux/arm64 to make push.
  • Replace the imagetools create retag with a single dual-tag buildx invocation.

Changes

Makefile

  • Add PLATFORMS (defaults to the host platform so local single-arch builds — e.g. loading into kind — keep working) and RELEASE_PLATFORMS (linux/amd64,linux/arm64); make push now builds a multi-arch manifest.
  • New setup-qemu target registers QEMU emulation for any multi-platform build regardless of whether the buildx builder already exists. The previous recipe registered QEMU only inside the builder-creation branch, so on a runner where the builder already existed emulation was skipped and the foreign-arch build failed with exec format error. Single-platform builds skip QEMU (native, not needed).
  • IMAGE_EXTRA_TAG adds an additional tag within the same buildx invocation, so a stable release publishes both the full and short tags from one build.

Dockerfiles (docker/*.Dockerfile)

  • Use BuildKit-provided TARGETOS/TARGETARCH for per-arch native builds. CGO_ENABLED=1 + GOEXPERIMENT=systemcrypto links against the target architecture's OpenSSL, so pure cross-compilation isn't possible — each arch is built natively under emulation.
  • Add # syntax=docker/dockerfile:1 and COPY --link.
  • Use package-path go build (e.g. ./cmd/hubagent/) so a future second source file in a package isn't silently dropped.
  • The pinned distroless base digest is a multi-arch image index, so BuildKit resolves the matching base layer per target arch.

release.yml

  • A single dual-tag make push replaces the old make push + imagetools create retag. Stable releases publish both vX.Y.Z and the short X.Y.Z; RC tags publish only the full form (the short-tag namespace stays reserved for stable releases consumers pin to).
  • The verify step now asserts each published tag is a real multi-arch manifest (via imagetools inspect) instead of only echoing tag strings.

Testing

  • Dry-runs confirm make push IMAGE_EXTRA_TAG=<v> forwards through the recursive make and emits two --tag flags per image; single-platform default emits one.
  • End-to-end build of refresh-token to a local registry: one buildx push produced both tags at the same digest, each a manifest list containing linux/amd64 + linux/arm64; the verify-step logic passed.
  • All three cmd main packages compile via the package-path form.
  • Confirmed the distroless base digest resolves to a multi-arch index.

…a single buildx

Make the hub-agent, member-agent, and refresh-token images multi-arch
(linux/amd64 + linux/arm64) and collapse the publish path into a single
dual-tag `docker buildx build`, removing the separate `imagetools create`
retag step.

- Makefile: add PLATFORMS / RELEASE_PLATFORMS; `push` now builds a
  multi-arch manifest. New `setup-qemu` target registers QEMU emulation
  for any multi-platform build regardless of whether the buildx builder
  already exists (the old recipe registered it only when creating the
  builder, so a pre-existing builder silently skipped emulation and the
  foreign-arch build failed with "exec format error"). IMAGE_EXTRA_TAG
  publishes the short alias within the same buildx push.
- Dockerfiles: rely on BuildKit-provided TARGETOS/TARGETARCH for per-arch
  native builds (CGO + GOEXPERIMENT=systemcrypto links against the target
  arch's OpenSSL, so cross-compilation is not possible); add
  `# syntax=docker/dockerfile:1`, `COPY --link`, and package-path
  `go build` so a future second source file is not silently dropped.
- release.yml: a single dual-tag `make push` replaces the imagetools
  retag (stable releases publish both vX.Y.Z and the short X.Y.Z; RC tags
  publish only the full form). The verify step now asserts each published
  tag is a real multi-arch manifest instead of only echoing tag strings.

Part of kubefleet-dev#693 (Phase 1: add linux/arm64 to make push; replace the
imagetools create retag with a single dual-tag buildx invocation).

Signed-off-by: Yetkin Timocin <ytimocin@microsoft.com>
@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant