Southbridge in Chelyabinsk en Bitrix in Kubernetes

In Tsjeljabinsk worden Sysadminka meetups voor systeembeheerders gehouden, en tijdens de laatste heb ik een presentatie gegeven over onze oplossing voor het draaien van applicaties op 1C-Bitrix in Kubernetes.

Bitrix, Kubernetes, Ceph — een geweldige combinatie?

Ik zal uitleggen hoe we dit alles hebben samengevoegd tot een werkende oplossing.

Laten we beginnen!

Southbridge in Chelyabinsk en Bitrix in Kubernetes

De meetup vond plaats op 18 april in Tsjeljabinsk. Over onze meetups kun je lezen op Timepad en kijken op YouTube.

Als je naar ons wilt komen met een presentatie of als luisteraar — welkom, schrijf naar vadim.isakanov@gmail.com en op Telegram t.me/vadimisakanov.

Mijn presentatie

Southbridge in Chelyabinsk en Bitrix in Kubernetes

Slides

Oplossing ‘Bitrix in Kubernetes, versie Southbridge 1.0’

Ik zal ons product bespreken in de stijl van ‘voor leken in Kubernetes’, zoals het tijdens de meetup werd gepresenteerd. Maar ik neem aan dat de woorden Bitrix, Docker, Kubernetes, Ceph wel tenminste op het niveau van Wikipedia-artikelen bij je bekend zijn.

Wat is er ĂŒberhaupt bekend over Bitrix in Kubernetes?

Er is heel weinig informatie op het internet over het draaien van applicaties op Bitrix in Kubernetes.
Ik heb alleen de volgende materialen gevonden:

De presentatie van Alexander Serbul, 1C-Bitrix, en Anton Tuzlukov van Qsoft:

Video afspelen

Ik raad aan om deze te beluisteren.

Ontwikkeling van een eigen oplossing door een gebruiker serkyron Mythen en realiteit.
Ik vond nog zo'n oplossing.

Ennn... dat is eigenlijk alles.

Ik waarschuw je, we hebben de kwaliteit van de oplossingen in de bovenstaande links niet gecontroleerd 🙂
Overigens sprak ik tijdens de voorbereiding van onze oplossing met Alexander Serbul, zijn presentatie was er toen nog niet, daarom zit er een punt in mijn slides dat zegt ‘Bitrix maakt geen gebruik van Kubernetes’.

Maar er zijn al veel kant-en-klare Docker-images voor het draaien van Bitrix in Docker: https://hub.docker.com/search?q=bitrix&type=image

Is dit voldoende voor het creëren van een volledige oplossing voor Bitrix in Kubernetes?
Nee. Er zijn een groot aantal problemen die opgelost moeten worden.

Wat zijn de problemen met Bitrix in Kubernetes?

De eerste — kant-en-klare images van Dockerhub zijn niet geschikt voor Kubernetes.

Als we een microservices-architectuur willen bouwen (en dat willen we meestal in Kubernetes), moet de applicatie in Kubernetes worden opgesplitst in containers en moet ervoor worden gezorgd dat elke container één kleine functie uitvoert (en dit goed doet). Waarom maar één? Kort gezegd — hoe eenvoudiger, hoe betrouwbaarder.
Als je het langer wilt houden — kijk alstublieft naar dit artikel en de video: https://habr.com/ru/company/southbridge/blog/426637/

Docker-images op Dockerhub zijn meestal gebouwd volgens het ‘alles-in-één’ principe, dus we moesten toch onze eigen ‘fiets’ maken en zelfs de images vanaf nul bouwen.

De tweede — de code van de site wordt aangepast vanuit het beheerpaneel.

We hebben een nieuw deel op de website gecreëerd - de code is bijgewerkt (er is een directory toegevoegd met de naam van het nieuwe deel).

We hebben de eigenschappen van de component vanuit het beheerderspaneel gewijzigd - de code is veranderd.

Kubernetes kan hier standaard niet mee omgaan, containers moeten onveranderlijk zijn (Stateless).

Reden: elke container (pod) in de cluster verwerkt slechts een deel van het verkeer. Als je de code in slechts één container (pod) wijzigt, zal de code in verschillende pods verschillend zijn, de website zal anders functioneren, en verschillende gebruikers zullen verschillende versies van de website zien. Zo kan het niet doorgaan.

De derde - we moeten het probleem van de deployment oplossen

Als we een monolithische structuur hebben en één 'klassieke' server, is alles heel eenvoudig: we zetten de nieuwe codebasis op, voeren de database-migratie uit, en schakelen het verkeer over naar de nieuwe codeversie. De overschakeling gebeurt onmiddellijk.
Als we een website in Kubernetes hebben, verdeeld in microservices, met veel containers met code - oeps. We moeten containers met de nieuwe codeversie bouwen, ze in plaats van oude uitrollen, de database-migratie correct uitvoeren, en idealiter moet dit onopgemerkt blijven voor bezoekers. Gelukkig helpt Kubernetes ons hierbij en ondersteunt het verschillende soorten deployments.

