Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: multiarch build by using crosscompilation #336

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/image-build-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,5 @@ jobs:
with:
context: .
push: false
# no need to explicitly set goarch,
# correct arch will be selected for each build platform
build-args: |
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to set this anymore. Default for the goarch= build-arg is empty string.

goarch=
platforms: ${{ env.BUILD_PLATFORMS }}
file: ./cmd/Dockerfile
4 changes: 0 additions & 4 deletions .github/workflows/image-push-main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ jobs:
with:
context: .
push: true
# no need to explicitly set goarch,
# correct arch will be selected for each build platform
build-args: |
goarch=
platforms: ${{ env.BUILD_PLATFORMS }}
tags: |
${{ env.IMAGE_NAME }}:latest
Expand Down
4 changes: 0 additions & 4 deletions .github/workflows/image-push-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ jobs:
with:
context: .
push: true
# no need to explicitly set goarch,
# correct arch will be selected for each build platform
build-args: |
goarch=
platforms: ${{ env.BUILD_PLATFORMS }}
tags: |
${{ steps.docker_meta.outputs.tags }}
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export GOROOT=$(BIN_DIR)/go/
export GOBIN = $(GOROOT)/bin/
export PATH := $(GOBIN):$(PATH):$(BIN_DIR)
GOPATH = $(CURDIR)/.gopath
GOARCH ?= amd64
GOARCH ?= $(shell uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
ORG_PATH = github.com/k8snetworkplumbingwg
PACKAGE = ovs-cni
OCI_BIN ?= $(shell if podman ps >/dev/null 2>&1; then echo podman; elif docker ps >/dev/null 2>&1; then echo docker; fi)
Expand Down
45 changes: 31 additions & 14 deletions cmd/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
FROM quay.io/centos/centos:stream9 as builder
FROM --platform=$BUILDPLATFORM quay.io/centos/centos:stream9 AS builder

RUN mkdir /workdir
WORKDIR /workdir
# Support overriding target GOARCH during `make docker-build`
ARG goarch=

COPY go.mod .
# these variable are automatically set during the multiarch build by docker buildx
ARG TARGETOS
ARG TARGETARCH
ENV TARGETOS=${TARGETOS:-linux}
ENV TARGETARCH=${TARGETARCH:-amd64}

ARG BUILDOS
ARG BUILDARCH
ENV BUILDOS=${BUILDOS:-linux}
ENV BUILDARCH=${BUILDARCH:-amd64}

ENV GOOS=${TARGETOS}
ENV GOARCH=${goarch:-$TARGETARCH}
ENV CGO_ENABLED=0
ENV GOFLAGS=-mod=vendor

WORKDIR /workdir

RUN dnf install -y wget

COPY go.mod .
COPY go.sum .

RUN GO_VERSION=$(sed -En 's/^go +(.*)$/\1/p' go.mod) && \
wget https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz && \
tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz && \
rm go${GO_VERSION}.linux-amd64.tar.gz
wget https://dl.google.com/go/go${GO_VERSION}.${BUILDOS}-${BUILDARCH}.tar.gz && \
tar -C /usr/local -xzf go${GO_VERSION}.${BUILDOS}-${BUILDARCH}.tar.gz && \
rm go${GO_VERSION}.${BUILDOS}-${BUILDARCH}.tar.gz

ENV PATH /usr/local/go/bin:$PATH
ENV PATH=/usr/local/go/bin:$PATH

COPY . .
RUN go mod download
Copy link
Member

@oshoval oshoval Nov 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious, why we need this suddenly ?

Copy link
Contributor Author

@ykulazhenkov ykulazhenkov Nov 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, we copy go.mod and go.sum to download dependencies explicitly (go mod download), then we copy other code files. This optimizes image rebuilds when only source code changes, allowing Docker to use cached dependencies.
This construction is employed to prevent re-downloading the dependencies whenever possible.
This is pretty common practice. For example, kubebuilder will generate Dockerfile that use such optimization https://github.com/kubernetes-sigs/kubebuilder/blob/cbc6e383c342f1337ab37ee4aa0755957a01f9c7/pkg/plugins/golang/v4/scaffolds/internal/templates/dockerfile.go#L46


ENV GOOS linux
# Support overriding target GOARCH during `make docker-build`
ARG goarch=amd64
ENV GOARCH=$goarch
ENV CGO_ENABLED 0
ENV GOFLAGS -mod=vendor
COPY . .

RUN mkdir /workdir/bin
RUN go build -tags no_openssl -o /workdir/bin/ovs ./cmd/plugin
Expand All @@ -30,6 +45,8 @@ RUN go build -tags no_openssl -o /workdir/bin/ovs-mirror-producer ./cmd/mirror-p
RUN go build -tags no_openssl -o /workdir/bin/ovs-mirror-consumer ./cmd/mirror-consumer

FROM registry.access.redhat.com/ubi9/ubi-minimal

RUN microdnf install -y findutils

COPY --from=builder /workdir/.version /.version
COPY --from=builder /workdir/bin/* /