From 9c1b3fbebe870e18d811e12f69258c12dd3e8b9f Mon Sep 17 00:00:00 2001 From: Paul Bastide Date: Wed, 24 Jul 2024 11:34:02 -0400 Subject: [PATCH] Adds support for multi platform support - Add linux/ppc64le,linux/s390x - Switch to distroless - Add support for podman Signed-off-by: Paul Bastide --- Makefile | 73 ++++++++++--------------------------- build/controller/Dockerfile | 8 ++-- build/scheduler/Dockerfile | 8 ++-- hack/build-images.sh | 46 +++++++++++++---------- 4 files changed, 52 insertions(+), 83 deletions(-) diff --git a/Makefile b/Makefile index fdcf5ce4b..1d74d75f9 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARCHS = amd64 arm64 COMMONENVVAR=GOOS=$(shell uname -s | tr A-Z a-z) BUILDENVVAR=CGO_ENABLED=0 INTEGTESTENVVAR=SCHED_PLUGINS_TEST_VERBOSE=1 +# Manage platform and builders +PLATFORMS ?= linux/amd64,linux/arm64,linux/s390x,linux/ppc64le +BUILDER ?= docker +ifeq ($(BUILDER),podman) + ALL_FLAG=--all +else + ALL_FLAG= +endif + # RELEASE_REGISTRY is the container registry to push # into. The default is to push to the staging # registry, not production(registry.k8s.io). @@ -25,6 +33,7 @@ RELEASE_VERSION?=v$(shell date +%Y%m%d)-$(shell git describe --tags --match "v*" RELEASE_IMAGE:=kube-scheduler:$(RELEASE_VERSION) RELEASE_CONTROLLER_IMAGE:=controller:$(RELEASE_VERSION) GO_BASE_IMAGE?=golang +DISTROLESS_BASE_IMAGE?=gcr.io/distroless/static:nonroot # VERSION is the scheduler's version # @@ -40,77 +49,35 @@ all: build .PHONY: build build: build-controller build-scheduler -.PHONY: build.amd64 -build.amd64: build-controller.amd64 build-scheduler.amd64 - -.PHONY: build.arm64v8 -build.arm64v8: build-controller.arm64v8 build-scheduler.arm64v8 - .PHONY: build-controller build-controller: $(COMMONENVVAR) $(BUILDENVVAR) go build -ldflags '-w' -o bin/controller cmd/controller/controller.go -.PHONY: build-controller.amd64 -build-controller.amd64: - $(COMMONENVVAR) $(BUILDENVVAR) GOARCH=amd64 go build -ldflags '-w' -o bin/controller cmd/controller/controller.go - -.PHONY: build-controller.arm64v8 -build-controller.arm64v8: - $(COMMONENVVAR) $(BUILDENVVAR) GOARCH=arm64 go build -ldflags '-w' -o bin/controller cmd/controller/controller.go - .PHONY: build-scheduler build-scheduler: $(COMMONENVVAR) $(BUILDENVVAR) go build -ldflags '-X k8s.io/component-base/version.gitVersion=$(VERSION) -w' -o bin/kube-scheduler cmd/scheduler/main.go -.PHONY: build-scheduler.amd64 -build-scheduler.amd64: - $(COMMONENVVAR) $(BUILDENVVAR) GOARCH=amd64 go build -ldflags '-X k8s.io/component-base/version.gitVersion=$(VERSION) -w' -o bin/kube-scheduler cmd/scheduler/main.go - -.PHONY: build-scheduler.arm64v8 -build-scheduler.arm64v8: - $(COMMONENVVAR) $(BUILDENVVAR) GOARCH=arm64 go build -ldflags '-X k8s.io/component-base/version.gitVersion=$(VERSION) -w' -o bin/kube-scheduler cmd/scheduler/main.go - .PHONY: local-image local-image: clean RELEASE_VERSION=$(RELEASE_VERSION) hack/build-images.sh -.PHONY: release-image.amd64 -release-image.amd64: clean - ARCH="amd64" \ - RELEASE_VERSION=$(RELEASE_VERSION) \ - REGISTRY=$(RELEASE_REGISTRY) \ - IMAGE=$(RELEASE_IMAGE)-amd64 \ - CONTROLLER_IMAGE=$(RELEASE_CONTROLLER_IMAGE)-amd64 \ - GO_BASE_IMAGE=$(GO_BASE_IMAGE) \ - ALPINE_BASE_IMAGE=$(ALPINE_BASE_IMAGE) \ - hack/build-images.sh - -.PHONY: release-image.arm64v8 -release-image.arm64v8: clean - ARCH="arm64" \ +.PHONY: release-image +release-image: + BUILDER=$(BUILDER) \ + PLATFORMS=$(PLATFORMS) \ RELEASE_VERSION=$(RELEASE_VERSION) \ REGISTRY=$(RELEASE_REGISTRY) \ - IMAGE=$(RELEASE_IMAGE)-arm64 \ - CONTROLLER_IMAGE=$(RELEASE_CONTROLLER_IMAGE)-arm64 \ + IMAGE=$(RELEASE_IMAGE) \ + CONTROLLER_IMAGE=$(RELEASE_CONTROLLER_IMAGE) \ GO_BASE_IMAGE=$(GO_BASE_IMAGE) \ - ALPINE_BASE_IMAGE=$(ALPINE_BASE_IMAGE) \ + DISTROLESS_BASE_IMAGE=$(DISTROLESS_BASE_IMAGE) \ hack/build-images.sh .PHONY: push-release-images -push-release-images: release-image.amd64 release-image.arm64v8 +push-release-images: release-image gcloud auth configure-docker - for arch in $(ARCHS); do \ - docker push $(RELEASE_REGISTRY)/$(RELEASE_IMAGE)-$${arch} ;\ - docker push $(RELEASE_REGISTRY)/$(RELEASE_CONTROLLER_IMAGE)-$${arch} ;\ - done - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create $(RELEASE_REGISTRY)/$(RELEASE_IMAGE) $(addprefix --amend $(RELEASE_REGISTRY)/$(RELEASE_IMAGE)-, $(ARCHS)) - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create $(RELEASE_REGISTRY)/$(RELEASE_CONTROLLER_IMAGE) $(addprefix --amend $(RELEASE_REGISTRY)/$(RELEASE_CONTROLLER_IMAGE)-, $(ARCHS)) - for arch in $(ARCHS); do \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest annotate --arch $${arch} $(RELEASE_REGISTRY)/$(RELEASE_IMAGE) $(RELEASE_REGISTRY)/$(RELEASE_IMAGE)-$${arch} ;\ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest annotate --arch $${arch} $(RELEASE_REGISTRY)/$(RELEASE_CONTROLLER_IMAGE) $(RELEASE_REGISTRY)/$(RELEASE_CONTROLLER_IMAGE)-$${arch} ;\ - done - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push $(RELEASE_REGISTRY)/$(RELEASE_IMAGE) ;\ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push $(RELEASE_REGISTRY)/$(RELEASE_CONTROLLER_IMAGE) ;\ + DOCKER_CLI_EXPERIMENTAL=enabled $(BUILDER) manifest push $(ALL_FLAG) $(RELEASE_REGISTRY)/$(RELEASE_IMAGE) ;\ + DOCKER_CLI_EXPERIMENTAL=enabled $(BUILDER) manifest push $(ALL_FLAG) $(RELEASE_REGISTRY)/$(RELEASE_CONTROLLER_IMAGE) ;\ .PHONY: update-vendor update-vendor: diff --git a/build/controller/Dockerfile b/build/controller/Dockerfile index bd2b5c0ea..950a47b35 100644 --- a/build/controller/Dockerfile +++ b/build/controller/Dockerfile @@ -11,17 +11,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -ARG ARCH ARG GO_BASE_IMAGE=golang -ARG ALPINE_BASE_IMAGE=$ARCH/alpine +ARG DISTROLESS_BASE_IMAGE=gcr.io/distroless/static:nonroot FROM $GO_BASE_IMAGE:1.21 WORKDIR /go/src/sigs.k8s.io/scheduler-plugins COPY . . -ARG ARCH -RUN make build-controller.$ARCH +RUN make build-controller -FROM $ALPINE_BASE_IMAGE:3.16 +FROM $DISTROLESS_BASE_IMAGE COPY --from=0 /go/src/sigs.k8s.io/scheduler-plugins/bin/controller /bin/controller diff --git a/build/scheduler/Dockerfile b/build/scheduler/Dockerfile index 40766c817..d4ca6e986 100644 --- a/build/scheduler/Dockerfile +++ b/build/scheduler/Dockerfile @@ -11,18 +11,16 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -ARG ARCH ARG GO_BASE_IMAGE=golang -ARG ALPINE_BASE_IMAGE=$ARCH/alpine +ARG DISTROLESS_BASE_IMAGE=gcr.io/distroless/static:nonroot FROM $GO_BASE_IMAGE:1.21 WORKDIR /go/src/sigs.k8s.io/scheduler-plugins COPY . . -ARG ARCH ARG RELEASE_VERSION -RUN RELEASE_VERSION=${RELEASE_VERSION} make build-scheduler.$ARCH +RUN RELEASE_VERSION=${RELEASE_VERSION} make build-scheduler -FROM $ALPINE_BASE_IMAGE:3.16 +FROM $DISTROLESS_BASE_IMAGE COPY --from=0 /go/src/sigs.k8s.io/scheduler-plugins/bin/kube-scheduler /bin/kube-scheduler diff --git a/hack/build-images.sh b/hack/build-images.sh index 9b2588e01..4bb621eae 100755 --- a/hack/build-images.sh +++ b/hack/build-images.sh @@ -26,35 +26,41 @@ CONTROLLER_DIR="${SCRIPT_ROOT}"/build/controller REGISTRY=${REGISTRY:-"localhost:5000/scheduler-plugins"} IMAGE=${IMAGE:-"kube-scheduler:latest"} CONTROLLER_IMAGE=${CONTROLLER_IMAGE:-"controller:latest"} + RELEASE_VERSION=${RELEASE_VERSION:-"v0.0.0"} BUILDER=${BUILDER:-"docker"} +GO_BASE_IMAGE=${GO_BASE_IMAGE:-"golang"} +DISTROLESS_BASE_IMAGE=${DISTROLESS_BASE_IMAGE:-"gcr.io/distroless/static:nonroot"} + +# -t is the Docker engine default +TAG_FLAG="-t" + +# nerdctl doesn't seem to have buildx if ! command -v ${BUILDER} && command -v nerdctl >/dev/null; then BUILDER=nerdctl fi -ARCH=${ARCH:-$(go env GOARCH)} -if [[ "${ARCH}" == "arm64" ]]; then - ARCH="arm64v8" +# podman needs the manifest flag in order to create a single image. +if [[ "${BUILDER}" == "podman" ]] +then + TAG_FLAG="--manifest" fi -GO_BASE_IMAGE=${GO_BASE_IMAGE:-"golang"} -ALPINE_BASE_IMAGE=${ALPINE_BASE_IMAGE:-"$ARCH/alpine"} - cd "${SCRIPT_ROOT}" +${BUILDER} buildx build \ + --platform=${PLATFORMS} \ + -f ${SCHEDULER_DIR}/Dockerfile \ + --build-arg RELEASE_VERSION=${RELEASE_VERSION} \ + --build-arg GO_BASE_IMAGE=${GO_BASE_IMAGE} \ + --build-arg DISTROLESS_BASE_IMAGE=${DISTROLESS_BASE_IMAGE} \ + ${TAG_FLAG} ${REGISTRY}/${IMAGE} . -${BUILDER} build \ - -f ${SCHEDULER_DIR}/Dockerfile \ - --build-arg ARCH=${ARCH} \ - --build-arg RELEASE_VERSION=${RELEASE_VERSION} \ - --build-arg GO_BASE_IMAGE=${GO_BASE_IMAGE} \ - --build-arg ALPINE_BASE_IMAGE=${ALPINE_BASE_IMAGE} \ - -t ${REGISTRY}/${IMAGE} . -${BUILDER} build \ - -f ${CONTROLLER_DIR}/Dockerfile \ - --build-arg ARCH=${ARCH} \ - --build-arg RELEASE_VERSION=${RELEASE_VERSION} \ - --build-arg GO_BASE_IMAGE=${GO_BASE_IMAGE} \ - --build-arg ALPINE_BASE_IMAGE=${ALPINE_BASE_IMAGE} \ - -t ${REGISTRY}/${CONTROLLER_IMAGE} . +${BUILDER} buildx build \ + --platform=${PLATFORMS} \ + -f ${CONTROLLER_DIR}/Dockerfile \ + --build-arg RELEASE_VERSION=${RELEASE_VERSION} \ + --build-arg GO_BASE_IMAGE=${GO_BASE_IMAGE} \ + --build-arg DISTROLESS_BASE_IMAGE=${DISTROLESS_BASE_IMAGE} \ + ${TAG_FLAG} ${REGISTRY}/${CONTROLLER_IMAGE} .