Skip to content

Commit 3d2a758

Browse files
authored
feat: Multi-arch image building (#805)
Signed-off-by: killianmuldoon <[email protected]> (cherry picked from commit 08d0048)
2 parents 5f35deb + c428d61 commit 3d2a758

File tree

4 files changed

+63
-22
lines changed

4 files changed

+63
-22
lines changed

Dockerfile

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
# Ensure the final image uses the correct platform
16+
ARG ARCH
17+
1518
# Build the manager binary
1619
FROM golang:1.20 as builder
1720

1821
WORKDIR /workspace
1922
# Add kubectl tool
20-
ARG TARGETPLATFORM
21-
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
22-
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/${TARGETPLATFORM}/kubectl"
23-
RUN chmod +x ./kubectl
23+
# Using the $ARCH in the name of the binary here ensures we don't get any cross-arch caching after this binary is downloaded.
24+
ARG ARCH
25+
RUN curl -L "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${ARCH}/kubectl" -o kubectl-${ARCH}
26+
RUN chmod +x ./kubectl-${ARCH}
2427

2528
# Copy the Go Modules manifests
2629
COPY go.mod go.mod
@@ -30,7 +33,6 @@ COPY go.sum go.sum
3033
RUN --mount=type=cache,target=/go/pkg/mod \
3134
go mod download -x
3235

33-
3436
# Copy the go source
3537
COPY ./ ./
3638

@@ -41,16 +43,15 @@ RUN mkdir crds && \
4143
cp -r deployment/network-operator/charts/node-feature-discovery/crds /workspace/crds/node-feature-discovery/
4244

4345
# Build
44-
ARG ARCH ?= $(shell go env GOARCH)
4546
ARG LDFLAGS
46-
ARG GO_BUILD_GC_ARGS
47-
RUN --mount=type=cache,target=/root/.cache/go-build \
48-
--mount=type=cache,target=/go/pkg/mod \
49-
CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -ldflags="${LDFLAGS}" -gcflags="${GO_BUILD_GC_ARGS}" -o manager main.go
50-
47+
ARG GCFLAGS
48+
RUN --mount=type=cache,target=/go/pkg/mod \
49+
--mount=type=cache,target=/root/.cache/go-build \
50+
CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -ldflags="${LDFLAGS}" -gcflags="${GCFLAGS}" -o manager main.go
5151

52-
FROM registry.access.redhat.com/ubi8-micro:8.8
52+
FROM --platform=linux/${ARCH} registry.access.redhat.com/ubi8-micro:8.8
5353

54+
ARG ARCH
5455
ARG BUILD_DATE
5556
ARG VERSION
5657
ARG VCS_REF
@@ -74,7 +75,7 @@ LABEL org.label-schema.vcs-url="https://github.com/Mellanox/network-operator"
7475

7576
WORKDIR /
7677
COPY --from=builder /workspace/manager .
77-
COPY --from=builder /workspace/kubectl /usr/local/bin
78+
COPY --from=builder /workspace/kubectl-${ARCH} /usr/local/bin/kubectl
7879
COPY --from=builder /workspace/crds /crds
7980

8081
COPY /webhook-schemas /webhook-schemas

Makefile

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,24 @@ VERSION?=master
3131
DATE=`date -Iseconds`
3232
COMMIT?=`git rev-parse --verify HEAD`
3333
LDFLAGS="-X github.com/Mellanox/network-operator/version.Version=$(BUILD_VERSION) -X github.com/Mellanox/network-operator/version.Commit=$(COMMIT) -X github.com/Mellanox/network-operator/version.Date=$(DATE)"
34+
GCFLAGS=""
3435
BUILD_VERSION := $(strip $(shell [ -d .git ] && git describe --always --tags --dirty))
3536
BUILD_TIMESTAMP := $(shell date -u +"%Y-%m-%dT%H:%M:%S%Z")
3637
VCS_BRANCH := $(strip $(shell git rev-parse --abbrev-ref HEAD))
3738
VCS_REF := $(strip $(shell [ -d .git ] && git rev-parse --short HEAD))
3839

3940
# Docker
4041
IMAGE_BUILDER?=docker
41-
IMAGEDIR=$(CURDIR)/images
4242
DOCKERFILE?=$(CURDIR)/Dockerfile
4343
TAG?=mellanox/network-operator
44+
REGISTRY?=docker.io
45+
IMAGE_NAME?=network-operator
46+
CONTROLLER_IMAGE=$(REGISTRY)/$(IMAGE_NAME)
4447
IMAGE_BUILD_OPTS?=
4548
BUNDLE_IMG?=network-operator-bundle:$(VERSION)
4649
# BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command
4750
BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)
51+
BUILD_ARCH= amd64 arm64
4852

4953
# USE_IMAGE_DIGESTS defines if images are resolved via tags or digests
5054
# You can enable this value if you would like to use SHA Based Digests
@@ -199,7 +203,8 @@ lint: | $(GOLANGCI_LINT) ; $(info running golangci-lint...) @ ## Run golangci-l
199203

