У Чэлябінску праходзяць мітапы сістэмных адміністратараў Sysadminka, і на апошнім з іх я рабіў даклад аб нашым рашэнні для працы прыкладанняў на 1С-Бітрыкс у Kubernetes.
Битрикс, Kubernetes, Сeph - выдатная сумесь?
Раскажу, як мы з усяго гэтага сабралі працуючае рашэнне.
Паехалі!
Мітап прайшоў 18 красавіка ў Чэлябінску. Пра нашы мітапы можна пачытаць у Timepad і паглядзець на ютубе.
Калі хочаце прыйсці да нас з дакладам або як слухач - велкам, пішыце на [электронная пошта абаронена] і ў Тэлеграм t.me/vadimisakanov.
Рашэнне "Бітрыкс у Kubernetes, версія Southbridge 1.0"
Я раскажу аб нашым рашэнні ў фармаце «для чайнікаў у Kubernetes», як гэта было зроблена на мітапе. Але мяркую, што словы Бітрыкс, Docker, Kubernetes, Ceph вам вядомыя хаця б на ўзроўні артыкулаў у Вікіпедыі.
Што ўвогуле ёсць гатовага пра Бітрыкс у Kubernetes?
Ва ўсім інтэрнэце вельмі мала інфармацыі аб рабоце прыкладанняў на Битрикс у Kubernetes.
Я знайшоў толькі такія матэрыялы:
Даклад Аляксандра Сербула, 1С-Бітрыкс, і Антона Тузлукова з Qsoft:
Папярэджваю, якасць працы рашэнняў па спасылках вышэй мы не правяралі 🙂
Дарэчы, пры падрыхтоўцы нашага рашэння я меў зносіны з Аляксандрам Сербулам, тады яго дакладу яшчэ не было, таму ў маіх слайдах ёсць пункт "Бітрыкс не карыстаецца Kubernetes".
Ці дастаткова гэтага для стварэння паўнавартаснага рашэння для Битрикс у 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 пад для рэдагавання кода сайта з адмін-панэлі (таксама абавязкова толькі адзін).
Вырашаем пытанні:
Дзе захоўваць сесіі?
Дзе захоўваць кэш?
Дзе захоўваць статыку, не размяшчаць жа гігабайты статыкі ў кучы кантэйнераў?
Як будзе працаваць база даных?
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 🙂 Гэта невялікі класічны модуль для Битрикс. Яго яшчэ няма ў адкрытым доступе, але мы плануем яго адчыніць.
Модуль усталёўваецца як звычайны модуль у Битрикс:
І выглядае вось так:
Ён дазваляе задаць cookie, якая ідэнтыфікуе адміністратара сайта і дазваляе Kubernetes адпраўляць трафік на upgrade пад.
Калі змены завершаны, трэба націснуць git push, змены кода будуць адпраўленыя ў git, далей сістэма збярэ выяву з новай версіяй кода і «раскача» яе па кластары, замяніўшы старыя поды.
Так, некалькі мыліцка, але пры гэтым мы захоўваем мікрасэрвісную архітэктуру і не забіраем у карыстачоў Битрикс каханую магчымасць паправіць код з адмінкі. У рэшце рэшт, гэта опцыя, можна задачу праўкі кода вырашыць па-іншаму.
Helm чарт
Для зборкі прыкладанняў у Kubernetes мы, як правіла, выкарыстоўваны пакетны мэнэджар Helm.
Для нашага рашэння Битрикс у Kubernetes Сяргей Бондараў, наш кіроўны сістэмны адміністратар, напісаў адмысловы Helm чарт.
Ён выконвае зборку worker, ugrade, cron подаў, наладжвае ingress'ы, сэрвісы, перадае зменныя з Kubernetes secrets у поды.
Код мы захоўваем у Gitlab, і зборку Helm таксама запускаем з Gitlab.
Helm таксама дазваляе рабіць "бясшвоўны" адкат, калі раптам пры дэплоі нешта пайшло не так. Прыемна, калі не вы ў паніцы "фіксіце код па фтп, таму што прад упаў", а Kubernetes робіць гэта аўтаматычна, прычым без даунтайма.
Дэплой
Так, мы фанаты Gitlab & Gitlab CI, выкарыстоўваем яго 🙂
Пры коміце ў Gitlab у рэпазітар праекта Gitlab запускае пайплайн, які выконвае разгортванне новай версіі асяроддзя.
этапы:
build (збіраем новы Docker вобраз)
test (тэстуем)
clean up (выдаляем тэставае асяроддзе)
push (адпраўляем яго ў Docker registry)
deploy (разгортваем прыкладанне ў Kubernetes праз Helm).
Ура, гатова, укараняем!
Ну ці задаём пытанні, калі яны ёсць.
Такім чынам, што мы зрабілі
З тэхнічнага пункту гледжання:
дакерызавалі Бітрыкс;
"разрэзалі" Битрикс на кантэйнеры, кожны з якіх выконвае мінімум функцый;
дабіліся stateless стану кантэйнераў;
вырашылі праблему з абнаўленнем Битрикс у Kubernetes;
усе функцыі Битрикс працягнулі працаваць (амаль усе);
адпрацавалі дэплой у Kubernetes і адкат паміж версіямі.
З пункту гледжання бізнэсу:
адмоваўстойлівасць;
інструменты Kubernetes (простая інтэграцыя з Gitlab CI, бясшвоўны дэплой, etc);
паролі ў сакрэтах (бачныя толькі тым, каму прама прадстаўлены доступ да пароляў);
зручна рабіць дадатковыя асяроддзі (для распрацоўкі, тэстаў і інш) усярэдзіне адзінай інфраструктуры.