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/
.container*
.manifest*
.push*
bin/

View File

@ -1,5 +1,7 @@
sudo: required
dist: xenial
language: go
services:
@ -9,7 +11,7 @@ go:
- 1.12.1
env:
- GO111MODULE=on
- GO111MODULE=on DOCKER_CLI_EXPERIMENTAL=enabled
install: true
@ -18,10 +20,12 @@ before_install:
script:
- make
- make vendor
- make unit
- make lint
- make container
after_success:
- 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
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 && \
tar -xf cni.tar.gz
FROM alpine
MAINTAINER squat <lserven@gmail.com>
FROM $FROM
LABEL maintainer="squat <lserven@gmail.com>"
RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
apk add --no-cache ipset iptables wireguard-tools@testing
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"]

105
Makefile
View File

@ -1,7 +1,11 @@
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
PKG := github.com/squat/$(PROJECT)
REGISTRY ?= index.docker.io
@ -33,10 +37,33 @@ OPENAPI_GEN_BINARY:=$(GOPATH)/bin/openapi-gen
BUILD_IMAGE ?= golang:1.12.1-alpine
all: build
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
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 $@
$(BINS): $(SRC) go.mod
@mkdir -p bin
@mkdir -p bin/$(ARCH)
@echo "building: $@"
@docker run --rm \
-u $$(id -u):$$(id -g) \
@ -115,6 +142,7 @@ $(BINS): $(SRC) go.mod
-w /$(PROJECT) \
$(BUILD_IMAGE) \
/bin/sh -c " \
GOARCH=$(ARCH) \
GOOS=linux \
GOCACHE=/$(PROJECT)/.cache \
CGO_ENABLED=0 \
@ -174,29 +202,66 @@ header: .header
exit 1; \
fi
container: .container-$(VERSION) container-name
.container-$(VERSION): $(BINS) Dockerfile
@docker build -t $(IMAGE):$(VERSION) .
@docker images -q $(IMAGE):$(VERSION) > $@
container: .container-$(ARCH)-$(VERSION) container-name
.container-$(ARCH)-$(VERSION): $(BINS) Dockerfile
@i=0; for a in $(ALL_ARCH); do [ "$$a" = $(ARCH) ] && break; i=$$((i+1)); done; \
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)
@docker tag $(IMAGE):$(VERSION) $(IMAGE):latest
@echo "container: $(IMAGE):latest"
container-latest: .container-$(ARCH)-$(VERSION)
@docker tag $(IMAGE):$(ARCH)-$(VERSION) $(IMAGE):$(ARCH)-latest
@echo "container: $(IMAGE):$(ARCH)-latest"
container-name:
@echo "container: $(IMAGE):$(VERSION)"
@echo "container: $(IMAGE):$(ARCH)-$(VERSION)"
push: .push-$(VERSION) push-name
.push-$(VERSION): .container-$(VERSION)
@docker push $(REGISTRY)/$(IMAGE):$(VERSION)
@docker images -q $(IMAGE):$(VERSION) > $@
manifest: .manifest-$(VERSION) manifest-name
.manifest-$(VERSION): Dockerfile $(addprefix push-, $(ALL_ARCH))
@docker manifest create --amend $(IMAGE):$(VERSION) $(addsuffix -$(VERSION), $(addprefix squat/$(PROJECT):, $(ALL_ARCH)))
@$(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
@docker push $(REGISTRY)/$(IMAGE):latest
@echo "pushed: $(IMAGE):latest"
@docker push $(REGISTRY)/$(IMAGE):$(ARCH)-latest
@echo "pushed: $(IMAGE):$(ARCH)-latest"
push-name:
@echo "pushed: $(IMAGE):$(VERSION)"
@echo "pushed: $(IMAGE):$(ARCH)-$(VERSION)"
clean: container-clean bin-clean
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/client/clientset/clientset/scheme
# 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/labels
k8s.io/apimachinery/pkg/types
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/util/runtime
k8s.io/apimachinery/pkg/watch
k8s.io/apimachinery/pkg/util/errors
k8s.io/apimachinery/pkg/util/validation
k8s.io/apimachinery/pkg/apis/meta/v1/unstructured
k8s.io/apimachinery/pkg/api/resource
k8s.io/apimachinery/pkg/util/intstr
k8s.io/apimachinery/pkg/conversion
k8s.io/apimachinery/pkg/util/json
k8s.io/apimachinery/pkg/util/validation/field
k8s.io/apimachinery/pkg/fields
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/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/third_party/forked/golang/json
k8s.io/apimachinery/pkg/api/meta
k8s.io/apimachinery/pkg/fields
k8s.io/apimachinery/pkg/util/cache
k8s.io/apimachinery/pkg/util/clock
k8s.io/apimachinery/pkg/util/diff
k8s.io/apimachinery/pkg/util/naming
k8s.io/apimachinery/pkg/util/wait
k8s.io/apimachinery/pkg/conversion/queryparams
k8s.io/apimachinery/pkg/version
k8s.io/apimachinery/pkg/runtime/serializer/streaming
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/recognizer
k8s.io/apimachinery/pkg/runtime/serializer/versioning
k8s.io/apimachinery/third_party/forked/golang/reflect
k8s.io/apimachinery/pkg/apis/meta/v1beta1
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/kubernetes
k8s.io/client-go/tools/clientcmd