Я почти никогда не касался настоящего кровавого энтерпрайза, поэтому те проекты, что я веду один, я развёртываю просто: nginx на хосте как reverse proxy, каждый отдельный сервис в своём контейнере systemd-nspawn. Работает как часы. Но вот никак не могу стандартизировать процесс обновления сервисов. Например, один из вариантов, которые я использую это git push. На удалённой стороне настроен git-hook, который сперва разворачивает приложение в отдельной дериктории, потом переключаёт символические ссылки и, наконец, вызывает systemctl reload <service> для бесшовной миграции на новую версию. Считаю, что это решение на коленке, хотя бы потому, что код git-hook лежит безпризорный на сервере, никак не версионируется. Да и развёртывание иногда происходит с ошибками, поэтому приходится заходить по ssh и ручками решать проблемы. Сейчас подумываю над тем, чтобы вервис заворачивать в образ. Образ можно собирать на локальной машине и как-то его доставлять на хост, там перезагружать через machinectl. Но тут же бесшовно не получается без нескольких реплик, нужно что-то думать.
Короче, если вы знаете какой-нибудь пример простого и надёжного развёртывания, буду рад о нём узнать Докеры и всякое монструозное говно для современых разрабов-одуванчиков не предлагать.
Здравствуйте, cppguard, Вы писали:
C>Короче, если вы знаете какой-нибудь пример простого и надёжного развёртывания, буду рад о нём узнать Докеры и всякое монструозное говно для современых разрабов-одуванчиков не предлагать.
Т.е. богомерзкий systemd это не для одуванчиков, а православный докер это для одуванчиков?
Альтернатива у тебя ровно одна: берешь ansible и деплоишь пушем со стороны CI/CD. Ансибл скрипты можно положить в гит. Но стопроцентно надежно в любом случае не получится, докер придумали не просто так.
Здравствуйте, Miroff, Вы писали:
M>Т.е. богомерзкий systemd это не для одуванчиков, а православный докер это для одуванчиков?
Как-то так =) Почему systemd богомерзский?
M>Альтернатива у тебя ровно одна: берешь ansible и деплоишь пушем со стороны CI/CD. Ансибл скрипты можно положить в гит. Но стопроцентно надежно в любом случае не получится, докер придумали не просто так.
Так я же писал, что собрать всё в образ и запихнуть на сервер я и с systemd могу. Как сделать zero downtime без дополнительных инстансов? Или докер прям из коробки поддерживает такое?
On Apr 22, 2024, 3:29 AM, cppguard <125804@users.rsdn.org> wrote:
C>Короче, если вы знаете какой-нибудь пример простого и надёжного развёртывания, буду рад о нём узнать Докеры и всякое монструозное говно для современых разрабов-одуванчиков не предлагать.
Какую характеристику ты хочешь улучшить? Сколько продуктов у тебя в проде поставляется?
Если в целом говорить, то сейчас принят подход IaC, но он лучше всего показывает себя, когда продуктов чем больше — тем лучше. На 1-2 продуктов я бы не занимался фигней.
zero-downtime недостижим малой кровью, у devOps-ов так же нет серебряной пули, тут даже k8s редко спасет для "zero-downtime". Если разработчик и devOps — это два разных человека, а не только роли, то используют обобщенные стартеры сценариев (например, rundeck), сами сценарии для оркестратора использую, как и все, ansible. Версии продуктов берутся из репозитория nexus.
PS. Описаная схема работает почти со всем. Геморрой доставляют только выкатка на AppStore и AppsMarket. Последний до сих пор делаю через скрипты из bamboo
⸻ ❧ “If you can’t yet do great things, do small things in a great way.” ― Napoleon Hill
Здравствуйте, cppguard, Вы писали:
C>Но вот никак не могу стандартизировать процесс обновления сервисов. C>Докеры и всякое монструозное говно для современых разрабов-одуванчиков не предлагать.
ежики плакали кололись но продолжали изобретать k8s из говна и баша
Серебряной пули у меня нет.
Но, из практики, в общем случае лучше, когда сборка артефактов и собственно их деплой разделены, логически и по времени.
Сборка создаёт версионированные артефакты.
Не суть важно в виде docker/packet образов, msi-инсталляторов или zip-файлов и кладет их в хранилище артифактов.
Это может быть что-то специализированное типа nexus/artifactofy, или, например, s3 bucket или network drive (smb, cerf, etc).
А деплой умеет взять артифакт по имени/версии и раскатать его на нужное окружение/ноду.
В простейшем случае деплоем может быть обычный bash-скрипт install.sh, который ты по ssh копируешь на сервер и вызываешь как нибудь так: install.sh -s my-service1 -v 1.2.3-beta
По поводу zero downtime конкретно с systemd. У него есть фича проброса сокета (socket activation), которая в теории как раз позволяет перезапускать сервис, не отключая активных клиентов.
Но само приложение должно это поддерживать явно. Имхо, изрядный геморрой.
Вот почитай, если интересно https://dev.to/vmihailenco/golang-zero-downtime-restarts-and-deploys-using-systemd-5b8o
RD>По поводу zero downtime конкретно с systemd. У него есть фича проброса сокета (socket activation), которая в теории как раз позволяет перезапускать сервис, не отключая активных клиентов. RD>Но само приложение должно это поддерживать явно. Имхо, изрядный геморрой.
Я в точности так и делаю. Возможно, я неправильно описал процесс. Ещё раз. У меня systemd-nspawn запускает контейнеры через сокетную активацию. А перед контейнерами стоит nginx, проксирующий все внешние запросы через unix socket. Серверы приложений: puma, gunicorn — поддерживают как сокетную активацию, так и zero downtime reload. Вся проблема заключается в том, что для достижения zero downtime мне приходится каким-то образом вручную обновлять приложения — развёртывать очередную версию и переключать символические ссылки. Я бы мог запаковать всё в образ и запустить образ как контейнер. Но тогда теряется нужный zero downtime. Вот об этом и был вопрос.
Здравствуйте, cppguard, Вы писали:
C>Короче, если вы знаете какой-нибудь пример простого и надёжного развёртывания, буду рад о нём узнать Докеры и всякое монструозное говно для современых разрабов-одуванчиков не предлагать.
Не нравится docker, возьми bocker Только чем docker монструозен, не понятно.
Здравствуйте, cppguard, Вы писали:
C>Как-то так =) Почему systemd богомерзский?
Потому что не unix way.
C>Так я же писал, что собрать всё в образ и запихнуть на сервер я и с systemd могу. Как сделать zero downtime без дополнительных инстансов? Или докер прям из коробки поддерживает такое?
Не поддерживает. Если ты хочешь zero downtime, тебе нужно поднять второй инстанс, убедиться что он работает, переключить трафик на новый инстанс и остановить старый инстнс. Или откатиться обратно, если новый инстанс не работает. По другому даже теоретически невозможно. Как именно ты этот процесс автоматизируешь большого значения не имеет. Хоть ansible, хоть bash, хоть chef, работать будет одинаково. В мире докера из коробки такое умеют docker swarm и kubernetes, но ради одного сервиса поднимать кубер это из пушки по воробьям. К тому же твое приложение должно быть адаптировано под кубер.
Здравствуйте, m2user, Вы писали:
RD>>Это может быть что-то специализированное типа nexus/artifactofy, или, например, s3 bucket или network drive (smb, cerf, etc).
M>Что такое cerf?
ceph, скорее всего. Лучшая сетевая файловая система на сегодняшний день.
переключать символические ссылки. Я бы мог запаковать всё в образ и запустить образ как контейнер. Но тогда теряется нужный zero downtime. Вот об этом и был вопрос.
zero downtime это что? почему тебе кажется, что с твоим переключением ссылок у тебя zero downtime?
Здравствуйте, Константин Л., Вы писали:
КЛ>zero downtime это что? почему тебе кажется, что с твоим переключением ссылок у тебя zero downtime?
Мне не кажется, я совершенно точно знаю. Те серверы, что я использую (puma и gunicorn) работают так:
1. Содержимое приложения (код и вспомогательные файлы) полностью загружается в память.
2. При этом путь до файлов сохраняется.
3. Когда приходит сигнал перезагрузить конфигурацию (например, SIGHUP), приложение перезагружается, используя сохранённый путь.
3а. Если путь это символическая ссылка, то разрешение ссылки до реального пути происходит каждый раз.
3б. Запросы, которые появились в процесс перезагрузки конфигурации либо обслуживаются старым кодом, либо уже новым. Но не теряются в процессе, и не возникает конфликта версий.
[]
C>3б. Запросы, которые появились в процесс перезагрузки конфигурации либо обслуживаются старым кодом, либо уже новым. Но не теряются в процессе, и не возникает конфликта версий.
в начальном посте ты пишешь "Да и развёртывание иногда происходит с ошибками". То есть толку от твоего zero-downtime не много, раз приходится руками что-то постоянно править.
то самое говно (по твоим словам) k8s, docker etc. зато делает свою работу четко.
Здравствуйте, Константин Л., Вы писали:
КЛ>в начальном посте ты пишешь "Да и развёртывание иногда происходит с ошибками". То есть толку от твоего zero-downtime не много, раз приходится руками что-то постоянно править.
Что-то ты тёплое с мягким путаешь. Если ошибка произошла, то версии не переключаются, запросы не теряются.
КЛ>то самое говно (по твоим словам) k8s, docker etc. зато делает свою работу четко.
Чем docker лучше systemd-nspawn?
Здравствуйте, cppguard, Вы писали:
C>Здравствуйте, Константин Л., Вы писали:
КЛ>>в начальном посте ты пишешь "Да и развёртывание иногда происходит с ошибками". То есть толку от твоего zero-downtime не много, раз приходится руками что-то постоянно править. C>Что-то ты тёплое с мягким путаешь. Если ошибка произошла, то версии не переключаются, запросы не теряются.
да, но толку от всей связки никакого, а значит zero downtime это уже не конкурентное преимущество
КЛ>>то самое говно (по твоим словам) k8s, docker etc. зато делает свою работу четко. C>Чем docker лучше systemd-nspawn?
Здравствуйте, cppguard, Вы писали:
КЛ>>то самое говно (по твоим словам) k8s, docker etc. зато делает свою работу четко. C>Чем docker лучше systemd-nspawn?
Оба контейнеры по сути, но docker это полное решение, включая репы, развёртывание, заливку нужного, сборку образов, слои, кеши и т.п.
А nspawn это только сам запускальщик контейнера, остальное надо колхозить с костылями.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай