In Tscheljabinsk finden die Sysadmin-Meetups von Sysadminka statt, und bei der letzten Veranstaltung habe ich ĂŒber unsere Lösung fĂŒr die Implementierung von 1C-Bitrix-Anwendungen in Kubernetes gesprochen.
Bitrix, Kubernetes, Ceph â eine perfekte Kombination?
Ich erklÀre Ihnen, wie wir aus all dem eine funktionierende Lösung entwickelt haben.
Los geht's!

Das Meetup fand am 18. April in Tscheljabinsk statt. Informationen ĂŒber unsere Meetups können Sie nachlesen unter und anschauen auf .
Wenn Sie uns einen Vortrag halten oder als Zuhörer teilnehmen möchten â herzlich willkommen, schreiben Sie an vadim.isakanov@gmail.com oder ĂŒber Telegram t.me/vadimisakanov.
Mein Vortrag
Lösung âBitrix in Kubernetes, Version Southbridge 1.0â
Ich werde Ihnen unsere Lösung im Format âfĂŒr Einsteiger in Kubernetesâ vorstellen, wie es beim Meetup gezeigt wurde. Ich gehe davon aus, dass Ihnen die Begriffe Bitrix, Docker, Kubernetes und Ceph zumindest auf Wikipedia-Ebene bekannt sind.
Was gibt es bereits an Informationen ĂŒber Bitrix in Kubernetes?
Im Internet gibt es sehr wenig Informationen zur Nutzung von Bitrix-Anwendungen in Kubernetes.
Ich habe nur folgende Materialien gefunden:
Der Vortrag von Alexander Serbul, 1C-Bitrix, und Anton Tuzlukov von Qsoft:

Ich empfehle, ihn anzuhören.
Entwicklung einer eigenen Lösung vom Nutzer .
Ich habe noch .
Und⊠das ist eigentlich alles.
Ich weise darauf hin, dass wir die QualitĂ€t der Arbeiten zu den oben genannten Lösungen nicht ĂŒberprĂŒft haben đ
Ăbrigens, wĂ€hrend der Vorbereitung unserer Lösung habe ich mit Alexander Serbul kommuniziert; zu diesem Zeitpunkt gab es seinen Vortrag noch nicht, weshalb in meinen Folien steht: âBitrix verwendet kein Kubernetesâ.
Aber es gibt bereits viele fertige Docker-Images fĂŒr Bitrix, die in Docker funktionieren:
Reicht das fĂŒr die Erstellung einer vollstĂ€ndigen Lösung fĂŒr Bitrix in Kubernetes aus?
Nein. Es gibt eine Vielzahl von Problemen, die gelöst werden mĂŒssen.
Was sind die Probleme mit Bitrix in Kubernetes?
Das erste â die fertigen Images aus Dockerhub sind nicht fĂŒr Kubernetes geeignet.
Wenn wir eine Mikroservice-Architektur aufbauen wollen (was wir in Kubernetes normalerweise wollen), muss die Anwendung in Kubernetes in Container aufgeteilt werden, und es muss sichergestellt werden, dass jeder Container eine kleine Funktion erfĂŒllt (und das gut macht). Warum nur eine? Kurz gesagt: Je einfacher, desto zuverlĂ€ssiger.
Wenn Sie mehr erfahren möchten â schauen Sie sich bitte diesen Artikel und das Video an:
Docker-Images in Dockerhub sind hauptsĂ€chlich nach dem Prinzip âalles in einemâ erstellt, weshalb wir tatsĂ€chlich unser eigenes Rad erfinden mussten und sogar die Images von Grund auf neu erstellen mussten.
Das zweite â der Code der Website wird ĂŒber das Admin-Panel bearbeitet.
Ein neuer Abschnitt auf der Website wurde erstellt â der Code wurde aktualisiert (ein Verzeichnis mit dem Namen des neuen Abschnitts wurde hinzugefĂŒgt).
Die Eigenschaften der Komponente im Administrationsbereich wurden geĂ€ndert â der Code hat sich geĂ€ndert.
Kubernetes kann standardmĂ€Ăig nicht damit arbeiten, Container mĂŒssen unverĂ€nderlich (Stateless) sein.
Grund: Jeder Container (Pod) im Cluster verarbeitet nur einen Teil des Traffics. Wenn der Code nur in einem Container (Pod) geÀndert wird, ist der Code in verschiedenen Pods unterschiedlich, die Website funktioniert unterschiedlich, und verschiedene Benutzer sehen unterschiedliche Versionen der Website. So kann man nicht arbeiten.
Das Dritte â wir mĂŒssen das Deployment-Problem lösen.
Wenn wir ein Monolith sind und einen âklassischenâ Server haben, ist alles ganz einfach: Wir setzen die neue Codebasis auf, fĂŒhren die Datenbankmigration durch und schalten den Traffic auf die neue Version des Codes um. Der Umschaltung erfolgt sofort.
Wenn wir eine Website in Kubernetes haben, die in Mikrodienste aufgeteilt ist und viele Container mit Code hat â oh je. Wir mĂŒssen Container mit der neuen Version des Codes erstellen, sie statt der alten ausrollen, die Datenbankmigration korrekt durchfĂŒhren und idealerweise dies unbemerkt fĂŒr die Besucher tun. GlĂŒcklicherweise unterstĂŒtzt uns Kubernetes dabei mit verschiedenen Arten des Deployments.
Der vierte Punkt â wir mĂŒssen das Problem mit der Speicherung von statischen Inhalten angehen.
Wenn Ihre Website "nur" 10 Gigabyte groà ist und Sie sie vollstÀndig in Containern bereitstellen, erhalten Sie Container mit einem Gewicht von 10 Gigabyte, die ewig deployt werden.
Die schwersten Teile der Website mĂŒssen auĂerhalb der Container gespeichert werden, und es stellt sich die Frage, wie man das richtig macht.
Was in unserer Lösung nicht enthalten ist.
Der gesamte Bitrix-Code ist nicht in Mikrofunktionen/Mikroservices aufgeteilt (z. B. Registrierung separat, Online-Shop-Modul separat usw.). Den gesamten Code-Basis speichern wir in jedem Container vollstÀndig.
Die Datenbank wird ebenfalls nicht in Kubernetes gespeichert (ich habe zwar Lösungen mit einer Datenbank in Kubernetes fĂŒr Entwicklerumgebungen umgesetzt, aber nicht fĂŒr die Produktion).
Administratoren der Website werden dennoch bemerken, dass die Website in Kubernetes lĂ€uft. Die Funktion âSystemprĂŒfungâ funktioniert nicht korrekt, um den Code der Website aus dem Admin-Panel zu bearbeiten, muss zuerst die SchaltflĂ€che âIch möchte den Code bearbeitenâ gedrĂŒckt werden.
Wir haben die Probleme gelöst, die Notwendigkeit von Microservices erkannt, und das Ziel ist klar â ein funktionierendes System fĂŒr die AusfĂŒhrung von Anwendungen auf Bitrix in Kubernetes zu schaffen, dabei sowohl die Möglichkeiten von Bitrix als auch die Vorteile von Kubernetes zu erhalten. Wir beginnen mit der Umsetzung.
Architektur von
Viele âArbeitsâ-Pods mit einem Webserver (Worker).
Ein Pod mit Cron-Tasks (unbedingt nur einer).
Ein Upgrade-Pod fĂŒr die Bearbeitung des Website-Codes aus dem Admin-Panel (auch hier unbedingt nur einer).

