Da wir Republik Website auf Kubernetes übersetzt haben



    Skandalöse, wichtige und einfach sehr coole Materialien werden nicht täglich in den Medien veröffentlicht. Kein Redakteur wird sich verpflichten, den Erfolg eines bestimmten Artikels mit 100% iger Genauigkeit vorherzusagen. Das Maximum, das das Team hat, ist auf der Ebene des Instinkts, "starkes" Material oder "normal" zu sagen. Alle Dann beginnt die unvorhersehbare Magie der Medien, dank derer der Artikel mit Dutzenden Links aus anderen Publikationen an die Spitze der Suchergebnisse gelangen kann oder das Material in Vergessenheit gerät. Und gerade bei der Veröffentlichung cooler Artikel fallen Medienseiten regelmäßig unter den ungeheuren Zustrom von Nutzern, den wir bescheiden als "Habraeffekt" bezeichnen.

    In diesem Sommer ist der Ort der Republik: Artikel zur Rentenreform, zur Schulbildung und zur Ernährung im Allgemeinen versammelten sich mit mehreren Millionen Lesern. Die Veröffentlichung jedes der genannten Materialien führte zu so hohen Belastungen, dass bis zum Sturz der Website der Republik absolut "ein bisschen ein Wort" vorlag. Die Verwaltung erkannte, dass es notwendig war, etwas zu ändern: Es musste die Struktur des Projekts geändert werden, um auf veränderte Arbeitsbedingungen (hauptsächlich externe Last) schnell reagieren zu können, während es auch in Momenten sehr starker Präsenzsprünge funktionsfähig und für die Leser zugänglich ist. Ein großer Bonus wäre der minimale manuelle Eingriff des technischen Teams der Republik in solchen Momenten.

    Nach den Ergebnissen einer gemeinsamen Diskussion mit Experten der Republik über verschiedene Optionen für die Umsetzung der geäußerten Anfragen haben wir uns entschlossen, die Website an Kubernetes * zu übertragen. Was uns das alles gekostet hat und heute unsere Geschichte sein wird.

    * Kein republikanischer Techniker wurde während des Umzugs verletzt

    Wie es im Allgemeinen aussah


    Alles begann natürlich mit den Verhandlungen, wie alles „jetzt“ und „dann“ geschehen wird. Das moderne Paradigma auf dem IT-Markt impliziert leider, dass, sobald ein Unternehmen eine Infrastrukturlösung erhält, eine schlüsselfertige Preisliste für Services vergeben wird. Es scheint, dass die Arbeit "schlüsselfertig" ist - was könnte schöner und schöner sein als der herkömmliche Direktor oder Geschäftsinhaber? Ich habe bezahlt, und der Kopf tut nicht weh: Planung, Entwicklung, Unterstützung - alles ist vorhanden, auf der Seite des Auftragnehmers kann das Unternehmen nur Geld verdienen, um einen so angenehmen Service bezahlen zu können.

    Die vollständige Übernahme der IT-Infrastruktur ist jedoch für den Kunden langfristig nicht immer angemessen. Es ist richtiger, aus allen Blickwinkeln als ein großes Team zusammenzuarbeiten, so dass der Kunde nach Abschluss des Projektes mit der neuen Infrastruktur weiterleben kann und die Kollegen von der Kundenseite nicht die Frage hatten: „Aber was haben Sie hier gemacht?“ Nach der Unterzeichnung des Abschlusszertifikats und präsentieren die Ergebnisse. Die gleiche Meinung wurde von den Jungs aus der Republik geteilt. In der Folge landeten wir für zwei Monate für vier Kunden in einer Landung, die nicht nur unsere Idee verwirklichte, sondern auch technisch vorbereitete Spezialisten auf der Seite der Republik für die weitere Arbeit und Existenz in der Realität des Kubernetes.

    Davon profitierten alle Beteiligten: Wir haben die Arbeiten schnell abgeschlossen, unsere Spezialisten auf neue Herausforderungen vorbereitet und die Republik als Auftraggeber für die Beratung mit eigenen Ingenieuren gewonnen. Die Publikation erhielt auch eine neue Infrastruktur, die an die „Habra-Effekte“ angepasst ist, das eigene Personal aus technischen Spezialisten und die Möglichkeit, bei Bedarf um Hilfe zu bitten.

    Brückenkopf kochen


    "Zerstören ist nicht zu bauen." Dieses Sprichwort trifft auf alles zu. Natürlich scheint es die einfachste Lösung gewesen zu sein, die Infrastruktur des Kunden als Geisel zu nehmen und diese, den Kunden an sich selbst zu ketten, oder die Aufteilung des vorhandenen Personals und die Notwendigkeit, Gurus in neuen Technologien einzustellen. Wir sind heute den dritten, nicht den populärsten Weg gegangen und haben mit der Ausbildung von Ingenieuren der Republik angefangen.

    Ungefähr diese Lösung, um den Betrieb der Website zu gewährleisten, die wir zu Beginn gesehen haben:


    Das heißt, Republic hatte nur zwei Eisenserver - Haupt- und Backup-Backup. Das Wichtigste für uns war, einen Paradigmenwechsel im Denken technischer Kundentechniker herbeizuführen, da sie zuvor mit einem sehr einfachen Bündel aus NGINX, PHP-fpm und PostgreSQL gearbeitet hatten. Jetzt mussten sie sich der skalierbaren Container-Architektur von Kubernetes stellen. Also haben wir zuerst die lokale Entwicklung der Republik in die Docker-Compose-Umgebung übertragen. Und das war nur der erste Schritt.

    Vor der Landung unserer Landing-Party behielten die Republic-Entwickler ihre lokale Arbeitsumgebung in virtuellen Maschinen, die über Vagrant konfiguriert wurden, oder sie arbeiteten direkt mit dem Dev-Server über Sftp. Basierend auf dem gemeinsamen Basisimage der virtuellen Maschine hat jeder Entwickler seine Schreibmaschine für sich selbst "vorkonfiguriert", wodurch sich eine ganze Reihe verschiedener Konfigurationen ergab. Als Ergebnis dieses Ansatzes wurde durch die Verbindung neuer Mitarbeiter mit dem Team die Zeit, die sie in das Projekt eintraten, exponentiell erhöht.

    In der neuen Realität haben wir dem Team eine transparentere Struktur der Arbeitsumgebung geboten. Es wurde deklarativ beschrieben, welche Software und welche Versionen für das Projekt benötigt werden, die Reihenfolge der Verbindungen und die Interaktionen zwischen Diensten (Anwendungen). Diese Beschreibung wurde in ein separates Git-Repository hochgeladen, damit sie bequem zentral verwaltet werden können.

    Alle notwendigen Anwendungen liefen in separaten Docker-Containern - und dies ist eine reguläre PHP-Site mit nginx, vielen statischen Image-Services (Größenänderung, Optimierung usw.) und ... einem separaten Service für in D geschriebene Web-Sockets Alle Konfigurationsdateien (nginx-conf, php-conf ...) wurden ebenfalls Bestandteil der Codebase des Projekts.

    Dementsprechend wurde die lokale Umgebung, die vollständig mit der aktuellen Serverinfrastruktur identisch ist, "neu erstellt". Auf diese Weise wurde der Zeitaufwand für die Aufrechterhaltung der gleichen Umgebung auf lokalen Entwicklungsmaschinen und dem Verkauf reduziert. Dies wiederum hat erheblich dazu beigetragen, völlig unnötige Probleme zu vermeiden, die durch die selbstgeschriebenen lokalen Konfigurationen der einzelnen Entwickler verursacht werden.

    Infolgedessen wurden die folgenden Dienste in der Docker-Compose-Umgebung bereitgestellt:

    • Web für PHP-Fpm-Anwendungen;
    • Nginx;
    • impproxy und cairosvg (Bilddienste);
    • Postgres;
    • Redis;
    • elastische Suche;
    • Trompete (der gleiche Dienst für Web-Sockets auf D).

    Aus Sicht der Entwickler blieb die Arbeit mit der Codebasis unverändert - sie wurde in die erforderlichen Dienste aus einem separaten Verzeichnis (Basis-Repository mit dem Standortcode) in das erforderliche Dienste: public-Verzeichnis in den nginx-Dienst, der gesamte PHP-Anwendungscode in den php-fpm-Dienst eingebunden. Aus dem separaten Verzeichnis (das alle Konfigurationsdateien der Compose-Umgebung enthält) in den Diensten nginx und php-fpm werden die entsprechenden Konfigurationsdateien angehängt. Die Verzeichnisse mit den Postgres-, Elasticsearch- und Redis-Daten werden ebenfalls auf dem lokalen Computer des Entwicklers bereitgestellt. Wenn also alle Container neu zusammengestellt / gelöscht werden müssen, gehen die Daten in diesen Services nicht verloren.

    Um mit Anwendungsprotokollen zu arbeiten - auch in der Docker-Compose-Umgebung - wurden die Dienste des ELK-Stacks erhöht. Zuvor wurden einige Anwendungsprotokolle in das Standardverzeichnis / var / log / ... geschrieben, php-Anwendungsprotokolle und Ausnahmen wurden in Sentry geschrieben. Eine solche Variante des "dezentralen" Protokollspeichers war im Betrieb äußerst unpraktisch. Jetzt wurden Anwendungen und Dienste für die Interaktion mit dem ELK-Stack konfiguriert und verfeinert. Der Umgang mit Protokollen ist viel einfacher geworden, die Entwickler haben eine praktische Schnittstelle zum Suchen und Filtern von Protokollen. In der Zukunft (bereits im Cube) können Sie die Protokolle einer bestimmten Version der Anwendung (z. B. kronzhoba, die vorgestern gestartet wurde) beobachten.

    Dann begann das republikanische Team eine kurze Phase der Anpassung. Das Team musste verstehen und lernen, wie man im neuen Entwicklungsparadigma arbeitet, in dem Folgendes berücksichtigt werden sollte:

    1. Anwendungen werden stateless, und sie können jederzeit Daten verlieren. Wenn Sie Datenbanken oder Sitzungen verwenden, sollten statische Dateien anders erstellt werden. PHP-Sitzungen sollten zentral gespeichert und zwischen allen Instanzen der Anwendung umgeschaltet werden. Es kann sich auch weiterhin um Dateien handeln, jedoch wird Redis aufgrund der einfacheren Verwaltung häufig für diesen Zweck verwendet. Datenbankcontainer müssen entweder ein Datadir in sich "einhängen" oder die Datenbank muss außerhalb der Containerinfrastruktur ausgeführt werden.
    2. Der Dateispeicher für etwa 50 bis 60 GB Bilder sollte nicht "in der Webanwendung" sein. Für diese Zwecke ist es notwendig, externe Speicher, CDN-Systeme usw. zu verwenden.
    3. Alle Anwendungen (Datenbanken, Anwendungsserver ...) sind jetzt separate "Dienste", und die Interaktion zwischen ihnen muss in Bezug auf den neuen Namespace konfiguriert werden.

    Nachdem das Entwicklungsteam der Republik die Innovationen beherrscht hatte, begannen wir, die Vertriebsinfrastruktur der Publikation an Kubernetes zu übertragen.

    Und hier ist Kubernetes


    Basierend auf der Umgebung, die für die lokale Entwicklung von Docker-Compose geschaffen wurde, begannen wir, das Projekt in einen „Cube“ zu übersetzen. Bei allen Services, für die das Projekt lokal erstellt wurde, haben wir „in Container gepackt“: Wir organisierten ein lineares und verständliches Verfahren zum Zusammenstellen von Anwendungen, zum Speichern von Konfigurationen und zum Erstellen von Statik. Aus der Sicht der Entwicklung haben wir die von uns benötigten Konfigurationsparameter in Umgebungsvariablen übernommen und begonnen, Sitzungen nicht in Dateien, sondern in Rettich zu speichern. Sie besaßen eine Testumgebung, in der sie eine funktionsfähige Version der Site bereitstellten.

    Da es sich um ein früheres monolithisches Projekt handelt, ist es offensichtlich, dass zwischen der Frontend- und der Backend-Version ein enger Zusammenhang bestand und die beiden Komponenten gleichzeitig eingesetzt wurden. Daher haben wir uns entschieden, Webanwendungen so zu erstellen, dass zwei Container gleichzeitig in einer Datei gedreht wurden: php-fpm und nginx.

    Wir haben auch eine automatische Skalierung entwickelt, um Webanwendungen an der Spitze des Datenverkehrs auf maximal 12 zu skalieren und bestimmte Aktivitäts- / Bereitschaftstests festzulegen, da die Anwendung mindestens 2 Minuten benötigt, um gestartet zu werden (da der Cache aufgewärmt werden muss, ...)

    Sofort gab es natürlich alle Arten von Untiefen und Nuancen. Zum Beispiel: Kompilierte Statik wurde sowohl von dem Webserver, der sie verteilte, als auch vom Anwendungsserver auf fpm benötigt, der Bilder im Fluge generierte, irgendwo per Code an svg. Wir haben verstanden, dass wir, um nicht zweimal aufstehen zu müssen, einen Zwischen-Build-Container und eine Endmontage erstellen müssen, um durch einen mehrstufigen Container zu Containerisieren. Zu diesem Zweck haben wir mehrere Zwischencontainer erstellt, in denen die Abhängigkeiten separat verschärft werden. Die Statik (css und js) wird separat gesammelt und dann in zwei Containern (in nginx und in fpm) aus dem Zwischencontainer kopiert.

    Wir fangen an


    Um mit den Dateien der ersten Iteration zu arbeiten, haben wir ein gemeinsames Verzeichnis erstellt, das mit allen Arbeitsmaschinen synchronisiert wurde. Mit dem Wort "synchronisiert" meine ich hier genau das, was Sie vor allem mit Horror denken können - rsync im Kreis. Offensichtlich eine schlechte Entscheidung. Als Ergebnis erhielten wir den gesamten Speicherplatz auf GlusterFS. Die Arbeit mit Bildern wurde so eingerichtet, dass sie von jedem Computer aus zugänglich waren und nichts langsamer wurde. Für das Zusammenspiel unserer Anwendungen mit Datenspeichersystemen (Postgres, Elasticsearch, Redis) wurden in k8s externalName-Dienste erstellt, um Verbindungsparameter an einer Stelle zu aktualisieren, beispielsweise bei einer dringenden Umstellung auf die Sicherungsdatenbank.

    Alle Arbeiten mit crones wurden in die neuen Entitäten k8s - cronjob eingebracht, die nach einem bestimmten Zeitplan laufen können.

    Als Ergebnis haben wir die folgende Architektur erhalten: Anklickbar




    Über schwierig


    Es war der Start der ersten Version, denn parallel zum vollständigen Umbau der Infrastruktur wurde die Site immer noch umgestaltet. Ein Teil der Website war mit den gleichen Parametern ausgestattet - für Statik und alles andere und einige - mit anderen. Dort war es notwendig, als ob ich noch mehr sagen wollte, mit all diesen mehrstufigen Containern pervertiert zu werden, Daten in einer anderen Reihenfolge von ihnen zu kopieren usw.

    Wir mussten auch mit Tamburinen rund um das CI \ CD-System tanzen, um all das zu lehren, wie man es aus verschiedenen Repositories und aus verschiedenen Umgebungen einsetzt und steuert. Schließlich benötigen Sie eine ständige Kontrolle über die Versionen der Anwendungen, damit Sie verstehen können, wann die Anwendung dieses oder des Dienstes stattfand und mit welcher Version der Anwendung bestimmte Fehler begannen. Zu diesem Zweck haben wir das richtige Protokollierungssystem (sowie die Protokollierungskultur selbst) eingerichtet und ELK implementiert. Kollegen haben gelernt, bestimmte Selektoren zu setzen, um zu sehen, welcher Cron welche Fehler erzeugt und wie er überhaupt ausgeführt wird, denn nach der Ausführung des Cron-Containers werden Sie nicht mehr in den "Cube" einsteigen.

    Am schwierigsten war es jedoch, die gesamte Codebasis zu überarbeiten und zu überarbeiten.

    Ich möchte Sie daran erinnern, dass Republic ein Projekt ist, das jetzt zehn Jahre alt wird. Es begann mit einem Team, ein anderes entwickelt sich gerade, und es ist wirklich schwierig, alle Quellcodes nach möglichen Fehlern und Fehlern zu suchen. In diesem Moment verband natürlich unsere Landungsparty aus vier Personen die Ressourcen des restlichen Teams: Wir haben angeklickt und die gesamte Website mit Tests gefahren, selbst in den Abschnitten, die echte Menschen seit 2016 nicht besucht haben.

    Keine Dateien irgendwo


    Am Montag, am frühen Morgen, als die Leute eine Massenmail mit einem Digest verschickten, bekamen wir alle einen Pfahl. Der Täter wurde ziemlich schnell gefunden: Ein Cronjob wurde gestartet und begann wütend, Briefe an alle zu senden, die in der vergangenen Woche eine Auswahl von Nachrichten erhalten wollten, und verschlang die Ressourcen des gesamten Clusters. Mit einem solchen Verhalten konnten wir nicht abfinden, so dass wir schnell strenge Grenzen für die Ressourcen hinstellen: wie viel CPU und Speicher kann essen Behälter verbrauchen und so weiter.

    Wie hat das Team der Entwickler Republic


    Unsere Tätigkeit hat viele Veränderungen mit sich gebracht, und das haben wir verstanden. Tatsächlich haben wir nicht nur die Infrastruktur der Publikation neu erstellt, sondern das Containerpaket "Primär-Backup-Server", das eine zusätzliche Containerlösung enthält, die bei Bedarf zusätzliche Ressourcen verbindet, und den Ansatz für die weitere Entwicklung vollständig geändert.

    Nach einiger Zeit erkannten die Jungs, dass es nicht direkt mit dem Code, sondern mit einer abstrakten Anwendung arbeitete. In Anbetracht der CI \ CD-Prozesse (auf der Basis von Jenkins) begannen sie mit dem Schreiben von Tests. Sie hatten vollständige Entwicklungsumgebungen für Entwicklungsumgebungen, in denen sie neue Versionen ihrer Anwendung in Echtzeit testen, beobachten können, wo etwas herunterfällt, und lernen zu leben neue perfekte Welt.

    Was der Kunde erhalten hat


    Zunächst bekam Republic endlich einen kontrollierten Bereitstellungsprozess! Früher war es so: In der Republik gab es eine verantwortliche Person, die zum Server ging, alles manuell startete, dann die Statik sammelte und mit den Händen überprüfte, dass nichts abgefallen war . Und der Verantwortliche hat jetzt eine Aufgabe - zu überwachen, wie die Veröffentlichung im Allgemeinen ablief.

    Nachdem der Push an den Master-Zweig erfolgt ist, entweder automatisch oder mit einer "Button" -Bereitstellung (periodisch aufgrund bestimmter Geschäftsanforderungen ist die automatische Bereitstellung deaktiviert), tritt Jenkins in die Schlacht ein: Das Projekt beginnt mit dem Aufbau. Zunächst werden alle Docker-Container zusammengestellt: Abhängigkeiten werden in den Vorbereitungscontainern (Composer, Garn, npm) festgelegt, wodurch der Build-Prozess beschleunigt werden kann, wenn sich die Liste der erforderlichen Bibliotheken nicht geändert hat. dann werden die container für php-fpm, nginx und andere dienstleistungen gesammelt, in die analog zu der Docker-Compose-Umgebung nur die erforderlichen Teile der Codebasis kopiert werden. Danach werden Tests ausgeführt, und im Falle eines erfolgreichen Bestehens der Tests werden Bilder in ein privates Repository gepusht, und in der Tat werden Bereitstellungen in einer Cuber-Instanz bereitgestellt.

    Dank der Übersetzung der Republik in k8s haben wir eine Architektur mit einem Cluster aus drei realen Maschinen erhalten, die gleichzeitig bis zu zwölf Kopien der Webanwendung erstellen können. Gleichzeitig entscheidet das System anhand der aktuellen Last, wie viele Exemplare es gerade benötigt. Wir nahmen Republic aus der Lotterie "arbeitet - funktioniert nicht" mit statischen Primär- und Backup-Servern und baute für sie ein flexibles System auf, das für eine lawinenartige Erhöhung der Belastung der Site bereit ist.

    An diesem Punkt kann sich die Frage stellen: „Jungs, Sie haben zwei Eisenstücke für dieselben Hardwarekomponenten ausgetauscht, aber mit Virtualisierung, was ist der Vorteil, sind Sie in Ordnung?“ Und natürlich wird es logisch sein. Aber nur zum Teil. Infolgedessen haben wir nicht nur Hardware mit Virtualisierung erhalten. Wir haben ein stabiles Arbeitsumfeld, das sowohl im Verkauf als auch bei den Jungfrauen gleich ist. Die Umgebung, die für alle Projektbeteiligten zentral verwaltet wird. Wir haben einen Mechanismus für das Zusammenstellen des gesamten Projekts und die Einführung von Releases, eine für alle, erhalten. Wir haben ein komfortables Projektorchestrierungssystem. Sobald das Team der Republik feststellt, dass es in der Regel nicht mehr über ausreichende Ressourcen und die Risiken ultrahoher Lasten verfügt (oder wenn es bereits geschehen ist und alles außer Betrieb ist), dauert es nur noch einen Server, und innerhalb von 10 Minuten wird die Rolle eines Clusterknotens eingeführt. alles ist wieder schön und gut.

    Zweitens erschien ein nahtloses Layout: Der Besucher gelangt entweder zur alten Version der Anwendung oder zur neuen Version. Und nicht wie zuvor, wenn der Inhalt neu sein könnte und die Stile alt sind.
    Damit ist das Geschäft zufrieden: Jetzt können Sie schneller und häufiger neue Dinge tun.
    Alles in allem von „Lass es uns versuchen“ bis „erledigt“, dauerte die Arbeit an dem Projekt 2 Monate. Das Team unsererseits ist eine heroische Landung von vier Personen + Unterstützung der „Basis“ für die Dauer der Überprüfung des Codes und der Tests.

    Was Nutzer bekommen


    Und die Besucher haben die Änderungen grundsätzlich nicht gesehen. Der Bereitstellungsprozess für die RollingUpdate-Strategie ist nahtlos aufgebaut. Das Rollout einer neuen Version der Site wirkt sich NICHT auf die Benutzer aus. Eine neue Version der Site ist erst verfügbar, wenn sie die Tests und die Verfügbarkeit / Verfügbarkeit der Probe bestanden haben. Sie sehen nur, dass die Website funktioniert und scheint nach der Veröffentlichung cooler Artikel nicht zu fallen. Das ist im Allgemeinen das, was jedes Projekt braucht.

    Jetzt auch beliebt: