- PVSM.RU - https://www.pvsm.ru -
В Челябинске проходят митапы системных администраторов Sysadminka, и на последнем из них я делал доклад о нашем решении для работы приложений на 1С-Битрикс в Kubernetes.
Битрикс, Kubernetes, Сeph — отличная смесь?
Расскажу, как мы из всего этого собрали работающее решение.
Поехали!
Митап прошел 18 апреля Челябинске. Про наши митапы можно почитать в Timepad [1] и посмотреть на ютубе [2].
Если хотите прийти к нам с докладом или как слушатель — велкам, пишите на vadim.isakanov@gmail.com и в Телеграм t.me/vadimisakanov.
Слайды [4]
Я расскажу о нашем решении в формате «для чайников в Kubernetes», как это было сделано на митапе. Но предполагаю, что слова Битрикс, Docker, Kubernetes, Ceph вам известны хотя бы на уровне статей в Википедии.
Во всем интернете очень мало информации о работе приложений на Битрикс в Kubernetes.
Я нашел только такие материалы:
Доклад Александра Сербула, 1С-Битрикс, и Антона Тузлукова из Qsoft:
Рекомендую послушать его.
Разработка собственного решения от пользователя serkyron [5] на Хабре [6].
Нашел еще такое решение [7].
Ииии… собственно, все.
Предупреждаю, качество работы решений по ссылкам выше мы не проверяли :-)
Кстати, при подготовке нашего решения я общался с Александром Сербулом, тогда его доклада еще не было, поэтому в моих слайдах есть пункт «Битрикс не пользуется Kubernetes».
Но зато готовых Docker образов для работы Битрикс в Docker уже много: https://hub.docker.com/search?q=bitrix&type=image [8]
Достаточно ли этого для создания полноценного решения для Битрикс в Kubernetes?
Нет. Есть большое количество проблем, которые нужно решить.
Первая — готовые образы из Dockerhub не подходят для Kubernetes
Если мы хотим построить микросервисную архитектуру (а в Kubernetes мы обычно хотим), приложение в Kubernetes нужно разделять на контейнеры и добиваться того, чтобы каждый контейнер выполнял одну маленькую функцию (и делал это хорошо). Почему только одну? Если кратко — чем проще, тем надежнее.
Если подлиннее —- посмотрите эту статью и видео, пожалуйста: https://habr.com/ru/company/southbridge/blog/426637/ [9]
Docker образы в Dockerhub в основном построены по принципу «все в одном», поэтому нам пришлось все-таки делать свой велосипед и даже образы делать с нуля.
Вторая — код сайта правится из админ-панели
Создали новый раздел на сайте — обновился код (добавилась директория с названием нового раздела).
Изменили свойства компонента из админ-панели — изменился код.
Kubernetes «по умолчанию» с таким работать не умеет, контейнеры должны быть не изменяемыми (Stateless).
Причина: каждый контейнер (под) в кластере обрабатывает только часть трафика. Если изменить код только в одном контейнере (поде), то в разных подах код будет разным, сайт будет работать по-разному, разным пользователям будут показываться разные версии сайта. Так жить нельзя.
Третья — нужно решать вопрос с деплоем
Если у нас монолит и один «классический» сервер, все совсем просто: разворачиваем новую кодовую базу, проводим миграцию БД, переключаем трафик на новую версию кода. Переключение происходит мгновенно.
Если у нас сайт в Kubernetes, распилен на микросервисы, контейнеров с кодом много — ой. Нужно собирать контейнеры с новой версией кода, выкатывать их вместо старых, правильно выполнять миграцию БД, и в идеале делать это незаметно для посетителей. Благо, в этом Kubernetes нам помогает, поддерживая целую тучу разных видов деплоя.
Четвертая — нужно решать вопрос с хранением статики
Если ваш сайт весит «всего лишь» 10 гигабайт и вы развернете его целиком в контейнерах, вы получите контейнеры весом в 10 гигабайт, которые будут деплоиться вечность.
Нужно хранить самые «тяжелые» части сайта вне контейнеров, и встает вопрос, как правильно это делать
Совсем весь код Битрикс на микрофункции/микросервисы не разрезан (так, чтобы регистрация отдельно, модуль интернет-магазина отдельно, и т.п.). Всю кодовую базу мы храним в каждом контейнере целиком.
Базу в Kubernetes также не храним (я все же реализовывал решения с базой в Kubernetes для окружений разработчиков, но не для продакшн).
Администраторам сайта все-таки будет заметно, что сайт работает в Kubernetes. Функция «проверка системы» работает некорректно, для редактирования кода сайта из админ-панели нужно сначала нажимать кнопку «хочу отредактировать код».
С проблемами определились, с необходимостью реализации микросервисности определились, цель ясна — получить работающую систему для работы приложений на Битрикс в Kubernetes, сохранив и возможности Битрикс, и преимущества Kubernetes. Начинаем реализацию.
Много «рабочих» подов с вебсервером (worker'ы).
Один под с крон-тасками (обязательно только один).
Один upgrade под для редактирования кода сайта из админ-панели (также обязательно только один).
Решаем вопросы:
Начинаем со сборки Docker образа.
Идеальный вариант — у нас один универсальный образ, на его основе мы получаем и worker-поды, и поды с кронтасками, и upgrade поды.
Мы сделали как раз такой образ [10].
В него включен nginx, apache/php-fpm (можно выбрать при сборке), msmtp для отправки почты, и cron.
При сборке образа в директорию /app копируется полная кодовая база сайта (за исключением тех частей, что мы вынесем в отдельный shared storage).
worker поды:
cron под:
upgrade под:
хранилище сессий
хранилище кэша Битрикс
Еще важно: пароли для подключения ко всему, от базы данных до почты, мы храним в 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/ [11].
Это позволяет использовать один и тот же код в окружениях dev, stage, test, prod (имена хостов memcached в них будут отличаться, поэтому в каждое окружение нам нужно передавать уникальное имя хостов для сессий).
Хранилище кэша Битрикс
Нам нужно откаузостойчивое хранилище, в которое все поды могли бы писать и из которого могли бы читать.
Также используем memcached.
Это решение рекомендуется самим Битрикс.
$ helm install stable/memcached --name cache
bitrix/.settings_extra.php — здесь в Битрикс задается, где у нас хранится кэш
Так же используем Environment Variables.
Есть разные подходы к выполнению кронтасков в Kubernetes.
Можно спорить о наиболее правильном, но в этом случае мы выбрали вариант "отдельный deployment с подами для кронтасков"
Как это сделано:
Что хорошего получаем:
Мы ведь говорили про upgrade под?
А как направлять туда трафик?
Ура, мы написали для этого модуль на php :) Это небольшой классический модуль для Битрикс. Его еще нет в открытом доступе, но мы планируем его открыть.
Модуль устанавливается как обычный модуль в Битрикс:
И выглядит вот так:
Он позволяет задать cookie, которая идентифицирует администратора сайта и позволяет Kubernetes отправлять трафик на upgrade под.
Когда изменения завершены, нужно нажать git push, изменения кода будут отправлены в git, далее система соберет образ с новой версией кода и «раскатает» ее по кластеру, заменив старые поды.
Да, несколько костыльно, но при этом мы сохраняем микросервисную архитектуру и не забираем у пользователей Битрикс любимую возможность поправить код из админки. В конце концов, это опция, можно задачу правки кода решить по-другому.
Для сборки приложений в 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 запускает пайплайн, который выполняет разворачивание новой версии окружения.
Этапы:
Ура, готово, внедряем!
Ну или задаем вопросы, если они есть.
С технической точки зрения:
С точки зрения бизнеса:
Автор: Вадим
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/sistemnoe-administrirovanie/321557
Ссылки в тексте:
[1] Timepad: https://sysadminka.timepad.ru
[2] ютубе: https://www.youtube.com/channel/UCMblNgU0Gt-TXb9GdVeeinw/
[3] Image: https://www.youtube.com/watch?v=MZqPNMUjr_M
[4] Слайды: https://yadi.sk/i/1q0YpFHBGBdtcg
[5] serkyron: https://habr.com/ru/users/serkyron/
[6] на Хабре: https://habr.com/ru/post/351286/
[7] такое решение: https://github.com/ESSch/kubernetes
[8] https://hub.docker.com/search?q=bitrix&type=image: https://hub.docker.com/search?q=bitrix&type=image
[9] https://habr.com/ru/company/southbridge/blog/426637/: https://habr.com/ru/company/southbridge/blog/426637/
[10] Мы сделали как раз такой образ: https://hub.docker.com/r/centosadmin/bitrixenv
[11] https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
[12] https://$host$cronjobname: https://%24host%24cronjobname
[13] Источник: https://habr.com/ru/post/456608/?utm_source=habrahabr&utm_medium=rss&utm_campaign=456608
Нажмите здесь для печати.