
Nach präsentieren wir seinen älteren Bruder — . Dies ist ein Open-Source-Projekt, das verwendet wird, um systematische Komponenten in einem Kubernetes-Cluster zu installieren, die man allgemein als Ergänzungen bezeichnen kann.
Warum überhaupt irgendwelche Ergänzungen?
Es ist kein Geheimnis, dass Kubernetes kein fertiges All-in-One-Produkt ist, und um einen „ausgewachsenen“ Cluster aufzubauen, sind verschiedene Ergänzungen erforderlich. Der Addon-Operator hilft dabei, diese Ergänzungen zu installieren, zu konfigurieren und aktuell zu halten.
Der Bedarf an zusätzlichen Komponenten im Cluster wird in der der Kollegen . Kurz gesagt, die Situation mit Kubernetes ist derzeit so, dass man für eine einfache Installation zum „Ausprobieren“ mit den Standardkomponenten auskommen kann, für Entwickler und Testzwecke kann man Ingress hinzufügen, aber um eine vollständige Installation zu haben, die man als „Ihre Produktion ist bereit“ bezeichnen kann, müssen rund ein Dutzend verschiedener Ergänzungen hinzugefügt werden: etwas für Monitoring, etwas für Logs, Ingress und Cert-Manager nicht vergessen, Knoten-Gruppen abteilen, Netzwerkrichtlinien hinzufügen, mit sysctl-Einstellungen und Pod-Autoscaler würzen…

Was ist das Besondere an der Arbeit mit ihnen?
Wie die Praxis zeigt, kommt es mit nur einer Installation nicht aus. Für eine komfortable Arbeit mit dem Cluster müssen Ergänzungen aktualisiert, deaktiviert (aus dem Cluster entfernt) werden, und manches möchte man möglicherweise vor der Installation im Produktions-Cluster testen.
Vielleicht reicht hier auch Ansible? Möglicherweise. Aber vollwertige Ergänzungen leben in der Regel nicht ohne Anpassungen. Diese Anpassungen können je nach Cluster-Variante (aws, gce, azure, bare-metal, do, …) unterschiedlich sein. Manche Einstellungen können nicht im Voraus festgelegt werden – sie müssen aus dem Cluster entnommen werden. Und der Cluster ist nicht statisch: Für einige Einstellungen muss man die Änderungen beobachten. Hier reicht Ansible nicht aus: Es wird ein Programm benötigt, das im Cluster lebt, d.h. ein Kubernetes Operator.
Diejenigen, die es ausprobiert haben , werden sagen, dass die Aufgaben der Installation und Aktualisierung der Ergänzungen sowie das Überwachen der Einstellungen mit Hilfe von für den Shell-Operator durchaus gelöst werden können. Man kann ein Skript schreiben, das eine bedingte kubectl apply ausführt und beispielsweise den ConfigMap überwacht, wo die Einstellungen gespeichert werden. Genau so ist es im Addon-Operator implementiert.
Wie ist es im Addon-Operator organisiert?
Bei der Entwicklung einer neuen Lösung haben wir folgende Prinzipien zugrunde gelegt:
- Der Addon-Installer muss unterstützen Vorlagen und deklarative Konfiguration. Wir verwenden keine magischen Skripte zur Installation von Addons. Der Addon-Operator nutzt Helm zur Installation von Addons. Zur Installation muss ein Chart erstellt und Werte definiert werden, die für die Konfiguration verwendet werden.
- Die Einstellungen können bei der Installation generiert werden, sie können aus dem Cluster abgerufen werden, oder Updates erhalten, indem man die Ressourcen des Clusters überwacht. Diese Operationen können mit Hooks implementiert werden.
- Die Einstellungen können im Cluster speichern. Zur Speicherung der Einstellungen im Cluster wird ein ConfigMap/addon-operator erstellt, und der Addon-Operator überwacht die Änderungen dieser ConfigMap. Der Addon-Operator gibt Hooks Zugriff auf die Einstellungen durch einfache Vereinbarungen.
- Das Addon hängt von den Einstellungen ab. Wenn sich die Einstellungen ändern, stellt der Addon-Operator das Helm-Chart mit neuen Werten bereit. Die Kombination aus Helm-Chart, Werten dafür und Hooks nennen wir Modul (siehe unten für Details).
- Staging. Es gibt keine magischen Release-Skripte. Der Update-Mechanismus ist ähnlich wie bei einer normalen Anwendung — die Addons und der Addon-Operator werden in ein Image zusammengebaut, getaggt und veröffentlicht.
- Ergebniskontrolle. Der Addon-Operator kann Metriken für Prometheus bereitstellen.
Was ist ein Addon im Addon-Operator?
Ein Addon kann alles sein, was dem Cluster neue Funktionen hinzufügt. Ein Beispiel für ein Addon ist die Installation von Ingress. Es kann jeder Operator oder Controller mit seiner eigenen CRD sein: prometheus-operator, cert-manager, kube-controller-manager usw. Oder etwas Kleines, das den Betrieb vereinfacht — zum Beispiel ein Secret Copier, der Registry-Geheimnisse in neue Namensräume kopiert, oder ein Sysctl Tuner, der Sysctl-Parameter auf neuen Knoten einstellt.
Zur Implementierung von Addons stellt der Addon-Operator mehrere Konzepte bereit:
- Helm-Chart wird verwendet, um verschiedene Software im Cluster zu installieren — zum Beispiel Prometheus, Grafana, nginx-ingress. Wenn das benötigte Element ein Helm-Chart hat, ist die Installation mit dem Addon-Operator sehr einfach.
- Wertestorage. Helm-Charts haben in der Regel viele verschiedene Einstellungen, die sich im Laufe der Zeit ändern können. Der Addon-Operator unterstützt die Speicherung dieser Einstellungen und kann ihre Änderungen überwachen, um das Helm-Chart mit neuen Werten neu zu installieren.
- Hooks — dies sind ausführbare Dateien, die vom Addon-Operator bei Ereignissen gestartet werden und die auf den Werte-Speicher zugreifen. Ein Hook kann Änderungen im Cluster überwachen und die Werte im Werte-Speicher aktualisieren. Das bedeutet, dass man mit Hooks eine Entdeckung durchführen kann, um beim Start oder nach einem Zeitplan Werte aus dem Cluster zu sammeln, oder man kann eine kontinuierliche Entdeckung durchführen, indem man Werte aus dem Cluster bei Änderungen im Cluster sammelt.
- Modul — ist eine Kombination aus Helm-Chart, Werte-Speicher und Hooks. Module können aktiviert und deaktiviert werden. Das Deaktivieren eines Moduls bedeutet das Löschen aller Releases des Helm-Charts. Module können sich dynamisch selbst aktivieren, zum Beispiel, wenn alle benötigten Module aktiviert sind oder wenn die Entdeckung in den Hooks die erforderlichen Parameter gefunden hat — dies geschieht mit einem unterstützenden enabled-Skript.
- Globale Hooks. Dies sind Hooks, die "für sich selbst" stehen, sie sind nicht in Module integriert und haben Zugriff auf den globalen Werte-Speicher, dessen Werte allen Hooks in den Modulen zur Verfügung stehen.
Wie arbeiten diese Teile zusammen? Betrachten wir das Bild aus der Dokumentation:

