Ein nüchterner Blick auf Helm 2: "Das ist es ..."

Wie jede andere Lösung hat Helm - der Paketmanager für Kubernetes - Vor-, Nachteile und Anwendungsbereiche. Wenn Sie ihn verwenden, sollten Sie Ihre Erwartungen richtig einschätzen ...


Wir verwenden Helm in unserem Arsenal an Strangwalzwerkzeugen. Zum Zeitpunkt des Schreibens befinden sich mehr als tausend Anwendungen in unseren Clustern und etwa 4000 Installationen dieser Anwendungen in verschiedenen Variationen. In regelmäßigen Abständen treten Probleme auf, aber im Allgemeinen sind wir mit der Lösung zufrieden. Wir haben keine Ausfallzeiten und Datenverluste.

Das Hauptmotiv für das Schreiben dieses Artikels besteht darin, dem Benutzer eine objektive Bewertung der Hauptprobleme von Helm 2 ohne endgültige Schlussfolgerungen sowie den Wunsch nach Erfahrungsaustausch und unseren Lösungen zu geben.

[BUG] Nach dem Rollout entspricht der Status der Release-Ressourcen im Cluster nicht dem beschriebenen Helm-Diagramm


Bei der Arbeit berücksichtigt Helm nicht den Status der Freigaberessourcen im Cluster. Bei der Neuinstallation wird das Ergebnis nur durch die aktuelle und die gespeicherte Konfiguration bestimmt. Daher ist der Status der Ressource im Cluster und in der Helm-Registrierung unterschiedlich, und Helm berücksichtigt dies nicht.

Überlegen Sie, wie sich dieses Problem manifestiert:

  1. Die Ressourcenvorlage im Diagramm entspricht dem Status X.
  2. Der Benutzer installiert das Diagramm (Pinne speichert den Status der Ressource X).
  3. Als Nächstes ändert der Benutzer die Ressource im Cluster manuell (der Status ändert sich von X zu Y).
  4. Ohne Änderungen vorzunehmen, führt es ein helm upgrade ... Und die Ressource befindet sich immer noch im Status Y, obwohl der Benutzer X erwartet.

Und das ist noch nicht alles. Irgendwann ändert der Benutzer die Ressourcenvorlage im Diagramm (neuer Status W) - dann haben wir nach dem helm upgrade zwei Szenarien:

  • Die Anwendung des XW-Patches nimmt ab.
  • Nach dem Anwenden des Patches geht die Ressource in den Zustand Z über, der nicht dem gewünschten entspricht.

Um ein solches Problem zu vermeiden, wird vorgeschlagen, die Arbeit mit Releases wie folgt zu organisieren: Niemand sollte Ressourcen manuell ändern . Helm ist das einzige Tool für die Arbeit mit Release-Ressourcen. Im Idealfall werden Diagrammänderungen im Git-Repository versioniert und ausschließlich auf der CD angewendet.

Wenn diese Option nicht geeignet ist, können Sie die Synchronisierung der Status der Freigaberessourcen überwachen . Die manuelle Synchronisierung kann folgendermaßen aussehen:

  1. Den Status der Release-Ressourcen erfahren wir über helm get .
  2. Den Status der Ressourcen in Kubernetes kubectl get über kubectl get .
  3. Wenn die Ressourcen unterschiedlich sind, synchronisieren wir Helm mit Kubernetes:
    1. Erstellen Sie einen separaten Zweig.
    2. Aktualisieren von Diagrammmanifesten. Vorlagen müssen mit den Ressourcenzuständen in Kubernetes übereinstimmen.
    3. Wir führen die Bereitstellung durch. Wir synchronisieren den Status in der Helm-Registrierung und im Cluster.
    4. Danach kann der Zweig gelöscht und die reguläre Arbeit fortgesetzt werden.

Beim Anwenden von Patches mit dem kubectl apply wird die sogenannte 3-Wege-Zusammenführung ausgeführt, d. H. Der tatsächliche Status der aktualisierten Ressource wird berücksichtigt. Sie können den Algorithmuscode hier sehen und hier darüber lesen.

Zum Zeitpunkt des Schreibens suchen Helm-Entwickler nach Möglichkeiten, 3-Wege-Zusammenführung in Helm 3 zu implementieren. Mit Helm 2 sind die Dinge nicht so rosig: Die Implementierung von 3-Wege-Zusammenführung ist nicht geplant, aber es gibt eine PR, um die Art und Weise zu korrigieren, wie Ressourcen erstellt werden - Sie können Details herausfinden oder sogar teilnehmen als Teil der relevanten Ausgabe .

[BUG] Fehler: Keine RESOURCE mit dem Namen NAME gefunden


