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!

De meetup vond plaats op 18 april in Tsjeljabinsk. Over onze meetups kun je lezen op en kijken op .
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
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:

Ik raad aan om deze te beluisteren.
Ontwikkeling van een eigen oplossing door een gebruiker .
Ik vond nog .
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:
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:
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).

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.
.
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 sessionphp.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. .
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 cachebitrix/.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 , 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:

En ziet er als volgt uit:

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=productionHelm 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).

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
