- Jinja 49.1%
- HCL 41.1%
- Go Template 9.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .woodpecker | ||
| inventories/example | ||
| playbooks | ||
| roles | ||
| terraform/example | ||
| .ansible-lint | ||
| .editorconfig | ||
| .gitignore | ||
| .yamllint | ||
| ansible.cfg | ||
| LICENSE | ||
| README.md | ||
| requirements.yml | ||
asvo-platform
Код для развертывания стартового хоста платформы ASVO, который будет запускать кластер.
Поддержка
В настоящее время платформа находится в пред-релизном состоянии. Возможно обилие ошибок и глюков. Поддержка пользователей осуществляется пока только в закрытой тг-группе силами самого сообщества: https://t.me/+BYHEKrajkKw3MjVi
АРМ оператора
Желательно иметь Linux в качестве ОС, но наверняка можно как-то работать и под Windows.
На самом АРМ необходимо или желательно иметь следующий софт:
- Ansible, для раскатки плейбуков;
- kubectl, для управления кластером;
- git, чтобы работать в репозитории с кодом инфраструктуры;
- k9s, если хотите управлять кластером через удобный псевдографический интерфейс;
- skopeo, чтобы заполнить registry инфраноды, если вы будете делать установку в закрытый контур;
- OpenTofu, если планируете использовать его для централизованного создания и управления виртуальными машинами;
- openssl, чтобы генерировать собственные сертификаты;
Подготовка инфраноды
Мы выполняли тестирование на операционной системе Ubuntu 24.04, но вся инфраструктура контейнерезирована, и по сути, от системы требуется только docker с плагином compose, то есть, теоретически, должно заработать на любой ОС.
Необходимо, чтобы инфранода была доступна для оператора по SSH, а так же чтобы у оператора была возможность выполнять эсколацию привелегий (команда sudo), либо чтобы он работал напрямую как root (не рекомендуется).
Создание кластера с использованием OpenTofu с Proxmox-провайдером
Если у вас развернута открытая платформа виртуализации Proxmox, вы можете так же использовать OpenTofu для быстрого и управляемого создания виртуальных машин под свой кластер на нем. Порядок действий для этого будет примерно такой:
- Создайте в вашем Proxmox-кластере cloud-init-образ ubuntu, например, воспользовшись этой инструкцией;
- Настройте токен доступа к API вашего proxmox;
- Скопируйте шаблон
cp -r terraform/example terraform/your-super-cluster/и отредактируйте файлы в нем под ваше окружение (providers.tf— адрес API вашего Proxmox,terraform.tfvars— узел, пул, сеть, ssh-ключи и пароль root); 3.1. Скопируйте.env.exampleв.envи впишите туда токен доступа к API (файл в .gitignore, в репозиторий не попадёт); - Инициализируйте окружение командой
tofu init— она же создаст.terraform.lock.hclс хешами провайдера (обратите внимание, реестры OpenTofu и HashiCorp блокируют доступ с российских IP-адресов, для инициализации используйте proxy или vpn); - После инициализации выполните
tofu plan, убедитесь в корректности планируемых действий, после чего выполнитеtofu apply;
Использование Proxmox с OpenTofu даст Вам возможность быстро создавать и управлять параметризированными окружениями, это очень сильная магия.
Создание кластера на Virtualbox
Если у Вас достаточно мощностей вашего АРМа, вы можете развернуть тестовый кластер прямо на нем, используя VirtualBox. Необходимо обеспечить минимум 3 шт. Control-Plane нод с хотя бы 4Gb RAM, и одну инфраноду, так же с 4 Gb. Можете попробовать запустить кластер на локальном VBox с меньшими ресурсами, но мы это не тестировали. Так же вам понадобится постоянное хранилище, как минимум, два диска: один под ОС TalosLinux, другой для CSI кластера (Linstor). Создайте необходимы виртуальные машины, настройте сеть (желательно, c VboxHostOnly-адаптером). Рекомендуем в процессе на разных этапах делать снапшоты виртуальных машин - так отладка будет быстрее и легче, но, желательно, в выключенном состояннии, чтобы не было проблем с "разъезжанием" кластера из-за того что какая-то нода "вернулась в прошлое" прежде, чем это сделали другие.
Создание кластера на "голом железе" (bare metal)
Это самый "хардкорный" вариант для начала, однако, именно он раскрывает всю мощь kubernetes и платформы ASVO. Для создания кластера на "голом железе" вам необходимо сперва подготвить само железо.
Вот примерный чек-лист:
- У нод кластера 4+ Gb опервтивной памяти (возможно, получится запустить на меньшем количестве, но вряд ли это будет жизнеспособно)
- Выставлен правильный приоритет загрузки: 1) Системный диск -> 2) Загрузка по сети (iPXE)
- Сетевая карта ноды должна поддерживать iPXE-загрузку. Обычно с этим нет проблем у серверного оборудования, однако, десктопное может подкачать. Если у вас достаточно старая сетевая карта, попробуйте обновить её прошивку или BIOS, если она встроенная. В крайнем случае воспользуйтесь специальным загрузчиком iPXE.iso с официального сайта, который можно записать на usb-накопитель или даже компакт-диск, чтобы система смогла загрузиться и передать управление сетевой карте
- Если хотите простой раскатки Linstor, убедитесь что диски на всех нодах определяются в udev единообразно (например, /dev/sda для целевого системного диска /dev/sdb для HDD, /dev/sdc для SSD). В противном случае придется сильно править манифесты Linstor. Чтобы проверить порядок отображения, загрузитесь с любого live-образа linux, и выполните команду lsblk. Чтобы поменять порядок определения дисков в Udev, поменяйте порядок подключения накопителей к материнской плате.
- Все физические диски должны быть очищены от любой разметки. Для того чтобы очистить диски от разметки, загрузитесь с любого live-образа linux, и выполните команду `wipefs -fa /dev/sdX' последовательно для каждого диска (sda, sdb, sdc...)
- Зафиксируйте MAC-адреса всех ваших нод (
ip -br link) - это понадобится для дальнейшего составляения манифестов - Все ноды видят друг друга и инфраноду через L2-сеть
Подготовка манифестов
Воспользуйтесь готовым шаблоном inventories/example — это кластер из трёх control-plane и трёх worker-нод с собственным registry на инфраноде. Скопируйте его под имя своего стенда и отредактируйте основные файлы:
inventories/example
├── group_vars
│ ├── all.yml
│ └── infra
│ ├── cli.yml - настройка прикладных утилит, а так же параметры загрузки ядра Talos
│ ├── components.yml - системные компоненты, устанавливаемые вместе с ОС
│ ├── global.yml - глобальные переменные кластера
│ ├── infra.yml - переменные сервисов на инфраноде
│ ├── talm.yml - переменные для Talm - рендера конфигураций Talos-нод
│ └── vault.yaml - пароли и ключи (зашифруйте через ansible-vault)
└── inventory.yml - описание нод кластера
Все адреса, домены и пароли в шаблоне — плейсхолдеры (192.168.100.0/24, example.loc, registry.example.com, CHANGEME), их нужно заменить на свои.
Обратите внимание, что для первоначальной инициализации gitea плейбуку будет нужно, чтобы в папке /root/.ssh/ лежали ssh-ключи admin admin.pub админ-пользователя Gitea, чтобы инициализировать репозиторий с кодом инфраструктуры. Не забудьте сгенерировать и "донести" его туда и публичный ключ в манифест infra.yml (так же можно добавить свои ключи туда). Так же вам понадобится ключевая пара для puller, создать её можно с помощью ssh-keygen.
При редактировании переменных Вам помогут readme-файлы ролей, смотрите каталог roles. По правилам линтера ansible, имя переменной должно начинаться с имени роли.
Раскатка инфраноды
Последовательность установки инфраноды будет одной и той же.
Подготовьте инфраструктурные сервисы инфраноды:
ansible-playbook -i inventories/<ваш_стенд>/inventory.yml playbooks/bootstrap/infra.yml
По окончании работы этого плейбука, на инфраноде будут созданы сервисы tier-0:
- chrony, для синхронизации времени на нодах кластера
- dnsmasq, для обеспечения загрузки по нод кластера через сеть и резолвинг DNS
- gitea, для обеспечения GitOps для системных кластерных служб
- httpd, для доставки основных системных манифестов и параметров до того, как заработает GitOps
- registry, для контейнеров кластера
Все сервисы находятся в compose-проектах по пути /opt/asvotech. Если что-то по этому пути не работает, используйте docker compose logs для отладки.
Контроль успешного развертывания сервисов - отсутствие ошибок в выводе ansible, а так же работающие контейнеры:
root@infra:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c75ea7fc61f8 registry.example.com/library/httpd:2.4.65-alpine "httpd -D FOREGROUND…" 3 days ago Up 3 days (healthy) 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp httpd
6a53e7493f8f registry.example.com/library/registry:3.0.0 "/entrypoint.sh /etc…" 3 days ago Up 3 days (healthy) 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp registry
c9bcac4b023c registry.example.com/dockurr/chrony:4.8 "/bin/startup" 3 days ago Up 3 days (healthy) 0.0.0.0:123->123/udp, [::]:123->123/udp chrony
1f2b0e27e313 registry.example.com/gitea/gitea:1.24.6-rootless "/usr/bin/dumb-init …" 3 days ago Up 3 days (healthy) 0.0.0.0:2222->2222/tcp, [::]:2222->2222/tcp, 0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp gitea
2351851e6398 registry.example.com/postgres:16.9-alpine "docker-entrypoint.s…" 3 days ago Up 3 days (healthy) 5432/tcp gitea-postgres
72cb51ecc4aa registry.example.com/dockurr/dnsmasq:2.91 "/sbin/tini -- /usr/…" 3 days ago Up 3 days (healthy) dnsmasq
Если всё ок, можно приступать к сетевой загрузке. Включите ваши виртуальные или физические ноды, проверьте ход загрузки по iPXE. Если вы всё сделали правильно, Talos у вас должен загрузиться в maintence-режиме на каждой из нод. Если это так, переходите к следующему этапу.
Раскатка кластера
Для раскатки кластера достаточно запустить плейбук:
ansible-playbook -i inventories/<ваш_стенд>/inventory.yml playbooks/cluster/create.yml
Он сам проконтролирует корректность загрузки нод кластера, и проведёт все необходимые манипуляции. Если плейбук отработал без ошибок, поздравляем, ваш кластер успешно установлен! Проверим это, получив к нему административный доступ. Для этого выполните:
cd /opt/asvotech/cluster/*имя_вашего_кластера*
talm kubeconfig -n X.X.X.X -e X.X.X.X
где X.X.X.X - ip-адрес любого из мастеров (control-plane нод) вашего кластера.
В результате вы получте файл kubeconfig, в директории ~/.kube/config, который позволит администрировать кластер. Его можно забрать с инфраноды на АРМ администратора.
Выполните команду "kubectl get no" чтобы увидеть состояние ваших нод, например:
root@talos-dev-infra:~# kubectl get no
NAME STATUS ROLES AGE VERSION
dev-master-1 Ready control-plane 23d v1.33.1
dev-master-2 Ready control-plane 23d v1.33.1
dev-master-3 Ready control-plane 23d v1.33.1
dev-worker-1 Ready <none> 23d v1.33.1
dev-worker-2 Ready <none> 23d v1.33.1
Все ноды должны быть в статусе "Ready"
Так же выполните команду
kubectl get pod -A
чтобы увидеть список работающих подов кластера. Все поды должны быть в статусе "Running" или "Completed".
Если вы всё сделали правильно и получили такой результат, можете переходить к следующему этапу. Кстати, здесь отличное место, чтобы сделать контрольный снапшот ваших виртуальных машин!
Установка платформы и последующее администрирование кластера
Итак, вы получили пустой, готовый к работе кластер. Давайте теперь наполним его системными службами и сервисами. Для начала склонируйте на свой АРМ GitOps-репозиторий с инфраноды. Если вы предали в Gitea на этапе подготовки манифестов собственные пользовательские ssh-ключи, будет достаточно выполнить команду:
git clone ssh://git@*АДРЕС_ИНФРАНОДЫ*:2222/*ИМЯ_КЛАСТЕРА*/cluster.git
Вы получите код инфраструктуры, с помощью редактирования которого вы сможете управлять вашим кластером! В противном случае, залогиньтесь в gitea по адресу https://АДРЕС_ИНФРАНОДЫ:3000/ и дайте себе все нужные доступы.
Инициализационный репозиторий имеет много предустановок (адресация, ssl-сертификаты и т.д.), которые, скорее всего, не подойдут для вас. Просмотрите все основные манифесты в папке flux/, platform/ИМЯ_СЕРВИСА/config и platform/ИМЯ_СЕРВИСА/kustomization код и исправьте нужные места. Не забудьте сделать git add/git commit/git push после своих правок!
После того, как репозиторий с кодом будет настроен, самое время применить его! Для этого нужно выполнить три действия:
- Создайте секрет с ssh-отпечатком Gitea и git-пользователя для flux:
ssh-keyscan -p 2222 *АДРЕС_ИНФРАНОДЫ* > known_hosts
kubectl create secret generic flux-ssh \
--namespace=cluster-flux \
--from-file=identity=./puller \
--from-file=identity.pub=./puller.pub \
--from-file=known_hosts=./known_hosts
- Настройте репозиторий, манифестируя с помошью
kubectl apply -f flux-gitrepo.yamlсоответствующий манифест:
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: cluster
namespace: cluster-flux
spec:
interval: 1m0s
ref:
branch: main
url: ssh://git@1**АДРЕС_ИНФРАНОДЫ**:2222/**ИМЯ_КЛАСТЕРА**/cluster.git
secretRef:
name: flux-ssh
- Настройте flux применять все .yaml-манифесты из папки ./flux/ репозитория:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: cluster
namespace: cluster-flux
spec:
interval: 1m0s
path: ./flux/
prune: true
sourceRef:
kind: GitRepository
name: cluster
targetNamespace: cluster-flux
wait: true
После последнего действия, если вы всё сделали правильно в кластере появится множество различных kustomizations и helmrelease, которые постепенно будут устанавливаться в кластер. Мониторить их состояние можно, например, вот так:
watch kubectl -n cluster-flux get helmreleases.helm.toolkit.fluxcd.io
и
watch kubectl -n cluster-flux get kustomizations.kustomize.toolkit.fluxcd.io
Если в итоге всё раскаталось правильно, вы должны будете увидеть что-то вроде:
$ kubectl -n cluster-flux get kustomizations.kustomize.toolkit.fluxcd.io
NAME AGE READY STATUS
certmanager-configs 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
cluster 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
cluster-auth 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
cluster-auth-configs 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
cluster-console 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
cluster-dns-configs 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
cluster-observability 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
cluster-s3 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
ingress 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
metallb-configs 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
metallb-kustomizations 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
piraeus-operator 3d True Applied revision: main@sha1:387a91bb45dc797911832f90a19c31b1c3f5e9d1
$ kubectl -n cluster-flux get helmreleases.helm.toolkit.fluxcd.io
NAME AGE READY STATUS
cluster-consoloe 3d True Helm install succeeded for release cluster-console/headlamp.v1 with chart headlamp@0.37.0
cluster-csi-affinity-controller 3d True Helm install succeeded for release cluster-csi/linstor-affinity-controller.v1 with chart linstor-affinity-controller@1.5.0
cluster-csi-linstor 3d True Helm install succeeded for release cluster-csi/linstor.v1 with chart linstor-cluster@1.1.1
cluster-dbms-cnpg 3d True Helm install succeeded for release cluster-dbms/cnpg.v1 with chart cloudnative-pg@0.26.1
cluster-dbms-dragonfly-operator 3d True Helm install succeeded for release cluster-dbms/dragonfly-operator.v1 with chart dragonfly-operator@v1.3.1
cluster-dbms-mariadb-crds 3d True Helm install succeeded for release cluster-dbms/mariadb-crds.v1 with chart mariadb-operator-crds@25.10.2
cluster-dbms-mariadb-operator 3d True Helm install succeeded for release cluster-dbms/mariadb-operator.v1 with chart mariadb-operator@25.10.2
cluster-dns 3d True Helm install succeeded for release cluster-dns/powerdns.v1 with chart powerdns@0.1.0
cluster-dns-external-dns 3d True Helm install succeeded for release cluster-dns/external-dns.v1 with chart external-dns@1.19.0
cluster-dns-operator 3d True Helm install succeeded for release cluster-dns/powerdns-operator.v1 with chart powerdns-operator@0.6.0
cluster-ingress 3d True Helm install succeeded for release cluster-ingress/ingress-int.v1 with chart ingress-nginx@4.13.3
cluster-ingress-ext 3d True Helm install succeeded for release cluster-ingress/ingress-ext.v1 with chart ingress-nginx@4.13.3
cluster-keycloak-edp-operator 3d True Helm install succeeded for release cluster-auth/keycloak-edp-operator.v1 with chart keycloak-operator@1.29.0
cluster-keycloak-operator 3d True Helm install succeeded for release cluster-auth/keycloak-operator.v1 with chart keycloak-operator@1.0.20251104042352
cluster-lb 3d True Helm install succeeded for release cluster-lb/metallb.v1 with chart metallb@0.15.2
cluster-observability 3d True Helm install succeeded for release cluster-observability/vm.v1 with chart victoria-metrics-k8s-stack@0.63.5
cluster-pki 3d True Helm install succeeded for release cluster-pki/cert-manager.v1 with chart cert-manager@v1.19.1
cluster-s3 3d True Helm install succeeded for release cluster-s3/sys-seaweedfs.v1 with chart seaweedfs@4.0.400
cluster-s3-csi 3d True Helm install succeeded for release cluster-s3/sys-seaweedfs-csi.v1 with chart seaweedfs-csi-driver@0.2.3
И на этом поздравляем, вы - великолепны!
Удаление кластера
Если ваш кластер был создан на виртуальных машинах, самый быстрый и простой способ удалить его - просто откатиться к начальному снапшоту с "пустыми" виртуалками. Так же, если вы использовали OpenTofu, можно снести весь ваш стенд, выполнив tofu destroy.
В случае с железным кластером, Вам сперва потребуется затереть разметку на всех дисках с данными, например, вот так:
#!/bin/bash
linstor_nodes=$(kubectl -n cluster-csi get pod | grep linstor-satellite | awk '{print $1}')
for node in $linstor_nodes; do
echo $node;
kubectl -n cluster-csi exec -it $node -- wipefs -fa /dev/sdb
kubectl -n cluster-csi exec -it $node -- wipefs -fa /dev/sdc
done
После чего запустить плейбук, разрушающий кластер:
ansible-playbook -i inventories/<ваш_стенд>/inventory.yml playbooks/cluster/reset.yml
После успешного сброса ноды снова загрузятся в maintence mode, и их можно будет использовать повторно
Лицензия
Copyright (C) 2026 ASVO
Этот проект распространяется на условиях GNU Affero General Public License версии 3 или, по вашему выбору, любой более поздней версии. Полный текст — в файле LICENSE.