Das Problem tritt auf, wenn neue Ressourcen erfolgreich erstellt werden, wenn der Rollout wiederholt wird, und der Rollout selbst letztendlich fehlschlägt. Neue Ressourcen sind diejenigen, die nicht in der letzten Installation des Diagramms enthalten waren.

Wenn der Rollout fehlschlägt, wird die Version in der mit FAILED gekennzeichneten Registrierung gespeichert . Während der Installation stützt sich Helm auf den Status der neuesten DEPLOYED- Version, die in diesem Fall nichts über neue Ressourcen weiß. Infolgedessen versucht Helm, diese Ressourcen neu zu erstellen, und schlägt mit dem Fehler "Keine Ressource mit dem Namen NAME gefunden" fehl (der Fehler sagt das Gegenteil aus, aber dies ist das Problem). Ein Teil des Problems besteht darin, dass Helm beim Erstellen des Patches den Status der Release-Ressourcen im Cluster nicht berücksichtigt, wie im vorherigen Abschnitt beschrieben.

Derzeit besteht die einzige Lösung darin, neue Ressourcen manuell zu entfernen.

Um einen solchen Status zu vermeiden, können neue Ressourcen, die beim aktuellen Upgrade / Rollback erstellt wurden, automatisch gelöscht werden, wenn der Befehl letztendlich fehlschlägt. Nach einer langen Diskussion mit den Entwicklern in Helm wurde für die --cleanup-on-fail / Rollback-Befehle die Option --cleanup-on-fail hinzugefügt, die die automatische Reinigung aktiviert, wenn der Rollout fehlschlägt. Unsere PR wird diskutiert und sucht nach der besten Lösung.

Ab Helm Version 2.13 wird in den --atomic zum helm install/upgrade des --atomic Option --atomic angezeigt, die das Reinigen und Zurücksetzen während einer fehlgeschlagenen Installation aktiviert (weitere Informationen finden Sie unter PR ).

[BUG] Fehler: Uhr geschlossen vor Bis Timeout


Das Problem kann auftreten, wenn der Helm-Hook zu lange ausgeführt wird (z. B. während Migrationen) - obwohl die angegebenen spec.activeDeadlineSeconds die helm install/upgrade des helm install/upgrade und spec.activeDeadlineSeconds entsprechenden Jobs nicht überschritten werden.

Dieser Fehler wird vom Kubernetes-API-Server generiert, während auf den Abschluss des Hook-Jobs gewartet wird. Helm behandelt diesen Fehler nicht und stürzt sofort ab - anstatt die Warteanforderung erneut zu versuchen.

Als Lösung können Sie das Zeitlimit im API-Server --min-request-timeout=xxx : --min-request-timeout=xxx in der Datei /etc/kubernetes/manifests/kube-apiserver.yaml .

[BUG] Fehler: UPGRADE FEHLGESCHLAGEN: "foo" hat keine bereitgestellten Releases


Wenn die erste Version über die helm install fehlgeschlagen ist, gibt das nachfolgende helm upgrade einen ähnlichen Fehler zurück.

Es scheint, dass die Lösung recht einfach ist: Sie müssen nach einer fehlgeschlagenen Erstinstallation manuell das helm delete --purge durchführen - helm delete --purge , aber diese manuelle Aktion helm delete --purge die CI / CD-Automatisierung. Um die Ausführung manueller Befehle nicht zu unterbrechen, können Sie die werf- Funktionen zum Rollout verwenden . Bei Verwendung von werf wird die problematische Version bei der Neuinstallation automatisch neu erstellt.

helm upgrade --install ab Helm 2.13 in den helm upgrade --install helm install und helm upgrade --install einfach die Option --atomic Nach einer fehlgeschlagenen Installation wird die Version automatisch gelöscht (Details siehe PR ).

Autorollback


In Helm fehlt die Option --autorollback , die sich beim --autorollback an die aktuell erfolgreiche Revision erinnert (wird --autorollback , wenn die letzte Revision nicht erfolgreich ist) und nach einem erfolglosen Bereitstellungsversuch auf die gespeicherte Revision zurückgesetzt wird.

Da es wichtig ist, dass das Produkt ohne Unterbrechungen funktioniert, muss nach Lösungen gesucht werden. Die Einführung sollte vorhersehbar sein. Um die Wahrscheinlichkeit von Produktausfällen zu minimieren, wird häufig ein Ansatz mit mehreren Schaltkreisen (z. B. Staging, QA und Produktion) verwendet, der darin besteht, die Schaltkreise nacheinander auf Schaltkreise auszurollen. Mit diesem Ansatz werden die meisten Probleme behoben, bevor sie produktiv eingeführt werden. In Verbindung mit Autorolback können Sie gute Ergebnisse erzielen.

