-
Notifications
You must be signed in to change notification settings - Fork 34
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
Enable Multi-Platform Support for kubemacpool Image Builds #441
base: main
Are you sure you want to change the base?
Enable Multi-Platform Support for kubemacpool Image Builds #441
Conversation
Hi @ashokpariya0. Thanks for your PR. PRs from untrusted users cannot be marked as trusted with I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
cc @RamLavi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ashokpariya0 , thank you for this change.
I added some comments, please take a look
Makefile
Outdated
# export PLATFORMS=linux/arm64,linux/s390x,linux/amd64 | ||
ARCH := $(shell uname -m | sed 's/x86_64/amd64/') | ||
DOCKER_BUILDER ?= kubemacpool-docker-builder | ||
KUBEMACPOOL_IMAGE_TAGGED_1 := ${REGISTRY}/${IMG}:${IMAGE_TAG} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please change KUBEMACPOOL_IMAGE_TAGGED_1
--> KUBEMACPOOL_IMAGE_TAGGED
and KUBEMACPOOL_IMAGE_TAGGED_2
--> KUBEMACPOOL_IMAGE_GIT_TAGGED
the current naming is not good, but it is still better than meaningless enumeration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change it in the appropriate commit. There should be no existence of KUBEMACPOOL_IMAGE_TAGGED_1 during any commit
$(OCI_BIN) push ${TLS_SETTING} ${REGISTRY}/${IMG}:${IMAGE_TAG} | ||
$(OCI_BIN) tag ${REGISTRY}/${IMG}:${IMAGE_TAG} ${REGISTRY}/${IMG}:${IMAGE_GIT_TAG} | ||
$(OCI_BIN) push ${TLS_SETTING} ${REGISTRY}/${IMG}:${IMAGE_GIT_TAG} | ||
ifeq ($(OCI_BIN),podman) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is there no docker counterpart?
In any case, if we don't want to support pushing with docker, we should be explicit, failing the operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this. In the existing code (https://github.com/k8snetworkplumbingwg/kubemacpool/blob/main/Makefile#L94-L98), I don't see any check to prevent pushing the image in the Docker case either. Just for clarification—docker buildx build combines both build and push into a single command, so there isn't a separate push command. This is the way it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me rephrase: in the existing code (https://github.com/k8snetworkplumbingwg/kubemacpool/blob/main/Makefile#L94-L98) you can either do docker/podman push/tag using the OCI_BIN env var.
Now however, you can only do it with podman:
ifeq ($(OCI_BIN),podman)
push,tag,etc...
endif
...
my original question is - why are you limiting it like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For building multi-platform images using docker buildx build, the build and push operations are combined into a single command, Therefore, the separate push and tag logic, which currently applies only to podman, isn't needed for docker when using buildx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
theoretically it is possible to split even for docker single arch / multi arch ?
(i see here --push
flag is used so i wonder)
https://github.com/k8snetworkplumbingwg/kubemacpool/pull/441/files#diff-8a6127c87c24bc27e5595386a152b920da0266e3b6d185a3e632cab440abf09bR10-R18
not saying we need to, first trying to understand
doing so gives advantage of more flexibility and symmetry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently it's not possible for multi arch images:
Below is the reason:
With docker buildx, the build result is stored only in the build cache by default. There are two options to handle the result, which I've already tested: --push and --load.
The --push flag pushes the built image to a container registry.
The --load flag loads the resulting image into the local Docker daemon. However, the --load option currently only supports single-platform images or simpler images. It does not work with multi-platform builds (i.e., manifest lists).
When using the --load flag with a multi-platform build, you'll encounter the following error:
docker exporter does not currently support exporting manifest lists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the explanation
theoretically for single arch, it is possible then right?
it is nice to have, as it will allow to just build instead build + push, but i am not sure it worths the effort, and all the other repos have it combined already
moreover we encourage podman over docker
it is Ram's decision here anyhow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, but with single arch we can directly use docker build , for multiplatform we need to use docker buildx build and we have to do like this
@@ -1,4 +1,21 @@ | |||
ARG BUILD_ARCH=amd64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please separate into 2 commits:
- moving repo go build to container (+1 btw)
- Adding multi arch thing..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You did so but the order of the commits is wrong.
Please separate to 2 commits. The first commit only moves the repo go build to a container, setting the ground to the main commit. The second does the main thing this PR is meant to do which is adding the multi arch
hack/build-kubemacpool-podman.sh
Outdated
@@ -0,0 +1,25 @@ | |||
#!/bin/bash | |||
|
|||
if [ -z "$ARCH" ] || [ -z "$PLATFORMS" ] || [ -z "$KUBEMACPOOL_IMAGE_TAGGED_1" ]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm missing KUBEMACPOOL_IMAGE_TAGGED_2 in the podman script. Is this intentional?
I would want both tag to be there. having both latest
and sha-specific tags allow us to be flexible picking the desired image when deployed from other operators like CNAO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, both tags are properly handled.
For multi-architecture support, we create a single manifest and tag it with both the git_sha_tag and the latest tag before pushing. This process, managed in the Makefile, ensures that both tags are properly handled.
Makefile
Outdated
container: manager | ||
$(OCI_BIN) build build/ -t ${REGISTRY}/${IMG}:${IMAGE_TAG} | ||
container: | ||
ifeq ($(OCI_BIN),podman) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer not over-complicating the Makefile with these conditions.
please call to a build-multiarch-kubemacpool
script that deals with both podman and docker cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
hack/build-kubemacpool-podman.sh
Outdated
--no-cache \ | ||
--build-arg BUILD_ARCH="$ARCH" \ | ||
--platform "$platform" \ | ||
--manifest "${KUBEMACPOOL_IMAGE_TAGGED_1}" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again what happened to KUBEMACPOOL_IMAGE_TAGGED_2 tagging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned earlier, this script creates only a single Podman manifest(this how multi-platform build works with podman), while the tagging with git_sha
is handled in the Makefile. so both tags are properly handled.
Thanks for the review Ram Please note that imo we should not merge any new PRs about cross compilation until
Even if this effort is important, we should not rush it until it is done correctly please. |
Okay, noted! I'll make the necessary updates. |
1d5d286
to
33e4a6b
Compare
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some comments (fast pass)
thanks
Makefile
Outdated
@@ -6,6 +6,16 @@ IMAGE_GIT_TAG ?= $(shell git describe --abbrev=8 --tags) | |||
IMG ?= $(REPO)/kubemacpool | |||
OCI_BIN ?= $(shell if podman ps >/dev/null 2>&1; then echo podman; elif docker ps >/dev/null 2>&1; then echo docker; fi) | |||
TLS_SETTING := $(if $(filter $(OCI_BIN),podman),--tls-verify=false,) | |||
PLATFORMS ?= linux/amd64,linux/s390x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo need to check benchmark before doing both
or best to just use the auto detect and have optional all
flag as raised on CNAO please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, Added auto detach and all flag option in latest commit.
build/Dockerfile
Outdated
FROM --platform=linux/${BUILD_ARCH} quay.io/centos/centos:stream9 AS builder | ||
RUN dnf install -y tar gzip jq && dnf clean all | ||
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/') && \ | ||
GO_VERSION=$(curl -L -s "https://go.dev/dl/?mode=json" | jq -r '.[0].version') && \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better to get go version from go.mod please
easier to maintain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
hack/build-kubemacpool-docker.sh
Outdated
|
||
IFS=',' read -r -a PLATFORM_LIST <<< "$PLATFORMS" | ||
|
||
BUILD_ARGS="--no-cache --build-arg BUILD_ARCH=$ARCH -f build/Dockerfile -t $KUBEMACPOOL_IMAGE_TAGGED -t $KUBEMACPOOL_IMAGE_GIT_TAGGED . --push" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why no cache?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
hack/build-kubemacpool-podman.sh
Outdated
|
||
for platform in "${PLATFORM_LIST[@]}"; do | ||
podman build \ | ||
--no-cache \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why no cache?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems --no-cache is recommend approach. Without --no-cache, the build is faster because it reuses previous layers. But this can sometimes cause outdated or incorrect dependencies to be used. Using --no-cache forces a fresh build, making sure all steps in the Dockerfile run again without using old layers. Since we already remove the old manifest before creating a new one, I think --no-cache is the best choice. However, I'm open to other suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imho we can omit it please and use caching, docker caching seems too fundamental to have bugs beside corner cases
we use caching so far and it is fine iiuc
speed is important (of course unless we find in the future it is buggy and then can report / workaround that)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay sure.
hack/init-buildx.sh
Outdated
if ! docker buildx > /dev/null 2>&1; then | ||
mkdir -p ~/.docker/cli-plugins | ||
BUILDX_VERSION=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | jq -r .tag_name) | ||
curl -L https://github.com/docker/buildx/releases/download/"${BUILDX_VERSION}"/buildx-"${BUILDX_VERSION}".linux-amd64 --output ~/.docker/cli-plugins/docker-buildx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it fine it has hardcoded linux-amd64
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch, fixed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, saw this on another PR of this effort (commented there)
621f919
to
44f660a
Compare
rm go${GO_VERSION}.${BUILDOS}-${BUILDARCH}.tar.gz | ||
|
||
ENV PATH=$PATH:/usr/local/go/bin | ||
COPY . . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please consider adding a RUN go mod download
before the copy, to improve layer building
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
ENV PATH=$PATH:/usr/local/go/bin | ||
COPY . . | ||
|
||
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -o build/_output/bin/manager github.com/k8snetworkplumbingwg/kubemacpool/cmd/manager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it just me or it builds remote sources which is not correct ?
i would expect something like
go build -o build/_output/bin/manager ./cmd/manager
(unless it compiles based on module name, not remote)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this is correct only,
Please check
Line 87 in f61b413
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build -o $(BIN_DIR)/manager github.com/k8snetworkplumbingwg/kubemacpool/cmd/manager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks,
imho it is better to be explicit with what we build please
./cmd/manager
EDIT - but no need in this PR if this was the case already
hack/build-kubemacpool-docker.sh
Outdated
else | ||
./hack/init-buildx.sh "$DOCKER_BUILDER" | ||
docker buildx build --platform "$PLATFORMS" $BUILD_ARGS | ||
docker buildx rm "$DOCKER_BUILDER" || true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
worth to add please redir of stderr to /dev/null, else the error would always be marked on CI spyglass (same please for all other repos where this effort was done)
(as done on hack/build-kubemacpool-podman.sh)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
44f660a
to
18f484e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please reorder the PR so that it is easier to review
$(OCI_BIN) push ${TLS_SETTING} ${REGISTRY}/${IMG}:${IMAGE_TAG} | ||
$(OCI_BIN) tag ${REGISTRY}/${IMG}:${IMAGE_TAG} ${REGISTRY}/${IMG}:${IMAGE_GIT_TAG} | ||
$(OCI_BIN) push ${TLS_SETTING} ${REGISTRY}/${IMG}:${IMAGE_GIT_TAG} | ||
ifeq ($(OCI_BIN),podman) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me rephrase: in the existing code (https://github.com/k8snetworkplumbingwg/kubemacpool/blob/main/Makefile#L94-L98) you can either do docker/podman push/tag using the OCI_BIN env var.
Now however, you can only do it with podman:
ifeq ($(OCI_BIN),podman)
push,tag,etc...
endif
...
my original question is - why are you limiting it like this?
@@ -1,4 +1,21 @@ | |||
ARG BUILD_ARCH=amd64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You did so but the order of the commits is wrong.
Please separate to 2 commits. The first commit only moves the repo go build to a container, setting the ground to the main commit. The second does the main thing this PR is meant to do which is adding the multi arch
Makefile
Outdated
# export PLATFORMS=linux/arm64,linux/s390x,linux/amd64 | ||
ARCH := $(shell uname -m | sed 's/x86_64/amd64/') | ||
DOCKER_BUILDER ?= kubemacpool-docker-builder | ||
KUBEMACPOOL_IMAGE_TAGGED_1 := ${REGISTRY}/${IMG}:${IMAGE_TAG} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change it in the appropriate commit. There should be no existence of KUBEMACPOOL_IMAGE_TAGGED_1 during any commit
18f484e
to
fa19101
Compare
…plumbingwg#440) The origin-kube-rbac-proxy image is not compatible with the s390x architecture. This change deploys an image that is multi arch supported. Signed-off-by: Ashok Pariya <[email protected]>
These changes provide multi-platform build support for the Kubemacpool CNI, enabling builds for Docker and Podman container runtimes. Signed-off-by: Ashok Pariya [email protected]
fa19101
to
bc8283b
Compare
These changes enable building and pushing kubemacpool container images for multiple platforms (amd64, s390x, arm64) from a single Dockerfile. Enhanced multi-platform support in the build process by adding a PLATFORMS argument in the Makefile for amd64, s390x, and arm64 architectures. Multi-platform build support is provided for both Docker and Podman container runtimes.
What this PR does / why we need it:
The upstream kubemacpool image (link) currently supports only the amd64 architecture. The proposed changes in this PR enable multi-platform support for the kubemacpool image, broadening its compatibility to include additional architectures.
Special notes for your reviewer:
Multiplatform Build Instruction: https://gist.github.com/ashokpariya0/33cf22401d17153b7f91b40295397ccd
Multi-platform build support is enabled for both Docker and Podman container runtimes, and the necessary changes have been made accordingly.
The PLATFORMS variable defines the target platforms for building the manager image, allowing support for multiple architectures.
To use this feature, you need to:
For Docker:
Have access to docker buildx. More information: [Docker Buildx Documentation](https://docs.docker.com/build/building/multi-platform/)
Ensure that BuildKit is enabled. More information: [Docker BuildKit Enhancements](https://docs.docker.com/develop/develop-images/build_enhancements/)
For Podman:
No additional dependencies are required to build multi-platform images. Podman supports this feature natively.
Release note: