Добавлены скрипты для полного рендера манифестов и точка входа образа.
This commit is contained in:
parent
492d31b253
commit
a713c46ed0
25
.dockerignore
Normal file
25
.dockerignore
Normal file
@ -0,0 +1,25 @@
|
||||
# В контекст сборки нужны только манифесты: clusters/, apps/, infrastructure/
|
||||
# и скрипты из hack/. Всё остальное — история, IDE, секреты — только раздувает
|
||||
# контекст и рискует уехать в образ.
|
||||
.git
|
||||
.gitignore
|
||||
.idea
|
||||
.claude
|
||||
CLAUDE.md
|
||||
.env
|
||||
.env.*
|
||||
docs
|
||||
*.md
|
||||
aero
|
||||
inventory.yaml
|
||||
tmp
|
||||
.tmp/
|
||||
snapshots
|
||||
out
|
||||
|
||||
# Секреты и ключи не должны попадать в контекст сборки даже случайно.
|
||||
*.pem
|
||||
*.key
|
||||
*.p12
|
||||
kubeconfig*
|
||||
*service-account*.json
|
||||
77
Dockerfile
Normal file
77
Dockerfile
Normal file
@ -0,0 +1,77 @@
|
||||
# Полная сборка манифестов IaC-репозитория для одного контура.
|
||||
#
|
||||
# docker build --build-arg CONTOUR=aero -t iac:aero .
|
||||
# docker run --rm iac:aero list # что собралось
|
||||
# docker run --rm iac:aero cat clusters # слои Flux одним потоком
|
||||
# docker run --rm -v "$PWD/out:/export" iac:aero export
|
||||
#
|
||||
# Контур — имя каталога в clusters/ (aero, brusnika-prod, dsinv, wb, ...).
|
||||
# Тот же идентификатор служит именем overlay внутри apps/* и infrastructure/*,
|
||||
# поэтому одного аргумента хватает на весь рендер.
|
||||
#
|
||||
# Сборка офлайновая: kustomize build разворачивает оверлеи и патчи, а
|
||||
# HelmRelease остаётся Custom Resource'ом — чарты тянет Flux уже в кластере.
|
||||
# Ни helm, ни доступ к OCI-реестру здесь не нужны. Исключение — валидация:
|
||||
# схемы CRD kubeconform берёт из сети (отключается VALIDATE=0).
|
||||
|
||||
ARG KUSTOMIZE_VERSION=v5.4.3
|
||||
ARG KUBECONFORM_VERSION=v0.6.7
|
||||
|
||||
FROM registry.k8s.io/kustomize/kustomize:${KUSTOMIZE_VERSION} AS kustomize
|
||||
FROM ghcr.io/yannh/kubeconform:${KUBECONFORM_VERSION} AS kubeconform
|
||||
|
||||
|
||||
FROM alpine:3.20 AS builder
|
||||
|
||||
# Контур обязателен по смыслу, но значение по умолчанию оставлено: сборка без
|
||||
# --build-arg собирает aero, а не падает на пустой переменной.
|
||||
ARG CONTOUR=aero
|
||||
ARG VALIDATE=1
|
||||
ARG KUBERNETES_VERSION=1.30.0
|
||||
|
||||
COPY --from=kustomize /app/kustomize /usr/local/bin/kustomize
|
||||
COPY --from=kubeconform /kubeconform /usr/local/bin/kubeconform
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
# Скрипт копируется отдельным слоем: правка манифестов не инвалидирует его,
|
||||
# а правка скрипта не тянет за собой пересборку базовых слоёв.
|
||||
COPY hack/render-contour.sh /usr/local/bin/render-contour
|
||||
RUN chmod +x /usr/local/bin/render-contour
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN render-contour "${CONTOUR}" /out
|
||||
|
||||
# Валидация отдельным слоем: смена версии Kubernetes не пересобирает рендер.
|
||||
# --ignore-missing-schemas пропускает ресурсы, чьих схем нет в каталоге
|
||||
# (часть CRD), но не заглушает ошибки в тех, что нашлись.
|
||||
RUN if [ "${VALIDATE}" = "1" ]; then \
|
||||
kubeconform \
|
||||
-kubernetes-version "${KUBERNETES_VERSION}" \
|
||||
-strict \
|
||||
-ignore-missing-schemas \
|
||||
-schema-location default \
|
||||
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
|
||||
-summary \
|
||||
/out/*.yaml ; \
|
||||
else \
|
||||
echo "VALIDATE=0 — проверка схемами пропущена" ; \
|
||||
fi
|
||||
|
||||
|
||||
FROM alpine:3.20
|
||||
|
||||
ARG CONTOUR=aero
|
||||
ENV CONTOUR=${CONTOUR}
|
||||
|
||||
LABEL org.opencontainers.image.title="iac-manifests" \
|
||||
org.opencontainers.image.description="Собранные манифесты контура ${CONTOUR}" \
|
||||
ru.iac.contour="${CONTOUR}"
|
||||
|
||||
COPY --from=builder /out /manifests
|
||||
COPY hack/entrypoint.sh /usr/local/bin/entrypoint
|
||||
RUN chmod +x /usr/local/bin/entrypoint
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint"]
|
||||
CMD ["list"]
|
||||
27
hack/entrypoint.sh
Normal file
27
hack/entrypoint.sh
Normal file
@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
# Точка входа образа с собранными манифестами.
|
||||
#
|
||||
# list — что собралось
|
||||
# cat [префикс] — весь контур (или его часть) одним потоком
|
||||
# export [путь] — скопировать манифесты в примонтированный каталог
|
||||
# <команда> — выполнить как есть
|
||||
set -eu
|
||||
|
||||
case "${1:-list}" in
|
||||
list)
|
||||
ls -1 /manifests
|
||||
;;
|
||||
cat)
|
||||
shift
|
||||
cat /manifests/"${1:-}"*.yaml
|
||||
;;
|
||||
export)
|
||||
dst="${2:-/export}"
|
||||
[ -d "$dst" ] || { echo "Каталог ${dst} не примонтирован" >&2; exit 1; }
|
||||
cp /manifests/*.yaml "$dst"/
|
||||
echo "Выгружено в ${dst}"
|
||||
;;
|
||||
*)
|
||||
exec "$@"
|
||||
;;
|
||||
esac
|
||||
61
hack/render-contour.sh
Normal file
61
hack/render-contour.sh
Normal file
@ -0,0 +1,61 @@
|
||||
#!/bin/sh
|
||||
# Рендер всех kustomization'ов, относящихся к одному контуру.
|
||||
#
|
||||
# render-contour.sh <контур> <каталог-результата>
|
||||
#
|
||||
# Используется из Dockerfile, но работает и локально — нужен только kustomize.
|
||||
set -eu
|
||||
|
||||
contour="${1:?не задан контур}"
|
||||
out="${2:?не задан каталог результата}"
|
||||
|
||||
if [ ! -d "clusters/${contour}" ]; then
|
||||
echo "Неизвестный контур: ${contour}" >&2
|
||||
echo "Доступные:" >&2
|
||||
ls clusters | sed 's/^/ - /' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$out"
|
||||
|
||||
build() {
|
||||
dir="$1"
|
||||
# Имя файла повторяет путь: clusters/aero/apps -> clusters.aero.apps.yaml
|
||||
name=$(echo "$dir" | tr '/' '.')
|
||||
echo " build ${dir}"
|
||||
# --load-restrictor LoadRestrictionsNone: слои ссылаются на apps/ и
|
||||
# infrastructure/ через ../../.., то есть выходят за корень kustomization.
|
||||
kustomize build --load-restrictor LoadRestrictionsNone "$dir" > "${out}/${name}.yaml"
|
||||
}
|
||||
|
||||
# Каталоги контура: сам clusters/<contour> и все его слои (controllers, configs,
|
||||
# apps, infrastructure — набор у контуров разный, поэтому ищем, а не перечисляем).
|
||||
# flux-system исключён: gotk-components.yaml генерирует `flux bootstrap`,
|
||||
# он и так лежит в репозитории готовым.
|
||||
echo "Контур ${contour}: слои Flux"
|
||||
find "clusters/${contour}" -name kustomization.yaml -not -path '*/flux-system/*' \
|
||||
| sed 's#/kustomization.yaml$##' | sort > /tmp/layers.txt
|
||||
while read -r dir; do
|
||||
build "$dir"
|
||||
done < /tmp/layers.txt
|
||||
|
||||
# Оверлеи приложений и инфраструктуры. Через слои они уже отрендерились, но
|
||||
# отдельные файлы дают поресурсный diff и ловят оверлей, который в слои пока
|
||||
# не подключён, — такой ломался бы уже при подключении.
|
||||
for root in apps infrastructure; do
|
||||
[ -d "$root" ] || continue
|
||||
echo "Контур ${contour}: оверлеи ${root}/*/${contour}"
|
||||
for dir in "$root"/*/"$contour"; do
|
||||
[ -f "${dir}/kustomization.yaml" ] || continue
|
||||
build "$dir"
|
||||
done
|
||||
done
|
||||
|
||||
# Пустой результат почти наверняка означает опечатку в имени контура —
|
||||
# лучше упасть на сборке, чем отдать пустой образ.
|
||||
if [ -z "$(ls -A "$out")" ]; then
|
||||
echo "Для контура ${contour} не собрано ни одного манифеста" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Готово: $(ls -1 "$out" | wc -l) файлов в ${out}"
|
||||
Loading…
Reference in New Issue
Block a user