Um das Autorollback zu organisieren, können Sie das Helmmonitor - Plugin verwenden, mit dem Sie das Rollback an Metriken von Prometheus binden können. Ein guter Artikel, der diesen Ansatz beschreibt, ist hier verfügbar.

Für einige unserer Projekte wird ein ziemlich einfacher Ansatz verwendet:

  1. Vor der Bereitstellung erinnern wir uns an die aktuelle Version (wir glauben, dass die Version in einer normalen Situation, wenn sie vorhanden ist, notwendigerweise im Status DEPLOYED ist):

     export _RELEASE_NAME=myrelease export _LAST_DEPLOYED_RELEASE=$(helm list -adr | \ grep $_RELEASE_NAME | grep DEPLOYED | head -n2 | awk '{print $2}') 
  2. Installation oder Upgrade ausführen:

     helm install/upgrade ... || export _DEPLOY_FAILED=1 
  3. Wir überprüfen den Status der Bereitstellung und führen einen Rollback auf den gespeicherten Status durch:

     if [ "$_DEPLOY_FAILED" == "1" ] && [ "x$_LAST_DEPLOYED_RELEASE" != "x" ] ; then helm rollback $_RELEASE_NAME $_LAST_DEPLOYED_RELEASE fi 
  4. Wir beenden die Pipeline mit einem Fehler, wenn die Bereitstellung nicht erfolgreich war:

     if [ "$_DEPLOY_FAILED" == "1" ] ; then exit 1 ; fi 

Ab Helm Version 2.13 reicht es beim Aufrufen des helm upgrade aus, die Option --atomic anzugeben. Nach einem fehlgeschlagenen Installations-Rollback wird automatisch ein Rollback durchgeführt (Details siehe PR ).

Warten auf die Verfügbarkeit von Release-Ressourcen und Feedback zum Zeitpunkt des Rollouts


Wie geplant sollte Helm die Ausführung der entsprechenden Lebendigkeits- und Bereitschaftstests überwachen, wenn die Option --wait :

 --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout 

Diese Funktion funktioniert jetzt nicht richtig: Nicht alle Ressourcen und nicht alle API-Versionen werden unterstützt. Und der erklärte Wartevorgang selbst befriedigt unsere Bedürfnisse nicht.

Wie bei kubectl wait gibt es keine schnelle Rückmeldung und es gibt keine Möglichkeit, dieses Verhalten zu regulieren. Wenn der Rollout fehlschlägt, werden wir ihn erst nach einer Zeitüberschreitung erfahren. Im Falle einer problematischen Installation ist es erforderlich, den Rollout-Prozess so früh wie möglich abzuschließen, die CI / CD-Pipeline umzudrehen, die Version auf die Arbeitsversion zurückzusetzen und mit dem Debuggen fortzufahren.

Wenn die problematische Version zurückgesetzt wird und Helm während des Rollout-Prozesses keine Informationen zurückgibt, worum geht es dann beim Debuggen ?! Im Fall von kubectl wait Sie einen separaten Prozess zum Anzeigen von Protokollen organisieren, für den Release-Ressourcennamen erforderlich sind. Wie man eine einfache und funktionierende Lösung organisiert, ist nicht sofort klar. Neben Pod-Protokollen können nützliche Informationen im Rollout-Prozess, Ressourcenereignisse ... enthalten sein.

Unser werf CI / CD-Dienstprogramm kann ein Helmdiagramm bereitstellen, die Verfügbarkeit von Ressourcen überwachen und Informationen zur Einführung anzeigen. Alle Daten werden zu einem einzigen Stream zusammengefasst und an das Protokoll ausgegeben.

Diese Logik wird in einer separaten Kubedog- Lösung erstellt. Mit dem Dienstprogramm können Sie eine Ressource abonnieren, Ereignisse und Protokolle empfangen sowie rechtzeitig über fehlgeschlagene Rollouts informiert werden. Das heißt, Als Lösung können Sie nach dem Aufruf von helm install/upgrade ohne die Option --wait kubedog für jede Release-Ressource aufrufen.

Wir wollten ein Tool entwickeln, das alle erforderlichen Informationen zum Debuggen in der Ausgabe der CI / CD-Pipeline bereitstellt. Lesen Sie mehr über das Dienstprogramm in unserem letzten Artikel .

Vielleicht wird eines Tages in Helm 3 eine ähnliche Lösung erscheinen, aber bisher ist unser Problem in einem suspendierten Zustand.

Sicherheit bei Verwendung von helm init standardmäßig


