Skip to content

Commit dbb963e

Browse files
tstaplerbobbypage
andcommitted
Add support for building multi-arch images
Only install libipmctl for amd64 versions of the docker image. Updated ipmctl to v02.00.00.3885 to fix intel/ipmctl#169 Updated base image to alpine:1.16 from alpine:1.15 to add zfs support on "arm" architecture. Co-authored-by: David Porter <[email protected]> Signed-of-by: Tyler Stapler <[email protected]>
1 parent 24e7a98 commit dbb963e

File tree

8 files changed

+173
-73
lines changed

8 files changed

+173
-73
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
cadvisor
22
/release
33
.vscode
4+
_output/
45

56
# Log files
67
*.log

Makefile

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,6 @@ GOLANGCI_VER := v1.45.2
1717
GO_TEST ?= $(GO) test $(or $(GO_FLAGS),-race)
1818
arch ?= $(shell go env GOARCH)
1919

20-
ifeq ($(arch), amd64)
21-
Dockerfile_tag := ''
22-
else
23-
Dockerfile_tag := '.''$(arch)'
24-
endif
25-
26-
2720
all: presubmit build test
2821

2922
test:
@@ -76,7 +69,7 @@ release:
7669
@./build/release.sh
7770

7871
docker-%:
79-
@docker build -t cadvisor:$(shell git rev-parse --short HEAD) -f deploy/Dockerfile$(Dockerfile_tag) .
72+
@docker build -t cadvisor:$(shell git rev-parse --short HEAD) -f deploy/Dockerfile .
8073

8174
docker-build:
8275
@docker run --rm -w /go/src/github.com/google/cadvisor -v ${PWD}:/go/src/github.com/google/cadvisor golang:1.18 make build
@@ -99,5 +92,6 @@ lint:
9992

10093
clean:
10194
@rm -f *.test cadvisor
95+
@rm -rf _output/
10296

10397
.PHONY: all build docker format release test test-integration lint presubmit tidy

build/build.sh

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,17 @@
1616

1717
set -e
1818

19+
export GOOS=${GOOS:-$(go env GOOS)}
20+
export GOARCH=${GOARCH:-$(go env GOARCH)}
1921
GO_FLAGS=${GO_FLAGS:-"-tags netgo"} # Extra go flags to use in the build.
2022
BUILD_USER=${BUILD_USER:-"${USER}@${HOSTNAME}"}
2123
BUILD_DATE=${BUILD_DATE:-$( date +%Y%m%d-%H:%M:%S )}
2224
VERBOSE=${VERBOSE:-}
23-
GOARCH=$1
25+
OUTPUT_NAME_WITH_ARCH=${OUTPUT_NAME_WITH_ARCH:-"false"}
2426

2527
repo_path="github.com/google/cadvisor"
2628

27-
version=$( git describe --tags --dirty --abbrev=14 | sed -E 's/-([0-9]+)-g/.\1+/' )
29+
version=${VERSION:-$( git describe --tags --dirty --abbrev=14 | sed -E 's/-([0-9]+)-g/.\1+/' )}
2830
revision=$( git rev-parse --short HEAD 2> /dev/null || echo 'unknown' )
2931
branch=$( git rev-parse --abbrev-ref HEAD 2> /dev/null || echo 'unknown' )
3032
go_version=$( go version | sed -e 's/^[^0-9.]*\([0-9.]*\).*/\1/' )
@@ -50,15 +52,15 @@ if [ -n "$VERBOSE" ]; then
5052
echo "Building with -ldflags $ldflags"
5153
fi
5254

55+
mkdir -p "$PWD/_output"
56+
output_file="$PWD/_output/cadvisor"
57+
if [ "${OUTPUT_NAME_WITH_ARCH}" = "true" ] ; then
58+
output_file="${output_file}-${version}-${GOOS}-${GOARCH}"
59+
fi
60+
5361
# Since github.com/google/cadvisor/cmd is a submodule, we must build from inside that directory
54-
output_file="$PWD/cadvisor"
5562
pushd cmd > /dev/null
56-
if [ -z "$GOARCH" ]
57-
then
5863
go build ${GO_FLAGS} -ldflags "${ldflags}" -o "${output_file}" "${repo_path}/cmd"
59-
else
60-
env GOOS=linux GOARCH=$GOARCH go build ${GO_FLAGS} -ldflags "${ldflags}" -o "${output_file}" "${repo_path}/cmd"
61-
fi
6264
popd > /dev/null
6365

6466
exit 0