Wir klÀren die Fragen:
- Wo sollen die Sitzungen gespeichert werden?
- Wo soll der Cache gespeichert werden?
- Wo soll die statische Datei gespeichert werden, sollen wir wirklich Gigabytes an Statik in zahlreichen Containern ablegen?
- Wie wird die Datenbank funktionieren?
Docker-Image
Wir beginnen mit dem Aufbau des Docker-Images.
Die ideale Lösung â wir haben ein universelles Image, darauf basierend erhalten wir sowohl Worker-Pods, als auch Pods mit Cron-Tasks und Upgrade-Pods.
.
Es enthÀlt Nginx, Apache/PHP-FPM (wÀhlbar beim Aufbau), msmtp zum Versenden von E-Mails und Cron.
Beim Aufbau des Images wird die vollstĂ€ndige Codebasis der Website in das Verzeichnis /app kopiert (auĂer den Teilen, die wir in einen separaten Shared Storage auslagern).
Microservices, Services
Worker-Pods:
- Container mit Nginx + Container Apache/PHP-FPM + msmtp
- msmtp konnte nicht in einen separaten Microservice ausgelagert werden, Bitrix beschwert sich, dass es keine E-Mails direkt senden kann.
- In jedem Container ist der vollstÀndige Code vorhanden.
- Ănderungen am Code in Containern sind nicht erlaubt.
Cron lÀuft unter:
- Container mit Apache, PHP, Cron.
- Im Lieferumfang enthalten ist der vollstÀndige Code.
- Ănderungen am Code in Containern sind verboten.
Upgrade erfolgt unter:
- Container mit Nginx + Container Apache/PHP-FPM + msmtp.
- Es gibt keine EinschrĂ€nkungen fĂŒr Ănderungen am Code in den Containern.
Sessionspeicher.
Cache-Speicher fĂŒr Bitrix.
AuĂerdem wichtig: Die Passwörter fĂŒr den Zugriff auf alles, von der Datenbank bis zur E-Mail, speichern wir in Kubernetes-Secrets. Der Vorteil ist, dass Passwörter nur von denjenigen eingesehen werden können, denen wir Zugang zu den Secrets gewĂ€hren, nicht von allen, die Zugang zum Code des Projekts haben.
Speicher fĂŒr statische Dateien.
Es kann alles Mögliche verwendet werden: Ceph, NFS (aber NFS empfehlen wir nicht fĂŒr die Produktion), Netzwerkspeicher von "Cloud"-Anbietern usw.
Der Speicher muss in den Containern mit dem Verzeichnis /upload/ der Website und anderen Verzeichnissen fĂŒr statische Dateien verbunden werden.
Datenbank
Zur Vereinfachung empfehlen wir, die Datenbank auĂerhalb von Kubernetes auszulagern. Eine Datenbank in Kubernetes ist eine komplexe Aufgabe, die das Schema erheblich komplizierter macht.
Sessionspeicher.
Wir verwenden memcached đ
Es bewĂ€ltigt die Speicherung von Sessions gut, kann clusterartig arbeiten und wird "nativ" als session.save_path in PHP unterstĂŒtzt. Solch ein System wurde schon vielfach in klassischen monolithischen Architekturen eingesetzt, als wir Cluster mit einer groĂen Anzahl von Webservern aufgebaut haben. FĂŒr das Deployment verwenden wir Helm.
$ helm install stable/memcached --name sessionphp.ini â hier sind die Einstellungen fĂŒr die Speicherung von Sessions in Memcached im Image festgelegt.
Wir verwendeten Umgebungsvariablen, um Informationen ĂŒber die Hosts mit Memcached zu ĂŒbermitteln. .
Dadurch können wir denselben Code in den Umgebungen dev, stage, test, prod verwenden (die Namen der Memcached-Hosts werden unterschiedlich sein, daher mĂŒssen wir fĂŒr jede Umgebung die eindeutigen Hostnamen fĂŒr die Sessions ĂŒbergeben).
Cache-Speicher Bitrix
Wir benötigen einen fehlertoleranten Speicher, in den alle Pods schreiben und aus dem sie lesen können.
AuĂerdem verwenden wir Memcached.
Diese Lösung wird von Bitrix selbst empfohlen.
$ helm install stable/memcached --name cachebitrix/.settings_extra.php â hier wird in Bitrix festgelegt, wo der Cache gespeichert ist.
Wir verwenden ebenfalls Umgebungsvariablen.
Cronjobs
Es gibt verschiedene AnsĂ€tze zur AusfĂŒhrung von Cronjobs in Kubernetes.
- ein separater Deployment mit Pod fĂŒr die AusfĂŒhrung von Cronjobs
- Cronjob zur AusfĂŒhrung von Cronjobs (wenn es sich um eine Web-App handelt â mit wget , oder kubectl exec in einen der Worker-Pods, usw.)
- etc.
Es lĂ€sst sich darĂŒber streiten, was die beste Lösung ist, aber wir haben uns in diesem Fall fĂŒr die Option «separates Deployment mit Pods fĂŒr Cronjobs» entschieden.
So wird es gemacht:
- Wir fĂŒgen die Cronjobs ĂŒber ConfigMap oder ĂŒber die Datei config/addcron hinzu.
- Wir starten den Container einmal, der identisch zum Worker-Pod ist + erlauben die AusfĂŒhrung der Cronjobs darin.
- Es wird die gleiche Codebasis verwendet, was die Containererstellung vereinfacht.
Was haben wir davon:
- Wir haben funktionierende Cronjobs in einer Umgebung, die identisch mit der der Entwickler (Docker) ist.
- Die Cronjobs mĂŒssen nicht «neu geschrieben» werden fĂŒr Kubernetes, sie funktionieren in der gleichen Form und mit der gleichen Codebasis wie zuvor.
- Alle Teammitglieder mit Commit-Rechten im Produktionsbranch können Cronjobs hinzufĂŒgen, nicht nur die Administratoren.
Das Southbridge K8SDeploy-Modul und das Bearbeiten von Code aus dem Admin-Panel.
Wir haben doch ĂŒber das Upgrade der Pods gesprochen?
Wie leiten wir den Traffic dorthin?
Hurra, wir haben dafĂŒr ein PHP-Modul geschrieben đ Es ist ein kleines klassisches Modul fĂŒr Bitrix. Es ist noch nicht öffentlich verfĂŒgbar, aber wir planen, es zu veröffentlichen.
Das Modul wird wie ein regulÀres Modul in Bitrix installiert:

Und sieht so aus:

Es ermöglicht die Festlegung eines Cookies, das den Administrator der Website identifiziert und Kubernetes ermöglicht, den Traffic auf das Upgrade-Deployment zu leiten.
Sobald die Ănderungen abgeschlossen sind, mĂŒssen Sie git push drĂŒcken; der Code wird an git gesendet, dann erstellt das System ein Image mit der neuen Version des Codes und verteilt es im Cluster, wobei die alten Pods ersetzt werden.
Ja, etwas umstĂ€ndlich, aber dabei bewahren wir die Microservices-Architektur und nehmen den Bitrix-Nutzern nicht die Möglichkeit, den Code aus dem Admin-Bereich zu bearbeiten. SchlieĂlich ist es eine Option; man kann die CodeĂ€nderung auch anders angehen.
Helm Chart
FĂŒr den Aufbau von Anwendungen in Kubernetes verwenden wir in der Regel den Paketmanager Helm.
FĂŒr unsere Bitrix-Lösung in Kubernetes hat Sergey Bondarev, unser leitender Systemadministrator, ein spezielles Helm Chart geschrieben.
Es erstellt Pods fĂŒr Worker, Upgrade und Cron, konfiguriert Ingresses, Services und ĂŒbertrĂ€gt Variablen aus Kubernetes Secrets in die Pods.
Wir speichern den Code in GitLab und starten auch den Helm-Bau aus GitLab.
Kurz gesagt, das sieht so aus:
$ helm upgrade --install project .helm --set image=registrygitlab.local/k8s/bitrix -f .helm/values.yaml --wait --timeout 300 --debug --tiller-namespace=productionHelm ermöglicht auch einen nahtlosen Rollback, falls bei der Bereitstellung etwas schiefgeht. Es ist beruhigend zu wissen, dass nicht Sie in Panik den Code per FTP âfixenâ, weil die Produktion ausgefallen ist, sondern Kubernetes das automatisch und ohne Ausfallzeiten erledigt.
Deployment
Ja, wir sind Fans von Gitlab & Gitlab CI, wir nutzen es đ
Beim Commit in Gitlab wird ein Pipeline im Projekt-Repository gestartet, die die Bereitstellung einer neuen Version der Umgebung durchfĂŒhrt.
Phasen:
- build (wir erstellen ein neues Docker-Image)
- test (wir fĂŒhren Tests durch)
- clean up (wir löschen die Testumgebung)
- push (wir senden es an das Docker-Registry)
- deploy (wir deployen die Anwendung in Kubernetes ĂŒber Helm).

Hurra, alles bereit, wir setzen es um!
Oder wir stellen Fragen, wenn es welche gibt.
Also, was haben wir gemacht
Aus technischer Sicht:
- Wir haben Bitrix dockerisiert;
- Wir haben Bitrix in Container unterteilt, von denen jeder minimale Funktionen ausfĂŒhrt;
- Wir haben den stateless Zustand der Container erreicht;
- Wir haben das Problem mit der Aktualisierung von Bitrix in Kubernetes gelöst;
- Alle Funktionen von Bitrix funktionieren weiterhin (fast alle);
- Wir haben das Deployment in Kubernetes und Rollbacks zwischen Versionen erfolgreich umgesetzt.
Aus geschÀftlicher Sicht:
- Fehlertoleranz;
- Kubernetes-Tools (einfache Integration mit Gitlab CI, nahtloses Deployment usw.);
- Passwörter in Geheimnissen (nur fĂŒr Benutzer sichtbar, denen der Zugriff auf die Passwörter direkt gewĂ€hrt wurde);
- ZusĂ€tzliche Umgebungen (fĂŒr Entwicklung, Tests usw.) bequem innerhalb einer einheitlichen Infrastruktur erstellen.
Quelle: habr.com