Wenn der Befehl helm init ausgeführt wird, wird die Serverkomponente standardmäßig mit ähnlichen Berechtigungen wie der Superuser im Cluster installiert, was beim Zugriff durch Dritte zu unerwünschten Konsequenzen führen kann.

Um die Sicherheit des Clusters zu gewährleisten, müssen die Funktionen von Tiller eingeschränkt und die Verbindung sichergestellt werden - die Sicherheit des Netzwerks, über das die Kommunikation zwischen Helm-Komponenten stattfindet.

Das erste kann durch die Verwendung des Standard-RBAC-Mechanismus von Kubernetes erreicht werden, der die Aktionen der Pinne einschränkt, und das zweite durch Einstellen von SSL. Weitere Informationen finden Sie in der Helmdokumentation: Sichern Ihrer Helminstallation .

Es wird angenommen, dass das Vorhandensein der Serverkomponente - Tiller - ein schwerwiegender architektonischer Fehler ist , buchstäblich eine fremde Ressource mit Superuser-Rechten im Kubernetes-Ökosystem. Zum Teil sind wir uns einig: Die Implementierung ist unvollständig, aber lassen Sie uns dies von der anderen Seite betrachten . Wenn Sie den Bereitstellungsprozess unterbrechen und den Helm-Client beenden, bleibt das System nicht in einem undefinierten Zustand, d. H. Pinne bringt den Freigabestatus auf gültig. Es ist auch wichtig zu verstehen, dass diese Funktionen trotz der Tatsache, dass Tiller in Helm 3 aufgegeben wird, irgendwie vom CRD-Controller ausgeführt werden.

Martian Go Vorlagen


Go-Vorlagen haben eine große Einstiegsschwelle, aber die Technologie hat keine Einschränkungen hinsichtlich der Funktionen und Probleme mit DRY. Die Grundprinzipien, Syntax, Funktionen und Operatoren werden in unserem vorherigen Artikel in der Helm-Reihe erläutert.

Mangel an Geheimnissen aus der Box


Es ist praktisch, Anwendungscode, Infrastruktur und Rollout-Vorlagen zu speichern und zu verwalten, wenn sie sich an einem Ort befinden. Und Geheimnisse sind keine Ausnahme.

Helm unterstützt keine sofort einsatzbereiten Geheimnisse. Es ist jedoch das Plugin für Helmgeheimnisse verfügbar, das im Wesentlichen eine Schicht zwischen Sops , Mozillas Geheimdienstmanager und Helm darstellt.

Bei der Arbeit mit Geheimnissen verwenden wir unsere eigene in werf implementierte Lösung ( Dokumentation zu Geheimnissen ). Von den Funktionen:

  • Einfache Implementierung.
  • Ein Geheimnis in einer Datei bewahren, nicht nur in YAML. Praktisch beim Speichern von Zertifikaten und Schlüsseln.
  • Regeneration von Geheimnissen mit einem neuen Schlüssel.
  • Rollout ohne geheimen Schlüssel (bei Verwendung von werf). Dies kann in Fällen nützlich sein, in denen der Entwickler nicht über diesen geheimen Schlüssel verfügt, jedoch eine Bereitstellung für einen Test oder eine lokale Verbindung gestartet werden muss.

Fazit


Helm 2 ist als stabiles Produkt positioniert, aber gleichzeitig gibt es viele Fehler, die in der Schwebe hängen (einige von ihnen halten mehrere Jahre!). Anstelle von Lösungen oder zumindest Patches werden alle Anstrengungen auf die Entwicklung von Helm 3 gerichtet.

Trotz der Tatsache, dass MR und Problem monatelang hängen bleiben können ( hier ist ein Beispiel dafür, wie wir eine before-hook-creation policy zum before-hook-creation policy von Hooks before-hook-creation policy für mehrere Monate hinzugefügt haben), können Sie dennoch an der Entwicklung des Projekts teilnehmen. Jeden Donnerstag findet eine halbstündige Kundgebung von Helm-Entwicklern statt, bei der Sie die Prioritäten und aktuellen Richtungen des Teams kennenlernen, Fragen stellen und Ihre eigenen Best Practices erzwingen können. Über Mete und andere Kommunikationskanäle wird hier ausführlich geschrieben.

Ob Sie Helm verwenden oder nicht, liegt natürlich bei Ihnen. Heute halten wir selbst an einer solchen Position fest, dass Helm trotz der Mängel eine akzeptable Lösung für den Einsatz darstellt und es für die gesamte Community nützlich ist, an seiner Entwicklung teilzunehmen.

PS


Lesen Sie auch in unserem Blog:

Source: https://habr.com/ru/post/de438814/


All Articles