In diesem Artikel werde ich unsere Erfahrungen mit der Migration von Preply nach Kubernetes beschreiben, wie und warum wir dies getan haben, auf welche Schwierigkeiten wir gestoĂen sind und welche Vorteile wir erzielt haben.

Kubernetes fĂŒr Kubernetes? Nein, geschĂ€ftliche Anforderungen!
Rund um Kubernetes gibt es viel Hype und das aus gutem Grund. Viele Leute sagen, dass es alle Probleme lösen wird, einige sagen, dass Sie höchstwahrscheinlich keine Kubernetes benötigen . Die Wahrheit liegt natĂŒrlich irgendwo dazwischen.

Alle diese Diskussionen darĂŒber, wo und wann Kubernetes benötigt wird, verdienen jedoch einen separaten Artikel. Jetzt werde ich ein wenig ĂŒber unsere GeschĂ€ftsanforderungen und die Funktionsweise von Preply vor der Migration zu Kubernetes sprechen:
- Als wir Skullcandy Flow verwendeten , hatten wir viele Zweige, die alle zu einem gemeinsamen Zweig namens
stage-rc
verschmolzen und auf der BĂŒhne eingesetzt wurden. Das QA-Team testete diese Umgebung, nachdem der Zweig im Master fröhlich getestet und der Master auf dem Produkt bereitgestellt worden war. Der gesamte Vorgang dauerte ca. 3-4 Stunden und wir konnten 0 bis 2 Mal am Tag bereitstellen - Als wir den defekten Code fĂŒr das Produkt bereitstellten, mussten wir alle Ănderungen, die in der neuesten Version enthalten waren, zurĂŒcksetzen. Es war auch schwierig zu finden, welche Ănderung unser Produkt beschĂ€digte
- Wir haben AWS Elastic Beanstalk zum Hosten unserer Anwendung verwendet. In unserem Fall dauerte jede Beanstalk-Bereitstellung 45 Minuten (die gesamte Pipeline zusammen mit den Tests wurde in 90 Minuten erstellt ). Das ZurĂŒcksetzen auf die vorherige Version der Anwendung dauerte 45 Minuten
Um unsere Produkte und Prozesse im Unternehmen zu verbessern, wollten wir:
- Brechen Sie einen Monolithen in Microservices
- Stellen Sie schneller und hÀufiger bereit
- Rollback schneller
- Ăndern Sie unseren Entwicklungsprozess, weil wir dachten, dass er nicht mehr effektiv ist
Unsere BedĂŒrfnisse
Wir verÀndern den Entwicklungsprozess
Um unsere Innovationen mit Skullcandy Flow umzusetzen, mussten wir fĂŒr jede Branche eine dynamische Umgebung schaffen. Bei unserem Ansatz mit Anwendungskonfiguration in Elastic Beanstalk war dies schwierig und teuer. Wir wollten Umgebungen schaffen, die:
- Schnell und einfach bereitzustellen (vorzugsweise Container)
- Arbeitete vor Ort Instanzen
- Sie waren Àhnlich wie Prod
Wir haben uns fĂŒr Trunk-Based Development entschieden. Mit seiner Hilfe verfĂŒgt jedes Feature ĂŒber einen eigenen Zweig, der unabhĂ€ngig vom Rest zu einem Master zusammengefĂŒhrt werden kann. Ein Hauptzweig kann jederzeit bereitgestellt werden.

Git-Flow und Trunk-Based Development
Stellen Sie schneller und hÀufiger bereit
Mit dem neuen Trunk-basierten Prozess konnten wir Innovationen schneller nacheinander an die Hauptniederlassung liefern. Dies hat uns sehr geholfen, defekten Code im Produkt zu finden und zurĂŒckzusetzen. Die Bereitstellungszeit betrug jedoch immer noch 90 Minuten und die Rollback-Zeit 45 Minuten. Aus diesem Grund konnten wir die Bereitstellung nicht hĂ€ufiger 4-5 Mal pro Tag durchfĂŒhren.
Bei der Verwendung der Servicearchitektur fĂŒr Elastic Beanstalk sind ebenfalls Probleme aufgetreten. Die naheliegendste Lösung bestand darin, Container und Instrumente zu verwenden, um sie zu orchestrieren. DarĂŒber hinaus hatten wir bereits Erfahrung mit Docker und Docker-Compose fĂŒr die lokale Entwicklung.
Unser nÀchster Schritt war die Erforschung der beliebten Container-Orchestratoren:
- AWS ECS
- Schwarm
- Apache Mesos
- Nomad
- Kubernetes
Wir haben uns entschieden, bei Kubernetes zu bleiben, und deshalb. Unter den fraglichen Orchestratoren hatte jeder einen wichtigen Fehler: ECS ist eine herstellerabhĂ€ngige Lösung, Swarm hat bereits die Kubernetes-Lorbeeren verloren, Apache Mesos sah mit seinen Zookeepern wie ein Raumschiff fĂŒr uns aus. Nomad schien interessant zu sein, aber es zeigte sich nur in der Integration mit anderen Hashicorp-Produkten vollstĂ€ndig. Wir waren auch enttĂ€uscht, dass die Namespaces in Nomad bezahlt wurden.
Trotz seiner hohen Einstiegsschwelle ist Kubernetes der De-facto-Standard in der Container-Orchestrierung. Kubernetes as a Service ist bei den meisten groĂen Cloud-Anbietern verfĂŒgbar. Das Orchester befindet sich in aktiver Entwicklung, hat eine groĂe Community von Benutzern und Entwicklern und eine gute Dokumentation.
Wir haben erwartet, dass unsere Plattform in einem Jahr vollstÀndig auf Kubernetes migriert wird. Zwei Plattformingenieure ohne Kubernetes-Erfahrung waren an der Teilstartmigration beteiligt.
Verwenden von Kubernetes
Wir haben mit dem Proof of Concept begonnen, einen Testcluster erstellt und alles, was wir getan haben, detailliert dokumentiert. Wir haben uns fĂŒr Kops entschieden , da EKS in unserer Region zu diesem Zeitpunkt noch nicht verfĂŒgbar war (in Irland wurde dies im September 2018 angekĂŒndigt).
WĂ€hrend der Arbeit mit dem Cluster haben wir Cluster-Autoscaler , Cert-Manager , Prometheus, Integrationen mit Hashicorp Vault, Jenkins und vieles mehr getestet. Wir haben mit Rolling-Update-Strategien âgespieltâ, waren mit mehreren Netzwerkproblemen konfrontiert, insbesondere mit DNS , und haben unser Wissen ĂŒber Cluster-Clustering gestĂ€rkt.
Sie verwendeten Spot-Instanzen , um die Infrastrukturkosten zu optimieren. Um Benachrichtigungen ĂŒber Spot- Probleme zu erhalten, verwendeten sie den Kube-Spot-Termination-Notice-Handler . Spot Instance Advisor kann Ihnen bei der Auswahl des Spot-Instanztyps helfen.
Wir haben die Migration von Skullcandy Flow zu Trunk-basierter Entwicklung gestartet, wo wir fĂŒr jede Pulrequest eine dynamische Phase gestartet haben. Dadurch konnten wir die Lieferzeit fĂŒr neue Funktionen von 4-6 auf 1-2 Stunden reduzieren .

Github Hook startet die Erstellung einer dynamischen Umgebung fĂŒr Pull-Anforderungen
Wir haben einen Testcluster fĂŒr diese dynamischen Umgebungen verwendet. Jede Umgebung befand sich in einem separaten Namespace. Entwickler hatten Zugriff auf das Kubernetes Dashboard, um ihren Code zu debuggen.
Wir sind froh, dass wir bereits 1-2 Monate nach Beginn der Nutzung von Kubernetes profitieren konnten.
BĂŒhnen- und Verkaufscluster
Unsere Einstellungen fĂŒr BĂŒhnen- und Produktcluster:
- kops und Kubernetes 1.11 (die neueste Version zum Zeitpunkt der Clustererstellung)
- Drei Hauptknoten in verschiedenen Zugriffszonen
- Private Netzwerktopologie mit dedizierter Bastion, Calico CNI
- Prometheus zum Sammeln von Metriken wird im selben Cluster wie PVC bereitgestellt (es ist zu berĂŒcksichtigen, dass wir Metriken nicht lange speichern).
- Datadog Agent fĂŒr APM
- Dex + dex-k8s-Authentifikator , um Entwicklern Zugriff auf den Cluster zu gewÀhren
- Knoten fĂŒr BĂŒhnencluster arbeiten vor Ort
Bei der Arbeit mit Clustern sind verschiedene Probleme aufgetreten. Beispielsweise unterschieden sich die Versionen des Nginx Ingress- und Datadog-Agenten in den Clustern. In diesem Zusammenhang funktionierten einige Dinge im Stage-Cluster, aber nicht im Produkt. Aus diesem Grund haben wir uns entschlossen, die Softwareversionen in den Clustern vollstÀndig einzuhalten, um solche FÀlle zu vermeiden.
Prod nach Kubernetes migrieren
BĂŒhnen- und Lebensmittelcluster sind bereit, und wir sind bereit, mit der Migration zu beginnen. Wir verwenden Monorepa mit folgender Struktur:
. âââ microservice1 â âââ Dockerfile â âââ Jenkinsfile â âââ ... âââ microservice2 â âââ Dockerfile â âââ Jenkinsfile â âââ ... âââ microserviceN â âââ Dockerfile â âââ Jenkinsfile â âââ ... âââ helm â âââ microservice1 â â âââ Chart.yaml â â âââ ... â â âââ values.prod.yaml â â âââ values.stage.yaml â âââ microservice2 â â âââ Chart.yaml â â âââ ... â â âââ values.prod.yaml â â âââ values.stage.yaml â âââ microserviceN â â âââ Chart.yaml â â âââ ... â â âââ values.prod.yaml â â âââ values.stage.yaml âââ Jenkinsfile
Die Stamm- Jenkinsfile
enthÀlt eine Korrespondenztabelle zwischen dem Namen des Mikrodienstes und dem Verzeichnis, in dem sich sein Code befindet. Wenn der Entwickler die Pull-Anforderung an den Master hÀlt, wird in GitHub ein Tag erstellt. Dieses Tag wird mithilfe von Jenkins gemÀà der Jenkins-Datei auf dem Produkt bereitgestellt.
Das helm/
Verzeichnis enthĂ€lt HELM-Diagramme mit zwei separaten Wertedateien fĂŒr BĂŒhne und Verkauf. Wir verwenden Skaffold, um viele HELM-Diagramme auf der BĂŒhne bereitzustellen. Wir haben versucht, die Schirmtabelle zu verwenden, haben jedoch festgestellt, dass die Skalierung schwierig ist.
In Ăbereinstimmung mit der Zwölf-Faktor-App schreibt jeder neue Mikrodienst im Produkt Protokolle in stdout, liest Geheimnisse aus Vault und verfĂŒgt ĂŒber eine Reihe grundlegender Warnungen (ĂberprĂŒfung der Anzahl der funktionierenden Herde, fĂŒnfhundert Fehler und Latens beim Eintritt).
UnabhÀngig davon, ob wir neue Funktionen in Microservices importieren oder nicht, in unserem Fall liegt die HauptfunktionalitÀt im Django-Monolithen, und dieser Monolith funktioniert immer noch mit Elastic Beanstalk.

Brechen Sie den Monolithen in Microservices // Der Vigeland Park in Oslo
Wir haben AWS Cloudfront als CDN verwendet und damit eine kanarische Bereitstellung wĂ€hrend unserer Migration. Wir haben begonnen, den Monolithen auf Kubernetes zu migrieren und ihn auf einigen Sprachversionen und auf den internen Seiten der Site (wie dem Admin-Panel) zu testen. Ein Ă€hnlicher Migrationsprozess ermöglichte es uns, Fehler auf dem Produkt zu erkennen und unsere Bereitstellungen in nur wenigen Iterationen zu verbessern. Innerhalb weniger Wochen haben wir den Zustand der Plattform, die Auslastung und die Ăberwachung ĂŒberwacht, und am Ende wurden 100% des Verkaufsverkehrs auf Kubernetes umgestellt.

Danach konnten wir die Verwendung von Elastic Beanstalk vollstÀndig ablehnen.
Zusammenfassung
Die vollstÀndige Migration dauerte 11 Monate, wie oben erwÀhnt. Wir planten, die Frist von 1 Jahr einzuhalten.
TatsÀchlich sind die Ergebnisse offensichtlich:
- Die Bereitstellungszeit verringerte sich von 90 Minuten auf 40 Minuten
- Die Anzahl der Bereitstellungen stieg von 0-2 auf 10-15 pro Tag (und wÀchst immer noch!)
- Die Rollback-Zeit verringerte sich von 45 auf 1-2 Minuten
- Wir können problemlos neue Microservices an das Produkt liefern
- Wir haben unsere Ăberwachung, Protokollierung und Verwaltung von Geheimnissen aufgerĂ€umt, sie zentralisiert und als Code beschrieben
Es war eine sehr coole Migrationserfahrung und wir arbeiten immer noch an vielen Plattformverbesserungen. Lesen Sie unbedingt den coolen Artikel ĂŒber die Erfahrungen mit Kubernetes aus dem Jura. Er war einer der YAML-Ingenieure, die an der Implementierung von Kubernetes in Preply beteiligt waren.