From 0df10e62cc0f17c8e8f29ddf609db4907e353b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20=C5=9Awi=C4=85tek?= Date: Sat, 28 Oct 2023 13:59:57 +0200 Subject: [PATCH] Build manager on the host Instead of building the manager binary during the docker image build, instead build it on the host and copy it to the image. This massively improves the performance of cross compilation, which is much faster natively vs emulation via QEMU. --- .github/workflows/publish-images.yaml | 31 ++++++++++---------- Dockerfile | 42 ++++----------------------- Makefile | 7 +++-- 3 files changed, 26 insertions(+), 54 deletions(-) diff --git a/.github/workflows/publish-images.yaml b/.github/workflows/publish-images.yaml index 1866ad884d..e629ffba49 100644 --- a/.github/workflows/publish-images.yaml +++ b/.github/workflows/publish-images.yaml @@ -7,6 +7,9 @@ on: workflow_dispatch: +env: + PLATFORMS: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le + jobs: publish: name: Publish container images @@ -14,6 +17,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 + with: + go-version: '~1.21.3' + - name: Unshallow run: git fetch --prune --unshallow @@ -34,7 +41,15 @@ jobs: grep -v '\#' versions.txt | grep autoinstrumentation-apache-httpd | awk -F= '{print "AUTO_INSTRUMENTATION_NGINX_VERSION="$2}' >> $GITHUB_ENV echo "VERSION_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV echo "VERSION=$(git describe --tags | sed 's/^v//')" >> $GITHUB_ENV - + + - name: Build the binary for each supported architecture + run: | + for platform in $(echo $PLATFORMS | tr "," "\n"); do + arch=${platform#*/} + echo "Building manager for $arch" + make manager ARCH=$arch + done + - name: Docker meta id: docker_meta uses: docker/metadata-action@v5 @@ -86,19 +101,5 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} - build-args: | - VERSION_PKG=github.com/open-telemetry/opentelemetry-operator/internal/version - VERSION=${{ env.VERSION }} - VERSION_DATE=${{ env.VERSION_DATE }} - OTELCOL_VERSION=${{ env.OTELCOL_VERSION }} - TARGETALLOCATOR_VERSION=${{ env.TARGETALLOCATOR_VERSION }} - OPERATOR_OPAMP_BRIDGE_VERSION=${{ env.OPERATOR_OPAMP_BRIDGE_VERSION }} - AUTO_INSTRUMENTATION_JAVA_VERSION=${{ env.AUTO_INSTRUMENTATION_JAVA_VERSION }} - AUTO_INSTRUMENTATION_NODEJS_VERSION=${{ env.AUTO_INSTRUMENTATION_NODEJS_VERSION }} - AUTO_INSTRUMENTATION_PYTHON_VERSION=${{ env.AUTO_INSTRUMENTATION_PYTHON_VERSION }} - AUTO_INSTRUMENTATION_DOTNET_VERSION=${{ env.AUTO_INSTRUMENTATION_DOTNET_VERSION }} - AUTO_INSTRUMENTATION_GO_VERSION=${{ env.AUTO_INSTRUMENTATION_GO_VERSION }} - AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION=${{ env.AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION }} - AUTO_INSTRUMENTATION_NGINX_VERSION=${{ env.AUTO_INSTRUMENTATION_NGINX_VERSION }} cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache diff --git a/Dockerfile b/Dockerfile index cff812ec5c..b170b0b19d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,51 +1,21 @@ # Build the manager binary -FROM golang:1.21-alpine as builder - -WORKDIR /workspace +FROM alpine:3.18 as builder RUN apk --no-cache add ca-certificates -# Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum -# cache deps before building and copying source so that we don't need to re-download as much -# and so that source changes don't invalidate our downloaded layer -RUN go mod download - -# Copy the go source -COPY main.go main.go -COPY apis/ apis/ -COPY controllers/ controllers/ -COPY internal/ internal/ -COPY pkg/ pkg/ -COPY versions.txt versions.txt - -ARG VERSION_PKG -ARG VERSION -ARG VERSION_DATE -ARG OTELCOL_VERSION -ARG TARGETALLOCATOR_VERSION -ARG OPERATOR_OPAMP_BRIDGE_VERSION -ARG AUTO_INSTRUMENTATION_JAVA_VERSION -ARG AUTO_INSTRUMENTATION_NODEJS_VERSION -ARG AUTO_INSTRUMENTATION_PYTHON_VERSION -ARG AUTO_INSTRUMENTATION_DOTNET_VERSION -ARG AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION -ARG AUTO_INSTRUMENTATION_NGINX_VERSION -ARG AUTO_INSTRUMENTATION_GO_VERSION - -# Build -RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -ldflags="-X ${VERSION_PKG}.version=${VERSION} -X ${VERSION_PKG}.buildDate=${VERSION_DATE} -X ${VERSION_PKG}.otelCol=${OTELCOL_VERSION} -X ${VERSION_PKG}.targetAllocator=${TARGETALLOCATOR_VERSION} -X ${VERSION_PKG}.operatorOpAMPBridge=${OPERATOR_OPAMP_BRIDGE_VERSION} -X ${VERSION_PKG}.autoInstrumentationJava=${AUTO_INSTRUMENTATION_JAVA_VERSION} -X ${VERSION_PKG}.autoInstrumentationNodeJS=${AUTO_INSTRUMENTATION_NODEJS_VERSION} -X ${VERSION_PKG}.autoInstrumentationPython=${AUTO_INSTRUMENTATION_PYTHON_VERSION} -X ${VERSION_PKG}.autoInstrumentationDotNet=${AUTO_INSTRUMENTATION_DOTNET_VERSION} -X ${VERSION_PKG}.autoInstrumentationGo=${AUTO_INSTRUMENTATION_GO_VERSION} -X ${VERSION_PKG}.autoInstrumentationApacheHttpd=${AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION} -X ${VERSION_PKG}.autoInstrumentationNginx=${AUTO_INSTRUMENTATION_NGINX_VERSION}" -a -o manager main.go - ######## Start a new stage from scratch ####### FROM scratch +ARG TARGETARCH + WORKDIR / # Copy the certs from the builder COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY --from=builder /workspace/manager . +# Copy binary built on the host +COPY bin/manager_${TARGETARCH} manager + USER 65532:65532 ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile index 863009f04c..aea1fac4b2 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ test: generate fmt vet ensure-generate-is-noop envtest # Build manager binary .PHONY: manager manager: generate fmt vet - go build -o bin/manager main.go + CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(ARCH) go build -o bin/manager_${ARCH} -ldflags ${LD_FLAGS} main.go # Run against the configured Kubernetes cluster in ~/.kube/config .PHONY: run @@ -240,8 +240,9 @@ scorecard-tests: operator-sdk # Build the container image, used only for local dev purposes # buildx is used to ensure same results for arm based systems (m1/2 chips) .PHONY: container -container: - docker buildx build --load --platform linux/${ARCH} -t ${IMG} --build-arg VERSION_PKG=${VERSION_PKG} --build-arg VERSION=${VERSION} --build-arg VERSION_DATE=${VERSION_DATE} --build-arg OTELCOL_VERSION=${OTELCOL_VERSION} --build-arg TARGETALLOCATOR_VERSION=${TARGETALLOCATOR_VERSION} --build-arg OPERATOR_OPAMP_BRIDGE_VERSION=${OPERATOR_OPAMP_BRIDGE_VERSION} --build-arg AUTO_INSTRUMENTATION_JAVA_VERSION=${AUTO_INSTRUMENTATION_JAVA_VERSION} --build-arg AUTO_INSTRUMENTATION_NODEJS_VERSION=${AUTO_INSTRUMENTATION_NODEJS_VERSION} --build-arg AUTO_INSTRUMENTATION_PYTHON_VERSION=${AUTO_INSTRUMENTATION_PYTHON_VERSION} --build-arg AUTO_INSTRUMENTATION_DOTNET_VERSION=${AUTO_INSTRUMENTATION_DOTNET_VERSION} --build-arg AUTO_INSTRUMENTATION_GO_VERSION=${AUTO_INSTRUMENTATION_GO_VERSION} --build-arg AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION=${AUTO_INSTRUMENTATION_APACHE_HTTPD_VERSION} --build-arg AUTO_INSTRUMENTATION_NGINX_VERSION=${AUTO_INSTRUMENTATION_NGINX_VERSION} . +container: GOOS = linux +container: manager + docker build -t ${IMG} . # Push the container image, used only for local dev purposes .PHONY: container-push