build/check_container.sh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2015 Google Inc. All rights reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
# Description:
17+
# This script is meant to run a basic test against each of the CPU architectures
18+
# cadvisor should support.
19+
#
20+
# This script requires that you have run qemu-user-static so that your machine
21+
# can interpret ELF binaries for other architectures using QEMU:
22+
# https://github.com/multiarch/qemu-user-static#getting-started
23+
#
24+
# $ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
25+
#
26+
# Usage:
27+
# ./check_container.sh gcr.io/tstapler-gke-dev/cadvisor:v0.44.1-test-4
28+
target_image=$1
29+
30+
# Architectures officially supported by cadvisor
31+
arches=( "amd64" "arm" "arm64" )
32+
33+
# Docker doesn't handle images with different architectures but the same tag.
34+
# Remove the container and the image use by it to avoid problems.
35+
cleanup() {
36+
echo Cleaning up the container $1
37+
docker stop $1
38+
docker rmi $target_image
39+
echo
40+
}
41+
42+
for arch in "${arches[@]}"; do
43+
echo Testing that we can run $1 on $arch and curl the /healthz endpoint
44+
echo
45+
container_id=$(docker run --platform "linux/$arch" -p 8080:8080 --rm --detach "$target_image")
46+
docker_exit_code=$?
47+
if [ $docker_exit_code -ne 0 ]; then
48+
echo Failed to run container docker exited with $docker_exit_code
49+
cleanup $container_id
50+
exit $docker_exit_code
51+
fi
52+
sleep 10
53+
echo
54+
echo Testing the container with curl:
55+
curl --show-error --retry 5 --fail -L 127.0.0.1:8080/healthz
56+
echo
57+
echo
58+
curl_exit=$?
59+
if [ $curl_exit -ne 0 ]; then
60+
echo Curling $target_image did not work
61+
cleanup $container_id
62+
exit $curl_exit
63+
fi
64+
echo Success!
65+
echo
66+
cleanup $container_id
67+
done

build/release.sh

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@
1616

1717
set -e
1818

19-
VERSION=$( git describe --tags --dirty --abbrev=14 | sed -E 's/-([0-9]+)-g/.\1+/' )
20-
# Only allow releases of tagged versions.
21-
TAGGED='^v[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta|rc)\.?[0-9]*)?$'
22-
if [[ ! "$VERSION" =~ $TAGGED ]]; then
23-
echo "Error: Only tagged versions are allowed for releases" >&2
24-
echo "Found: $VERSION" >&2
19+
if [ -z "$VERSION" ]; then
20+
VERSION=$( git describe --tags --dirty --abbrev=14 | sed -E 's/-([0-9]+)-g/.\1+/' )
21+
# Only allow releases of tagged versions.
22+
TAGGED='^v[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta|rc)\.?[0-9]*)?$'
23+
if [[ ! "$VERSION" =~ $TAGGED ]]; then
24+
echo "Error: Only tagged versions are allowed for releases" >&2
25+
echo "Found: $VERSION" >&2
26+
exit 1
27+
fi
28+
fi
29+
30+
read -p "Please confirm: $VERSION is the desired version (Type y/n to continue):" -n 1 -r
31+
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
2532
exit 1
2633
fi
2734

@@ -36,31 +43,51 @@ export BUILD_USER="$git_user"
3643
export BUILD_DATE=$( date +%Y%m%d ) # Release date is only to day-granularity
3744
export VERBOSE=true
3845

39-
# Build the release binary with libpfm4 for docker container
40-
export GO_FLAGS="-tags=libpfm,netgo"
41-
build/build.sh
42-
4346
# Build the docker image
4447
echo ">> building cadvisor docker image"
45-
gcr_tag="gcr.io/cadvisor/cadvisor:$VERSION"
46-
docker build -t $gcr_tag -f deploy/Dockerfile .
48+
image_name=${IMAGE_NAME:-"gcr.io/cadvisor/cadvisor"}
49+
final_image="$image_name:${VERSION}"
4750

48-
# Build the release binary without libpfm4 to not require libpfm4 in runtime environment
49-
unset GO_FLAGS
50-
build/build.sh
51+
docker buildx rm cadvisor-builder || true
52+
docker buildx create --name cadvisor-builder
53+
docker buildx use cadvisor-builder
5154

