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:
- Die Ressourcenvorlage im Diagramm entspricht dem Status X.
- Der Benutzer installiert das Diagramm (Pinne speichert den Status der Ressource X).
- Als Nächstes ändert der Benutzer die Ressource im Cluster manuell (der Status ändert sich von X zu Y).
- 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:
- Den Status der Release-Ressourcen erfahren wir über
helm get
. - Den Status der Ressourcen in Kubernetes
kubectl get
über kubectl get
. - Wenn die Ressourcen unterschiedlich sind, synchronisieren wir Helm mit Kubernetes:
- Erstellen Sie einen separaten Zweig.
- Aktualisieren von Diagrammmanifesten. Vorlagen müssen mit den Ressourcenzuständen in Kubernetes übereinstimmen.
- Wir führen die Bereitstellung durch. Wir synchronisieren den Status in der Helm-Registrierung und im Cluster.
- 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:
- 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}')
- Installation oder Upgrade ausführen:
helm install/upgrade ... || export _DEPLOY_FAILED=1
- 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
- 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: