Southbridge у Челябінську та Бітрікс у Kubernetes

У Челябінську проходять мітапи системних адміністраторів Sysadminka, і на останньому з них я робив доповідь про наше рішення для роботи додатків на 1С-Бітрікс у Kubernetes.

Бітрікс, Kubernetes, Сeph – відмінна суміш?

Розповім, як ми з усього цього зібрали діюче рішення.

Поїхали!

Southbridge у Челябінську та Бітрікс у Kubernetes

Мітап пройшов 18 квітня у Челябінську. Про наші мітапи можна почитати в Timepad і подивитися на ютубі.

Якщо хочете прийти до нас з доповіддю або як слухач - велкам, пишіть на [захищено електронною поштою] і в телеграмах t.me/vadimisakanov.

Моя доповідь

Southbridge у Челябінську та Бітрікс у Kubernetes

Слайды

Рішення «Бітрікс у Kubernetes, версія Southbridge 1.0»

Я розповім про наше рішення у форматі «для чайників у Kubernetes», як це було зроблено на мітапі. Але гадаю, що слова Бітрікс, Docker, Kubernetes, Ceph вам відомі хоча б на рівні статей у Вікіпедії.

Що взагалі є готового про Бітрікс у Kubernetes?

У всьому інтернеті дуже мало інформації про роботу програм на Бітрікс у Kubernetes.
Я знайшов лише такі матеріали:

Доповідь Олександра Сербула, 1С-Бітрікс, та Антона Тузлукова з Qsoft:

Рекомендую послухати його.

Розробка власного рішення від користувача serkyron на Хабрі.
Знайшов ще таке рішення.

ІІІ… власне, все.

Попереджаю, якість роботи рішень за посиланнями вища ми не перевіряли 🙂
До речі, під час підготовки нашого рішення я спілкувався з Олександром Сербулом, тоді його доповіді ще не було, тож у моїх слайдах є пункт «Бітрікс не користується Kubernetes».

Але готових Docker образів для роботи Бітрікс у Docker вже багато: https://hub.docker.com/search?q=bitrix&type=image

Чи достатньо для створення повноцінного рішення для Бітрікс в Kubernetes?
Ні. Є багато проблем, які потрібно вирішити.

У чому проблеми з Бітрікс у Kubernetes?

Перша – готові образи з Dockerhub не підходять для Kubernetes

Якщо ми хочемо побудувати мікросервісну архітектуру (а в Kubernetes ми зазвичай хочемо), додаток у Kubernetes потрібно розділяти на контейнери та домагатися того, щоб кожен контейнер виконував одну маленьку функцію (і робив це добре). Чому лише одну? Якщо коротко — що простіше, то надійніше.
Якщо автентичніше - подивіться цю статтю та відео, будь ласка: https://habr.com/ru/company/southbridge/blog/426637/

Docker образи в Dockerhub переважно побудовані за принципом «все в одному», тому нам довелося все-таки робити свій велосипед і навіть образи робити з нуля.

Друга - код сайту правиться з адмін-панелі

Створили новий розділ на сайті – оновився код (додалася директорія з назвою нового розділу).

Змінили властивості компонента з адмін-панелі – змінився код.

Kubernetes "за замовчуванням" з таким працювати не вміє, контейнери повинні бути не змінними (Stateless).

Причина: кожен контейнер (під) у кластері обробляє лише частину трафіку. Якщо змінити код тільки в одному контейнері (поде), то в різних подах код буде різним, сайт працюватиме по-різному, різним користувачам будуть відображатися різні версії сайту. Так жити не можна.

Третя – треба вирішувати питання з деплоєм

Якщо у нас моноліт і один «класичний» сервер, все просто: розгортаємо нову кодову базу, проводимо міграцію БД, переключаємо трафік на нову версію коду. Перемикання відбувається миттєво.
Якщо у нас сайт у Kubernetes, розпиляний на мікросервіси, контейнерів з кодом багато — ой. Потрібно збирати контейнери з новою версією коду, викочувати їх замість старих, правильно виконувати міграцію БД і в ідеалі робити це непомітно для відвідувачів. Добре, що в цьому Kubernetes нам допомагає, підтримуючи цілу хмару різних видів деплою.

Четверта – треба вирішувати питання зі зберіганням статики

Якщо ваш сайт важить «лише» 10 гігабайт і ви розгорнете його повністю в контейнерах, ви отримаєте контейнери вагою 10 гігабайт, які будуть деплоїтися вічність.
Потрібно зберігати найважчі частини сайту поза контейнерами, і постає питання, як правильно це робити

Чого немає у нашому рішенні

Зовсім код Бітрікс на мікрофункції/мікросервіси не розрізаний (так, щоб реєстрація окремо, модуль інтернет-магазину окремо, тощо). Всю кодову базу ми зберігаємо у кожному контейнері цілком.

Базу в Kubernetes також не зберігаємо (я все ж таки реалізовував рішення з базою в Kubernetes для оточення розробників, але не для продакшн).

Адміністраторам сайту все-таки буде помітно, що сайт працює у Kubernetes. Функція "перевірка системи" працює некоректно, для редагування коду сайту з адмін-панелі потрібно спочатку натискати кнопку "хочу відредагувати код".

З проблемами визначилися, з необхідністю реалізації мікросервісності визначилися, мета зрозуміла - отримати працюючу систему для роботи додатків на Бітрікс у Kubernetes, зберігши і можливості Бітрікс, та переваги Kubernetes. Починаємо реалізацію.

Архітектура

Багато «робітників» подів із вебсервером (worker'и).
Один під з крон-тасками (обов'язково лише один).
Один upgrade під редагування коду сайту з адмін-панелі (також обов'язково тільки один).

Southbridge у Челябінську та Бітрікс у Kubernetes

Вирішуємо питання:

  • Де зберігати сесії?
  • Де зберігати кеш?
  • Де зберігати статику, не розміщувати ж гігабайти статики у купі контейнерів?
  • Як працюватиме база даних?

Docker образ

Починаємо зі складання Docker образу.

Ідеальний варіант - у нас один універсальний образ, на його основі ми отримуємо і worker-поди, і поди з кронтасками, і upgrade поди.

Ми зробили саме такий образ.

У нього включений nginx, apache/php-fpm (можна вибрати під час складання), msmtp для надсилання пошти, та cron.

При складанні образу в директорію /app копіюється повна кодова база сайту (за винятком тих частин, що ми винесемо в окремий shared storage).

Мікросервісність, сервіси

worker піди:

  • Контейнер з nginx + контейнер apache/php-fpm + msmtp
  • msmtp винести в окремий мікросервіс не вийшло, Бітрікс починає обурюватись, що не може безпосередньо надіслати пошту
  • У кожному контейнері є повна кодова база.
  • Заборона зміни коду в контейнерах.

cron під:

  • контейнер з apache, php, cron
  • в комплекті повна кодова база
  • заборона на зміну коду у контейнерах

upgrade під:

  • контейнер з nginx + контейнер apache/php-fpm + msmtp
  • заборони на зміну коду у контейнерах немає

сховище сесій

сховище кешу Бітрікс

Ще важливо: паролі для підключення до всього, від бази даних до пошти ми зберігаємо в kubernetes secrets. Отримуємо бонус, паролі видно лише тим, кому ми даємо доступ до секретів, а не всім, хто має доступ до кодової бази проекту.

Сховище для статики

Можна використовувати будь-що: ceph, nfs (але nfs не рекомендуємо для продакшн), network storage від «хмарних» провайдерів, etc.

Сховище потрібно буде підключати в контейнерах /upload/ директорію сайту та інші директорії зі статикою.

База даних

Для простоти радимо виносити базу за межі Kubernetes. База в Kubernetes - окреме складне завдання, вона зробить схему набагато складнішою.

Сховище сесій

Використовуємо memcached 🙂

Він добре справляється із зберіганням сесій, кластеризується, «нативно» підтримується як session.save_path у php. Така система багато разів відпрацьована ще в класичній монолітній архітектурі, коли ми будували кластери з великою кількістю веб-серверів. Для деплою ми використовуємо helm.

$ helm install stable/memcached --name session

php.ini - тут в образі задані налаштування для зберігання сесій в memcached

Ми використовували Environment Variables для передачі даних про хостів з memcached https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
Це дозволяє використовувати той самий код в оточеннях dev, stage, test, prod (імена хостів memcached в них будуть відрізнятися, тому в кожне оточення нам потрібно передавати унікальне ім'я хостів для сесій).
Сховище кешу Бітрікс

Нам потрібне відкаузостійке сховище, в яке всі поди могли б писати і з якого могли б читати.

Також використовуємо memcached.
Це рішення рекомендується самим Бітріксом.

$ helm install stable/memcached --name cache

bitrix/.settings_extra.php — тут у Бітрікс задається, де у нас зберігається кеш

Також використовуємо Environment Variables.

Кронтаски

Є різні підходи до виконання кронтасків у Kubernetes.

  • окремий deployment з подом для виконання кронтасків
  • cronjob для виконання кронтасків (якщо це web app - з wget https://$host$cronjobname, або kubectl exec всередину одного з worker подів, і т.п.)
  • і т.п.

Можна сперечатися про найбільш правильне, але в цьому випадку ми вибрали варіант "окремий deployment з подами для кронтасків"

Як це зроблено:

  • крон-таски додаємо через ConfigMap або через файл config/addcron
  • в одному примірнику запускаємо контейнер, ідентичний worker-поду + дозволяємо виконання крон-таск в ньому
  • використовується та ж кодова база, завдяки уніфікації складання контейнера проста

Що хорошого отримуємо:

  • маємо працюючі кронтаски в оточенні, ідентичному оточенню розробників (docker)
  • кронтаски не потрібно «переписувати» для Kubernetes, вони працюють у тому ж вигляді і в тій же кодовій базі, що й раніше
  • крон-таски можуть додавати всі члени команди з правами commit у production гілку, а не тільки адміни

Модуль Southbridge K8SDeploy та редагування коду з адмін-панелі

Адже ми говорили про upgrade під?
А як спрямовувати туди трафік?
Ура, ми написали для цього модуль на php 🙂 Це невеликий класичний модуль для Бітрікс. Його ще немає у відкритому доступі, але ми плануємо його відкрити.
Модуль встановлюється як звичайний модуль у Бітрікс:

Southbridge у Челябінську та Бітрікс у Kubernetes

І виглядає ось так:

Southbridge у Челябінську та Бітрікс у Kubernetes

Він дозволяє встановити cookie, яка ідентифікує адміністратора сайту і дозволяє Kubernetes відправляти трафік на upgrade під.

Коли зміни завершено, потрібно натиснути git push, зміни коду будуть відправлені в git, далі система збере образ з новою версією коду і «розкотить» її кластером, замінивши старі поди.

Так, трохи милицею, але при цьому ми зберігаємо мікросервісну архітектуру і не забираємо у користувачів Бітрікс улюблену можливість поправити код з адмінки. Зрештою, це опція, можна завдання редагування коду вирішити по-іншому.

Helm чарт

Для складання додатків у Kubernetes ми зазвичай використовуємо пакетний менеджер Helm.
Для нашого рішення Бітрікс у Kubernetes Сергій Бондарєв, наш провідний системний адміністратор, написав спеціальний Helm чарт.

Він виконує складання worker, ugrade, cron подів, налаштовує ingress'и, сервіси, передає змінні з Kubernetes secrets у поди.

Код ми зберігаємо в Gitlab, і складання Helm також запускаємо з Gitlab.

Якщо коротко, це виглядає так

$ helm upgrade --install project .helm --set image=registrygitlab.local/k8s/bitrix -f .helm/values.yaml --wait --timeout 300 --debug --tiller-namespace=production

Helm також дозволяє робити безшовний відкат, якщо раптом при депло щось пішло не так. Приємно, коли не ви в паніці фіксуйте код по фтп, тому що прод впав, а Kubernetes робить це автоматично, причому без даунтайму.

Деплой

Так, ми фанати Gitlab & Gitlab CI, використовуємо його 🙂
При комітті Gitlab в репозитарій проекту Gitlab запускає пайплайн, який виконує розгортання нової версії оточення.

Етапи:

  • build (збираємо новий Docker образ)
  • test (тестуємо)
  • clean up (видаляємо тестове оточення)
  • push (надсилаємо його в Docker registry)
  • deploy (розгортаємо програму в Kubernetes через Helm).

Southbridge у Челябінську та Бітрікс у Kubernetes

Ура, готово, впроваджуємо!
Ну чи ставимо запитання, якщо вони є.

Отже, що ми зробили

З технічного погляду:

  • докеризували Бітрікс;
  • «розрізали» Бітрікс на контейнери, кожен із яких виконує мінімум функцій;
  • досягли стабільного стану контейнерів;
  • вирішили проблему з оновленням Бітрікс у Kubernetes;
  • всі функції Бітрікс продовжили працювати (майже всі);
  • відпрацювали деплою в Kubernetes та відкат між версіями.

З погляду бізнесу:

  • відмовостійкість;
  • інструменти Kubernetes (проста інтеграція із Gitlab CI, безшовний деплой, etc);
  • паролі в секретах (видні лише тим, кому прямо надано доступ до паролів);
  • зручно робити додаткові оточення (для розробки, тестів та ін.) усередині єдиної інфраструктури.

Джерело: habr.com

Додати коментар або відгук