55+
# Build binaries
56+
57+
# A mapping of the docker arch name to the qemu arch name
58+
declare -A arches=( ["amd64"]="x86_64" ["arm"]="arm" ["arm64"]="aarch64")
59+
60+
for arch in "${arches[@]}"; do
61+
if ! hash "qemu-${arch}-static"; then
62+
echo Releasing multi arch containers requires qemu-user-static.
63+
echo
64+
echo Please install using apt-get install qemu-user-static or
65+
echo a similar package for your OS.
66+
67+
exit 1
68+
fi
69+
done
70+
71+
for arch in "${!arches[@]}"; do
72+
GOARCH="$arch" OUTPUT_NAME_WITH_ARCH="true" build/build.sh
73+
arch_specific_image="${image_name}-${arch}:${VERSION}"
74+
docker buildx build --platform "linux/${arch}" --build-arg VERSION="$VERSION" -f deploy/Dockerfile -t "$arch_specific_image" --progress plain --push .
75+
docker manifest create --amend "$final_image" "$arch_specific_image"
76+
docker manifest annotate --os=linux --arch="$arch" "$final_image" "$arch_specific_image"
77+
done
78+
docker manifest push "$final_image"
79+
docker buildx rm cadvisor-builder
5280
echo
53-
echo "double-check the version below:"
54-
echo "VERSION=$VERSION"
55-
echo
56-
echo "To push docker image to gcr:"
57-
echo "docker push $gcr_tag"
81+
echo "Release info (copy to the release page)":
5882
echo
59-
echo "Release info (copy to the release page):"
83+
echo Multi Arch Container Image:
84+
echo $final_image
6085
echo
61-
echo "Docker Image: N/A"
62-
echo "gcr.io Image: $gcr_tag"
86+
echo Architecture Specific Container Images:
87+
for arch in "${!arches[@]}"; do
88+
echo "${image_name}-${arch}:${VERSION}"
89+
done
6390
echo
64-
sha256sum --tag cadvisor
65-
91+
echo Binaries:
92+
(cd _output && find . -name "cadvisor-${VERSION}*" -exec sha256sum --tag {} \;)
6693
exit 0

deploy/Dockerfile

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
FROM alpine:3.15 AS build
1+
FROM mirror.gcr.io/library/golang:1.18-alpine3.16 AS build
22

