Продолжение поста Время собирать k8s.
Как можно просто собирать сложный многокомпонентный проект под разные платформы.
Это не единственный способ, но это универсальный подход, который можно адаптировать под микросервисную архитектуру, модулит, мобильную или системную разработку.
Как решить проблемы которые решает Bazel, без Bazel.
Buildx и гибкий подход к архитектуре помогут решить нам эту задачу.
Для того, чтобы создать builder для arm64:
docker buildx create \
--append \
--bootstrap \
--name=<NAME> \
--driver=kubernetes \
--platform=linux/arm64 \
--node=builder-arm64 \
--driver-opt=namespace=<NAMESPACE>,nodeselector="kubernetes.io/arch=arm64"
Более подробно архитектура описана в kube-buildx-farm.md
Buildx использует QEMU, когда мы указываем «чужую» для хоста архитектуру:
docker buildx ls
kube-build-farm kubernetes
\_ kube-build-farm0 \_ kubernetes:///kube-build-farm?
kube-build-farm-arm64 kubernetes
\_ kube-build-farm-arm640 \_ kubernetes:///kube-build-farm-arm64?deployment=buildkit-2f2c1ac5-7bf7-4de9-96ce-95611e5a94cd-k72ck&kubeconfig= running v0.20.0 linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/loong64, linux/arm/v7, linux/arm/v6
default* docker
\_ default \_ default
В кластере могут быть сотни узлов, что позволит распаралеллить сборку и таким ускорит сборку и тестирование проекта в десятки раз. Компонентов для сборки тоже кстати могут быть сотни.
В нашем случае каждый компонент собирается в отдельном Dockerfile:
find /k8s-release/ -iname "Dockerfile.*"
/srv/k8s-release/Dockerfile.kube-apiserver
/srv/k8s-release/Dockerfile.kube-scheduler
/srv/k8s-release/Dockerfile.kubectl
/srv/k8s-release/Dockerfile.etcd
/srv/k8s-release/Dockerfile.kube-proxy
/srv/k8s-release/Dockerfile.kube-controller-manager
/srv/k8s-release/Dockerfile.kubelet
/srv/k8s-release/Dockerfile.flannel
Потом они подключаются через общий docker compose конфиг:
flannel-builder:
build:
context: .
dockerfile: Dockerfile.flannel
args:
- FLANNEL_VERSION=v0.26.4
- FLANNEL_GIT_URL=https://github.com/flannel-io/flannel.git
entrypoint: ["sh", "-c", "cp /usr/local/bin/flanneld /output/flanneld"]
volumes:
- ./output:/output
Docker compose использует переменную $DOCKER_DEFAULT_PLATFORM для определения целевой платформы. Ее мы и будем использовать в Makefile который выступает в роли фронтенда для сборочной системы/автоматизации:
# Switch to the appropriate Buildx builder based on KUBE_BUILDER or KUBE_BUILDER_ARM64
switch-builder:
ifeq ($(KUBE_BUILDER_ARM64),1)
@echo "Switching to Kubernetes ARM64 Buildx builder..."
@docker buildx use kube-build-farm-arm64 || { echo >&2 "Error: Kubernetes ARM64 Buildx builder not found."; exit 1; }
else ifeq ($(KUBE_BUILDER),1)
@echo "Switching to Kubernetes Buildx builder..."
@docker buildx use kube-build-farm || { echo >&2 "Error: Kubernetes Buildx builder not found."; exit 1; }
else
@echo "Switching to default Buildx builder..."
@docker buildx use default
endif
# Define the default platform based on $KUBE_BUILDER
ifeq ($(KUBE_BUILDER_ARM64),1)
DOCKER_DEFAULT_PLATFORM := linux/arm64
else
DOCKER_DEFAULT_PLATFORM := linux/amd64
endif
Make заточен под определенный круг задач — он отлично подходит для манипуляции и парсинга строковых данных, а так же выполнения команд shell.
Не забываем про документацию (доки-как код) и встраиваем описание прямо в Make:
Usage: make <target>
Targets:
help Display this help message
build Perform a simple build using Buildx
build-no-cache Perform a simple build using Buildx without cache
archive Create a git archive with branch and commit in the name
bundle Create a git bundle with branch and commit in the name
clean Clean up generated files
Variables:
FLANNEL_GIT_URL Flannel Git repository URL (default: https://github.com/flannel-io/flannel.git)
FLANNEL_VERSION Flannel version to use (default: v0.26.4)
KUBE_GIT_URL Kubernetes Git repository URL (default: https://github.com/kubernetes/kubernetes.git)
KUBE_BUILDER Use Kubernetes to build images (default: 0, set to 1 to enable)
KUBE_BUILDER_ARM64 Use Kubernetes ARM64 builder (default: 0, set to 1 to enable)
KUBE_VERSION Kubernetes version to use (default: v1.32.2)
ETCD_VERSION Etcd version to use (default: v3.5.9)
COMPOSE_DOCKER_CLI_BUILD Enable Docker CLI build (set to 1)
DOCKER_BUILDKIT Enable BuildKit for Docker builds (set to 1)

Благодаря модульному подходу можно без проблем расширять проект для того, чтобы собирать платформу.