Skip to content

Commit 446b8ed

Browse files
committed
Support multi-arch images with docker-buildx
1 parent 5c086c8 commit 446b8ed

File tree

4 files changed

+71
-54
lines changed

4 files changed

+71
-54
lines changed

Dockerfile.controller

+12-15
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
ARG GOLANG_VERSION=1.22.2
2-
FROM nvidia/cuda:12.4.1-base-ubuntu22.04 as build
1+
ARG CUDA_VERSION=12.4.1
2+
ARG BASE_DIST=ubi8
3+
FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${BASE_DIST} AS build
34

4-
RUN apt-get update && \
5-
apt-get install -y wget make git gcc \
6-
&& \
7-
rm -rf /var/lib/apt/lists/*
5+
ARG GOLANG_VERSION=1.22.2
6+
RUN yum install -y wget make git gcc
87

9-
ARG GOLANG_VERSION=x.x.x
10-
#TODO: Remove arch discovery
118
RUN set -eux; \
129
\
1310
arch="$(uname -m)"; \
@@ -17,7 +14,7 @@ RUN set -eux; \
1714
aarch64) ARCH='arm64' ;; \
1815
*) echo "unsupported architecture" ; exit 1 ;; \
1916
esac; \
20-
wget -nv -O - https://storage.googleapis.com/golang/go1.22.2.linux-amd64.tar.gz \
17+
wget -nv -O - https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-${ARCH}.tar.gz \
2118
| tar -C /usr/local -xz
2219

2320
ENV GOPATH /go
@@ -43,11 +40,12 @@ COPY internal/controller/instaslice_controller.go internal/controller/instaslice
4340
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
4441
RUN go build -o bin/manager cmd/controller/main.go
4542

46-
FROM nvidia/cuda:12.4.1-base-ubuntu22.04
43+
ARG CUDA_VERSION=12.4.1
44+
ARG BASE_DIST=ubi8
45+
FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${BASE_DIST}
4746

4847
# Remove CUDA libs(compat etc) in favor of libs installed by the NVIDIA driver
49-
RUN rm -f cuda-*.deb
50-
RUN apt-get --purge -y autoremove cuda-*
48+
RUN dnf remove -y cuda-*
5149

5250
ENV NVIDIA_DISABLE_REQUIRE="true"
5351
ENV NVIDIA_VISIBLE_DEVICES=all
@@ -60,9 +58,8 @@ COPY --from=build /workspace/bin/manager .
6058
# Install / upgrade packages here that are required to resolve CVEs
6159
ARG CVE_UPDATES
6260
RUN if [ -n "${CVE_UPDATES}" ]; then \
63-
rm -f /etc/apt/sources.list.d/cuda.list && \
64-
apt-get update && apt-get upgrade -y ${CVE_UPDATES} && \
65-
rm -rf /var/lib/apt/lists/*; \
61+
yum update -y ${CVE_UPDATES} && \
62+
rm -rf /var/cache/yum/*; \
6663
fi
6764

6865
ENTRYPOINT ["/manager"]

Dockerfile.daemonset

+12-16
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
ARG GOLANG_VERSION=1.22.2
2-
FROM nvidia/cuda:12.4.1-base-ubuntu22.04 as build
1+
ARG CUDA_VERSION=12.4.1
2+
ARG BASE_DIST=ubi8
3+
FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${BASE_DIST} AS build
34

4-
RUN apt-get update && \
5-
apt-get install -y wget make git gcc \
6-
&& \
7-
rm -rf /var/lib/apt/lists/*
5+
ARG GOLANG_VERSION=1.22.2
6+
RUN yum install -y wget make git gcc
87

9-
ARG GOLANG_VERSION=x.x.x
10-
#TODO: Remove arch discovery
118
RUN set -eux; \
129
\
1310
arch="$(uname -m)"; \
@@ -17,7 +14,7 @@ RUN set -eux; \
1714
aarch64) ARCH='arm64' ;; \
1815
*) echo "unsupported architecture" ; exit 1 ;; \
1916
esac; \
20-
wget -nv -O - https://storage.googleapis.com/golang/go1.22.2.linux-amd64.tar.gz \
17+
wget -nv -O - https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-${ARCH}.tar.gz \
2118
| tar -C /usr/local -xz
2219

2320
ENV GOPATH /go
@@ -43,27 +40,26 @@ COPY internal/controller/instaslice_daemonset.go internal/controller/instaslice_
4340
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
4441
RUN go build -o bin/daemonset cmd/daemonset/main.go
4542

46-
FROM nvidia/cuda:12.4.1-base-ubuntu22.04
43+
ARG CUDA_VERSION=12.4.1
44+
ARG BASE_DIST=ubi8
45+
FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${BASE_DIST}
4746

4847
# Remove CUDA libs(compat etc) in favor of libs installed by the NVIDIA driver
49-
RUN rm -f cuda-*.deb
50-
RUN apt-get --purge -y autoremove cuda-*
48+
RUN dnf remove -y cuda-*
5149

5250
ENV NVIDIA_DISABLE_REQUIRE="true"
5351
ENV NVIDIA_VISIBLE_DEVICES=all
5452
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
5553

56-
5754
WORKDIR /
5855

5956
COPY --from=build /workspace/bin/daemonset .
6057

6158
# Install / upgrade packages here that are required to resolve CVEs
6259
ARG CVE_UPDATES
6360
RUN if [ -n "${CVE_UPDATES}" ]; then \
64-
rm -f /etc/apt/sources.list.d/cuda.list && \
65-
apt-get update && apt-get upgrade -y ${CVE_UPDATES} && \
66-
rm -rf /var/lib/apt/lists/*; \
61+
yum update -y ${CVE_UPDATES} && \
62+
rm -rf /var/cache/yum/*; \
6763
fi
6864

6965
ENTRYPOINT ["/daemonset"]

Makefile

+26-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Image URL to use all building/pushing image targets
22
IMG ?= asm582/instaslicev2-controller:latest
33
IMG_DMST ?= asm582/instaslicev2-daemonset:latest
4+
45
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
56
ENVTEST_K8S_VERSION = 1.29.0
67

@@ -17,6 +18,13 @@ endif
1718
# tools. (i.e. podman)
1819
CONTAINER_TOOL ?= docker
1920

21+
ifeq ($(CONTAINER_TOOL),podman)
22+
MULTI_ARCH_OPTION=--manifest
23+
else
24+
MULTI_ARCH_OPTION=--push --provenance=false --tag
25+
endif
26+
27+
2028
# Setting SHELL to bash allows bash commands to be executed by recipes.
2129
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
2230
SHELL = /usr/bin/env bash -o pipefail
@@ -93,11 +101,11 @@ build: manifests generate fmt vet ## Build manager binary.
93101
go build -o bin/daemonset cmd/daemonset/main.go
94102
.PHONY: run-controller
95103
run-controller: manifests generate fmt vet ## Run a controller from your host.
96-
sudo -E go run ./cmd/controller/main.go
104+
sudo -E go run ./cmd/controller/main.go
97105

98106
.PHONY: run-daemonset
99107
run-daemonset: manifests generate fmt vet ## Run a controller from your host.
100-
sudo -E go run ./cmd/daemonset/main.go
108+
sudo -E go run ./cmd/daemonset/main.go
101109

102110
# If you wish to build the manager image targeting other platforms you can use the --platform flag.
103111
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
@@ -113,21 +121,23 @@ docker-push: ## Push docker image with the manager.
113121
$(CONTAINER_TOOL) push ${IMG_DMST}
114122

115123
# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple
116-
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
117-
# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/
118-
# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/
119-
# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
120-
# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option.
121-
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
124+
# architectures. Make sure that base image in the Dockerfile/Containerfile is itself multi-platform, and includes
125+
# the requested plaforms. Unlike "docker buildx", for multi-platform images podman requires creating a manifest.
126+
PLATFORMS ?= linux/arm64,linux/amd64
122127
.PHONY: docker-buildx
123-
docker-buildx: ## Build and push docker image for the manager for cross-platform support
124-
# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
125-
sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
126-
- $(CONTAINER_TOOL) buildx create --name project-v3-builder
127-
$(CONTAINER_TOOL) buildx use project-v3-builder
128-
- $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross .
129-
- $(CONTAINER_TOOL) buildx rm project-v3-builder
130-
rm Dockerfile.cross
128+
docker-buildx: ## Build and push docker images with multi-platform support
129+
if [ "$(CONTAINER_TOOL)" == "podman" ]; then \
130+
$(CONTAINER_TOOL) manifest rm ${IMG} || true; \
131+
$(CONTAINER_TOOL) manifest create ${IMG}; \
132+
$(CONTAINER_TOOL) manifest rm ${IMG_DMST} || true; \
133+
$(CONTAINER_TOOL) manifest create ${IMG_DMST}; \
134+
fi
135+
DOCKER_BUILDKIT=1 $(CONTAINER_TOOL) buildx build --platform=$(PLATFORMS) $(MULTI_ARCH_OPTION) ${IMG} -f Dockerfile.controller .
136+
DOCKER_BUILDKIT=1 $(CONTAINER_TOOL) buildx build --platform=$(PLATFORMS) $(MULTI_ARCH_OPTION) ${IMG_DMST} -f Dockerfile.daemonset .
137+
if [ "$(CONTAINER_TOOL)" == "podman" ]; then \
138+
$(CONTAINER_TOOL) manifest push ${IMG}; \
139+
$(CONTAINER_TOOL) manifest push ${IMG_DMST}; \
140+
fi
131141

132142
.PHONY: build-installer
133143
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.

README.md

+21-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Experimental InstaSlice works with GPU operator to create mig slices on demand.
99
### Prerequisites
1010
- [Go](https://go.dev/doc/install) v1.22.0+
1111
- [Docker](https://docs.docker.com/get-docker/) v17.03+
12+
- [Docker buildx plugin](https://github.com/docker/buildx) for building cross-platform images.
1213
- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) v1.11.3+.
1314
- Access to a [KinD](https://kind.sigs.k8s.io/docs/user/quick-start/) cluster.
1415

@@ -42,7 +43,7 @@ Experimental InstaSlice works with GPU operator to create mig slices on demand.
4243
|==================+==================================+===========+=======================|
4344
| No MIG devices found |
4445
+-----------------------------------------------------------------------------------------+
45-
46+
4647
+-----------------------------------------------------------------------------------------+
4748
| Processes: |
4849
| GPU GI CI PID Type Process name GPU Memory |
@@ -77,7 +78,7 @@ nvidia-operator-validator-kh6jf 1/1 Runnin
7778

7879
```sh
7980
(base) openstack@netsres62:~/asmalvan/instaslice2$ nvidia-smi
80-
Thu Apr 25 10:08:24 2024
81+
Thu Apr 25 10:08:24 2024
8182
+-----------------------------------------------------------------------------------------+
8283
| NVIDIA-SMI 550.54.14 Driver Version: 550.54.14 CUDA Version: 12.4 |
8384
|-----------------------------------------+------------------------+----------------------+
@@ -125,15 +126,15 @@ Thu Apr 25 10:08:24 2024
125126
| 1 10 0 3 | 12MiB / 4864MiB | 14 0 | 1 0 0 0 0 |
126127
| | 0MiB / 8191MiB | | |
127128
+------------------+----------------------------------+-----------+-----------------------+
128-
129+
129130
+-----------------------------------------------------------------------------------------+
130131
| Processes: |
131132
| GPU GI CI PID Type Process name GPU Memory |
132133
| ID ID Usage |
133134
|=========================================================================================|
134135
| No running processes found |
135136
+-----------------------------------------------------------------------------------------+
136-
(base) openstack@netsres62:~/asmalvan/instaslice2$
137+
(base) openstack@netsres62:~/asmalvan/instaslice2$
137138
```
138139

139140

@@ -239,7 +240,7 @@ Done
239240
| 1 2 0 0 | 37MiB / 19968MiB | 42 0 | 3 0 2 0 0 |
240241
| | 0MiB / 32767MiB | | |
241242
+------------------+----------------------------------+-----------+-----------------------+
242-
243+
243244
+-----------------------------------------------------------------------------------------+
244245
| Processes: |
245246
| GPU GI CI PID Type Process name GPU Memory |
@@ -285,7 +286,7 @@ kubectl delete pod cuda-vectoradd-5
285286
| 1 2 0 0 | 37MiB / 19968MiB | 42 0 | 3 0 2 0 0 |
286287
| | 0MiB / 32767MiB | | |
287288
+------------------+----------------------------------+-----------+-----------------------+
288-
289+
289290
+-----------------------------------------------------------------------------------------+
290291
| Processes: |
291292
| GPU GI CI PID Type Process name GPU Memory |
@@ -300,7 +301,20 @@ kubectl delete pod cuda-vectoradd-5
300301

301302
**All in one command**
302303

303-
make docker-build && make docker-push && make deploy
304+
make docker-build && make docker-push && make deploy
305+
306+
Cross-platform or multi-arch images can be built and pushed using
307+
`make docker-buildx`. When using Docker as your container tool, make
308+
sure to create a builder instance. Refer to
309+
[Multi-platform images](https://docs.docker.com/build/building/multi-platform/)
310+
for documentation on building mutli-platform images with Docker.
311+
312+
You can change the destination platform(s) by
313+
setting `PLATFORMS`, e.g.
314+
315+
```sh
316+
PLATFORMS=linux/arm64,linux/amd64 make docker-buildx
317+
```
304318

305319
**Build and push your image to the location specified by `IMG`:**
306320

0 commit comments

Comments
 (0)