Как я построил свой Homelab по принципам GitOPS

Привет всем. Довольно давно слежу за проектом samohosting, а вот написать только сейчас решился.

В общем в очередной раз решил снести весь свой лаб и построить заново и сейчас расскажу то как у меня всё устроено.

Немного про железо.
2 железные ноды на старых Xeon-ах:

  • Intel(R) Xeon(R) CPU E5-2670 v3

  • 128 GB RAM

  • несколько SSD дисков, общим объемом 6 TB

  • Intel(R) Xeon(R) CPU E5-2690 v4

  • 128 GB RAM

  • несколько SSD дисков, общим объемом 3 TB

  • 2 x Nvidia RTX 3090 24GB

Раньше я держал еще в свой инстанс gitlab под весь код, но это такая дурка и больше я поддерживать его не хочу, так что решил уехать в обычный внешний официальный gitlab на бесплатный тариф.

Из этих двух железок создан Proxmox кластер, на котором собственно весь workload и живет.

Я старался сразу делать так, чтобы в случае чп или чего либо еще, мне потом не пришлось бы вспоминать что и как у меня настроено, чтобы всю инфраструктуру можно было бы поднять из гита, по этому GitOps first подход:

  1. Terraform - накатываем виртуалки в proxmox. Если кто решит тоже идти в терраформ, сразу рекомендую использовать данного провайдера. Он довольно хорошо и гибко себя показал.

  2. Ansible - для раскатывания k8s с KubeVip для того чтобы при смерти одного из мастеров kubevip сам менял мастера и всё продолжило бы работать. Кластер встает из kubeadm. Пришлось долго повозиться с тем чтобы это всё взлетело.

    Помимо кубера, ansible еще и рулит теми настройками ПО, которые не лезут в кубер, а остаются на виртуалках - postgres, harbor, traefik, ollama и так далее.

  3. ArgoCD - ну тут собственно и так и есть GitOps подход. 95% всего работает в кубе и поднимается с помощью арго.

Входной точкой в мою сеть является есс-но роутер. У меня OpenWRT и он весь траффик с 80 и 443 порта направляет в traefik и тот уже дальше рулит. В кубере Istio Ingress Gateway + некоторое ПО еще и в Service Mesh для хорошего мониторинга из коробки.

Помимо самого Proxmox Terraform еще и рулит рилмами и клиентами в KeyCloak. Почти все внешние сервисы мои закрыты кейлоком, не закрыты лишь те которые публичны.
Если ПО поддерживает OIDC из коробки, то там настраиваю отдельный clientId, если нет, то траффик идет через плагин oidc для Traefik.

Мониторинг - victoria metrics k8s stack. Отличная история чтобы сразу из коробки всё работало.
Логи - Vector + Elastic + Kibana.

Логи и метрики собираются как с кластера кубера, так и с виртуалок.

Чуть скомкано расписал, но вот как есть. Если есть вопросики или что-то еще - буду рад ответить.

7 лайков

Вот это приличный подход, по железу вопрос у меня аналогичная сборка - шумит как самолёт выхода не нахожу либо на балкон ставить либо кулера Noctua или аналоги. В комнате ее держать шумно.

1 лайк

Есть аналог дешевле в виде Arctic. + замена PSU на более тихие вариации. Помогут если уж и не снизить уровень шума, то хотя бы сделать его не таким раздражающим.

так и не успел в тележку кинуть вопросик алексей. У меня примерно таккая е лаба, мне бы немного гайд - как дотянуть кк до уровня cicd развертывания приложений, ну и по куберу ты классно расписал. я пока в такие дебри не лезу

но интересно

Пиши конечно, чем смогу помогу

Не подскажите, ansible может работать по принципу “state“? Т.к. не особо знаком с этой штукой, и вот хочу тож пойти по такому пути. Есть конечно для этого NixOS, по сути почти идеал, но для моей задачи закрытой инфры что без сети может проработать пару лет, не подходит, т.к. требует слишком громоздкой инфры

Тут есть 3 типа команд/подхода (для каждой команды/действия независимо)

  1. Привести с нужному состоянию - файл должен присутствовать, если нет, то создаем, данный пакет должен быть установлен, если нет, то устанавливаем
  2. Выполняем действие без условий - обновляем пакеты, копируем конфиги, что-то запускаем
  3. Ручная логика - проверили, что репозиторий не установлен, тогда копируем файлы, прописываем репозиторий, выполняем обновление. Тут мы прописываем несколько команд и условия выполнения последующих в зависимости от статуса предыдущих
  4. Триггер - выполнить действие в конце, если сработал триггер, например, перезапустить сервис если были изменены конфиги (в соответствующих командах взводим триггер)

Сохранения состояния по типа terraform нет

Ну, значится буду сочитать подходы и 1 и 3

в большинстве случаев ansible используется как средство приведения системы в нужное состояние. task-и в ansible сами проверяют нужно ли выполнять действие и репортят о том было ли реально выполнено изменение. state долгосрочно хранить не имеет особого смысла в реалиях ansible. проверка обычно не занимает много времени/ресурсов. только если у вас очень сложная кастомная конфигурация может потребоваться написать какие то доп. условия

в ansible есть такая концепция как facts - информация автоматически собранная с хоста под контролем ansible, которая кешируются, сохраняется между запусками ansible команд. Но если вы хотите написать логику на основе фактов, это нужно делать явно, “из коробки” нет никакой магии/автоматизации вокруг этого

ansible может быть настроен довольно гибко, “условный state” можно реализовать самому буквально 20 строками конфигурации. Но опять же “из коробки” нет готового функционала который учитывает этот state. нужно дополнять playbook-и проверками state самостоятельно, ну или путь кастома - модуль какой нибудь написать

Понял принял спасибо, я понимаю что из коробки решения не будет. Главное что это в приницпе можно сделать.

А что конкретно Вам надо? Если вам нужен стейт, то есть 2 варианта

  1. Вам не нужен стейт
  2. Вам нужен другой инструмент

Тянуть стейд в ansible нет смысла, как уже было написано выше: проверка состояния и приведение к этому состоянию работает очень быстро, единственный минус, как по мне, так это то, что он использует Python на удаленной стороне, как для сбора фактов, так и для выполнения большинства команд, а у меня очень много мелких alpine окружений и python ставить туда вообще не хочется, поэтому таски пишутся на чистом шеле и достаточно громоздкие без “магии” ansible

По сути команды распаковываются в что-то вида
if [ ! -f /etc/file.ext ] ; then cp src /etc/file.ext; fi
if dpkg -l | grep adduser | grep '^rc' ; then apt install -y adduser ; fi

facts используется в основном для полиморфности, например, для установки nginx в систему одинаковой командой, а под капотом вызываются команды для конкретного дистрибутива

Если мы говорим про условный terraform, и его стейт, то там создаются ресурсы, этих ресурсов может быть много и стейт нужен в том числе для того, чтобы понимать, что условная dbvm создалась в облаке с id 12345 и при следующем запуске нам не надо создавать виртуалку заново, если нам надо настроить группу безопасности для этой виртуалки, то из стейта получаем ее id и потом по этому id производим настройку сущностей в другой системе

Поэтому я и написал, что или стейт не нужен в ansible или нужную задачу лучше решать более подходящими для нее инструментами

В данный момент я ищю инструментарий с помощью которого я мог бы описывать инфраструктуру в виде кода + держать это всё с помощью git(т.е. GitOps), а так же что бы это всё работало в среде без сети долгое время(я не с РФ, однако всё равно рассматриваю и пытаюсь найти решения что будут работать без сети вообще, скажем так на всякий случай).
Я уже имел 1.5 годовой опыт с NixOS как основной ОС для домашнего ПК и сервера, и удалённых VPS, решение это крайне интересное, однако оно требует во истенну моунструозную инфраструктуру(как минимум дисковое пространство от 300ТБ) чисто для поддержания репозиториев в стабильной ветке, к тому же имеет свой ЯП который делали под чем-то тяжелым, потому отсеиваю его из за этого.
Ansible с хост ос alpine linux и VM/LXC на debian или том же alpine выглядят сильно экономичнее, т.к. репозиторий обоих систем весят где-то до 600гб для AMD64, и при этом всё остальное же не требует огромного количества места для инфры. Скажем так попытка сделать как в NixOS но другими подходами и инструментами, и блин сильно менее требовательно