3-
RUN apk --no-cache add libc6-compat device-mapper findutils zfs build-base linux-headers python3 bash git wget cmake pkgconfig ndctl-dev && \
3+
ARG VERSION
4+
5+
# Install build depdencies for all supported arches
6+
RUN apk --no-cache add bash build-base cmake device-mapper findutils git \
7+
libc6-compat linux-headers ndctl-dev pkgconfig python3 wget zfs && \
48
apk --no-cache add thin-provisioning-tools --repository http://dl-3.alpinelinux.org/alpine/edge/main/ && \
5-
apk --no-cache add go==1.16.10-r0 --repository http://dl-3.alpinelinux.org/alpine/v3.14/community/ && \
69
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \
710
rm -rf /var/cache/apk/*
811

@@ -15,35 +18,39 @@ RUN export DBG="-g -Wall" && \
1518
make -e -C libpfm-4.11.0 && \
1619
make install -C libpfm-4.11.0
1720

18-
RUN git clone -b v02.00.00.3820 https://github.com/intel/ipmctl/ && \
21+
# ipmctl only supports Intel x86_64 processors.
22+
# https://github.com/intel/ipmctl/issues/163
23+
RUN if [ "$(uname --machine)" = "x86_64" ]; then \
24+
git clone -b v02.00.00.3885 https://github.com/intel/ipmctl/ && \
1925
cd ipmctl && \
2026
mkdir output && \
2127
cd output && \
2228
cmake -DRELEASE=ON -DCMAKE_INSTALL_PREFIX=/ -DCMAKE_INSTALL_LIBDIR=/usr/local/lib .. && \
2329
make -j all && \
24-
make install
30+
make install; fi
2531

2632
ADD . /go/src/github.com/google/cadvisor
2733
WORKDIR /go/src/github.com/google/cadvisor
2834

29-
ENV GOROOT /usr/lib/go
30-
ENV GOPATH /go
31-
ENV GO_FLAGS="-tags=libpfm,netgo,libipmctl"
32-
33-
RUN ./build/build.sh
35+
# libipmctl only works on x86_64 CPUs.
36+
RUN export GO_TAGS="-tags=libfpm,netgo"; \
37+
if [ "$(uname --machine)" = "x86_64" ]; then \
38+
export GO_TAGS="$GO_TAGS,libipmctl"; \
39+
fi; \
40+
GO_FLAGS="-tags=$GO_TAGS" ./build/build.sh
3441

35-
FROM alpine:3.15
42+
FROM mirror.gcr.io/library/alpine:3.16
3643
3744

38-
RUN apk --no-cache add libc6-compat device-mapper findutils zfs ndctl && \
45+
RUN apk --no-cache add libc6-compat device-mapper findutils ndctl zfs && \
3946
apk --no-cache add thin-provisioning-tools --repository http://dl-3.alpinelinux.org/alpine/edge/main/ && \
4047
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \
4148
rm -rf /var/cache/apk/*
4249

43-
# Grab cadvisor,libpfm4 and libipmctl from "build" container.
50+
# Grab cadvisor,libpfm4 and libipmctl from "build" container if they exist (libipmctl only works on amd64/x86_64).
4451
COPY --from=build /usr/local/lib/libpfm.so* /usr/local/lib/
4552
COPY --from=build /usr/local/lib/libipmctl.so* /usr/local/lib/
46-
COPY --from=build /go/src/github.com/google/cadvisor/cadvisor /usr/bin/cadvisor
53+
COPY --from=build /go/src/github.com/google/cadvisor/_output/cadvisor /usr/bin/cadvisor
4754

4855
EXPOSE 8080
4956

deploy/Dockerfile.ppc64le

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
FROM ppc64le/alpine:3.15
22
3+
# Deprecated: the Dockerfile in this directory should support ppc64le
4+
# Simply build using: docker buildx build --platform linux/ppc64le -f Dockerfile .
35

46
RUN apk --no-cache add libc6-compat device-mapper findutils zfs && \
57
apk --no-cache add thin-provisioning-tools --repository http://dl-3.alpinelinux.org/alpine/edge/main/ && \

docs/development/releasing.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,32 @@ Command: `make release`
5151
- Try to build it from the release branch, since we include that in the binary version
5252
- Verify the ldflags output, in particular check the Version, BuildUser, and GoVersion are expected
5353

54-
Once the build is complete, check the VERSION and note the sha256 hash.
55-
56-
## 4. Push the Docker images
57-
58-
`make release` should output a command to push the image. Alternatively, run:
54+
Once the build is complete, copy the output after `Release info...` and save it to use in step 5
5955

56+
Example:
6057
```
61-
$ PATCH_VERSION=v0.23.0
62-
$ docker push gcr.io/cadvisor/cadvisor:$PATCH_VERSION
58+
Multi Arch Container:
59+
gcr.io/cadvisor/cadvisor:v0.44.1-test-8
60+
61+
Architecture Specific Containers:
62+
gcr.io/cadvisor/cadvisor-arm:v0.44.1-test-8
63+
gcr.io/cadvisor/cadvisor-arm64:v0.44.1-test-8
64+
gcr.io/cadvisor/cadvisor-amd64:v0.44.1-test-8
65+
66+
Binaries:
67+
SHA256 (cadvisor-v0.44.1-test-8-linux-arm64) = e5e3f9e72208bc6a5ef8b837473f6c12877ace946e6f180bce8d81edadf66767
68+
SHA256 (cadvisor-v0.44.1-test-8-linux-arm) = 7d714e495a4f50d9cc374bd5e6b5c6922ffa40ff1cc7244f2308f7d351c4ccea
69+
SHA256 (cadvisor-v0.44.1-test-8-linux-amd64) = ea95c5a6db8eecb47379715c0ca260a8a8d1522971fd3736f80006c7f6cc9466
6370
```
6471

65-
## 5. Cut the release
72+
## 4. Cut the release
6673

6774
Go to https://github.com/google/cadvisor/releases and click "Draft a new release"
6875

6976
- "Tag version" and "Release title" should be preceded by 'v' and then the version. Select the tag pushed in step 2.b
7077
- Copy an old release as a template (e.g. github.com/google/cadvisor/releases/tag/v0.23.1)
7178
- Body should start with release notes (from CHANGELOG.md)
72-
- Next is the Docker image: `gcr.io/cadvisor/cadvisor:$VERSION`
73-
- Next are the binary hashes (from step 3)
74-
- Upload the binary build in step 3
79+
- Next are the docker images and binary hashes you copied (from step 3).
80+
- Upload the binaries build in step 3, they are located in the `_output` directory.
7581
- If this is a minor version release, mark the release as a "pre-release"
76-
- Click publish when done
77-
78-
## 6. Finalize the release
79-
80-
~~Once you are satisfied with the release quality (generally we wait until the next minor release), it is time to remove the "pre-release" tag~~
81-
82-
cAdvisor is no longer pushed with the :latest tag. This is to ensure tagged images are immutable.
82+
- Click publish when done

0 commit comments

Comments
 (0)