В docker-compose.yaml описывались 25 сервисов, а на хосте существовали
контейнеры только для 9. Остальные 16 — django, celery, frontend, s3-proxy,
processing-api/frontend, engine, measurements, nginx и их зависимости
(postgres, redis, rabbitmq, minio с init-контейнерами) — развёрнуты в k3s и
описаны в apps/ и infrastructure/. Дубликат не просто лежал мёртвым грузом,
а расходился с кластером и вводил в заблуждение.
Что это был именно мёртвый груз, а не «выключенный на время» стек:
* контейнеров не существовало вовсе — не Exited, а не создавались;
* именованных томов sarex-postgres-data, sarex-redis-data,
sarex-rabbitmq-data, sarex-minio-data в docker volume ls нет;
* стек был взаимно несовместим: nginx публиковал 80/443, те же порты
публикует k3s-server (внутри его контейнера на них сидит istio
ingressgateway), и docker compose up nginx упал бы на bind;
* подъём был выключен по умолчанию (sarex_compose_up: false).
Заодно убрано всё, что обслуживало только удалённые сервисы:
* sarex_services, sarex_compose_up, задача up и poe-таски stack/up;
* оба handler'а (пересоздание nginx/backend/celery) — файл handlers
остался пустым и удалён;
* генерация самоподписанного сертификата и cert_dir: TLS выписывает
cert-manager внутри кластера, верхнего nginx больше нет;
* каталоги nginx/, backend/, engine/ и задачи их копирования;
* k3s/manifests/processing — DNS-мост на IP compose-postgres/minio,
которых больше не существует (в кластере он и не был создан).
poe install теперь идёт через platform, а не через удалённый stack — это
заодно чинит старую дыру, из-за которой install не поднимал подложку.
Проверено: docker compose config отдаёт ровно 9 сервисов, совпадающих с
docker ps на aero-01; ansible-lint новых замечаний не даёт.
416 lines
22 KiB
YAML
416 lines
22 KiB
YAML
# GitOps-ПОДЛОЖКА КОНТУРА, И ТОЛЬКО ОНА.
|
||
#
|
||
# Здесь описано ровно то, что не может жить внутри кластера, потому что кластер
|
||
# на этом и стоит: сами ноды k3s, git-репозиторий-источник (gitea), хранилище
|
||
# секретов (vault) и одноразовые установщики, доводящие всё это до состояния,
|
||
# в котором за дело берётся Flux.
|
||
#
|
||
# ПРИКЛАДНОГО СТЕКА ЗДЕСЬ НЕТ И БЫТЬ НЕ ДОЛЖНО. Django, celery, frontend,
|
||
# processing, measurements, bim, а также postgres, redis, rabbitmq и minio
|
||
# развёрнуты в k3s и описаны декларативно в apps/ и infrastructure/; источник
|
||
# правды для них — репозиторий в gitea, а не этот файл. Раньше они дублировались
|
||
# и здесь; дубликат удалён, потому что расходился с кластером и вводил в
|
||
# заблуждение. Возвращать их сюда не надо: nginx конфликтовал бы с k3s-server за
|
||
# порты 80/443 (их занимает istio ingressgateway внутри контейнера ноды), а
|
||
# вторая копия СУБД тихо разъехалась бы с той, где лежат данные.
|
||
#
|
||
# Поднимает всё это ansible-роль sarex_stack тремя волнами — см. aero/roles/
|
||
# sarex_stack/tasks/platform.yml, порядок там значим.
|
||
|
||
# Общая конфигурация воркер-нод k3s — см. сервисы k3s-worker-1..2.
|
||
# У каждой ноды СВОЙ том состояния и СВОЙ каталог PVC-хранилища: провижинер
|
||
# local-path кладёт данные на ту ноду, где под запустился первым, и через
|
||
# nodeAffinity навсегда привязывает к ней PV.
|
||
x-k3s-worker: &k3s-worker
|
||
image: ${K3S_IMAGE:-rancher/k3s:v1.36.2-k3s1}
|
||
command: ["agent"]
|
||
privileged: true
|
||
cgroup: host # kubelet в cgroup v2 (Ubuntu 22.04+/RedOS)
|
||
restart: unless-stopped
|
||
depends_on:
|
||
k3s-server:
|
||
condition: service_healthy
|
||
environment:
|
||
K3S_URL: https://k3s-server:6443
|
||
K3S_TOKEN: ${K3S_TOKEN:-supersecrettoken}
|
||
# ВНИМАНИЕ: volumes здесь не задаём — merge-ключ `<<:` не сливает списки,
|
||
# и volumes сервиса перекрыл бы якорь целиком. Монтирования, включая
|
||
# registries.yaml, перечислены в каждом воркере явно.
|
||
tmpfs:
|
||
- /run
|
||
- /var/run
|
||
ulimits:
|
||
nproc: 65535
|
||
nofile:
|
||
soft: 65535
|
||
hard: 65535
|
||
|
||
services:
|
||
k3s-server:
|
||
image: ${K3S_IMAGE:-rancher/k3s:v1.36.2-k3s1}
|
||
container_name: k3s-server
|
||
hostname: k3s-server # имя ноды в кластере — см. комментарий у воркеров
|
||
command:
|
||
- server
|
||
- --tls-san=127.0.0.1
|
||
- --tls-san=k3s-server
|
||
- --tls-san=${K3S_API_HOST:-127.0.0.1} # внешний IP/домен для доступа к apiserver извне
|
||
- --disable=traefik
|
||
# Встроенный в k3s local-path-provisioner отключён: его заменяет чарт
|
||
# local-path-provisioner из репозитория (clusters/aero/controllers).
|
||
# Два провижинера с одним именем StorageClass дрались бы за одни и те же
|
||
# PVC. Каталог данных при этом НЕ меняется — чарту задан тот же путь
|
||
# /var/lib/rancher/k3s/storage, который смонтирован с хоста ниже.
|
||
- --disable=local-storage
|
||
privileged: true
|
||
cgroup: host # kubelet в cgroup v2 (Ubuntu 22.04+/RedOS)
|
||
restart: unless-stopped
|
||
environment:
|
||
K3S_TOKEN: ${K3S_TOKEN:-supersecrettoken}
|
||
K3S_KUBECONFIG_OUTPUT: /output/kubeconfig.yaml
|
||
K3S_KUBECONFIG_MODE: "644"
|
||
ports:
|
||
# Под istio ingressgateway занимает hostPort 80/443 ВНУТРИ этого
|
||
# контейнера и через nodeAffinity живёт только на control-plane, то есть
|
||
# именно здесь. Публикация этих портов наружу — единственное, что отделяет
|
||
# сервисы контура от внешнего мира; маршрутизация дальше по домену задаётся
|
||
# в infrastructure/istio-config/aero (Gateway + VirtualService).
|
||
- "80:80" # ingress http
|
||
- "443:443" # ingress https
|
||
# kube-apiserver наружу НЕ публикуем: доступ к нему — только изнутри
|
||
# compose-сети, по имени k3s-server:6443 (так к нему ходят flux-bootstrap
|
||
# и одноразовые init-контейнеры).
|
||
# Если понадобится внешний kubectl — раскомментируй и ОБЯЗАТЕЛЬНО
|
||
# ограничь фаерволом до доверенных адресов.
|
||
# - "6443:6443"
|
||
volumes:
|
||
- k3s-server-data:/var/lib/rancher/k3s # etcd/state, образы, манифесты — только named volume
|
||
- ./k3s:/output:z # отсюда забираем контекст k8s (:z — SELinux label для RedOS)
|
||
- ./k3s/registries.yaml:/etc/rancher/k3s/registries.yaml:ro,z # доступ containerd к cr.yandex
|
||
# PVC-данные local-path-provisioner (StorageClass local-path, он же default
|
||
# в k3s). Перекрываем ровно дефолтный путь провижинера, поэтому настраивать
|
||
# ConfigMap local-path-config не нужно. Bind-mount на хост означает, что
|
||
# файлы БД/очередей/объектов переживают пересоздание контейнера k3s и
|
||
# доступны для бэкапа обычными средствами хоста.
|
||
# Каталог намеренно не вложен в ./k3s: тот смонтирован ещё и как /output,
|
||
# и данные PVC засветились бы там же. У каждой ноды свой подкаталог, иначе
|
||
# сервер видел бы каталоги воркеров как посторонние PV в своём storage.
|
||
- ./k3s-storage/server:/var/lib/rancher/k3s/storage:z
|
||
tmpfs:
|
||
- /run
|
||
- /var/run
|
||
ulimits:
|
||
nproc: 65535
|
||
nofile:
|
||
soft: 65535
|
||
hard: 65535
|
||
healthcheck:
|
||
test: ["CMD", "kubectl", "get", "--raw=/readyz"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 30
|
||
start_period: 30s
|
||
|
||
# hostname задаёт ИМЯ НОДЫ в кластере (k3s берёт его из hostname). Без него
|
||
# нодой становится ID контейнера, а он меняется при пересоздании — и тогда
|
||
# local-path PV, привязанные к старому имени через nodeAffinity, «повисают».
|
||
k3s-worker-1:
|
||
<<: *k3s-worker
|
||
container_name: k3s-worker-1
|
||
hostname: k3s-worker-1
|
||
volumes:
|
||
- k3s-worker-1-data:/var/lib/rancher/k3s
|
||
- ./k3s-storage/worker-1:/var/lib/rancher/k3s/storage:z
|
||
- ./k3s/registries.yaml:/etc/rancher/k3s/registries.yaml:ro,z
|
||
|
||
k3s-worker-2:
|
||
<<: *k3s-worker
|
||
container_name: k3s-worker-2
|
||
hostname: k3s-worker-2
|
||
volumes:
|
||
- k3s-worker-2-data:/var/lib/rancher/k3s
|
||
- ./k3s-storage/worker-2:/var/lib/rancher/k3s/storage:z
|
||
- ./k3s/registries.yaml:/etc/rancher/k3s/registries.yaml:ro,z
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# GitOps-подложка контура: gitea (источник) + vault (секреты) + flux (в k3s).
|
||
# Порядок: gitea → gitea-init (админ/орг/репо) → flux-bootstrap (ставит Flux
|
||
# в k3s и привязывает его к репозиторию в gitea).
|
||
# ---------------------------------------------------------------------------
|
||
gitea:
|
||
image: ${GITEA_IMAGE:-gitea/gitea:1.22}
|
||
container_name: gitea
|
||
restart: unless-stopped
|
||
environment:
|
||
USER_UID: 1000
|
||
USER_GID: 1000
|
||
GITEA__server__ROOT_URL: ${GITEA_ROOT_URL:-http://localhost:3000/}
|
||
GITEA__server__SSH_PORT: ${GITEA_SSH_PORT:-2222}
|
||
# Пропускаем web-визард установки: конфигурация задаётся здесь, админа
|
||
# заводит gitea-init. Без INSTALL_LOCK первый запрос уводит на /install.
|
||
GITEA__security__INSTALL_LOCK: "true"
|
||
GITEA__database__DB_TYPE: sqlite3
|
||
GITEA__service__DISABLE_REGISTRATION: "true"
|
||
ports:
|
||
- "3000:3000" # web UI (80/443 заняты k3s)
|
||
- "${GITEA_SSH_PORT:-2222}:22" # git over ssh
|
||
volumes:
|
||
- ./gitea-data:/data:z # :z — SELinux label для RedOS
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-fsS", "http://localhost:3000/api/healthz"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 12
|
||
start_period: 20s
|
||
# Статический IP по образцу postgres/minio. Он обязателен: source-controller
|
||
# Flux работает ВНУТРИ k3s, где своя DNS (CoreDNS), и имя compose-сети
|
||
# `gitea` там не резолвится. Поды k3s дотягиваются до 172.28.0.0/16 через
|
||
# SNAT на ноде, поэтому в URL источника используется именно этот адрес.
|
||
networks:
|
||
default:
|
||
ipv4_address: 172.28.0.12
|
||
|
||
# Одноразовый провижининг gitea: администратор + организация + пустой репозиторий.
|
||
# Делит /data с gitea (CLI пишет в ту же sqlite), поэтому запускается тем же uid.
|
||
# Все шаги идемпотентны: повторный прогон на готовой инсталляции — no-op.
|
||
gitea-init:
|
||
image: ${GITEA_IMAGE:-gitea/gitea:1.22}
|
||
container_name: gitea-init
|
||
restart: "no"
|
||
user: "1000:1000"
|
||
depends_on:
|
||
gitea:
|
||
condition: service_healthy
|
||
environment:
|
||
GITEA_ADMIN_USER: ${GITEA_ADMIN_USER:-sarex}
|
||
GITEA_ADMIN_PASSWORD: ${GITEA_ADMIN_PASSWORD:?GITEA_ADMIN_PASSWORD is required}
|
||
GITEA_ADMIN_EMAIL: ${GITEA_ADMIN_EMAIL:-sarex@sarex.local}
|
||
GITEA_ORG: ${GITEA_ORG:-infra}
|
||
GITEA_REPO: ${GITEA_REPO:-iac}
|
||
volumes:
|
||
- ./gitea-data:/data:z
|
||
entrypoint: ["/bin/sh", "-ec"]
|
||
command:
|
||
- |
|
||
export GITEA_WORK_DIR=/data/gitea
|
||
CONF=/data/gitea/conf/app.ini
|
||
|
||
# 1. Администратор. Существующий пользователь → ненулевой код, это норма.
|
||
gitea --config "$$CONF" admin user create \
|
||
--admin --username "$$GITEA_ADMIN_USER" --password "$$GITEA_ADMIN_PASSWORD" \
|
||
--email "$$GITEA_ADMIN_EMAIL" --must-change-password=false 2>&1 \
|
||
| grep -v 'already exists' || true
|
||
|
||
API=http://gitea:3000/api/v1
|
||
AUTH="$$GITEA_ADMIN_USER:$$GITEA_ADMIN_PASSWORD"
|
||
|
||
# 2. Организация. 422 = уже существует.
|
||
curl -fsS -u "$$AUTH" -X POST "$$API/orgs" \
|
||
-H 'Content-Type: application/json' \
|
||
-d "{\"username\":\"$$GITEA_ORG\"}" >/dev/null 2>&1 || true
|
||
|
||
# 3. Репозиторий. auto_init=false — первый коммит сделает flux bootstrap.
|
||
curl -fsS -u "$$AUTH" -X POST "$$API/orgs/$$GITEA_ORG/repos" \
|
||
-H 'Content-Type: application/json' \
|
||
-d "{\"name\":\"$$GITEA_REPO\",\"private\":true,\"auto_init\":false}" \
|
||
>/dev/null 2>&1 || true
|
||
|
||
# Проверяем, что репозиторий действительно доступен — иначе flux bootstrap
|
||
# упадёт позже и менее внятно.
|
||
curl -fsS -u "$$AUTH" "$$API/repos/$$GITEA_ORG/$$GITEA_REPO" >/dev/null
|
||
echo "gitea-init: $$GITEA_ORG/$$GITEA_REPO готов"
|
||
|
||
vault:
|
||
image: ${VAULT_IMAGE:-hashicorp/vault:1.18}
|
||
container_name: vault
|
||
restart: unless-stopped
|
||
# Только "server", без -config: entrypoint образа сам добавляет
|
||
# -config=/vault/config. Явный путь к файлу внутри этого же каталога
|
||
# приводит к двойной загрузке конфига и падению на
|
||
# "listen tcp4 0.0.0.0:8200: bind: address already in use".
|
||
command: ["server"]
|
||
cap_add:
|
||
- IPC_LOCK
|
||
environment:
|
||
VAULT_ADDR: http://127.0.0.1:8200
|
||
volumes:
|
||
# :ro осознанно — entrypoint пишет в лог безвредные "chown: Read-only
|
||
# file system", но конфиг остаётся неизменяемым изнутри контейнера.
|
||
- ./vault/config:/vault/config:ro,z
|
||
- sarex-vault-data:/vault/file
|
||
- sarex-vault-init:/vault/init
|
||
healthcheck:
|
||
# /v1/sys/health отдаёт 200 только когда Vault инициализирован и распечатан
|
||
# (501 — не инициализирован, 503 — запечатан). Значит healthy здесь
|
||
# означает «готов принимать секреты», и на это можно вешать depends_on.
|
||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8200/v1/sys/health"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 30
|
||
start_period: 10s
|
||
# Статический IP: на него ссылается k8s-Endpoints `vault` (DNS-мост в k3s,
|
||
# namespace vault). Через этот мост vault-agent-injector и внедрённые в поды
|
||
# агенты ходят к Vault, который живёт здесь, в compose, а не в кластере.
|
||
networks:
|
||
default:
|
||
ipv4_address: 172.28.0.13
|
||
|
||
# Инициализация и авто-распечатывание Vault. Живёт постоянно: после рестарта
|
||
# хоста Vault поднимается запечатанным, и цикл распечатывает его сам.
|
||
# Ключ и root-токен лежат на отдельном volume (sarex-vault-init), не в git.
|
||
vault-init:
|
||
image: ${VAULT_IMAGE:-hashicorp/vault:1.18}
|
||
container_name: vault-init
|
||
restart: unless-stopped
|
||
depends_on:
|
||
vault:
|
||
condition: service_started
|
||
environment:
|
||
VAULT_ADDR: http://vault:8200
|
||
volumes:
|
||
- sarex-vault-init:/vault/init
|
||
entrypoint: ["/bin/sh", "-ec"]
|
||
command:
|
||
- |
|
||
UNSEAL=/vault/init/unseal.key
|
||
ROOT=/vault/init/root.token
|
||
|
||
while :; do
|
||
# `vault operator init -status`: 0 — инициализирован, 2 — нет,
|
||
# прочее — Vault ещё не отвечает. Под `set -e` ненулевой код нужно
|
||
# перехватить явно, иначе скрипт завершится.
|
||
rc=0
|
||
vault operator init -status >/dev/null 2>&1 || rc=$$?
|
||
|
||
if [ "$$rc" -eq 0 ]; then
|
||
# Инициализирован. `vault status`: 0 — распечатан, 2 — запечатан.
|
||
if ! vault status >/dev/null 2>&1; then
|
||
if [ -s "$$UNSEAL" ]; then
|
||
vault operator unseal "$$(cat $$UNSEAL)" >/dev/null \
|
||
&& echo "vault-init: распечатан"
|
||
else
|
||
echo "vault-init: Vault запечатан, но $$UNSEAL отсутствует —" \
|
||
"распечатать нечем (том sarex-vault-init потерян?)" >&2
|
||
fi
|
||
fi
|
||
|
||
elif [ "$$rc" -eq 2 ]; then
|
||
# Отвечает, но не инициализирован — инициализируем одним ключом.
|
||
# Текстовый вывод парсим awk'ом: jq в образе нет.
|
||
if vault operator init -key-shares=1 -key-threshold=1 > /vault/init/init.txt 2>/dev/null; then
|
||
awk '/^Unseal Key 1:/{print $$4}' /vault/init/init.txt > "$$UNSEAL"
|
||
awk '/^Initial Root Token:/{print $$4}' /vault/init/init.txt > "$$ROOT"
|
||
chmod 600 "$$UNSEAL" "$$ROOT" /vault/init/init.txt
|
||
vault operator unseal "$$(cat $$UNSEAL)" >/dev/null
|
||
echo "vault-init: инициализирован и распечатан"
|
||
|
||
# kv-v2 на пути secrets/ — так же, как в k8s-контурах
|
||
# (манифесты ссылаются на secrets/data/...).
|
||
VAULT_TOKEN="$$(cat $$ROOT)" vault secrets enable -path=secrets kv-v2 \
|
||
>/dev/null 2>&1 && echo "vault-init: включён kv-v2 на secrets/"
|
||
fi
|
||
fi
|
||
|
||
sleep 10
|
||
done
|
||
|
||
# Одноразовый провижининг namespace flux-system и DNS-моста до gitea.
|
||
# Должен отработать ДО flux-bootstrap: тот дожидается готовности GitRepository,
|
||
# а она невозможна, пока source-controller не может отрезолвить источник.
|
||
flux-k8s-init:
|
||
image: ${K3S_IMAGE:-rancher/k3s:v1.36.2-k3s1}
|
||
container_name: flux-k8s-init
|
||
restart: "no"
|
||
depends_on:
|
||
k3s-server:
|
||
condition: service_healthy
|
||
environment:
|
||
GITEA_BRIDGE_IP: ${GITEA_BRIDGE_IP:-172.28.0.12}
|
||
volumes:
|
||
- ./k3s/kubeconfig.yaml:/kube/config:ro,z
|
||
- ./k3s/manifests/flux:/manifests:ro,z
|
||
entrypoint: ["/bin/sh", "-ec"]
|
||
command:
|
||
- |
|
||
sed "s|__GITEA_BRIDGE_IP__|$$GITEA_BRIDGE_IP|g" /manifests/bridge-gitea.yaml \
|
||
| kubectl --kubeconfig /kube/config \
|
||
--server https://k3s-server:6443 --insecure-skip-tls-verify \
|
||
apply -f -
|
||
|
||
# Одноразовый bootstrap FluxCD внутрь k3s с привязкой к репозиторию в gitea.
|
||
# Flux — это контроллеры Kubernetes, в compose живёт только этот установщик.
|
||
# После успешного прогона источником правды становится gitea, а не compose.
|
||
flux-bootstrap:
|
||
image: ${FLUX_CLI_IMAGE:-ghcr.io/fluxcd/flux-cli:v2.8.5}
|
||
container_name: flux-bootstrap
|
||
restart: "no"
|
||
depends_on:
|
||
k3s-server:
|
||
condition: service_healthy
|
||
gitea-init:
|
||
condition: service_completed_successfully
|
||
flux-k8s-init:
|
||
condition: service_completed_successfully
|
||
# Один и тот же URL резолвится в двух разных контекстах: внутри k3s — через
|
||
# Service флакс-моста, здесь, в compose-сети, — через эту запись в /etc/hosts.
|
||
# Без неё flux CLI не смог бы запушить манифесты в репозиторий.
|
||
extra_hosts:
|
||
- "gitea.flux-system.svc.cluster.local:${GITEA_BRIDGE_IP:-172.28.0.12}"
|
||
environment:
|
||
GITEA_ADMIN_USER: ${GITEA_ADMIN_USER:-sarex}
|
||
GITEA_ADMIN_PASSWORD: ${GITEA_ADMIN_PASSWORD:?GITEA_ADMIN_PASSWORD is required}
|
||
GITEA_ORG: ${GITEA_ORG:-infra}
|
||
GITEA_REPO: ${GITEA_REPO:-iac}
|
||
AERO_GIT_BRANCH: ${AERO_GIT_BRANCH:-master}
|
||
AERO_FLUX_PATH: ${AERO_FLUX_PATH:-clusters/aero}
|
||
# Должен совпадать с ipv4_address сервиса gitea.
|
||
GITEA_BRIDGE_IP: ${GITEA_BRIDGE_IP:-172.28.0.12}
|
||
volumes:
|
||
- ./k3s/kubeconfig.yaml:/kube/config:ro,z
|
||
entrypoint: ["/bin/sh", "-ec"]
|
||
command:
|
||
- |
|
||
# k3s пишет kubeconfig с server: https://127.0.0.1:6443 — изнутри другого
|
||
# контейнера это неверный адрес. Подменяем на имя сервиса; сертификат
|
||
# apiserver уже содержит --tls-san=k3s-server, поэтому TLS проверяется
|
||
# штатно, без --insecure.
|
||
sed 's#https://127.0.0.1:6443#https://k3s-server:6443#' /kube/config > /tmp/kubeconfig
|
||
export KUBECONFIG=/tmp/kubeconfig
|
||
|
||
# Адрес источника — имя Service'а моста (flux-k8s-init), а не IP: так
|
||
# адрес gitea задан ровно в одном месте — переменной GITEA_BRIDGE_IP.
|
||
#
|
||
# --interval=2m задаёт периодичность проверок у GitRepository и корневой
|
||
# Kustomization в clusters/aero/flux-system/gotk-sync.yaml. Задаётся
|
||
# именно флагом, потому что этот файл генерирует сам bootstrap и правка
|
||
# руками затирается при следующем прогоне (в нём так и написано:
|
||
# "DO NOT EDIT"). Дефолтные 10 минут растягивали цикл «правка → проверка»
|
||
# до получаса.
|
||
flux bootstrap git \
|
||
--url="http://gitea.flux-system.svc.cluster.local:3000/$$GITEA_ORG/$$GITEA_REPO.git" \
|
||
--branch="$$AERO_GIT_BRANCH" \
|
||
--path="$$AERO_FLUX_PATH" \
|
||
--username="$$GITEA_ADMIN_USER" \
|
||
--password="$$GITEA_ADMIN_PASSWORD" \
|
||
--token-auth \
|
||
--allow-insecure-http \
|
||
--interval=2m
|
||
|
||
volumes:
|
||
k3s-server-data:
|
||
k3s-worker-1-data:
|
||
k3s-worker-2-data:
|
||
gitea-data:
|
||
sarex-vault-data: # file-хранилище Vault
|
||
sarex-vault-init: # unseal-ключ и root-токен (только для vault-init)
|
||
|
||
# Дефолтной сети задаём фиксированный subnet, чтобы закрепить IP за gitea и vault.
|
||
# На эти адреса ссылаются k8s-Endpoints DNS-мостов внутри k3s (namespace
|
||
# flux-system и vault): у кластера своя DNS, и имена compose-сети в ней не
|
||
# резолвятся, а поды дотягиваются до 172.28.0.0/16 через SNAT на ноде.
|
||
# Данные PVC (postgres, minio, rabbitmq) живут в k3s и томов здесь не имеют.
|
||
networks:
|
||
default:
|
||
ipam:
|
||
config:
|
||
- subnet: 172.28.0.0/16 |