Pakete und Paketmanager für k8s

    Wir alle benutzen eine Art Paketmanager, einschließlich der Putzfrau Aunt Galya, die gerade ein iPhone in der Tasche hat. Es besteht jedoch keine generelle Übereinstimmung hinsichtlich der Funktionen der Paketmanager und der Standardumdrehungen für RP und dpkg für das Betriebssystem. Die Build-Systeme werden Paketmanager genannt. Wir schlagen vor, über ihre Funktionen nachzudenken - was es ist und warum sie in der modernen Welt benötigt werden. Und dann werden wir in Richtung Kubernetes graben und Helm aus der Sicht dieser Funktionen sorgfältig betrachten.


    Lassen Sie uns sehen, warum in diesem Diagramm nur die Vorlagenfunktion grün hervorgehoben ist und welche Probleme bei der Montage und Verpackung, der Automatisierung der Umgebung und anderen auftreten. Aber keine Sorge, der Artikel endet nicht damit, dass alles schlecht ist. Die Community konnte sich nicht damit abfinden und bietet alternative Tools und Lösungen an - lassen Sie uns damit umgehen.

    Ivan Glushkov ( gli ) hat uns dabei mit seinem Bericht zu RIT ++, der Video- und Textversion dieser ausführlichen und detaillierten Präsentation, geholfen .

    Die Videos zu diesem und anderen Vorträgen zu DevOps auf RHS ++ sind veröffentlicht und können in unserem Youtube-Kanal kostenlos angesehen werden.  Suchen Sie nach Antworten auf Ihre Arbeitsfragen.


    Über den Sprecher: Ivan Glushkov entwickelt seit 15 Jahren Software. Es ist mir gelungen, in MZ, in Echo über die Plattform für Kommentare zu arbeiten, um an der Entwicklung von Compilern für den Elbrus-Prozessor in MCST mitzuwirken. Jetzt mit Infrastrukturprojekten in Postmates beschäftigt. Ivan ist einer der führenden Podcasts von DevZen , in dem sie über unsere Konferenzen sprechen: Es gibt RIT ++ und  hier HighLoad ++.

    Paketmanager


    Obwohl jeder Paketmanager verwendet, gibt es keine Vereinbarung darüber, was er ist. Es gibt ein gemeinsames Verständnis, und jedes hat sein eigenes.

    Erinnern wir uns, an welche Arten von Paketmanagern zuerst gedacht wird:

    • Standardpaketmanager aller Betriebssysteme: rpm, dpkg, portage , ...
    • Paketmanager für verschiedene Programmiersprachen: Cargo, Cabal, Rebar3, Mix , ...

    Ihre Hauptfunktion besteht darin, Befehle auszuführen, um ein Paket zu installieren, ein Paket zu aktualisieren, ein Paket zu löschen und Abhängigkeiten zu verwalten. Bei Paketmanagern in Programmiersprachen ist alles etwas komplizierter. Beispielsweise gibt es Befehle wie "Paket ausführen" oder "Release erstellen" (Build / Run / Release). Es stellt sich heraus, dass dies bereits ein Montagesystem ist, obwohl wir es auch Paketmanager nennen.


    All dies ist nur der Tatsache geschuldet, dass Sie es nicht einfach nehmen können und ... lassen Sie die Liebhaber von Haskell diesen Vergleich verzeihen. Sie können eine binäre Datei ausführen, aber Sie können ein Programm nicht in Haskell oder C ausführen. Sie müssen es zunächst irgendwie vorbereiten. Und diese Vorbereitung ist ziemlich kompliziert und die Benutzer möchten, dass alles automatisch erledigt wird.

    Entwicklung


    Derjenige, der mit dem GNU libtool gearbeitet hat, das für ein großes Projekt aus einer großen Anzahl von Komponenten erstellt wurde, lacht nicht über den Zirkus. Es ist wirklich sehr schwierig und einige Fälle können nicht grundsätzlich gelöst werden, sondern können nur umgangen werden.

    Im Vergleich dazu sind moderne Paketmanager von Sprachen wie Rust viel bequemer - Sie drücken einen Knopf und alles funktioniert. Obwohl in der Tat, unter der Haube eine Vielzahl von Problemen gelöst. Gleichzeitig erfordern all diese neuen Funktionen etwas, insbesondere eine Datenbank. Obwohl im Paket-Manager selbst das aufgerufen werden kann, was Sie möchten, nenne ich es Datenbank Die Daten werden dort gespeichert: über installierte Pakete, über ihre Versionen, verbundene Repositorys, Versionen in diesen Repositorys. All dies muss irgendwo gespeichert werden, so dass es eine interne Datenbank gibt.

    Die Entwicklung in dieser Programmiersprache, das Testen dieser Programmiersprache wird gestartet - alles ist eingebaut und befindet sich darin, die Arbeit wird sehr bequem . Die meisten modernen Sprachen haben diesen Ansatz unterstützt. Sogar diejenigen, die nicht unterstützt haben, beginnen zu unterstützen, weil die Gemeinschaft zerquetscht wird und sagt, dass dies in der modernen Welt ohne dies unmöglich ist.

    Jede Lösung hat jedoch nicht nur Vorteile, sondern auch Nachteile . Der Nachteil ist, dass Wrapper, zusätzliche Dienstprogramme und die integrierte "Datenbank" benötigt werden.

    Docker


    Denken Sie, dass Docker ein Paketmanager ist oder nicht?

    Egal wie, aber in der Tat ja. Ich kenne kein korrekteres Dienstprogramm, um die Anwendung zusammen mit allen Abhängigkeiten vollständig zu installieren und durch Drücken einer Taste zum Laufen zu bringen. Was ist das, wenn kein Paketmanager? Dies ist ein großartiger Batchmanager!

    Maxim Lapshin hat bereits gesagt, dass es mit Docker viel einfacher geworden ist und ist es auch. Docker verfügt über ein integriertes Build-System, alle diese Datenbanken, Bindungen und Dienstprogramme.

    Was ist der Preis für alle Vorteile? Wer mit Docker arbeitet, denkt wenig über industrielle Anwendungen nach. Ich habe diese Erfahrung und der Preis ist tatsächlich sehr hoch:

    • Die Informationsmenge (Bildgröße), die im Docker-Image gespeichert werden soll. Es ist notwendig, alle Abhängigkeiten, Teile von Dienstprogrammen und Bibliotheken darin zu packen. Das Image ist groß und Sie müssen wissen, wie Sie damit arbeiten.
    • Viel komplizierter ist, dass der Paradigmenwechsel stattfindet .

    Zum Beispiel hatte ich die Aufgabe, ein Programm zur Verwendung von Docker zu übersetzen. Das Programm wurde von dem Team entwickelt, das sich im Laufe der Jahre entwickelt hat. Ich komme, wir machen alles, was in den Büchern steht: Wir malen die Geschichten der Benutzer, die Rollen, sehen, was und wie sie funktionieren, ihre Standardroutinen.

    Ich sage:

    - Docker kann alle Ihre Probleme lösen. Sehen Sie, wie es gemacht wird.

    - Alles wird auf Knopfdruck sein - super! Aber wir wollen SSH in Kubernetes-Containern machen.

    - Warten Sie, nirgendwo SSH.

    - Ja, ja, alles ist gut ... Können Sie SSH verwenden?

    Um die Wahrnehmung der Benutzer in eine neue Richtung zu lenken, ist viel Zeit erforderlich, eine Aufklärungsarbeit und viel Aufwand sind erforderlich.

    Ein weiterer Faktor im Preis ist die Docker-Registry - externes Repository für Images, es muss irgendwie installiert und gesteuert werden. Es gibt eigene Probleme, Müllsammler usw., und es kann oft fallen, wenn es nicht befolgt wird, aber das ist alles gelöst.

    Kubernetes


    Endlich erreichten wir Kubernetes. Dies ist ein cooles OpenSource-Anwendungsverwaltungssystem, das von der Community aktiv unterstützt wird. Obwohl sie ursprünglich dieselbe Firma verlassen hat, verfügt Kubernetes jetzt über eine große Gemeinschaft, und es ist unmöglich, mit ihr Schritt zu halten, es gibt praktisch keine Alternativen.

    Interessanterweise arbeiten alle Kubernetes-Knoten in Kubernetes selbst durch Container und alle externen Anwendungen durch Container - alles funktioniert durch Container ! Dies ist ein Plus und ein Minus.

    Kubernetes bietet viele nützliche Funktionen und Eigenschaften: Verteilung, Fehlertoleranz, die Fähigkeit, mit verschiedenen Cloud-Diensten zu arbeiten, wobei der Schwerpunkt auf der Microservice-Architektur liegt. Das alles ist interessant und cool, aber wie kann man die Anwendung in Kubernetes installieren?

    Wie installiere ich die Anwendung?


    Installieren Sie das Docker-Image in der Docker-Registrierung.

    Hinter diesem Satz steht der Abgrund. Stellen Sie sich vor, Sie haben eine Anwendung, zum Beispiel in Ruby, geschrieben, und Sie müssen das Docker-Image in die Docker-Registrierung aufnehmen. Dies bedeutet, dass Sie:

    • Bereiten Sie ein Docker-Bild vor.
    • verstehen, wie es läuft, auf welchen Versionen es basiert;
    • in der Lage sein, es zu testen;
    • sammeln, füllen Sie die Docker-Registry aus, die Sie übrigens zuvor installiert haben.

    In der Tat ist dies ein großer Schmerz in einer Zeile.

    Außerdem müssen Sie die Anwendungsmanifeste noch in Bezug auf (Ressourcen) k8s beschreiben. Die einfachste Möglichkeit:

    • Beschreibung des Einsatzes + Pod, Service + Ingress (möglich);
    • Führen Sie den Befehl kubectl apply -f resources.yaml aus, und übertragen Sie alle Ressourcen auf diesen Befehl.



    Gandhi reibt sich die Hände an einer Folie - es sieht so aus, als hätte ich bei Kubernetes einen Paketmanager gefunden. Kubectl ist jedoch kein Paketmanager. Es sagt einfach, dass ich den endgültigen Zustand des Systems sehen möchte. Dies ist keine Paketinstallation, keine Abhängigkeitsoperation, keine Assembly - es ist nur "Ich möchte diesen Endzustand sehen".

    Helm


    Endlich kommen wir zu Helm. Helm ist ein Mehrzweckprogramm. Nun überlegen wir, welche Entwicklungsrichtungen Helm hat und arbeiten dort mit ihm zusammen.

    Template Engine


    Erstens ist Helm eine Template Engine. Wir haben die Notwendigkeit diskutiert, Ressourcen vorzubereiten, und das Problem besteht darin, in Kubernetes zu schreiben (es ist möglich und nicht nur in yaml). Das interessanteste ist, dass es sich um statische Dateien für Ihre spezielle Anwendung in dieser speziellen Umgebung handelt.

    Wenn Sie jedoch mit mehreren Umgebungen arbeiten und nicht nur über Produktion, sondern auch über Staging, Testen, Entwicklung und verschiedene Umgebungen für verschiedene Teams verfügen, benötigen Sie mehrere ähnliche Manifestationen. Zum Beispiel, weil sich auf einem der Server mehrere Server befinden und Sie eine große Anzahl von Replikaten benötigen und auf dem anderen nur eine Replik. Es gibt keine Datenbank, die auf RDS zugreift, und Sie müssen PostgreSQL darin installieren. Und hier haben wir die alte Version, und Sie müssen alles ein bisschen neu schreiben.

    All diese Vielfalt führt dazu, dass Sie Ihr Manifest für Kubernetes mitnehmen, überall kopieren und überall anpassen müssen: Ändern Sie hier eine Zahl, etwas anderes. Es wird sehr unangenehm.

    Die Lösung ist einfach - Sie müssen Vorlagen eingeben . Das heißt, Sie bilden das Manifest, definieren darin Variablen und definieren dann die außerhalb definierten Variablen als Datei. Die Vorlage erstellt das endgültige Manifest. Es stellt sich heraus, dass das gleiche Manifest für alle Umgebungen wiederverwendet wird, was viel praktischer ist.

    Zum Beispiel das Manifest für Helm.


    • Der wichtigste Teil von Helm ist Chart.yaml , der beschreibt, was das Manifest ist, welche Versionen und wie es funktioniert.
    • Vorlagen  sind lediglich Ressourcenvorlagen von Kubernet, die Variablen in sich enthalten. Diese Variablen müssen in einer externen Datei oder in der Befehlszeile definiert werden, jedoch immer außerhalb.
    • values.yaml  ist der Standardname für die Datei mit Variablen für diese Vorlagen.

    Der einfachste Startbefehl zum Installieren des Diagramms ist helm ./wordpress (Ordner). Um einige Parameter neu zu definieren, sagen wir: "Ich möchte diese Parameter genau neu definieren und solche Werte festlegen."

    Helm bewältigt diese Aufgabe, deshalb markieren wir sie grün im Diagramm.


    Echte Nachteile erscheinen:

    • Ausführlichkeit . Ressourcen sind vollständig in Kubernetes definiert, es werden keine Konzepte zusätzlicher Abstraktionsebenen eingeführt: Wir schreiben einfach alles, was wir für Kubernetes schreiben möchten, und ersetzen dort Variablen.
    • Wiederholen Sie sich nicht - trifft nicht zu. Sie müssen dasselbe oft wiederholen. Wenn Sie zwei ähnliche Dienste mit unterschiedlichen Namen haben, müssen Sie den gesamten Ordner vollständig kopieren (meistens) und die erforderlichen Dateien ändern.

    Bevor wir in die Richtung von Helm - dem Paketmanager, eintauchen, für den ich das alles erzähle, wollen wir sehen, wie Helm mit Abhängigkeiten arbeitet.

    Mit Abhängigkeiten arbeiten


    Mit Abhängigkeiten arbeitet Helm hart. Erstens gibt es eine Requirements.yaml-Datei, die zu dem passt, von dem wir abhängig sind. Bei der Arbeit mit Anforderungen werden Anforderungen gemacht. Sperren - Dies ist der aktuelle Status (Impression) aller Abhängigkeiten. Danach lädt er sie in einen Ordner namens / charts herunter.

    Es gibt Werkzeuge zur Kontrolle: wer, wie, wo anzuschließen ist - Tags und Bedingungen , mit deren Hilfe in welcher Umgebung festgelegt wird, abhängig davon, welche externen Parameter verbunden werden oder welche Abhängigkeiten nicht vorhanden sind.

    Angenommen, Sie haben PostgreSQL für die Staging-Umgebung (oder RDS for Production oder NoSQL für Tests). Durch die Installation dieses Pakets in Production installieren Sie PostgreSQL nicht, da es dort nicht benötigt wird - nur mithilfe von Tags und Bedingungen.

    Was ist hier interessant?

    • Helm mischt alle Ressourcen aller Abhängigkeiten und Anwendungen;
    • sortieren -> installieren / aktualisieren

    Nachdem wir alle Abhängigkeiten in / charts heruntergeladen haben (diese Abhängigkeiten können beispielsweise 100 sein), nimmt Helm in sich und kopiert alle Ressourcen. Nachdem er die Vorlagen gerendert hat, sammelt er alle Ressourcen an einem Ort und sortiert sie in einer Art eigener Reihenfolge. Sie können diese Reihenfolge nicht beeinflussen. Sie müssen selbst entscheiden, von was Ihr Paket abhängt, und wenn das Paket transitive Abhängigkeiten aufweist, müssen Sie sie alle in die Beschreibung in den Anforderungen aufnehmen. Yaml. Dies muss berücksichtigt werden.

    Stapelmanager


    Helm installiert Anwendungen und Abhängigkeiten, und Sie können Helm-Installation mitteilen - und das Paket wird installiert. Das ist also ein Paketmanager.

    Wenn Sie über ein externes Repository verfügen, in das Sie ein Paket hochladen, können Sie nicht als lokaler Ordner darauf zugreifen, sondern sagen Sie einfach: "Nehmen Sie dieses Paket, und installieren Sie es mit solchen Parametern."

    Es gibt offene Repositorys mit einer großen Anzahl von Paketen. Zum Beispiel können Sie Folgendes ausführen: helm install -f prod / values.yaml stable / wordpress

    Vom stabilen Repository nehmen Sie WordPress und installieren es. Sie können alles tun: Suchen / Aktualisieren / Löschen. Es stellt sich tatsächlich heraus, Helm-Paketmanager.

    Aber es gibt Nachteile: alle transitiven Abhängigkeitenmuss nach innen gedreht werden Dies ist ein großes Problem, wenn es sich bei transitiven Abhängigkeiten um eigenständige Anwendungen handelt und Sie zum Testen und Entwickeln separat damit arbeiten möchten.

    Ein weiterer Nachteil ist die End-to-End-Konfiguration . Wenn Sie über eine Datenbank verfügen, deren Name auf alle Pakete übertragen werden muss, ist dies möglich, aber schwierig.



    Meistens passiert es nicht, dass Sie eine kleine Tasche installiert haben, und es funktioniert. Die Welt ist komplex: Die Anwendung hängt von der Anwendung ab, die wiederum auch von der Anwendung abhängt - man muss sie irgendwie geschickt anpassen. Helm weiß nicht, wie er sie unterstützen soll, oder er unterstützt ihn bei großen Problemen. Manchmal muss man viel mit einem Tamburin tanzen, damit es funktioniert. Dies ist schlecht, daher ist der "Paketmanager" im Schema rot markiert.



    Montage und Verpackung


    "Sie können die Anwendung nicht einfach in Kubernetes aufnehmen und ausführen". Sie müssen es erstellen, dh ein Docker-Image erstellen, in die Docker-Registrierung schreiben usw. Obwohl alle Definitionen des Pakets in Helm enthalten sind. Wir definieren, was ein Paket ist, welche Funktionen und Felder vorhanden sein sollen, Signaturen und Authentifizierung (das Sicherheitssystem Ihres Unternehmens wird sich sehr freuen). Daher scheint einerseits der Build und das Packaging unterstützt zu werden, andererseits ist die Arbeit mit Docker-Images nicht konfiguriert.

    Helm erlaubt nicht, die Anwendung ohne das Docker-Image zu starten. Gleichzeitig ist Helm nicht zum Erstellen und Packen konfiguriert, das heißt, er kann nicht mit Docker-Images arbeiten.

    Dies ist dasselbe, als würden Sie zur Durchführung einer Upgrade-Installation für eine kleine Bibliothek in einen Remote-Ordner geschickt, um den Compiler auszuführen.

    Daher sagen wir, dass Helm nicht mit Bildern arbeiten kann.


    Entwicklung


    Der nächste Kopfschmerz ist die Entwicklung. In der Entwicklung möchten wir unseren Code schnell und bequem ändern. Die Zeit ist verstrichen, als Sie Lochkarten gelocht haben und das Ergebnis nach 5 Tagen erzielt wurde. Jeder ist es gewohnt, im Editor einen Buchstaben durch einen anderen zu ersetzen, die Zusammenstellung zu drücken und das bereits geänderte Programm funktioniert.

    Es stellt sich außerdem heraus, dass beim Ändern des Codes viele zusätzliche Aktionen erforderlich sind: Vorbereiten einer Docker-Datei; Führen Sie Docker aus, um ein Bild zu erstellen. irgendwo, um es zu schieben; Bereitstellung für den Kubernetes-Cluster. Und nur dann bekommen Sie, was Sie von Production erwarten, und können die Funktionsweise des Codes überprüfen.

    Immer noch Unannehmlichkeiten aufgrund eines zerstörerischen UpdatesHelm Upgrade. Sie haben gesehen, wie alles funktioniert, durch kubectl exec sah der Container aus, alles ist in Ordnung. An diesem Punkt starten Sie ein Update, ein neues Image wird heruntergeladen, neue Ressourcen werden gestartet und alte werden gelöscht - alles muss von vorne beginnen.

    Der größte Schmerz sind große Bilder.. Die meisten Unternehmen arbeiten nicht mit kleinen Anwendungen. Oft ist dies nicht ein Supermonolith, sondern zumindest ein kleiner Monolith. Im Laufe der Zeit nimmt das Wachstum der Jahresringe zu, wodurch sich die Codebasis erhöht, und nach und nach wird die Anwendung ziemlich groß. Ich bin mehr als einmal auf Docker-Images gestoßen, die größer als 2 GB sind. Stellen Sie sich jetzt vor, Sie ändern ein Byte in Ihrem Programm, drücken eine Taste und ein Docker-Image mit zwei Gigabyte beginnt sich zusammenzusetzen. Dann drücken Sie die nächste Taste und die Übertragung von 2 GB auf den Server beginnt.

    Mit Docker können Sie mit Ebenen arbeiten, d. H. prüft, ob eine Schicht vorhanden ist, und sendet die fehlende Schicht. Aber die Welt ist so, dass sie öfter eine einzige Schicht sein wird. Während 2 GB auf den Server gehen, während sie und die Docker-Registry nach Kubernetes kommen, rollen Sie alle Boxen aus, bis Sie endlich loslegen - Sie können sicher Tee trinken.

    Helm bietet keine Hilfe bei der Arbeit mit großen Docker-Bildern. Ich glaube, das sollte nicht so sein, aber die Helm-Entwickler wissen es besser als alle Benutzer, und Steve Jobs lächelt dies.



    Der Entwicklungsblock wurde ebenfalls rot.



    Automatisierung der Umgebung


    Der letzte Bereich, die Umgebungsautomatisierung, ist ein interessanter Bereich. Vor der Docker-Welt (und Kubernetes als verwandtem Modell) konnte nicht gesagt werden: "Ich möchte meine Anwendung auf diesem Server oder auf diesen Servern installieren, sodass n Repliken, 50 Abhängigkeiten vorhanden sind und alles automatisch funktioniert!" das war, war aber nicht!

    Kubernetes bietet dies und es ist logisch, es irgendwie zu verwenden, um beispielsweise zu sagen: "Ich implementiere hier eine neue Umgebung, und ich möchte, dass alle Entwicklungsteams, die ihre Anwendungen vorbereitet haben, einfach auf einen Knopfdruck klicken, und alle diese Anwendungen werden automatisch in der neuen Umgebung installiert." . Theoretisch sollte Helm dabei helfen, damit die Konfiguration von einer externen Datenquelle - S3, GitHub - von überall her übernommen werden kann.

    Es ist wünschenswert, dass es in Helm einen speziellen Button „Mach mich endlich gut!“ - und es würde sofort gut werden. Kubernetes ermöglicht es Ihnen, dies zu tun.

    Dies ist besonders praktisch, da Kubernetes überall ausgeführt werden können und über die API ausgeführt werden. Wenn Sie Minikube lokal oder in AWS oder in der Google Cloud Engine ausführen, erhalten Sie Kubernetes aus der Box und funktionieren überall gleich: Drücken Sie eine Taste, und alles ist in Ordnung.

    Es sieht so aus, als ob Helm Ihnen dies erlaubt. Denn sonst, was war der Sinn von Helm?

    Aber es stellt sich heraus, nein!


    Automatisierungsumgebung fehlt.

    Alternativen


    Wenn es eine Anwendung von Kubernetes gibt, die jeder verwendet (dies ist nun tatsächlich die Lösungsnummer 1), aber gleichzeitig die oben genannten Probleme von Helm, kann die Community nicht anders als zu beantworten. Es begann, alternative Werkzeuge und Lösungen zu entwickeln.

    Template-Engines


    Es scheint, dass Helm als Template-Engine alle Probleme gelöst hat, aber die Community schafft immer noch Alternativen. Ich erinnere mich an die Probleme der Template Engine: Ausführlichkeit und Wiederverwendung von Code.

    Ein guter Vertreter hier ist Ksonnet. Es verwendet ein grundlegend anderes Datenmodell und Konzepte und arbeitet nicht mit Kubernetes-Ressourcen, sondern mit eigenen Definitionen:
    Prototyp (params) -> Komponente -> Anwendung -> Umgebungen.


    Es gibt Teile (Teile), aus denen der Prototyp besteht. Der Prototyp wird durch externe Daten parametrisiert, und eine Komponente wird angezeigt. Mehrere Komponenten bilden eine Anwendung, die ausgeführt werden kann. Es läuft in verschiedenen Umgebungen. Es gibt einige verständliche Links zu Kubernetes-Ressourcen, aber es gibt möglicherweise keine direkte Analogie.

    Der Hauptzweck des Aufkommens von Ksonnet war natürlich die Wiederverwendung von Ressourcen . Sie wollten es so machen, dass Sie es nach dem Schreiben des Codes später überall verwenden können, was die Entwicklungsgeschwindigkeit erhöht. Wenn Sie eine große externe Bibliothek erstellen, können die Benutzer ihre Ressourcen ständig dort ablegen, und die gesamte Community kann sie wiederverwenden.

    Theoretisch ist es günstig. Ich habe es praktisch nicht benutzt.

    Paketmanager


    Das Problem hierbei sind, wie wir uns erinnern, verschachtelte Abhängigkeiten, End-to-End-Konfigurationen und transitive Abhängigkeiten. Ihr Ksonnet löst nicht. Ksonnet hat ein sehr ähnliches Modell wie Helm, das auch die Liste der Abhängigkeiten in der Datei definiert, in ein bestimmtes Verzeichnis hochgeladen wird usw. Der Unterschied ist, dass Sie Patches erstellen können, das heißt, Sie bereiten einen Ordner vor, in den Sie Patches für bestimmte Pakete einfügen.


    Wenn Sie einen Ordner hochladen, überlappen sich diese Patches, und das Ergebnis, das durch das Zusammenfügen mehrerer Patches erzielt wird, kann verwendet werden. Außerdem gibt es eine Validierung von Konfigurationen für Abhängigkeiten. Das mag praktisch sein, aber es ist immer noch sehr roh, es gibt fast keine Dokumentation und die Version ist auf 0,1 eingefroren. Ich denke es ist zu früh um es zu benutzen.


    Der Paketmanager ist also KubePack.und ich habe noch keine anderen Alternativen gesehen.

    Entwicklung


    Die Lösungen sind in verschiedene Kategorien unterteilt:

    1. versuche auf Helm zu arbeiten;
    2. anstelle von Helm;
    3. Sie verwenden einen grundsätzlich anderen Ansatz, bei dem sie versuchen, direkt in einer Programmiersprache zu arbeiten.
    4. und andere Variationen, die später.

    1. Entwicklung über Helm


    Ein guter Vertreter ist Entwurf . Ziel ist es, die Anwendung testen zu können, bevor der Code festgeschrieben wird, d. H., Um den aktuellen Status anzuzeigen. Entwurf verwendet die Heroku-Programmiermethode:

    • es gibt Pakete für Ihre Sprachen (Pack);
    • schreibe in Python "Hallo, Welt!";
    • Drücken Sie die Taste, eine Docker-Datei wird automatisch erstellt (Sie schreiben sie nicht).
    • Ressourcen werden automatisch erstellt, alles startet, es wird an die Docker-Registry gesendet, die Sie konfigurieren mussten;
    • Die Anwendung startet automatisch.

    Dies kann in jedem Verzeichnis mit Code erfolgen, alles scheint schnell, einfach und gut zu sein.

    In Zukunft ist es jedoch besser, mit Helm zu arbeiten, weil Draft Helm-Ressourcen erstellt. Wenn Ihr Code produktionsbereit ist, sollten Sie nicht hoffen, dass Draft Helm-Ressourcen gut schafft. Sie müssen sie noch manuell erstellen.

    Es stellt sich heraus, dass Entwurf benötigt wird, um schnell zu beginnen und ganz am Anfang zu versuchen, bevor Sie mindestens eine Helm-Ressource geschrieben haben. Entwurf ist der erste Anwärter für diese Richtung.

    2. Entwicklung ohne Helm


    Bei der Entwicklung ohne Helm-Charts werden dieselben Kubernetes-Manifestationen erstellt, die ansonsten über Helm-Charts erstellt würden. Ich schlage drei Alternativen vor:

    • GitKube;
    • Skaffold;
    • Schmiede

    Sie alle sind Helm sehr ähnlich, die Unterschiede in kleinen Details. Insbesondere wird in einem Teil der Lösungen davon ausgegangen, dass Sie die Befehlszeilenschnittstelle verwenden, und in Chart wird davon ausgegangen, dass Sie git Push und Hooks verwalten.

    Am Ende laufen noch Docker Build, Docker Push und kubectl Rollout. Alle Probleme, die wir für Helm aufgelistet haben, werden überhaupt nicht gelöst. Es ist nur eine Alternative mit den gleichen Nachteilen.

    3. Entwicklung in der Sprache der Anwendung


    Die nächste Alternative ist die Entwicklung in der Sprache der Anwendung. Hier ist ein gutes Beispiel - Metapartikel . Angenommen, Sie schreiben Code in Python und direkt in Python fangen Sie an zu denken, was Sie von der Anwendung erwarten.

    Ich halte dies für ein sehr interessantes Konzept, da der Entwickler meist nicht darüber nachdenken möchte, wie die Anwendung auf den Servern funktionieren soll, wie die Konfiguration in sysconfig richtig eingestellt ist usw. Es ist eine wichtige Arbeitsanwendung.

    Wenn es richtig ist, eine funktionierende Anwendung zu beschreiben, aus welchen Bestandteilen sie besteht und wie sie miteinander interagieren, kann eine Art Magie dieses Wissen aus der Sicht der Anwendung in Kubernetes-Ressourcen verwandeln.

    Mit Hilfe von Dekorateuren bestimmen wir: wo sich das Repository befindet, wie man es richtig schiebt; welche Dienste sind und wie sie miteinander interagieren; Es sollten so viele Replikate im Cluster usw. sein.


    Ich weiß nicht, wie es Ihnen geht, aber persönlich mag ich es nicht, wenn statt mir eine Art Magie entscheidet, dass Sie aus den Python-Definitionen eine solche Kubernetes-config machen müssen. Und wenn ich noch eine brauche?

    All dies funktioniert bis zu einer bestimmten Grenze, während die Anwendung ziemlich standardisiert ist. Danach beginnen die Probleme. Angenommen, ich möchte einen Vorinstallationscontainer starten, bevor der Hauptcontainer ausgeführt wird, der einige Aktionen zum Konfigurieren des zukünftigen Containers ausführt. Dies geschieht alles im Rahmen von Kubernetes-configs, aber ich weiß nicht, ob dies im Rahmen von Metaparticle geschieht.

    Ich zitiere gewöhnliche einfache Beispiele, und es gibt viele mehr davon, es gibt viele Parameter in der Spezifikation von Kubernetes-configs. Ich bin sicher, dass sie in Dekorateuren wie Metaparticle nicht vollständig vorhanden sind.



    Der Metapartikel erscheint im Diagramm und wir haben drei alternative Ansätze für Helm diskutiert. Es gibt jedoch zusätzliche, und sie sind meiner Meinung nach sehr vielversprechend.

    Telepresence / Ksync - einer von ihnen. Stellen Sie sich vor, Sie haben bereits eine Bewerbung geschrieben, es gibt auch Helm-Ressourcen. Sie haben die Anwendung installiert, sie wurde irgendwo im Cluster gestartet, und in diesem Moment möchten Sie etwas ausprobieren, beispielsweise eine Zeile in Ihrem Code ändern. Natürlich spreche ich nicht von Produktionsclustern, obwohl einige für die Produktion verantwortlich sind.

    Das Problem von Kubernetes besteht darin, dass Sie diese lokalen Änderungen über das Docker-Update über die Registrierung an Kubernetes übertragen müssen. Sie können jedoch eine andere Zeile in den Cluster bringen. Sie können den lokalen Ordner und den Remote-Ordner synchronisieren, der sich auf der Feuerstelle befindet.

    Ja, natürlich sollte gleichzeitig ein Compiler im Image vorhanden sein, alles, was für die Entwicklung notwendig ist, sollte vorhanden sein. Aber was für ein Komfort: Wir installieren die Anwendung, ändern mehrere Zeilen, die Synchronisierung funktioniert automatisch, der aktualisierte Code wird auf der Seite angezeigt, wir beginnen mit der Kompilierung und den Tests - nichts bricht, nichts aktualisiert, keine zerstörerischen Aktualisierungen, da in Helm keine Aktualisierungen ausgeführt werden Anwendung

    Meiner Meinung nach ist dies eine hervorragende Lösung für das Problem.

    4. Entwicklung für Kubernetes ohne Kubernetes


    Ich dachte immer, dass es keinen Sinn hätte, mit Kubernetes ohne Kubernetes zu arbeiten. Ich dachte, dass es besser ist, einmal Helm-Definitionen zu erstellen und die entsprechenden Werkzeuge zu verwenden, damit Sie in der lokalen Entwicklung eine einzige Konfiguration für alles haben. Aber im Laufe der Zeit wurde ich mit der Realität konfrontiert und sah Anwendungen, für die es äußerst schwierig ist. Nun bin ich zu dem Schluss gekommen, dass es einfacher ist, eine Docker-Compose-Datei zu schreiben.

    Wenn Sie eine Docker-Compose-Datei ausführen, führen Sie alle die gleichen Bilder aus und hängen, genau wie im vorherigen Fall, den lokalen Ordner im Ordner des Docker-Containers an, nicht nur in Kubernetes, sondern nur in Docker-Compose, das lokal ausgeführt wird . Dann einfach den Compiler laufen lassen und alles funktioniert gut. Der Nachteil ist, dass Sie zusätzliche Konfigurationen für Docker benötigen. Der Vorteil ist Geschwindigkeit und Einfachheit.

    In meinem Beispiel habe ich versucht, in minikube dasselbe zu starten, was ich mit Docker-Compose versucht habe, und der Unterschied war enorm. Es hat schlecht funktioniert, es gab unverständliche Probleme, und Sie setzen Docker-Compose in 10 Zeilen an, und alles funktioniert. Da Sie mit den gleichen Bildern arbeiten, ist die Wiederholbarkeit gewährleistet.


    Docker-compose wird unserem Schema hinzugefügt, und insgesamt stellt sich heraus, dass die Community all diese Lösungen zur Lösung des Entwicklungsproblems zusammenfasst.

    Montage und Verpackung


    Ja, Montage und Verpackung sind für Helm ein Problem, aber wahrscheinlich hatten die Entwickler von Helm recht. Jedes Unternehmen verfügt über ein eigenes CI / CD-System, das Artefakte, Prüfungen und Tests sammelt. Wenn sie es schon hat - warum dieses Problem in Helm schließen, wenn jeder sein eigenes hat? Vielleicht schlägt eine korrekte Lösung fehl, jede hat Modifikationen.

    Wenn Sie über ein CI / CD verfügen, gibt es eine Integration in ein externes Repository. Andocken werden automatisch für jeden Commit erfasst, Set-Tests werden ausgeführt, und Sie können die Schaltfläche drücken und alles schließen. Sie haben das Problem gelöst - es bleibt nicht übrig.

    CI / CD ist wirklich eine Lösung für das Build- und Verpackungsproblem, und wir malen es grün.

    Ergebnisse




    Von den 5 Richtungen schließt Helm selbst nur die Template-Engine. Sofort wird klar, warum es erstellt wurde. Die restlichen Lösungen, die die Community gemeinsam hinzufügte, die Probleme der Entwicklung, Montage und Verpackung werden durch externe Lösungen vollständig gelöst. Dies ist nicht ganz bequem, es ist nicht immer einfach, im Rahmen der etablierten Traditionen im Unternehmen zu arbeiten, aber vielleicht zumindest.

    Zukünftiger Helm


    Ich habe Angst, dass keiner von uns sicher weiß, wozu Helm kommen soll. Wie wir gesehen haben, wissen die Helm-Entwickler manchmal besser, was zu tun ist. Ich denke, dass die meisten Probleme, die wir betrachtet haben, durch die nächsten Versionen von Helm nicht geschlossen werden.

    Mal sehen, was der aktuellen Roadmap hinzugefügt wurde. Es gibt ein solches Repository Kuberneres Helm in der Community , in dem es Entwicklungspläne und gute Dokumentation gibt, die in der nächsten Version von Helm V3 erscheinen werden .

    Haftungsausschluss, nur cli


    Wir haben diese Details noch nicht besprochen, deshalb werden wir jetzt überlegen. Die Helm-Architektur besteht aus zwei Teilen:

    1. Der Client-Teil, den Sie auf dem lokalen Computer ausführen (cmd usw.).
    2. Tiller ist der zweite Teil, der auf einem Server in Kubernetes läuft.

    Tiller verarbeitet Anforderungen, die Sie über die Befehlszeilenschnittstelle senden. Sie sagen also: "Ich möchte diese Karte installieren" - und tatsächlich sammelt Helm sie, packt sie, schickt sie an Tiller und er entscheidet bereits: "Oh, etwas ist zu mir gekommen! Es sieht so aus, als ob es in die nächsten Ressourcen von Kubernetes projiziert wird “- und startet.

    Laut den Helm-Entwicklern sollte ein Tiller pro Cluster arbeiten und den gesamten Technologiezoo des Clusters verwalten. Es stellte sich jedoch heraus, dass es für einen ordnungsgemäßen gemeinsamen Zugriff vorteilhafter ist, nicht nur einen, sondern mehrere Tiller zu haben - für jeden Namespace. Tiller kann also nur Ressourcen in dem Namespace erstellen, in dem er ausgeführt wird, und hatte nicht das Recht, in benachbarte Namespaces zu gehen. Dadurch ist es möglich, den Verantwortungsbereich, den Sichtbarkeitsbereich für verschiedene Teams, aufzuteilen.

    Die nächste Version von V3 Tiller wird dies nicht tun.


    Und warum wird er überhaupt gebraucht? Im Wesentlichen enthält es Informationen, die über die Befehlszeilenschnittstelle übertragen werden, um Ressourcen in Kubernetes zu starten. Es stellt sich heraus, dass Kubernetes bereits genau die gleichen Informationen enthält, die in Tiller enthalten sind. Mit kubectl cli kann ich dasselbe tun.

    Anstelle von Tiller wird ein Ereignissystem eingeführt . Alle neuen Ressourcen, die Sie über die Befehlszeilenschnittstelle an Kubernetes senden, enthalten Ereignisse: Einstellungen, Änderungen, Löschungen, Vor- und Nachereignisse. Es gibt einige dieser Ereignisse.

    Chart Lua-Skripte


    Einige davon können nicht bearbeitet werden, andere nicht und Sie können dies mit Hilfe von Lua-Skripts tun . Beim Erstellen eines Diagramms fügen Sie eine Sammlung von Lua-Skripts hinzu, die Sie in einem speziellen Ordner ablegen. Sie werden den Umgang mit externen Ereignissen vollständig verfolgen. Es muss bequem sein. In der Tat können einige der Probleme, die wir zuvor besprochen haben, mit diesem Ansatz gelöst werden.


    Lua und Ereignisse können zu Entwicklungsproblemen führen, da sowohl auf der Serverseite als auch auf der Seite der Umgebungsautomation kontrolliert werden kann, was zu tun ist, wenn etwas passiert.

    Leider gibt es immer noch keine Implementierung, man kann nur vermuten. Aber theoretisch ist das wichtigste Problem für mich die Automatisierung der Umgebung, wir können sie komplett schließen. Sie können eine neue Anwendung an Kubernetes schreiben, einige Konfigurationsdateien an sie senden und mithilfe des von Ihnen programmierten Mechanismus wird die Anwendung alles installieren, was Sie möchten. Mal sehen was passiert.

    Objekt freigeben + Release freigeben


    Um den Release-Prozess vollständig zu verfolgen, wird ein Release-Objekt mit Informationen dazu angezeigt, welches Release geschrieben wurde. Es wurde noch nicht bekannt gegeben, dass es sich um ein Release-Objekt handelt, wie es erstellt wird, ob es sich um eine CRD handelt oder nicht.

    Bindung an den freigegebenen Namespace


    Dieses Release-Objekt wird in dem Namespace erstellt, in dem alles lief, und dementsprechend ist es nicht erforderlich, Tiller an den Namespace zu binden - das Problem, das ich zuvor erwähnt habe.

    CRD: Controller


    In der fernen Zukunft denken Entwickler darüber nach, einen CRD-Controller für Helm für Fälle zu erstellen, die vom Standard-Push-Modell nicht abgedeckt werden können. Informationen über die Umsetzung davon gibt es jedoch nicht.

    Sammlung von Rezepten


    Insgesamt empfehle ich die Verwendung des Systems.


    Das ist natürlich Helm . Es wird von der Community erstellt, alle alternativen Lösungen werden von unabhängigen Teams erstellt, bei denen wir nicht sicher sind, wie lange sie existieren werden. Unglücklicherweise können sie übermorgen ihre Projekte aufgeben, und Sie bleiben am Boden des Trogs. Und Helm ist immer noch Teil von Kubernetes. Darüber hinaus wird es Probleme entwickeln und möglicherweise lösen.

    Natürlich CI / CD , automatischer Build durch Commit. In unserem Unternehmen haben wir die Integration mit Slack gemacht., wir haben einen Bot, der Ihnen mitteilt, wann ein neuer Build in master durchlaufen wurde und dass alle Tests erfolgreich waren. Sie sagen zu ihm: "Ich möchte es in Staging installieren" - und er installiert, sagt: "Ich möchte dort einen Test durchführen!" - und er startet. Ziemlich bequem.

    Verwenden Sie für die Entwicklung Docker-Compose oder Telepresence.

    Mehrere Versionen desselben Dienstes




    Am Ende werden wir die Situation analysieren, wenn es zwei Anwendungen A und B gibt, die von C abhängig sind, jedoch C verschiedene Versionen. Müssen Sie dieses Problem lösen:

    • für die Entwicklung, weil wir tatsächlich die gleiche, aber zwei verschiedene Versionen entwickeln müssen;
    • zur Freigabe;
    • für Namenskonflikte, da die Installation von zwei Paketen unterschiedlicher Versionen in allen Standardpaketmanagern Probleme verursachen kann.

    In der Tat entscheidet Kubernetes alles für uns - Sie müssen es nur richtig verwenden.



    Ich würde Ihnen raten, 4 Chart in Bezug auf Helm, 3 Repositories zu erstellen (für das C-Repository sind dies nur zwei verschiedene Zweige). Was am interessantesten ist, sollten alle Installationen für Version 1 und Version 2 Informationen zur Version oder für den Dienst enthalten, für den sie erstellt wurde. Eine der Lösungen auf der Folie, Anhang C; Der Versionsname gibt an, dass dies die Version v1 für Service A ist. Der Dienstname enthält auch eine Version. Dies ist das einfachste Beispiel, das Sie auf eine völlig andere Weise ausführen können. Das Wichtigste ist jedoch, dass die Namen eindeutig sind.

    Die zweite ist transitive Abhängigkeiten und hier komplizierter.


    Sie entwickeln zum Beispiel eine Servicekette und möchten A testen. Dazu müssen Sie alle Abhängigkeiten, von denen A abhängig ist, einschließlich transitiv, an die Helm-Definition Ihres Pakets übergeben. Gleichzeitig möchten Sie jedoch B entwickeln und auch testen. Die Vorgehensweise ist unverständlich, da Sie alle transitiven Abhängigkeiten mit einbeziehen müssen.

    Daher empfehle ich Ihnen, nicht alle Abhängigkeiten in jedes Paket einzufügen, sondern sie unabhängig zu machen und von außen zu verwalten, was ausgeführt wird. Dies ist unbequem, aber es ist das geringere von zwei Übeln.

    Nützliche Links


    Entwurf

    GitKube

    Helm

    Ksonnet

    • Telegrammaufkleber: ein , zwei

    Sig-Apps

    KubePack

    Metaparticle

    Skaffold

    Helm v3

    Docker-Compose

    Ksync

    Telepresence

    Drohne

    Forge

    Speaker-Profil Ivan Glushkov auf GitHub , in  twitter , auf  Habré .

    Tolle Neuigkeiten

    Auf unserem Youtube-Kanal haben wir  ein Video mit allen Berichten zu DevOps vom RIT ++ Festival geöffnet . Dies ist eine separate Wiedergabeliste , aber in der vollständigen Liste der Videos gibt es viele nützliche Informationen von anderen Konferenzen.

    Noch besser ist es, den Kanal und den Newsletter zu abonnieren , denn im kommenden Jahr werden viele Devos auf uns warten : im Mai im Rahmen von RIT ++; im Frühjahr, Sommer und Herbst als HighLoad ++ - Bereich und als separate Herbst DevOpsConf Russia .

    Jetzt auch beliebt: