Makefile,Dockerfile: add multi-arch images

This commit changes the build-system for Kilo to create container images
for multiple architectures. This will enable running Kilo on Arm
devices, e.g. Raspberry Pis. This is accomplished using Docker
manifests.
This commit is contained in:
Lucas Servén Marín 2019-05-16 19:07:58 +02:00
parent 81d6077fc2
commit adb09ce620
No known key found for this signature in database
GPG Key ID: 586FEAF680DA74AD
5 changed files with 111 additions and 39 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.cache/ .cache/
.container* .container*
.manifest*
.push* .push*
bin/ bin/

View File

@ -1,5 +1,7 @@
sudo: required sudo: required
dist: xenial
language: go language: go
services: services:
@ -9,7 +11,7 @@ go:
- 1.12.1 - 1.12.1
env: env:
- GO111MODULE=on - GO111MODULE=on DOCKER_CLI_EXPERIMENTAL=enabled
install: true install: true
@ -18,10 +20,12 @@ before_install:
script: script:
- make - make
- make vendor
- make unit - make unit
- make lint - make lint
- make container - make container
after_success: after_success:
- docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
- make push && make push-latest - docker run --rm --privileged multiarch/qemu-user-static:register
- make manifest && make manifest-latest

View File

@ -1,12 +1,14 @@
ARG FROM=alpine
FROM alpine AS cni FROM alpine AS cni
RUN apk add --no-cache curl && \ RUN apk add --no-cache curl && \
curl -Lo cni.tar.gz https://github.com/containernetworking/plugins/releases/download/v0.7.5/cni-plugins-amd64-v0.7.5.tgz && \ curl -Lo cni.tar.gz https://github.com/containernetworking/plugins/releases/download/v0.7.5/cni-plugins-amd64-v0.7.5.tgz && \
tar -xf cni.tar.gz tar -xf cni.tar.gz
FROM alpine FROM $FROM
MAINTAINER squat <lserven@gmail.com> LABEL maintainer="squat <lserven@gmail.com>"
RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
apk add --no-cache ipset iptables wireguard-tools@testing apk add --no-cache ipset iptables wireguard-tools@testing
COPY --from=cni bridge host-local loopback portmap /opt/cni/bin/ COPY --from=cni bridge host-local loopback portmap /opt/cni/bin/
COPY bin/kg /opt/bin/ ARG GOARCH
COPY bin/$GOARCH/kg /opt/bin/
ENTRYPOINT ["/opt/bin/kg"] ENTRYPOINT ["/opt/bin/kg"]

105
Makefile
View File

@ -1,7 +1,11 @@
export GO111MODULE=on export GO111MODULE=on
.PHONY: all push container clean container-name container-latest push-latest fmt lint test unit vendor header generate client deepcopy informer lister openapi .PHONY: push container clean container-name container-latest push-latest fmt lint test unit vendor header generate client deepcopy informer lister openapi manifest manfest-latest manifest-annotate manifest manfest-latest manifest-annotate
BINS := $(addprefix bin/,kg kgctl) ARCH ?= amd64
ALL_ARCH := amd64 arm arm64
DOCKER_ARCH := "" arm "arm64 armv8"
IMAGE_ARCH := amd64 armhf arm64
BINS := $(addprefix bin/$(ARCH)/,kg kgctl)
PROJECT := kilo PROJECT := kilo
PKG := github.com/squat/$(PROJECT) PKG := github.com/squat/$(PROJECT)
REGISTRY ?= index.docker.io REGISTRY ?= index.docker.io
@ -33,10 +37,33 @@ OPENAPI_GEN_BINARY:=$(GOPATH)/bin/openapi-gen
BUILD_IMAGE ?= golang:1.12.1-alpine BUILD_IMAGE ?= golang:1.12.1-alpine
all: build
build: $(BINS) build: $(BINS)
build-%:
@$(MAKE) --no-print-directory ARCH=$* build
container-latest-%:
@$(MAKE) --no-print-directory ARCH=$* container-latest
container-%:
@$(MAKE) --no-print-directory ARCH=$* container
push-latest-%:
@$(MAKE) --no-print-directory ARCH=$* push-latest
push-%:
@$(MAKE) --no-print-directory ARCH=$* push
all-build: $(addprefix build-, $(ALL_ARCH))
all-container: $(addprefix container-, $(ALL_ARCH))
all-push: $(addprefix push-, $(ALL_ARCH))
all-container-latest: $(addprefix container-latest-, $(ALL_ARCH))
all-push-latest: $(addprefix push-latest-, $(ALL_ARCH))
generate: client deepcopy informer lister openapi generate: client deepcopy informer lister openapi
client: pkg/k8s/clientset/versioned/typed/kilo/v1alpha1/peer.go client: pkg/k8s/clientset/versioned/typed/kilo/v1alpha1/peer.go
@ -107,7 +134,7 @@ pkg/k8s/apis/kilo/v1alpha1/openapi_generated.go: pkg/k8s/apis/kilo/v1alpha1/type
go fmt $@ go fmt $@
$(BINS): $(SRC) go.mod $(BINS): $(SRC) go.mod
@mkdir -p bin @mkdir -p bin/$(ARCH)
@echo "building: $@" @echo "building: $@"
@docker run --rm \ @docker run --rm \
-u $$(id -u):$$(id -g) \ -u $$(id -u):$$(id -g) \
@ -115,6 +142,7 @@ $(BINS): $(SRC) go.mod
-w /$(PROJECT) \ -w /$(PROJECT) \
$(BUILD_IMAGE) \ $(BUILD_IMAGE) \
/bin/sh -c " \ /bin/sh -c " \
GOARCH=$(ARCH) \
GOOS=linux \ GOOS=linux \
GOCACHE=/$(PROJECT)/.cache \ GOCACHE=/$(PROJECT)/.cache \
CGO_ENABLED=0 \ CGO_ENABLED=0 \
@ -174,29 +202,66 @@ header: .header
exit 1; \ exit 1; \
fi fi
container: .container-$(VERSION) container-name container: .container-$(ARCH)-$(VERSION) container-name
.container-$(VERSION): $(BINS) Dockerfile .container-$(ARCH)-$(VERSION): $(BINS) Dockerfile
@docker build -t $(IMAGE):$(VERSION) . @i=0; for a in $(ALL_ARCH); do [ "$$a" = $(ARCH) ] && break; i=$$((i+1)); done; \
@docker images -q $(IMAGE):$(VERSION) > $@ ia=""; \
j=0; for a in $(IMAGE_ARCH); do [ "$$i" -eq "$$j" ] && ia="$$a" && break; j=$$((j+1)); done; \
docker build -t $(IMAGE):$(ARCH)-$(VERSION) --build-arg FROM=multiarch/alpine:$$ia-v3.9 --build-arg GOARCH=$(ARCH) .
@docker images -q $(IMAGE):$(ARCH)-$(VERSION) > $@
container-latest: .container-$(VERSION) container-latest: .container-$(ARCH)-$(VERSION)
@docker tag $(IMAGE):$(VERSION) $(IMAGE):latest @docker tag $(IMAGE):$(ARCH)-$(VERSION) $(IMAGE):$(ARCH)-latest
@echo "container: $(IMAGE):latest" @echo "container: $(IMAGE):$(ARCH)-latest"
container-name: container-name:
@echo "container: $(IMAGE):$(VERSION)" @echo "container: $(IMAGE):$(ARCH)-$(VERSION)"
push: .push-$(VERSION) push-name manifest: .manifest-$(VERSION) manifest-name
.push-$(VERSION): .container-$(VERSION) .manifest-$(VERSION): Dockerfile $(addprefix push-, $(ALL_ARCH))
@docker push $(REGISTRY)/$(IMAGE):$(VERSION) @docker manifest create --amend $(IMAGE):$(VERSION) $(addsuffix -$(VERSION), $(addprefix squat/$(PROJECT):, $(ALL_ARCH)))
@docker images -q $(IMAGE):$(VERSION) > $@ @$(MAKE) --no-print-directory manifest-annotate
@docker manifest push $(IMAGE):$(VERSION) > $@
manifest-latest: .manifest-$(VERSION) $(addprefix push-latest-, $(ALL_ARCH))
@docker manifest create --amend $(IMAGE):latest $(addsuffix -latest, $(addprefix squat/$(PROJECT):, $(ALL_ARCH)))
@$(MAKE) --no-print-directory manifest-annotate
@docker manifest push $(IMAGE):latest
@echo "manifest: $(IMAGE):latest"
manifest-annotate:
@i=0; \
for a in $(ALL_ARCH); do \
annotate=; \
j=0; for da in $(DOCKER_ARCH); do \
if [ "$$j" -eq "$$i" ] && [ -n "$$da" ]; then \
annotate="docker manifest annotate $(IMAGE):$(VERSION) $(IMAGE):$$a-$(VERSION) --os linux --arch"; \
k=0; for ea in $$da; do \
[ "$$k" = 0 ] && annotate="$$annotate $$ea"; \
[ "$$k" != 0 ] && annotate="$$annotate --variant $$ea"; \
k=$$((k+1)); \
done; \
$$annotate; \
fi; \
j=$$((j+1)); \
done; \
i=$$((i+1)); \
done
manifest-name:
@echo "manifest: $(IMAGE_ROOT):$(VERSION)"
push: .push-$(ARCH)-$(VERSION) push-name
.push-$(ARCH)-$(VERSION): .container-$(ARCH)-$(VERSION)
@docker push $(REGISTRY)/$(IMAGE):$(ARCH)-$(VERSION)
@docker images -q $(IMAGE):$(ARCH)-$(VERSION) > $@
push-latest: container-latest push-latest: container-latest
@docker push $(REGISTRY)/$(IMAGE):latest @docker push $(REGISTRY)/$(IMAGE):$(ARCH)-latest
@echo "pushed: $(IMAGE):latest" @echo "pushed: $(IMAGE):$(ARCH)-latest"
push-name: push-name:
@echo "pushed: $(IMAGE):$(VERSION)" @echo "pushed: $(IMAGE):$(ARCH)-$(VERSION)"
clean: container-clean bin-clean clean: container-clean bin-clean
rm -r .cache rm -r .cache

28
vendor/modules.txt vendored
View File

@ -194,48 +194,48 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextension
k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions
k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme
# k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1 # k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1
k8s.io/apimachinery/pkg/apis/meta/v1
k8s.io/apimachinery/pkg/runtime
k8s.io/apimachinery/pkg/runtime/schema
k8s.io/apimachinery/pkg/runtime/serializer/json
k8s.io/apimachinery/pkg/api/errors k8s.io/apimachinery/pkg/api/errors
k8s.io/apimachinery/pkg/labels k8s.io/apimachinery/pkg/labels
k8s.io/apimachinery/pkg/types k8s.io/apimachinery/pkg/types
k8s.io/apimachinery/pkg/util/strategicpatch k8s.io/apimachinery/pkg/util/strategicpatch
k8s.io/apimachinery/pkg/apis/meta/v1
k8s.io/apimachinery/pkg/runtime
k8s.io/apimachinery/pkg/runtime/schema
k8s.io/apimachinery/pkg/runtime/serializer k8s.io/apimachinery/pkg/runtime/serializer
k8s.io/apimachinery/pkg/util/runtime k8s.io/apimachinery/pkg/util/runtime
k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/pkg/watch
k8s.io/apimachinery/pkg/util/errors k8s.io/apimachinery/pkg/util/errors
k8s.io/apimachinery/pkg/util/validation k8s.io/apimachinery/pkg/util/validation
k8s.io/apimachinery/pkg/apis/meta/v1/unstructured
k8s.io/apimachinery/pkg/api/resource k8s.io/apimachinery/pkg/api/resource
k8s.io/apimachinery/pkg/util/intstr
k8s.io/apimachinery/pkg/conversion k8s.io/apimachinery/pkg/conversion
k8s.io/apimachinery/pkg/util/json k8s.io/apimachinery/pkg/fields
k8s.io/apimachinery/pkg/util/validation/field
k8s.io/apimachinery/pkg/selection k8s.io/apimachinery/pkg/selection
k8s.io/apimachinery/pkg/util/intstr
k8s.io/apimachinery/pkg/conversion/queryparams
k8s.io/apimachinery/pkg/util/json
k8s.io/apimachinery/pkg/util/naming
k8s.io/apimachinery/pkg/util/sets k8s.io/apimachinery/pkg/util/sets
k8s.io/apimachinery/pkg/runtime/serializer/recognizer
k8s.io/apimachinery/pkg/util/framer
k8s.io/apimachinery/pkg/util/yaml
k8s.io/apimachinery/pkg/apis/meta/v1/unstructured
k8s.io/apimachinery/pkg/util/validation/field
k8s.io/apimachinery/pkg/util/mergepatch k8s.io/apimachinery/pkg/util/mergepatch
k8s.io/apimachinery/third_party/forked/golang/json k8s.io/apimachinery/third_party/forked/golang/json
k8s.io/apimachinery/pkg/api/meta k8s.io/apimachinery/pkg/api/meta
k8s.io/apimachinery/pkg/fields
k8s.io/apimachinery/pkg/util/cache k8s.io/apimachinery/pkg/util/cache
k8s.io/apimachinery/pkg/util/clock k8s.io/apimachinery/pkg/util/clock
k8s.io/apimachinery/pkg/util/diff k8s.io/apimachinery/pkg/util/diff
k8s.io/apimachinery/pkg/util/naming
k8s.io/apimachinery/pkg/util/wait k8s.io/apimachinery/pkg/util/wait
k8s.io/apimachinery/pkg/conversion/queryparams
k8s.io/apimachinery/pkg/version k8s.io/apimachinery/pkg/version
k8s.io/apimachinery/pkg/runtime/serializer/streaming k8s.io/apimachinery/pkg/runtime/serializer/streaming
k8s.io/apimachinery/pkg/util/net k8s.io/apimachinery/pkg/util/net
k8s.io/apimachinery/pkg/runtime/serializer/json
k8s.io/apimachinery/pkg/runtime/serializer/protobuf k8s.io/apimachinery/pkg/runtime/serializer/protobuf
k8s.io/apimachinery/pkg/runtime/serializer/recognizer
k8s.io/apimachinery/pkg/runtime/serializer/versioning k8s.io/apimachinery/pkg/runtime/serializer/versioning
k8s.io/apimachinery/third_party/forked/golang/reflect k8s.io/apimachinery/third_party/forked/golang/reflect
k8s.io/apimachinery/pkg/apis/meta/v1beta1 k8s.io/apimachinery/pkg/apis/meta/v1beta1
k8s.io/apimachinery/pkg/apis/meta/internalversion k8s.io/apimachinery/pkg/apis/meta/internalversion
k8s.io/apimachinery/pkg/util/framer
k8s.io/apimachinery/pkg/util/yaml
# k8s.io/client-go v11.0.0+incompatible # k8s.io/client-go v11.0.0+incompatible
k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes
k8s.io/client-go/tools/clientcmd k8s.io/client-go/tools/clientcmd