De vierde - we moeten het probleem van de opslag van statische bestanden oplossen

Als je website 'slechts' 10 gigabyte groot is en je het geheel in containers uitrolt, krijg je containers van 10 gigabyte die een eeuwigheid zullen worden gedeployed.
We moeten de 'zwaarste' delen van de website buiten de containers opslaan, en de vraag is hoe we dit het beste kunnen doen.

Wat ontbreekt in onze oplossing

De volledige Bitrix-code is niet opgesplitst in microfuncties/microservices (dus, registratie apart, module voor de webwinkel apart, enz.). We bewaren de hele codebasis in elke container.

We bewaren de database in Kubernetes ook niet (ik heb wel oplossingen met een database in Kubernetes gerealiseerd voor ontwikkelomgevingen, maar niet voor productie).

Beheerders van de website zullen echter opmerken dat de website in Kubernetes draait. De functie 'systeemcontrole' werkt niet correct, om de code van de website vanuit het beheerderspaneel te bewerken, moet je eerst op de knop 'ik wil de code bewerken' drukken.

We have addressed the issues, clarified the need for microservices, and have a clear goal — to create a functioning system for running Bitrix applications on Kubernetes, preserving both Bitrix's capabilities and the advantages of Kubernetes. We are starting the implementation.

Architectuur

Many 'worker' pods with a web server.
One pod with cron tasks (only one is required).
One upgrade pod for editing the site's code from the admin panel (also, only one is required).

Southbridge in Chelyabinsk en Bitrix in Kubernetes

We are solving the following issues:

  • Where to store sessions?
  • Where to store the cache?
  • Where to store static files? We can't place gigabytes of static files in a bunch of containers.
  • How will the database operate?

Docker image

We start by building the Docker image.

The ideal option is to have one universal image, which we use to obtain both worker pods and pods with cron tasks, as well as upgrade pods.

We have created exactly such an image..

It includes nginx, apache/php-fpm (which can be selected during the build), msmtp for sending emails, and cron.

During the image build, the complete code base of the site is copied to the /app directory (except for those parts we will move to a separate shared storage).

Microservices, services

worker pods:

  • Container with nginx + container apache/php-fpm + msmtp
  • msmtp could not be separated into its own microservice; Bitrix starts complaining that it cannot send emails directly.
  • Each container has the complete code base.
  • Modification of code in containers is prohibited.

cron pod:

  • container with apache, php, cron
  • includes the complete code base
  • modification of code in containers is prohibited

upgrade pod:

  • container with nginx + container apache/php-fpm + msmtp
  • there is no prohibition on changing code in containers

session storage

Bitrix cache storage

Additionally important: passwords for connecting to everything from the database to email are stored in Kubernetes secrets. We get the bonus that passwords are visible only to those we give access to the secrets, not to everyone who has access to the project's code base.

Storage for static files

Anything can be used: ceph, nfs (but we do not recommend nfs for production), network storage from 'cloud' providers, etc.

The storage needs to be connected in the containers to the /upload/ directory of the site and other directories with static files.

Database

For simplicity, we recommend placing the database outside of Kubernetes. A database in Kubernetes is a separate complex task, which will make the schema significantly more complicated.

Session storage

We use memcached 🙂

Het beheert sessies goed, is geclusterd en wordt ‘native’ ondersteund als session.save_path in php. Dit systeem is talloze keren getest in de klassieke monolithische architectuur, toen we clusters bouwden met veel webservers. Voor de deployment gebruiken we helm.

$ helm install stable/memcached --name session

php.ini – hier zijn de instellingen voor het opslaan van sessies in memcached ingesteld in de afbeelding

We gebruikten omgevingsvariabelen om gegevens over de hosts met memcached door te geven. https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
Dit stelt ons in staat dezelfde code te gebruiken in de omgevingen dev, stage, test, prod (de namen van de memcached hosts zullen verschillen, daarom moeten we voor elke omgeving een unieke naam voor de sessiehosts doorgeven).
Cache opslag voor Bitrix

We hebben een fouttolerante opslag nodig waar alle pods naar kunnen schrijven en lezen.

We gebruiken ook memcached.
Deze oplossing wordt aanbevolen door Bitrix zelf.

$ helm install stable/memcached --name cache

bitrix/.settings_extra.php – hier wordt in Bitrix ingesteld waar onze cache is opgeslagen

We gebruiken ook omgevingsvariabelen.

Cron-taken

