From fe093a0c0eaffffdfae322f144b30746f66baea1 Mon Sep 17 00:00:00 2001 From: Ying WANG Date: Tue, 28 May 2024 11:49:37 -0600 Subject: [PATCH] Security: Make distroless image default and publish mimir-alpine --- .github/workflows/scripts/build-images.sh | 2 +- .github/workflows/test-build-deploy.yml | 14 ++--- Makefile | 54 ++++++++++++------- cmd/mimir/Dockerfile | 10 ++-- ...ockerfile.distroless => Dockerfile.alpine} | 10 ++-- 5 files changed, 52 insertions(+), 38 deletions(-) rename cmd/mimir/{Dockerfile.distroless => Dockerfile.alpine} (69%) diff --git a/.github/workflows/scripts/build-images.sh b/.github/workflows/scripts/build-images.sh index cd83cfa132b..15408c6f9fb 100755 --- a/.github/workflows/scripts/build-images.sh +++ b/.github/workflows/scripts/build-images.sh @@ -19,7 +19,7 @@ do make \ BUILD_IN_CONTAINER=false \ PUSH_MULTIARCH_TARGET="type=oci,dest=$OUTPUT/$NAME.oci" \ - PUSH_MULTIARCH_TARGET_DISTROLESS="type=oci,dest=$OUTPUT/$NAME\-distroless.oci" \ + PUSH_MULTIARCH_TARGET_ALPINE="type=oci,dest=$OUTPUT/$NAME\-alpine.oci" \ PUSH_MULTIARCH_TARGET_CONTINUOUS_TEST="type=oci,dest=$OUTPUT/$NAME\-continuous\-test.oci" \ push-multiarch-$target done diff --git a/.github/workflows/test-build-deploy.yml b/.github/workflows/test-build-deploy.yml index 104beea3817..91286a674bd 100644 --- a/.github/workflows/test-build-deploy.yml +++ b/.github/workflows/test-build-deploy.yml @@ -281,15 +281,15 @@ jobs: - name: Build Mimir with race-detector run: | # When building uptodate_race target, we create two images since - # a Dockerfile.distroless exists. The distroless image is built with - # the `-distroless` suffix. + # a Dockerfile.alpine exists. The alpine image is built with + # the `-alpine` suffix. # We build both until we have finished migrating to distroless. # We test the distroless race image in every integration test. # We test the (legacy) alpine race image when deploying (aka pushing). make BUILD_IN_CONTAINER=false cmd/mimir/.uptodate_race export IMAGE_TAG_RACE=$(make image-tag-race) - export MIMIR_DISTROLESS_IMAGE="grafana/mimir-distroless:$IMAGE_TAG_RACE" - export MIMIR_ALPINE_IMAGE="grafana/mimir:$IMAGE_TAG_RACE" + export MIMIR_DISTROLESS_IMAGE="grafana/mimir:$IMAGE_TAG_RACE" + export MIMIR_ALPINE_IMAGE="grafana/mimir-alpine:$IMAGE_TAG_RACE" docker save $MIMIR_DISTROLESS_IMAGE -o ./mimir_race_image_distroless docker save $MIMIR_ALPINE_IMAGE -o ./mimir_race_image_alpine - name: Upload archive with race-enabled Mimir @@ -355,7 +355,7 @@ jobs: run: | export IMAGE_TAG_RACE=$(make image-tag-race) docker load -i ./mimir_race_image_distroless - docker run "grafana/mimir-distroless:$IMAGE_TAG_RACE" --version + docker run "grafana/mimir:$IMAGE_TAG_RACE" --version - name: Preload Images # We download docker images used by integration tests so that all images are available # locally and the download time doesn't account in the test execution time, which is subject @@ -364,7 +364,7 @@ jobs: - name: Integration Tests run: | export IMAGE_TAG_RACE=$(make image-tag-race) - export MIMIR_IMAGE="grafana/mimir-distroless:$IMAGE_TAG_RACE" + export MIMIR_IMAGE="grafana/mimir:$IMAGE_TAG_RACE" export IMAGE_TAG=$(make image-tag) export MIMIRTOOL_IMAGE="grafana/mimirtool:$IMAGE_TAG" export MIMIR_CHECKOUT_DIR="/go/src/github.com/grafana/mimir" @@ -428,7 +428,7 @@ jobs: run: | export IMAGE_TAG_RACE=$(make image-tag-race) docker load -i ./mimir_race_image_alpine - docker run "grafana/mimir:$IMAGE_TAG_RACE" --version + docker run "grafana/mimir-alpine:$IMAGE_TAG_RACE" --version - name: Preload Images # We download docker images used by integration tests so that all images are available # locally and the download time doesn't account in the test execution time, which is subject diff --git a/Makefile b/Makefile index 8c5562b07b5..f8595fc5d23 100644 --- a/Makefile +++ b/Makefile @@ -103,11 +103,11 @@ SED ?= $(shell which gsed 2>/dev/null || which sed) --build-arg=goproxyValue=$(GOPROXY_VALUE) \ -t $(IMAGE_PREFIX)$(shell basename $(@D))-continuous-test:$(IMAGE_TAG) $(@D)/; \ fi; - if [ -f $(@D)/Dockerfile.distroless ]; then \ - $(SUDO) docker build -f $(@D)/Dockerfile.distroless \ + if [ -f $(@D)/Dockerfile.alpine ]; then \ + $(SUDO) docker build -f $(@D)/Dockerfile.alpine \ --build-arg=revision=$(GIT_REVISION) \ --build-arg=goproxyValue=$(GOPROXY_VALUE) \ - -t $(IMAGE_PREFIX)$(shell basename $(@D))-distroless:$(IMAGE_TAG) $(@D)/; \ + -t $(IMAGE_PREFIX)$(shell basename $(@D))-alpine:$(IMAGE_TAG) $(@D)/; \ fi; @echo $(SUDO) docker build --build-arg=revision=$(GIT_REVISION) --build-arg=goproxyValue=$(GOPROXY_VALUE) -t $(IMAGE_PREFIX)$(shell basename $(@D)) -t $(IMAGE_PREFIX)$(shell basename $(@D)):$(IMAGE_TAG) $(@D)/ @@ -117,7 +117,7 @@ SED ?= $(shell which gsed 2>/dev/null || which sed) @echo Image name: $(IMAGE_PREFIX)$(shell basename $(@D)) @echo Image name: $(IMAGE_PREFIX)$(shell basename $(@D)):$(IMAGE_TAG) @echo Image name: $(IMAGE_PREFIX)$(shell basename $(@D))-continuous-test:$(IMAGE_TAG) - @echo Image name: $(IMAGE_PREFIX)$(shell basename $(@D))-distroless:$(IMAGE_TAG) + @echo Image name: $(IMAGE_PREFIX)$(shell basename $(@D))-alpine:$(IMAGE_TAG) @echo @echo Please use '"make push-multiarch-build-image"' to build and push build image. @echo Please use '"make push-multiarch-mimir"' to build and push Mimir image. @@ -126,24 +126,32 @@ SED ?= $(shell which gsed 2>/dev/null || which sed) %/$(UPTODATE_RACE): GOOS=linux %/$(UPTODATE_RACE): %/Dockerfile - # Build Dockerfile.distroless if it exists, we use distroless/base-nossl-debian12 as base image since race detector needs glibc packages. - if [ -f $(@D)/Dockerfile.distroless ]; then \ - $(SUDO) docker build -f $(@D)/Dockerfile.distroless \ + # Build Dockerfile.alpine if it exists + if [ -f $(@D)/Dockerfile.alpine ]; then \ + $(SUDO) docker build -f $(@D)/Dockerfile.alpine \ --build-arg=revision=$(GIT_REVISION) \ --build-arg=goproxyValue=$(GOPROXY_VALUE) \ --build-arg=USE_BINARY_SUFFIX=true \ --build-arg=BINARY_SUFFIX=_race \ - --build-arg=BASEIMG="gcr.io/distroless/base-nossl-debian12" \ - -t $(IMAGE_PREFIX)$(shell basename $(@D))-distroless:$(IMAGE_TAG_RACE) $(@D)/; \ + --build-arg=EXTRA_PACKAGES="gcompat" \ + -t $(IMAGE_PREFIX)$(shell basename $(@D))-alpine:$(IMAGE_TAG_RACE) $(@D)/; \ fi; @echo # We need gcompat -- compatibility layer with glibc, as race-detector currently requires glibc, but Alpine uses musl libc instead. - $(SUDO) docker build --build-arg=revision=$(GIT_REVISION) --build-arg=goproxyValue=$(GOPROXY_VALUE) --build-arg=USE_BINARY_SUFFIX=true --build-arg=BINARY_SUFFIX=_race --build-arg=EXTRA_PACKAGES="gcompat" -t $(IMAGE_PREFIX)$(shell basename $(@D)):$(IMAGE_TAG_RACE) $(@D)/ + # for grafana/mimir which is based on distroless image, the EXTRA_PACKAGES is just ignored. + $(SUDO) docker build \ + --build-arg=revision=$(GIT_REVISION) \ + --build-arg=goproxyValue=$(GOPROXY_VALUE) \ + --build-arg=USE_BINARY_SUFFIX=true \ + --build-arg=BINARY_SUFFIX=_race \ + --build-arg=EXTRA_PACKAGES="gcompat" \ + --build-arg=BASEIMG="gcr.io/distroless/base-nossl-debian12" \ + -t $(IMAGE_PREFIX)$(shell basename $(@D)):$(IMAGE_TAG_RACE) $(@D)/ @echo @echo Go binaries were built using GOOS=$(GOOS) and GOARCH=$(GOARCH) @echo @echo Image name: $(IMAGE_PREFIX)$(shell basename $(@D)):$(IMAGE_TAG_RACE) - @echo Image name: $(IMAGE_PREFIX)$(shell basename $(@D))-distroless:$(IMAGE_TAG_RACE) + @echo Image name: $(IMAGE_PREFIX)$(shell basename $(@D))-alpine:$(IMAGE_TAG_RACE) @echo @touch $@ @@ -151,7 +159,7 @@ SED ?= $(shell which gsed 2>/dev/null || which sed) # Other options are documented in https://docs.docker.com/engine/reference/commandline/buildx_build/#output. # CI workflow uses PUSH_MULTIARCH_TARGET="type=oci,dest=file.oci" to store images locally for next steps in the pipeline. PUSH_MULTIARCH_TARGET ?= type=registry -PUSH_MULTIARCH_TARGET_DISTROLESS ?= type=registry +PUSH_MULTIARCH_TARGET_ALPINE ?= type=registry PUSH_MULTIARCH_TARGET_CONTINUOUS_TEST ?= type=registry # This target compiles mimir for linux/amd64 and linux/arm64 and then builds and pushes a multiarch image to the target repository. @@ -164,7 +172,13 @@ push-multiarch-%/$(UPTODATE): $(MAKE) GOOS=linux GOARCH=amd64 BINARY_SUFFIX=_linux_amd64 $(DIR)/$(shell basename $(DIR)); \ $(MAKE) GOOS=linux GOARCH=arm64 BINARY_SUFFIX=_linux_arm64 $(DIR)/$(shell basename $(DIR)); \ fi - $(SUDO) docker buildx build -o $(PUSH_MULTIARCH_TARGET) --platform linux/amd64,linux/arm64 --build-arg=revision=$(GIT_REVISION) --build-arg=goproxyValue=$(GOPROXY_VALUE) --build-arg=USE_BINARY_SUFFIX=true -t $(IMAGE_PREFIX)$(shell basename $(DIR)):$(IMAGE_TAG) $(DIR)/ + $(SUDO) docker buildx build \ + -o $(PUSH_MULTIARCH_TARGET) \ + --platform linux/amd64,linux/arm64 \ + --build-arg=revision=$(GIT_REVISION) \ + --build-arg=goproxyValue=$(GOPROXY_VALUE) \ + --build-arg=USE_BINARY_SUFFIX=true \ + -t $(IMAGE_PREFIX)$(shell basename $(DIR)):$(IMAGE_TAG) $(DIR)/ # Build Dockerfile.continuous-test if [ -f $(DIR)/Dockerfile.continuous-test ]; then \ @@ -176,15 +190,15 @@ push-multiarch-%/$(UPTODATE): --build-arg=USE_BINARY_SUFFIX=true \ -t $(IMAGE_PREFIX)$(shell basename $(DIR))-continuous-test:$(IMAGE_TAG) $(DIR)/; \ fi; - # Build Dockerfile.distroless if it exists - if [ -f $(DIR)/Dockerfile.distroless ]; then \ - $(SUDO) docker buildx build -f $(DIR)/Dockerfile.distroless \ - -o $(PUSH_MULTIARCH_TARGET_DISTROLESS) \ + # Build Dockerfile.alpine if it exists + if [ -f $(DIR)/Dockerfile.alpine ]; then \ + $(SUDO) docker buildx build -f $(DIR)/Dockerfile.alpine \ + -o $(PUSH_MULTIARCH_TARGET_ALPINE) \ --platform linux/amd64,linux/arm64 \ --build-arg=revision=$(GIT_REVISION) \ --build-arg=goproxyValue=$(GOPROXY_VALUE) \ --build-arg=USE_BINARY_SUFFIX=true \ - -t $(IMAGE_PREFIX)$(shell basename $(DIR))-distroless:$(IMAGE_TAG) $(DIR)/; \ + -t $(IMAGE_PREFIX)$(shell basename $(DIR))-alpine:$(IMAGE_TAG) $(DIR)/; \ fi; push-multiarch-mimir: ## Push mimir docker image. @@ -740,8 +754,8 @@ integration-tests: ## Run all integration tests. integration-tests: cmd/mimir/$(UPTODATE) go test -tags=requires_docker,stringlabels ./integration/... -integration-tests-race: ## Run all integration tests with race-enabled Mimir-distroless docker image. -integration-tests-race: export MIMIR_IMAGE=$(IMAGE_PREFIX)mimir-distroless:$(IMAGE_TAG_RACE) +integration-tests-race: ## Run all integration tests with race-enabled distroless docker image. +integration-tests-race: export MIMIR_IMAGE=$(IMAGE_PREFIX)mimir:$(IMAGE_TAG_RACE) integration-tests-race: cmd/mimir/$(UPTODATE_RACE) go test -timeout 30m -tags=requires_docker,stringlabels ./integration/... diff --git a/cmd/mimir/Dockerfile b/cmd/mimir/Dockerfile index b7fb5013751..b096b29c5a4 100644 --- a/cmd/mimir/Dockerfile +++ b/cmd/mimir/Dockerfile @@ -1,11 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-only -# Provenance-includes-location: https://github.com/cortexproject/cortex/cmd/cortex/Dockerfile -# Provenance-includes-license: Apache-2.0 -# Provenance-includes-copyright: The Cortex Authors. +# We use different base images for mimir and mimir race images since race-detector needs glibc packages. +# See difference between distroless static and base-nossl at https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md. -FROM alpine:3.19.1 -ARG EXTRA_PACKAGES -RUN apk add --no-cache ca-certificates tzdata $EXTRA_PACKAGES +ARG BASEIMG=gcr.io/distroless/static-debian12 +FROM ${BASEIMG} # Expose TARGETOS and TARGETARCH variables. These are supported by Docker when using BuildKit, but must be "enabled" using ARG. ARG TARGETOS ARG TARGETARCH diff --git a/cmd/mimir/Dockerfile.distroless b/cmd/mimir/Dockerfile.alpine similarity index 69% rename from cmd/mimir/Dockerfile.distroless rename to cmd/mimir/Dockerfile.alpine index b096b29c5a4..b7fb5013751 100644 --- a/cmd/mimir/Dockerfile.distroless +++ b/cmd/mimir/Dockerfile.alpine @@ -1,9 +1,11 @@ # SPDX-License-Identifier: AGPL-3.0-only -# We use different base images for mimir and mimir race images since race-detector needs glibc packages. -# See difference between distroless static and base-nossl at https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md. +# Provenance-includes-location: https://github.com/cortexproject/cortex/cmd/cortex/Dockerfile +# Provenance-includes-license: Apache-2.0 +# Provenance-includes-copyright: The Cortex Authors. -ARG BASEIMG=gcr.io/distroless/static-debian12 -FROM ${BASEIMG} +FROM alpine:3.19.1 +ARG EXTRA_PACKAGES +RUN apk add --no-cache ca-certificates tzdata $EXTRA_PACKAGES # Expose TARGETOS and TARGETARCH variables. These are supported by Docker when using BuildKit, but must be "enabled" using ARG. ARG TARGETOS ARG TARGETARCH