Skip to content

Commit

Permalink
Build manager on the host
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
swiatekm committed Oct 30, 2023
1 parent 55c5673 commit 0df10e6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 54 deletions.
31 changes: 16 additions & 15 deletions .github/workflows/publish-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ on:

workflow_dispatch:

env:
PLATFORMS: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le

jobs:
publish:
name: Publish container images
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v4
with:
go-version: '~1.21.3'

- name: Unshallow
run: git fetch --prune --unshallow

Expand All @@ -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
Expand Down Expand Up @@ -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
42 changes: 6 additions & 36 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 0df10e6

Please sign in to comment.