Sysadminka systemadministratörsmöten äger rum i Chelyabinsk, och vid den sista gav jag en rapport om vår lösning för att köra applikationer på 1C-Bitrix i Kubernetes.
Bitrix, Kubernetes, Ceph - en fantastisk blandning?
Jag ska berätta hur vi sammanställer en fungerande lösning från allt detta.
Låt oss gå!
Mötet ägde rum den 18 april i Tjeljabinsk. Du kan läsa om våra träffar på Timepad och titta på Youtube.
Vill du komma till oss med ett reportage eller som lyssnare – välkommen, skriv till [e-postskyddad] och på Telegram t.me/vadimisakanov.
Lösning "Bitrix i Kubernetes, version Southbridge 1.0"
Jag kommer att prata om vår lösning i formatet "för dummies i Kubernetes", som gjordes vid mötet. Men jag antar att du kan orden Bitrix, Docker, Kubernetes, Ceph åtminstone på artiklarnas nivå på Wikipedia.
Vad är färdigt med Bitrix i Kubernetes?
Det finns väldigt lite information på hela Internet om driften av Bitrix-applikationer i Kubernetes.
Jag hittade bara dessa material:
Rapport av Alexander Serbul, 1C-Bitrix och Anton Tuzlukov från Qsoft:
Jag varnar dig, vi har inte kontrollerat kvaliteten på lösningarna i länkarna ovan :)
Förresten, när jag förberedde vår lösning pratade jag med Alexander Serbul, då hade hans rapport ännu inte dykt upp, så i mina bilder finns det ett objekt "Bitrix använder inte Kubernetes."
Räcker detta för att skapa en komplett lösning för Bitrix i Kubernetes?
Nej. Det finns ett stort antal problem som måste lösas.
Vilka är problemen med Bitrix i Kubernetes?
För det första är färdiga bilder från Dockerhub inte lämpliga för Kubernetes
Om vi vill bygga en mikroservicearkitektur (och det gör vi vanligtvis i Kubernetes), måste vi separera vår Kubernetes-applikation i behållare och låta varje behållare utföra en liten funktion (och göra det bra). Varför bara en? Kort sagt, ju enklare desto mer pålitlig.
För att vara mer specifik, titta på den här artikeln och videon, vänligen: https://habr.com/ru/company/southbridge/blog/426637/
Docker-bilder i Dockerhub är huvudsakligen byggda på allt-i-ett-principen, så vi var fortfarande tvungna att göra vår egen cykel och till och med skapa bilder från grunden.
För det andra - webbplatskoden redigeras från adminpanelen
Vi skapade en ny sektion på webbplatsen - koden uppdaterades (en katalog med namnet på den nya sektionen lades till).
Om du ändrade egenskaperna för en komponent från adminpanelen ändrades koden.
Kubernetes "som standard" kan inte fungera med detta; behållare måste vara tillståndslösa.
Orsak: Varje behållare (pod) i klustret bearbetar bara en del av trafiken. Om du bara ändrar koden i en behållare (pod), kommer koden att vara olika i olika pods, sajten kommer att fungera annorlunda och olika versioner av sajten kommer att visas för olika användare. Du kan inte leva så.
För det tredje - du måste lösa problemet med distributionen
Om vi har en monolit och en "klassisk" server är allt ganska enkelt: vi distribuerar en ny kodbas, migrerar databasen, byter trafik till den nya versionen av koden. Bytet sker omedelbart.
Om vi har en sajt i Kubernetes, uppskuren i mikrotjänster, finns det många behållare med kod - åh. Du måste samla behållare med en ny version av koden, rulla ut dem istället för de gamla, migrera databasen korrekt och helst göra detta obemärkt av besökarna. Lyckligtvis hjälper Kubernetes oss med detta, och stöder en hel massa olika typer av distributioner.
För det fjärde - du måste lösa problemet med att lagra statik
Om din webbplats "bara" är på 10 gigabyte och du distribuerar den helt i behållare, kommer du att sluta med 10 gigabyte behållare som tar en evighet att distribuera.
Du måste lagra de "tyngsta" delarna av webbplatsen utanför containrar, och frågan uppstår om hur man gör detta korrekt
Vad saknas i vår lösning?
Hela Bitrix-koden är inte uppdelad i mikrofunktioner/mikrotjänster (så att registreringen är separat, nätbutiksmodulen är separat etc.). Vi lagrar hela kodbasen i varje container.
Vi lagrar inte heller databasen i Kubernetes (jag implementerade fortfarande lösningar med en databas i Kubernetes för utvecklingsmiljöer, men inte för produktion).
Webbplatsadministratörer kommer fortfarande att märka att webbplatsen körs på Kubernetes. Funktionen "systemkontroll" fungerar inte korrekt; för att redigera webbplatskoden från adminpanelen måste du först klicka på knappen "Jag vill redigera koden".
Problemen har identifierats, behovet av att implementera mikrotjänster har bestämts, målet är tydligt - att få ett fungerande system för att köra applikationer på Bitrix i Kubernetes, bevara både kapaciteten hos Bitrix och fördelarna med Kubernetes. Låt oss börja implementera.
Arkitektur
Det finns många "fungerande" pods med en webbserver (arbetare).
En under med cron-uppgifter (endast en krävs).
En uppgradering för redigering av webbplatskoden från adminpanelen (också endast en krävs).
Vi löser frågor:
Var lagrar man sessioner?
Var lagrar man cachen?
Var ska man lagra statik, inte placera gigabyte statik i en massa behållare?
Hur kommer databasen att fungera?
Docker-bild
Vi börjar med att bygga en Docker-bild.
Det perfekta alternativet är att vi har en universell bild, på grundval av den får vi arbetarpods, pods med Crontasks och uppgraderar pods.
Den innehåller nginx, apache/php-fpm (kan väljas under byggandet), msmtp för att skicka e-post och cron.
Vid sammansättning av bilden kopieras hela kodbasen för webbplatsen till /app-katalogen (med undantag för de delar som vi kommer att flytta till en separat delad lagring).
Mikrotjänster, tjänster
arbetarkapslar:
Behållare med nginx + behållare apache/php-fpm + msmtp
Det gick inte att flytta msmtp till en separat mikrotjänst, Bitrix börjar bli upprörd över att den inte kan skicka mail direkt
Det finns inget förbud mot att byta kod i containrar
sessionslagring
Bitrix-cachelagring
En annan viktig sak: vi lagrar lösenord för att ansluta till allt, från databasen till e-post, i kubernetes hemligheter. Vi får en bonus: lösenord är endast synliga för dem som vi ger tillgång till hemligheterna och inte för alla som har tillgång till projektets kodbas.
Lagring för statik
Du kan använda vad som helst: ceph, nfs (men vi rekommenderar inte nfs för produktion), nätverkslagring från molnleverantörer, etc.
Lagringen kommer att behöva anslutas i behållare till /upload/-katalogen på webbplatsen och andra kataloger med statiskt innehåll.
databas
För enkelhetens skull rekommenderar vi att flytta databasen utanför Kubernetes. Basen i Kubernetes är en separat komplex uppgift; det kommer att göra schemat till en storleksordning mer komplext.
Sessionslagring
Vi använder memcached :)
Den hanterar sessionslagring bra, är klustrad och stöds "nativet" som session.save_path i php. Ett sådant system har testats många gånger i den klassiska monolitiska arkitekturen, då vi byggde kluster med ett stort antal webbservrar. För utplacering använder vi rodret.
$ helm install stable/memcached --name session
php.ini - här innehåller bilden inställningar för lagring av sessioner i memcached
Vi använde miljövariabler för att skicka data om värdar med memcached https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
Detta gör att du kan använda samma kod i dev, stage, test, prod-miljöer (de memcachade värdnamnen i dem kommer att vara olika, så vi måste skicka ett unikt värdnamn för sessioner till varje miljö).
Bitrix-cachelagring
Vi behöver feltålig lagring som alla poddar kan skriva till och läsa från.
Vi använder också memcached.
Denna lösning rekommenderas av Bitrix själv.
$ helm install stable/memcached --name cache
bitrix/.settings_extra.php - här i Bitrix anges var cachen lagras
Vi använder även miljövariabler.
Krontaski
Det finns olika sätt att köra Crontasks i Kubernetes.
separat distribution med en pod för att köra Crontasks
cronjob för att utföra crontasks (om detta är en webbapp - med wget https://$host$cronjobname, eller kubectl exec inuti en av arbetarkapslarna, etc.)
och så vidare
Du kan argumentera om den mest korrekta, men i det här fallet valde vi alternativet "separat distribution med pods för Crontasks"
Hur det är gjort:
lägg till cron-uppgifter via ConfigMap eller via config/addcron-filen
i ett fall lanserar vi en behållare som är identisk med worker pod + tillåter exekvering av kronuppgifter i den
samma kodbas används, tack vare föreningen är containermonteringen enkel
Vad bra vi får:
vi har arbetande Crontasks i en miljö som är identisk med utvecklarnas miljö (docker)
Crontasks behöver inte ”skrivas om” för Kubernetes, de fungerar i samma form och i samma kodbas som tidigare
cron-uppgifter kan läggas till av alla teammedlemmar med commit-rättigheter till produktionsgrenen, inte bara admins
Southbridge K8SDeploy modul och kodredigering från adminpanelen
Vi pratade om uppgradering under?
Hur dirigerar man trafiken dit?
Hurra, vi skrev en modul för detta i PHP :) Detta är en liten klassisk modul för Bitrix. Den är ännu inte tillgänglig för allmänheten, men vi planerar att öppna den.
Modulen är installerad som en vanlig modul i Bitrix:
Och det ser ut så här:
Det låter dig ställa in en cookie som identifierar webbplatsens administratör och tillåter Kubernetes att skicka trafik till uppgraderingspodden.
När ändringarna är klara måste du klicka på git push, kodändringarna kommer att skickas till git, sedan kommer systemet att bygga en bild med en ny version av koden och "rulla ut" den över klustret och ersätta de gamla pods .
Ja, det är lite av en krycka, men samtidigt upprätthåller vi mikrotjänstarkitekturen och tar inte ifrån Bitrix-användare deras favorittillfälle att korrigera koden från adminpanelen. I slutändan är detta ett alternativ; du kan lösa problemet med att redigera koden på ett annat sätt.
Rordiagram
För att bygga applikationer på Kubernetes använder vi vanligtvis Helm-pakethanteraren.
För vår Bitrix-lösning i Kubernetes skrev Sergey Bondarev, vår ledande systemadministratör, ett speciellt Helm-diagram.
Den bygger worker, ugrade, cron pods, konfigurerar ingresser, tjänster och överför variabler från Kubernetes hemligheter till pods.
Vi lagrar koden i Gitlab, och vi kör även Helm-bygget från Gitlab.
Helm låter dig också göra en "sömlös" återställning om något plötsligt går fel under driftsättningen. Det är skönt när du inte är i panik "fixa koden via ftp eftersom proden föll", men Kubernetes gör det automatiskt och utan stillestånd.
Distribuera
Ja, vi är fans av Gitlab & Gitlab CI, vi använder det :)
När Gitlab förbinder sig i Gitlab till projektförrådet, lanserar Gitlab en pipeline som distribuerar en ny version av miljön.
steg:
bygga (bygga en ny Docker-bild)
testa (testa)
städa upp (ta bort testmiljön)
push (vi skickar det till Docker-registret)
distribuera (vi distribuerar programmet till Kubernetes via Helm).
Hurra, det är klart, låt oss implementera det!
Tja, eller ställ frågor om det finns några.
Så vad gjorde vi
Ur teknisk synvinkel:
dockeriserad Bitrix;
"klipp" Bitrix i behållare, som var och en utför ett minimum av funktioner;
uppnått tillståndslöst tillstånd av containrar;
löste problemet med att uppdatera Bitrix i Kubernetes;
alla Bitrix-funktioner fortsatte att fungera (nästan alla);
Vi arbetade med distribution till Kubernetes och återställning mellan versioner.
Ur affärsmässig synvinkel:
feltolerans;
Kubernetes-verktyg (enkel integration med Gitlab CI, sömlös distribution, etc);
hemliga lösenord (endast synliga för dem som får direkt tillgång till lösenorden);
Det är bekvämt att skapa ytterligare miljöer (för utveckling, tester, etc.) inom en enda infrastruktur.