200204
.PHONY: lint-dockerfile
201205
lint-dockerfile: $(HADOLINT) ; $(info running Dockerfile lint with hadolint...) @ ## Run hadolint
202-
$Q $(HADOLINT) Dockerfile
206+
# Ignoring warning DL3029: Do not use --platform flag with FROM
207+
$Q $(HADOLINT) --ignore DL3029 Dockerfile
203208

204209
.PHONY: lint-helm
205210
lint-helm: $(HELM) ; $(info running lint for helm charts...) @ ## Run helm lint
@@ -259,11 +264,42 @@ image: ; $(info Building Docker image...) @ ## Build container image
259264
--build-arg VCS_REF="$(VCS_REF)" \
260265
--build-arg VCS_BRANCH="$(VCS_BRANCH)" \
261266
--build-arg LDFLAGS=$(LDFLAGS) \
267+
--build-arg ARCH="$(ARCH)" \
268+
--build-arg GCFLAGS="$(GCFLAGS)" \
262269
-t $(TAG) -f $(DOCKERFILE) $(CURDIR) $(IMAGE_BUILD_OPTS)
263270

264271
image-push:
265272
$(IMAGE_BUILDER) push $(TAG)
266273

274+
# Container image
275+
.PHONY: image-build
276+
image-build: ; $(info Building Docker image...) @ ## Build container image
277+
DOCKER_BUILDKIT=1 $(IMAGE_BUILDER) build --build-arg BUILD_DATE="$(BUILD_TIMESTAMP)" \
278+
--build-arg VERSION="$(BUILD_VERSION)" \
279+
--build-arg VCS_REF="$(VCS_REF)" \
280+
--build-arg VCS_BRANCH="$(VCS_BRANCH)" \
281+
--build-arg LDFLAGS=$(LDFLAGS) \
282+
--build-arg ARCH="$(ARCH)" \
283+
--build-arg GCFLAGS="$(GCFLAGS)" \
284+
-t $(CONTROLLER_IMAGE)-$(ARCH):$(VERSION) -f $(DOCKERFILE) $(CURDIR) $(IMAGE_BUILD_OPTS)
285+
286+
image-build-%:
287+
make ARCH=$* image-build
288+
289+
.PHONY: image-build-multiarch
290+
image-build-multiarch: $(addprefix image-build-,$(BUILD_ARCH))
291+
292+
image-push-for-arch:
293+
$(IMAGE_BUILDER) push $(CONTROLLER_IMAGE)-$(ARCH):$(VERSION)
294+
295+
image-push-for-arch-%:
296+
make ARCH=$* image-push-for-arch
297+
298+
.PHONY: image-push-multiarch
299+
image-push-multiarch: $(addprefix image-push-for-arch-,$(BUILD_ARCH))
300+
$(IMAGE_BUILDER) manifest create $(CONTROLLER_IMAGE):$(VERSION) $(shell echo $(BUILD_ARCH) | sed -e "s~[^ ]*~$(CONTROLLER_IMAGE)\-&:$(VERSION)~g")
301+
$(IMAGE_BUILDER) manifest push --purge $(CONTROLLER_IMAGE):$(VERSION)
302+
267303
.PHONY: chart-build
268304
chart-build: $(HELM) ; $(info Building Helm image...) @ ## Build Helm Chart
269305
@if [ -z "$(APP_VERSION)" ]; then \

README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -447,13 +447,17 @@ Example can be found under `./example/crs/mellanox.com_v1alpha1_macvlannetwork_c
447447
A deployment example can be found under `example` folder [here](https://github.com/Mellanox/network-operator/blob/master/example/README.md).
448448
449449
## Docker image
450-
Network operator uses `alpine` base image by default. To build Network operator with
451-
another base image you need to pass `BASE_IMAGE` argument:
452-
450+
To build a container image for Network Operator use:
451+
```bash
452+
make image
453453
```
454-
docker build -t network-operator \
455-
--build-arg BASE_IMAGE=registry.access.redhat.com/ubi8/ubi-minimal:latest \
456-
.
454+
455+
To build a multi-arch image and publish to a registry use:
456+
```bash
457+
export REGISTRY=example.com/registry
458+
export IMAGE_NAME=network-operator
459+
export VERSION=v1.1.1
460+
make image-build-multiarch image-push-multiarch
457461
```
458462

459463
## Driver Containers

skaffold.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ build:
1111
docker:
1212
buildArgs:
1313
## Used for debugging. Disable inlining and optimizations in the go compiler. Passed to go build using `-gcflags`
14-
GO_BUILD_GC_ARGS: "all=-N -l"
14+
GCFLAGS: "all=-N -l"
1515
dockerfile: Dockerfile
1616
manifests:
1717
## Deploy the manager.

0 commit comments

Comments
 (0)