Es gibt zwei Arbeits-Szenarien:
- Der globale Hook wird bei einem Ereignis ausgelöst — zum Beispiel bei einer Änderung der Ressource im Cluster. Dieser Hook verarbeitet die Änderungen und schreibt neue Werte in den globalen Werte-Speicher. Der Addon-Operator bemerkt, dass der globale Speicher sich geändert hat und startet alle Module. Jedes Modul entscheidet mithilfe seiner Hooks, ob es aktiviert werden soll, und aktualisiert seinen Werte-Speicher. Wenn das Modul aktiviert ist, beginnt der Addon-Operator mit der Installation des Helm-Charts. Dem Helm-Chart stehen dabei die Werte aus dem Speicher des Moduls sowie aus dem globalen Speicher zur Verfügung.
- Das zweite Szenario ist einfacher: Der Modul-Hook wird bei einem Ereignis ausgelöst und ändert die Werte im Werte-Speicher des Moduls. Der Addon-Operator bemerkt dies und startet das Helm-Chart mit den aktualisierten Werten.
Ein Addon kann als einzelner Hook oder als ein Helm-Chart realisiert werden, oder sogar als mehrere abhängige Module — das hängt von der Komplexität des im Cluster installierten Components und vom erforderlichen Flexibilitätsgrad der Einstellungen ab. Zum Beispiel gibt es im Repository () das sysctl-tuner-Addon, das sowohl als einfaches Modul mit Hook und Helm-Chart als auch unter Verwendung eines Werte-Speichers implementiert ist, was die Möglichkeit bietet, Einstellungen durch Bearbeitung von ConfigMap hinzuzufügen.
Lieferung von Updates
Einige Worte zur Organisation von Komponentenuppdates, die vom Addon-Operator installiert werden.
Um den Addon-Operator im Cluster zu starten, muss man ein Image mit Erweiterungen in Form von Hook-Dateien und Helm-Charts zusammenstellen, die Binärdatei hinzufügen Addon-Operator und alles, was für die Hooks benötigt wird: bash, kubectl, jq, python usw. Weiterhin kann dieses Image wie eine gewöhnliche Anwendung im Cluster ausgerollt werden, und wahrscheinlich möchten Sie eine Art von Tagging-Schema organisieren. Wenn es nur wenige Cluster gibt, kann derselbe Ansatz wie bei Anwendungen ausreichen: neue Version, neue Version, alle Cluster durchgehen und das Image bei den Pods anpassen. Wenn es sich jedoch um eine bedeutende Anzahl von Clustern handelt, scheint uns das Konzept der Selbstaktualisierung aus dem Kanal besser geeignet.
So sieht es bei uns aus:
- Ein Kanal ist im Grunde ein Identifikator, der beliebig festgelegt werden kann (z.B. dev/stage/ea/stable).
- Der Name des Kanals ist das Tag des Images. Wenn Updates in den Kanal ausgerollt werden müssen, wird ein neues Image erstellt und mit dem Namen des Kanals getaggt.
- Wenn ein neues Image im Registry erscheint, wird der Addon-Operator neu gestartet und mit dem neuen Image gestartet.
Das ist nicht die beste Praxis, wie in der geschrieben steht. So sollte man es nicht machen, aber es geht um eine gewöhnliche Anwendung, die in einem Cluster lebt.Im Falle des Addon-Operators ist die Anwendung eine Vielzahl von Deployments, die über die Cluster verteilt sind, und die Selbstaktualisierung hilft enorm und erleichtert das Leben.
Kanäle helfen auch bei Tests:Wenn es einen unterstützenden Cluster gibt, kann dieser auf einen Kanal stage eingestellt werden, um Updates daran zu testen, bevor sie in die Kanäle ea und stableausgerollt werden. Wenn im Cluster mit dem Kanal ea ein Fehler aufgetreten ist, kann er auf stableumgeschaltet werden, während die Problematik mit diesem Cluster untersucht wird. Wenn der Cluster aus der aktiven Unterstützung genommen wird, wird er auf seinen "eingefrorenen" Kanal umgeschaltet — zum Beispiel, freeze-2019-03-20..
Neben den Updates von Hooks und Helm-Charts könnte es notwendig sein, auch eine externe Komponente zu aktualisieren.Wenn Sie einen Fehler im hypothetischen Node-Exporter bemerkt haben und sogar wissen, wie man ihn patcht. Danach haben Sie einen PR eröffnet und warten auf die neue Version, um alle Cluster durchzugehen und die Version des Images zu erhöhen. Um nicht unbestimmte Zeit zu warten, kann man seinen eigenen Node-Exporter erstellen und bis zur Annahme des PR auf ihn umschalten.
Im Grunde kann man das auch ohne Addon-Operator machen, aber mit dem Addon-Operator wird das Modul zur Installation des Node-Exporters in einem Repository sichtbar, das Dockerfile für den Bau seines eigenen Bildes kann hier ebenfalls aufbewahrt werden, und es wird für alle Beteiligten einfacher zu verstehen, was passiert... Und wenn es mehrere Cluster gibt, wird es einfacher, sowohl seinen PR zu testen als auch eine neue Version aufzuspielen!
Diese Organisation zur Aktualisierung von Komponenten funktioniert bei uns erfolgreich, aber man kann auch ein anderes passendes Schema umsetzen — denn in diesem Fall ist der Addon-Operator eine einfache Binärdatei..
Fazit
Die Prinzipien, die im Addon-Operator umgesetzt sind, ermöglichen es, einen transparenten Prozess zur Erstellung, Testung, Installation und Aktualisierung von Erweiterungen im Cluster zu etablieren, der mit den Prozessen der normalen Anwendungsentwicklung vergleichbar ist.
Die Erweiterungen für den Addon-Operator im Modulformat (Helm-Chart + Hooks) können der breiten Öffentlichkeit zur Verfügung gestellt werden. Wir, die Firma Flant, planen, im Laufe des Sommers unsere Entwicklungen in Form solcher Erweiterungen zu veröffentlichen. Machen Sie mit der Entwicklung auf GitHub mit (, ), probieren Sie aus, Ihre eigene Erweiterung basierend auf und , warten Sie auf Neuigkeiten auf Habré und auf unserem !
P.S.
Lesen Sie auch in unserem Blog:
- «»;
- «».
Quelle: habr.com