Er zijn verschillende benaderingen voor het uitvoeren van cron-taken in Kubernetes.

  • een aparte deployment met een pod voor het uitvoeren van cron-taken
  • cronjob voor het uitvoeren van cron-taken (als het een webapp is – met wget https://$host$cronjobname, of kubectl exec binnen een van de worker pods, enz.)
  • enz.

Je kunt van mening verschillen over wat de beste aanpak is, maar in dit geval hebben we gekozen voor de optie ‘aparte deployment met pods voor cron-taken’

Hoe het is gedaan:

  • we voegen cron-taken toe via ConfigMap of via het bestand config/addcron
  • we starten één exemplaar van de container op, identiek aan de worker-pod + we staan het uitvoeren van cron-taken daarin toe
  • dezelfde codebase wordt gebruikt, waardoor de containerbouw eenvoudig is

Wat goed is:

  • we hebben werkende cron-taken in een omgeving die identiek is aan die van de ontwikkelaars (docker)
  • cron-taken hoeven niet ‘herschreven’ te worden voor Kubernetes, ze werken in dezelfde vorm en met dezelfde codebase als voorheen
  • alle teamleden met commit-rechten in de production branch kunnen cron-taken toevoegen, niet alleen beheerders

Module Southbridge K8SDeploy en het bewerken van code vanuit de admin-interface

We hadden het toch over de upgrade van de pod?
Hoe leiden we daar het verkeer naartoe?
Hoera, we hebben hiervoor een php-module geschreven 🙂 Dit is een kleine klassieke module voor Bitrix. Deze is nog niet openbaar beschikbaar, maar we zijn van plan deze open te stellen.
De module wordt geĂŻnstalleerd als een gewone module in Bitrix:

Southbridge in Chelyabinsk en Bitrix in Kubernetes

En ziet er als volgt uit:

Southbridge in Chelyabinsk en Bitrix in Kubernetes

Het stelt een cookie in die de site beheerder identificeert en stelt Kubernetes in staat om verkeer naar de upgrade pod te sturen.

Wanneer de wijzigingen voltooid zijn, moet je op git push drukken, de codewijzigingen worden naar git gestuurd, waarna het systeem een afbeelding met de nieuwe versie van de code zal verzamelen en deze over het cluster zal verspreiden, waarbij oude pods worden vervangen.

Ja, het is een beetje een omweg, maar we behouden de microservicesarchitectuur en ontnemen de gebruikers van Bitrix de mogelijkheid om de code vanuit de adminomgeving aan te passen. Tenslotte is dit een optie; de taak om de code te bewerken kan ook anders worden opgelost.

Helm chart

Voor het bouwen van applicaties in Kubernetes gebruiken we doorgaans de pakketbeheerder Helm.
Voor onze Bitrix-oplossing in Kubernetes heeft Sergey Bondarev, onze hoofd systeembeheerder, een speciale Helm chart geschreven.

Het voert de bouw van worker-, upgrade- en cron-pods uit, configureert ingangen, services en geeft variabelen van Kubernetes secrets door aan de pods.

We slaan de code op in Gitlab en starten ook de Helm-bouw vanuit Gitlab.

Kort gezegd ziet het er zo uit

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

Helm maakt ook een 'naadloze' rollback mogelijk als er tijdens de deployment iets misgaat. Het is fijn dat je niet in paniek de 'code via FTP moet fixen omdat de productie is gevallen', maar dat Kubernetes dit automatisch zonder downtime doet.

Deploy

Ja, we zijn fan van Gitlab & Gitlab CI, we maken er gebruik van 🙂
Bij een commit in Gitlab start Gitlab een pijplijn in de projectrepository die een nieuwe versie van de omgeving uitrolt.

Fasen:

  • build (we bouwen een nieuw Docker-image)
  • test (we testen)
  • clean up (we verwijderen de testomgeving)
  • push (we sturen het naar de Docker-registry)
  • deploy (we zetten de applicatie uit in Kubernetes via Helm).

Southbridge in Chelyabinsk en Bitrix in Kubernetes

Hoera, het is klaar, we implementeren!
Of we stellen vragen als die er zijn.

Dus, wat hebben we gedaan

Technisch gezien:

  • we hebben Bitrix gedockeriseerd;
  • we hebben Bitrix 'in containers gesneden', die elk minimaal aan functies voldoen;
  • we hebben een stateless status van de containers bereikt;
  • we hebben het probleem met het updaten van Bitrix in Kubernetes opgelost;
  • alle functies van Bitrix blijven werken (bijna allemaal);
  • we hebben de uitrol in Kubernetes en de rollback tussen versies geoptimaliseerd.

Zicht op de business:

  • betrouwbaarheid;
  • Kubernetes-tools (eenvoudige integratie met Gitlab CI, naadloze uitrol, etc);
  • wachtwoorden in secrets (alleen zichtbaar voor degenen die toegang tot de wachtwoorden hebben gehad);
  • het is handig om extra omgevingen (voor ontwikkeling, tests enz.) binnen een enkele infrastructuur te maken.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers đŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster