Build ARM docker images (#4794)

Build ARM docker images in the release workflow.

# Changes:
- Add a new env key `DOCKER_MULTIARCH` and `DOCKER_PUSH`. When set, it will build multi-arch images and push them to the registry. See https://github.com/docker/buildx/issues/59 for why it must be pushed to the registry.
- Usage of `crazy-max/ghaction-docker-buildx ` is necessary as it already configured with the ability to perform cross-compilation (using QEMU) so we can just use it, instead of manually set up it.
- Usage of `buildx` now make default global arguments. (See: https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope)

# Follow-up:
- Releasing the CLI binary file in ARM architecture. The docker images resulting from these changes already build in the ARM arch. Still, we need to make another adjustment like how to retrieve those binaries and to name it correctly as part of Github Release artifacts.

Signed-off-by: Ali Ariff <ali.ariff12@gmail.com>
This commit is contained in:
Ali Ariff 2020-08-05 20:14:01 +02:00 committed by GitHub
parent f38bdf8ecc
commit 61d7dedd98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 96 additions and 46 deletions

View File

@ -37,12 +37,22 @@ jobs:
key: ${{ runner.os }}-buildx-${{ matrix.target }}-${{ env.TAG }} key: ${{ runner.os }}-buildx-${{ matrix.target }}-${{ env.TAG }}
restore-keys: | restore-keys: |
${{ runner.os }}-buildx-${{ matrix.target }}- ${{ runner.os }}-buildx-${{ matrix.target }}-
- name: Build docker images - name: Configure gcloud
# linkerd/linkerd2-action-gcloud@v1.0.1
uses: linkerd/linkerd2-action-gcloud@308c4df
with:
cloud_sdk_service_account_key: ${{ secrets.CLOUD_SDK_SERVICE_ACCOUNT_KEY }}
gcp_project: ${{ secrets.GCP_PROJECT }}
gcp_zone: ${{ secrets.GCP_ZONE }}
- name: Set up Docker Buildx
# crazy-max/ghaction-docker-buildx@v3.2.0
uses: crazy-max/ghaction-docker-buildx@552c9de
- name: Build & Push Multi Arch Images
env: env:
DOCKER_TRACE: 1 DOCKER_TRACE: 1
run: | DOCKER_MULTIARCH: 1
docker buildx create --driver docker-container --use DOCKER_PUSH: 1
bin/docker-build-${{ matrix.target }} run: bin/docker-build-${{ matrix.target }}
- name: Prune docker layers cache - name: Prune docker layers cache
# changes generate new images while the existing ones don't get removed # changes generate new images while the existing ones don't get removed
# so we manually do that to avoid bloating the cache # so we manually do that to avoid bloating the cache
@ -54,8 +64,9 @@ jobs:
env: env:
ARCHIVES: /home/runner/archives ARCHIVES: /home/runner/archives
run: | run: |
bin/docker-pull-binaries $TAG
mkdir -p $ARCHIVES mkdir -p $ARCHIVES
cp -r ./target/cli/windows/linkerd $ARCHIVES/linkerd-windows.exe cp -r $PWD/target/release/linkerd2-cli-$TAG-windows.exe $ARCHIVES/linkerd-windows.exe
# `with.path` values do not support environment variables yet, so an # `with.path` values do not support environment variables yet, so an
# absolute path is used here. # absolute path is used here.
# #
@ -67,19 +78,6 @@ jobs:
with: with:
name: image-archives name: image-archives
path: /home/runner/archives path: /home/runner/archives
- name: Configure gcloud
# linkerd/linkerd2-action-gcloud@v1.0.1
uses: linkerd/linkerd2-action-gcloud@308c4df
with:
cloud_sdk_service_account_key: ${{ secrets.CLOUD_SDK_SERVICE_ACCOUNT_KEY }}
gcp_project: ${{ secrets.GCP_PROJECT }}
gcp_zone: ${{ secrets.GCP_ZONE }}
- name: Push docker images to registry
run: |
. bin/_docker.sh
docker_push "${{ matrix.target }}" "$TAG"
docker_retag "${{ matrix.target }}" "$TAG" main
docker_push "${{ matrix.target }}" main
# todo: Keep in sync with `kind_integration.yml` # todo: Keep in sync with `kind_integration.yml`
windows_static_cli_tests: windows_static_cli_tests:
name: Static CLI tests (windows) name: Static CLI tests (windows)

View File

@ -1,19 +1,22 @@
ARG RUNTIME_IMAGE=debian:buster-20200514-slim ARG RUNTIME_IMAGE=debian:buster-20200514-slim
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies # Precompile key slow-to-build dependencies
FROM golang:1.14.2-alpine as go-deps FROM --platform=$BUILDPLATFORM golang:1.14.2-alpine as go-deps
WORKDIR /linkerd-build WORKDIR /linkerd-build
COPY go.mod go.sum ./ COPY go.mod go.sum ./
COPY bin/install-deps bin/ COPY bin/install-deps bin/
RUN go mod download RUN go mod download
RUN ./bin/install-deps ARG TARGETARCH
RUN ./bin/install-deps $TARGETARCH
FROM debian:buster-20200514-slim as fetch FROM --platform=$BUILDPLATFORM $RUNTIME_IMAGE as fetch
RUN apt-get update && apt-get install -y ca-certificates curl jq RUN apt-get update && apt-get install -y ca-certificates curl jq
WORKDIR /build WORKDIR /build
COPY bin/fetch-proxy bin/fetch-proxy COPY bin/fetch-proxy bin/fetch-proxy
COPY .proxy-version proxy-version COPY .proxy-version proxy-version
RUN (proxy=$(bin/fetch-proxy $(cat proxy-version)) && \ ARG TARGETARCH
RUN (proxy=$(bin/fetch-proxy $(cat proxy-version) $TARGETARCH) && \
mv "$proxy" linkerd2-proxy) mv "$proxy" linkerd2-proxy)
## compile proxy-identity agent ## compile proxy-identity agent
@ -22,9 +25,10 @@ WORKDIR /linkerd-build
COPY pkg/flags pkg/flags COPY pkg/flags pkg/flags
COPY pkg/tls pkg/tls COPY pkg/tls pkg/tls
COPY pkg/version pkg/version COPY pkg/version pkg/version
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly ./pkg/... ARG TARGETARCH
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -mod=readonly ./pkg/...
COPY proxy-identity proxy-identity COPY proxy-identity proxy-identity
RUN CGO_ENABLED=0 GOOS=linux go build -o /out/proxy-identity -mod=readonly -ldflags "-s -w" ./proxy-identity RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o /out/proxy-identity -mod=readonly -ldflags "-s -w" ./proxy-identity
FROM $RUNTIME_IMAGE as runtime FROM $RUNTIME_IMAGE as runtime
COPY --from=fetch /build/target/proxy/LICENSE /usr/lib/linkerd/LICENSE COPY --from=fetch /build/target/proxy/LICENSE /usr/lib/linkerd/LICENSE

View File

@ -20,6 +20,15 @@ export DOCKER_BUILDKIT=${DOCKER_BUILDKIT:-}
# buildx cache directory. Needed if DOCKER_BUILDKIT is used # buildx cache directory. Needed if DOCKER_BUILDKIT is used
export DOCKER_BUILDKIT_CACHE=${DOCKER_BUILDKIT_CACHE:-} export DOCKER_BUILDKIT_CACHE=${DOCKER_BUILDKIT_CACHE:-}
# When set together with DOCKER_BUILDKIT, it will build the multi-arch images. Currently DOCKER_PUSH is also required
export DOCKER_MULTIARCH=${DOCKER_MULTIARCH:-}
# When set together with DOCKER_MULTIARCH, it will push the multi-arch images to the registry
export DOCKER_PUSH=${DOCKER_PUSH:-}
# Default supported docker image architectures
export SUPPORTED_ARCHS=linux/amd64,linux/arm64,linux/arm/v7
docker_repo() { docker_repo() {
repo=$1 repo=$1
@ -53,10 +62,33 @@ docker_build() {
if [ -n "$DOCKER_BUILDKIT_CACHE" ]; then if [ -n "$DOCKER_BUILDKIT_CACHE" ]; then
cache_params="--cache-from type=local,src=${DOCKER_BUILDKIT_CACHE} --cache-to type=local,dest=${DOCKER_BUILDKIT_CACHE},mode=max" cache_params="--cache-from type=local,src=${DOCKER_BUILDKIT_CACHE} --cache-to type=local,dest=${DOCKER_BUILDKIT_CACHE},mode=max"
fi fi
log_debug " :; docker buildx $rootdir $cache_params --load -t $repo:$tag -f $file $*"
output_params="--load"
if [ -n "$DOCKER_MULTIARCH" ]; then
# Pushing multi-arch images to gcr.io with the same tag that already exists is not possible
# The issue is on gcr as pushing the same tag in docker hub works fine
# Related issues: https://github.com/eclipse/che/issues/16983, https://github.com/open-policy-agent/gatekeeper/issues/665
if (docker buildx imagetools inspect "$repo:$tag"); then
echo "Build skipped. Image already exists"
exit 0
fi
output_params="--platform $SUPPORTED_ARCHS"
if [ -n "$DOCKER_PUSH" ]; then
output_params+=" --push"
else
echo "Error: env DOCKER_PUSH=1 is missing"
echo "When building the multi-arch images it is required to push the images to the registry"
echo "See https://github.com/docker/buildx/issues/59 for more details"
exit 1
fi
fi
log_debug " :; docker buildx $rootdir $cache_params $output_params -t $repo:$tag -f $file $*"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
docker buildx build "$rootdir" $cache_params \ docker buildx build "$rootdir" $cache_params \
--load \ $output_params \
-t "$repo:$tag" \ -t "$repo:$tag" \
-f "$file" \ -f "$file" \
"$@" \ "$@" \

View File

@ -17,7 +17,8 @@ if [ "$version" = latest ]; then
fi fi
assetbase="https://github.com/linkerd/linkerd2-proxy/releases/download/release%2F${version}" assetbase="https://github.com/linkerd/linkerd2-proxy/releases/download/release%2F${version}"
pkgname="linkerd2-proxy-${version}-amd64" arch=${2:-amd64}
pkgname="linkerd2-proxy-${version}-${arch}"
pkgfile="${pkgname}.tar.gz" pkgfile="${pkgname}.tar.gz"
shafile="${pkgname}.txt" shafile="${pkgname}.txt"

View File

@ -7,9 +7,10 @@ set -eu
bindir=$( cd "${0%/*}" && pwd ) bindir=$( cd "${0%/*}" && pwd )
rootdir=$( cd "$bindir"/.. && pwd ) rootdir=$( cd "$bindir"/.. && pwd )
arch=${1:-amd64}
cd "$rootdir" cd "$rootdir"
CGO_ENABLED=0 GOOS=linux go install -mod=readonly \ CGO_ENABLED=0 GOOS=linux GOARCH=$arch go install -mod=readonly \
github.com/golang/protobuf/jsonpb \ github.com/golang/protobuf/jsonpb \
github.com/grpc-ecosystem/go-grpc-prometheus \ github.com/grpc-ecosystem/go-grpc-prometheus \
github.com/prometheus/client_golang/api \ github.com/prometheus/client_golang/api \

View File

@ -1,10 +1,13 @@
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies # Precompile key slow-to-build dependencies
FROM golang:1.14.2-alpine as go-deps FROM --platform=$BUILDPLATFORM golang:1.14.2-alpine as go-deps
WORKDIR /linkerd-build WORKDIR /linkerd-build
COPY go.mod go.sum ./ COPY go.mod go.sum ./
COPY bin/install-deps bin/ COPY bin/install-deps bin/
RUN go mod download RUN go mod download
RUN ./bin/install-deps ARG TARGETARCH
RUN ./bin/install-deps $TARGETARCH
## compile binaries ## compile binaries
FROM go-deps as golang FROM go-deps as golang
@ -23,14 +26,15 @@ RUN mkdir -p /out
RUN go generate -mod=readonly ./pkg/charts/static RUN go generate -mod=readonly ./pkg/charts/static
# Cache builds without version info # Cache builds without version info
ARG TARGETARCH
RUN CGO_ENABLED=0 GOOS=darwin go build -o /out/linkerd-darwin -tags prod -mod=readonly -ldflags "-s -w" ./cli RUN CGO_ENABLED=0 GOOS=darwin go build -o /out/linkerd-darwin -tags prod -mod=readonly -ldflags "-s -w" ./cli
RUN CGO_ENABLED=0 GOOS=linux go build -o /out/linkerd-linux -tags prod -mod=readonly -ldflags "-s -w" ./cli RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o /out/linkerd-linux -tags prod -mod=readonly -ldflags "-s -w" ./cli
RUN CGO_ENABLED=0 GOOS=windows go build -o /out/linkerd-windows -tags prod -mod=readonly -ldflags "-s -w" ./cli RUN CGO_ENABLED=0 GOOS=windows go build -o /out/linkerd-windows -tags prod -mod=readonly -ldflags "-s -w" ./cli
ARG LINKERD_VERSION ARG LINKERD_VERSION
ENV GO_LDFLAGS="-s -w -X github.com/linkerd/linkerd2/pkg/version.Version=${LINKERD_VERSION}" ENV GO_LDFLAGS="-s -w -X github.com/linkerd/linkerd2/pkg/version.Version=${LINKERD_VERSION}"
RUN CGO_ENABLED=0 GOOS=darwin go build -o /out/linkerd-darwin -tags prod -mod=readonly -ldflags "${GO_LDFLAGS}" ./cli RUN CGO_ENABLED=0 GOOS=darwin go build -o /out/linkerd-darwin -tags prod -mod=readonly -ldflags "${GO_LDFLAGS}" ./cli
RUN CGO_ENABLED=0 GOOS=linux go build -o /out/linkerd-linux -tags prod -mod=readonly -ldflags "${GO_LDFLAGS}" ./cli RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o /out/linkerd-linux -tags prod -mod=readonly -ldflags "${GO_LDFLAGS}" ./cli
RUN CGO_ENABLED=0 GOOS=windows go build -o /out/linkerd-windows -tags prod -mod=readonly -ldflags "${GO_LDFLAGS}" ./cli RUN CGO_ENABLED=0 GOOS=windows go build -o /out/linkerd-windows -tags prod -mod=readonly -ldflags "${GO_LDFLAGS}" ./cli
## export without sources & dependencies ## export without sources & dependencies

View File

@ -1,10 +1,13 @@
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies # Precompile key slow-to-build dependencies
FROM golang:1.14.2-alpine as go-deps FROM --platform=$BUILDPLATFORM golang:1.14.2-alpine as go-deps
WORKDIR /linkerd-build WORKDIR /linkerd-build
COPY go.mod go.sum ./ COPY go.mod go.sum ./
COPY bin/install-deps bin/ COPY bin/install-deps bin/
RUN go mod download RUN go mod download
RUN ./bin/install-deps ARG TARGETARCH
RUN ./bin/install-deps $TARGETARCH
## compile cni-plugin utility ## compile cni-plugin utility
FROM go-deps as golang FROM go-deps as golang
@ -12,7 +15,8 @@ WORKDIR /linkerd-build
COPY pkg pkg COPY pkg pkg
COPY controller controller COPY controller controller
COPY cni-plugin cni-plugin COPY cni-plugin cni-plugin
RUN CGO_ENABLED=0 GOOS=linux go build -o /go/bin/linkerd-cni -v -mod=readonly ./cni-plugin/ ARG TARGETARCH
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o /go/bin/linkerd-cni -v -mod=readonly ./cni-plugin/
FROM debian:buster-20200514-slim FROM debian:buster-20200514-slim
WORKDIR /linkerd WORKDIR /linkerd

View File

@ -1,10 +1,13 @@
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies # Precompile key slow-to-build dependencies
FROM golang:1.14.2-alpine as go-deps FROM --platform=$BUILDPLATFORM golang:1.14.2-alpine as go-deps
WORKDIR /linkerd-build WORKDIR /linkerd-build
COPY go.mod go.sum ./ COPY go.mod go.sum ./
COPY bin/install-deps bin/ COPY bin/install-deps bin/
RUN go mod download RUN go mod download
RUN ./bin/install-deps ARG TARGETARCH
RUN ./bin/install-deps $TARGETARCH
## compile controller service ## compile controller service
FROM go-deps as golang FROM go-deps as golang
@ -18,8 +21,8 @@ COPY charts/partials charts/partials
# Generate static templates # Generate static templates
# TODO: `go generate` does not honor -mod=readonly # TODO: `go generate` does not honor -mod=readonly
RUN go generate -mod=readonly ./pkg/charts/static RUN go generate -mod=readonly ./pkg/charts/static
ARG TARGETARCH
RUN CGO_ENABLED=0 GOOS=linux go build -o /out/controller -tags prod -mod=readonly -ldflags "-s -w" ./controller/cmd RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o /out/controller -tags prod -mod=readonly -ldflags "-s -w" ./controller/cmd
## package runtime ## package runtime
FROM scratch FROM scratch

View File

@ -1,13 +1,16 @@
ARG BUILDPLATFORM=linux/amd64
# Precompile key slow-to-build dependencies # Precompile key slow-to-build dependencies
FROM golang:1.14.2-alpine as go-deps FROM --platform=$BUILDPLATFORM golang:1.14.2-alpine as go-deps
WORKDIR /linkerd-build WORKDIR /linkerd-build
COPY go.mod go.sum ./ COPY go.mod go.sum ./
COPY bin/install-deps bin/ COPY bin/install-deps bin/
RUN go mod download RUN go mod download
RUN ./bin/install-deps ARG TARGETARCH
RUN ./bin/install-deps $TARGETARCH
## bundle web assets ## bundle web assets
FROM node:14-buster as webpack-bundle FROM --platform=$BUILDPLATFORM node:14-buster as webpack-bundle
RUN curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.21.1 --network-concurrency 1 RUN curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.21.1 --network-concurrency 1
ENV PATH /root/.yarn/bin:$PATH ENV PATH /root/.yarn/bin:$PATH
@ -36,8 +39,8 @@ COPY web/main.go web
COPY web/srv web/srv COPY web/srv web/srv
COPY controller controller COPY controller controller
COPY pkg pkg COPY pkg pkg
ARG TARGETARCH
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -o web/web -ldflags "-s -w" ./web RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -mod=readonly -o web/web -ldflags "-s -w" ./web
## package it all up ## package it all up
FROM debian:buster-20200514-slim FROM debian:buster-20200514-slim