Hinweis perev. : Mit diesem Artikel eröffnen wir eine Reihe von Veröffentlichungen über den Paketmanager für Kubernetes, die wir aktiv in der täglichen Arbeit verwenden, - Helm. Der ursprüngliche Autor des Materials ist Matt Butcher, einer der Gründer des Helm-Projekts, der an Open Source-Projekten bei Microsoft arbeitet und 8 technische Bücher schreibt (insbesondere „Go in Practice“). Der Artikel wird jedoch durch unsere (manchmal umfangreichen) Kommentare ergänzt und in Kürze um neue Anmerkungen zu Helm mit einem praktischeren Schwerpunkt erweitert. UPDATE (09/03/2018): Die Fortsetzung erschien - " Praktische Bekanntschaft mit dem Paketmanager für Kubernetes - Helm ".
Im Juni wechselte Helm vom Status des leitenden Projekts von Kubernetes zur Cloud Native Computing Foundation (CNCF). CNCF wird zur Mutterorganisation für die besten Open-Source-Cloud-Native-Tools ihrer Art. Daher ist es für Helm eine große Ehre, Teil einer solchen Stiftung zu werden. Und unser erstes bedeutendes Projekt unter der Schirmherrschaft von CNCF ist wirklich groß angelegt: Wir erstellen Helm 3.
Eine kurze Geschichte von Helm
Helm erschien ursprünglich als Deis Open Source-Projekt. Es wurde nach dem Vorbild von
Homebrew (dem Paketmanager für macOS - ca. Übersetzung ) erstellt . Die Aufgabe, die Helm 1 hatte, bot Benutzern die Möglichkeit, ihre ersten Workloads schnell auf Kubernetes zu installieren. Die offizielle Ankündigung von Helm erfolgte auf der ersten KubeCon San Francisco Konferenz im Jahr 2015.
Hinweis trans .: Ab der ersten Version, die als dm (Deployment Manager) bezeichnet wurde, wurde die YAML-Syntax ausgewählt, um Kubernetes-Ressourcen zu beschreiben, und Jinja-Vorlagen und Python-Skripte wurden beim Schreiben von Konfigurationen unterstützt.Eine einfache Webanwendungsvorlage könnte folgendermaßen aussehen:Yamlresources: - name: frontend type: github.com/kubernetes/application-dm-templates/common/replicatedservice:v1 properties: service_port: 80 container_port: 80 external_service: true replicas: 3 image: gcr.io/google_containers/example-guestbook-php-redis:v3 - name: redis type: github.com/kubernetes/application-dm-templates/storage/redis:v1 properties: null
Bei der Beschreibung der Komponenten der ausgerollten Anwendung werden der Name, die verwendete Vorlage sowie die erforderlichen Parameter dieser Vorlage angegeben. Im obigen Beispiel verwenden die frontend
und redis
Vorlagen aus dem offiziellen Repository.Bereits in dieser Version können Sie Ressourcen aus einer gemeinsamen Wissensdatenbank verwenden, eigene Vorlagen-Repositorys erstellen und aufgrund der Parameter und der Verschachtelung von Vorlagen komplexe Anwendungen erstellen.Die Helm 1-Architektur besteht aus drei Komponenten. Das folgende Diagramm zeigt die Beziehung zwischen ihnen:
Manager
führt die Funktion eines Webservers aus (die Kommunikation mit Clients erfolgt über die REST-API), verwaltet die Bereitstellungen im Kubernetes-Cluster und wird als Data Warehouse verwendet.- Die
expandybird
Komponente bringt Benutzerkonfigurationen in eine flache Form, d.h. wendet Jinja-Vorlagen an und führt Python-Skripte aus. - Nach Erhalt einer flachen Konfiguration führt
resourcifier
die erforderlichen Aufrufe an kubectl durch und gibt gegebenenfalls Status- und Fehlermeldungen an den manager
.
Um die Funktionen der ersten Version von Helm zu verstehen, werde ich beim Befehl dm
helfen :
Hilfeausgabe von dm Usage: ./dm [<flags>] <command> [(<template-name> | <deployment-name> | (<configuration> [<import1>...<importN>]))] Commands: expand Expands the supplied configuration(s) deploy Deploys the named template or the supplied configuration(s) list Lists the deployments in the cluster get Retrieves the supplied deployment manifest Lists manifests for deployment or retrieves the supplied manifest in the form (deployment[/manifest]) delete Deletes the supplied deployment update Updates a deployment using the supplied configuration(s) deployed-types Lists the types deployed in the cluster deployed-instances Lists the instances of the named type deployed in the cluster templates Lists the templates in a given template registry (specified with --registry) registries Lists the registries available describe Describes the named template in a given template registry getcredential Gets the named credential used by a registry setcredential Sets a credential used by a registry createregistry Creates a registry that holds charts Flags: -apitoken string Github api token that overrides GITHUB_API_TOKEN environment variable -binary string Path to template expansion binary (default "../expandybird/expansion/expansion.py") -httptest.serve string if non-empty, httptest.NewServer serves on this address and blocks -name string Name of deployment, used for deploy and update commands (defaults to template name) -password string Github password that overrides GITHUB_PASSWORD environment variable -properties string Properties to use when deploying a template (eg, --properties k1=v1,k2=v2) -regex string Regular expression to filter the templates listed in a template registry -registry string Registry name (default "application-dm-templates") -registryfile string File containing registry specification -service string URL for deployment manager (default "http://localhost:8001/api/v1/proxy/namespaces/dm/services/manager-service:manager") -serviceaccount string Service account file containing JWT token -stdin Reads a configuration from the standard input -timeout int Time in seconds to wait for response (default 20) -username string Github user name that overrides GITHUB_USERNAME environment variable --stdin requires a file name and either the file contents or a tar archive containing the named file. a tar archive may include any additional files referenced directly or indirectly by the named file.
Und jetzt zurück zum Originaltext über die Geschichte von Helm ...Einige Monate später haben wir uns mit dem Kubernetes Deployment Manager-Team von Google zusammengetan und mit der Arbeit an Helm 2 begonnen. Ziel war es, die Verwendung von Helm durch Hinzufügen der folgenden Elemente zu vereinfachen:
- Diagrammvorlagen („Diagramm“ - ein Analogon eines Pakets im Helm-Ökosystem - ca. übersetzt ) zur Anpassung;
- Cluster-Management für Teams;
- vollständiges Diagramm-Repository;
- stabiles und signiertes Paketformat;
- starkes Engagement für die semantische Versionierung und die Aufrechterhaltung der Abwärtskompatibilität von Version zu Version.
Um diese Ziele zu erreichen, wurde dem Helm-Ökosystem eine zweite Komponente hinzugefügt. Es wurde zum internen Tiller-Cluster, der die Installation von Helm-Diagrammen und deren Verwaltung ermöglichte.
Hinweis perev .: In der zweiten Version von Helm ist die einzige im Cluster verbleibende Komponente für den Installationslebenszyklus ( Release ) verantwortlich, und die Konfigurationsvorbereitung wird an den Helm-Client gesendet.Wenn ein Neustart des Clusters bei Verwendung der ersten Version von Helm zu einem vollständigen Verlust der Servicedaten führte (da diese im RAM gespeichert waren), werden in Helm 2 alle Daten in ConfigMaps
gespeichert, d. H. Ressourcen in Kubernetes. Ein weiterer wichtiger Schritt war der Übergang von einer synchronen API (bei der jede Anforderung blockiert wurde) zur Verwendung von asynchronem gRPC.Seit dem Start von Helm 2 im Jahr 2016 hat das Kubernetes-Projekt ein explosives Wachstum und bedeutende neue Möglichkeiten erfahren. Die rollenbasierte Zugriffskontrolle (RBAC) wurde hinzugefügt. Viele neue Ressourcentypen werden eingeführt. Erfundene Ressourcen von Drittanbietern (Custom Resource Definitions, CRD). Und vor allem gibt es Best Practices. Helm ging all diese Änderungen durch und diente weiterhin den Bedürfnissen der Kubernetes-Benutzer. Uns wurde jedoch klar, dass es an der Zeit war, wesentliche Änderungen daran vorzunehmen, damit die Bedürfnisse dieses sich entwickelnden Ökosystems weiterhin erfüllt werden.
Also kamen wir zu Helm 3. Als nächstes werde ich über einige der Innovationen sprechen, die in der Projekt-Roadmap vorgestellt werden.
Grüße Lua
In Helm 2 haben wir Vorlagen eingeführt. In der frühen Phase der Helm 2-Entwicklung unterstützten wir Go, Jinja-Vorlagen, sauberen Python-Code und hatten sogar einen Prototyp der Ksonnet-Unterstützung. Das Vorhandensein vieler Engines für Vorlagen führte jedoch zu mehr Problemen als es löste. Daher sind wir an dem Punkt angelangt, einen zu wählen.
Go-Vorlagen hatten vier Vorteile:
- Die Bibliothek ist in Go integriert .
- Vorlagen werden in einer streng eingeschränkten Sandbox-Umgebung ausgeführt.
- wir könnten beliebige Funktionen und Objekte in die Engine einfügen;
- Sie haben gut mit YAML zusammengearbeitet.
Obwohl wir die Benutzeroberfläche in Helm beibehalten haben, um andere Template-Engines zu unterstützen, sind Go-Templates zu unserem Standardstandard geworden. Die Erfahrung der nächsten Jahre hat gezeigt, wie Ingenieure vieler Unternehmen mithilfe von Go-Vorlagen Tausende von Diagrammen erstellt haben.
Und wir haben von ihren Enttäuschungen erfahren:
- Die Syntax ist schwer zu lesen und schlecht dokumentiert.
- Sprachprobleme wie unveränderliche Variablen, komplizierte Datentypen und restriktive Sichtbarkeitsregeln haben aus einfachen Dingen komplexe gemacht.
- Die Unfähigkeit, Funktionen in Vorlagen zu definieren, machte die Erstellung wiederverwendbarer Bibliotheken noch schwieriger.
Am wichtigsten ist, dass wir mithilfe der Vorlagensprache Kubernetes-Objekte auf ihre Liniendarstellung „abgeschnitten“ haben. (Mit anderen Worten, Vorlagenentwickler mussten Kubernetes-Ressourcen als Textdokumente im YAML-Format verwalten.)
Arbeiten Sie an Objekten, nicht an YAML-Stücken
Immer wieder hörten wir von Benutzern eine Anfrage nach der Möglichkeit, Kubernetes-Ressourcen als Objekte und nicht als Zeichenfolgen zu überprüfen und zu ändern. Gleichzeitig waren sie fest davon überzeugt, dass es unabhängig von der Art der Implementierung, die wir dafür gewählt haben, leicht zu erlernen und im Ökosystem gut gepflegt sein sollte.
Nach monatelanger Recherche haben wir uns entschlossen, eine integrierte Skriptsprache bereitzustellen, die in einer Sandbox verpackt und angepasst werden kann. Unter den Top 20 Sprachen gab es nur einen Kandidaten, der die Anforderungen erfüllte:
Lua .
1993 erstellte eine Gruppe brasilianischer IT-Ingenieure eine einfache Skriptsprache zum Einbetten in ihre Tools. Lua hat eine einfache Syntax, wird weitgehend unterstützt und ist seit langem in der Liste der
Top-20-Sprachen enthalten . Es wird von IDE- und Texteditoren unterstützt, es gibt viele Handbücher und Tutorials. In einem solchen bestehenden Ökosystem möchten wir unsere Lösung entwickeln.
Unsere Arbeit an Helm Lua befindet sich noch im konzeptionellen Beweisstadium und wir erwarten eine Syntax, die sowohl vertraut als auch flexibel ist. Wenn Sie die alten und die neuen Ansätze vergleichen, können Sie sehen, wohin wir uns bewegen.
Hier ist
ein Beispiel für eine Herdvorlage mit Alpine in Helm 2:
apiVersion: v1 kind: Pod metadata: name: {{ template "alpine.fullname" . }} labels: heritage: {{ .Release.Service }} release: {{ .Release.Name }} chart: {{ .Chart.Name }}-{{ .Chart.Version }} app: {{ template "alpine.name" . }} spec: restartPolicy: {{ .Values.restartPolicy }} containers: - name: waiter image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} command: ["/bin/sleep", "9000"]
In dieser einfachen Vorlage sehen Sie sofort alle integrierten Vorlagenanweisungen, z. B.
{{ .Chart.Name }}
.
Und hier ist die Definition desselben Herdes in der vorläufigen Version des Lua-Codes:
unction create_alpine_pod(_) local pod = { apiVersion = "v1", kind = "Pod", metadata = { name = alpine_fullname(_), labels = { heritage = _.Release.Service or "helm", release = _.Release.Name, chart = _.Chart.Name .. "-" .. _.Chart.Version, app = alpine_name(_) } }, spec = { restartPolicy = _.Values.restartPolicy, containers = { { name = waiter, image = _.Values.image.repository .. ":" .. _.Values.image.tag, imagePullPolicy = _.Values.image.pullPolicy, command = { "/bin/sleep", "9000" } } } } } _.resources.add(pod) end
Es ist nicht erforderlich, jede Zeile dieses Beispiels zu betrachten, um zu verstehen, was passiert. Es ist sofort ersichtlich, dass der Code unter definiert ist. Anstatt YAML-Zeichenfolgen mit integrierten Vorlagenanweisungen zu verwenden, definieren wir sie in Lua als Objekt.
Kürzen wir diesen Code
Da wir direkt mit Objekten arbeiten (anstatt einen großen Textball zu bearbeiten), können wir die Skripterstellung voll ausnutzen. Die Möglichkeiten, gemeinsam genutzte Bibliotheken zu erstellen, die hier angezeigt werden, sind sehr attraktiv. Und wir hoffen, dass wir durch die Einführung spezialisierter Bibliotheken (oder die Erlaubnis der Community, diese zu erstellen) den obigen Code auf etwa Folgendes reduzieren können:
local pods = require("mylib.pods"); function create_alpine_pod(_) myPod = pods.new("alpine:3.7", _) myPod.spec.restartPolicy = "Always"
In diesem Beispiel verwenden wir die Möglichkeit, mit der Definition einer Ressource als Objekt zu arbeiten, wodurch Eigenschaften einfach festgelegt werden können, während die Prägnanz und Lesbarkeit des Codes erhalten bleibt.
Vorlagen ... Lua ... Warum nicht alle zusammen?
Obwohl die Vorlagen nicht für alle Aufgaben so wunderbar sind, haben sie dennoch gewisse Vorteile. Templates in Go ist eine stabile Technologie mit einer etablierten Benutzerbasis und vielen vorhandenen Diagrammen. Viele Diagrammentwickler behaupten, dass sie gerne Vorlagen schreiben. Daher werden wir die Vorlagenunterstützung nicht entfernen.
Stattdessen möchten wir, dass sowohl Vorlagen als auch Lua gleichzeitig verwendet werden. Lua-Skripte haben vor und nach dem Rendern Zugriff auf Helm-Vorlagen, sodass fortgeschrittene Diagrammentwickler komplexe Transformationen an vorhandenen Diagrammen durchführen können, während die einfache Möglichkeit erhalten bleibt, Helm-Diagramme mit Vorlagen zu erstellen.
Wir sind sehr ermutigt von der Unterstützung von Skripten auf Lua, aber gleichzeitig werden wir einen bedeutenden Teil der Helm-Architektur los ...
Abschied von Tiller
Während der Entwicklung von Helm 2 haben wir Tiller als Integrationskomponente mit Deployment Manager eingeführt. Tiller spielte eine wichtige Rolle für Teams, die an demselben Cluster arbeiten: Es ermöglichte die Interaktion mit denselben Releases für viele verschiedene Administratoren.
Tiller fungierte jedoch als riesiger Sudo-Server und gewährte jedem, der Zugriff auf Tiller hat, eine breite Palette von Rechten. Und unser Standardinstallationsschema war eine zulässige Konfiguration. Daher mussten die Ingenieure von DevOps und SRE die zusätzlichen Schritte zur Installation von Tiller in mandantenfähigen Clustern lernen.
Darüber hinaus konnten wir uns mit dem Aufkommen von CRD nicht mehr zuverlässig auf Tiller verlassen, um den Status aufrechtzuerhalten oder als zentrale Drehscheibe für Helm-Release-Informationen zu fungieren. Wir konnten diese Informationen nur als separate Einträge in Kubernetes speichern.
Das Hauptziel von Tiller kann ohne Tiller selbst erreicht werden. Daher war eine der ersten Entscheidungen, die während der Planungsphase von Helm 3 getroffen wurden, die vollständige Aufgabe von Tiller.
Sicherheitsverbesserung
Ohne Pinne wird das Helm-Sicherheitsmodell radikal vereinfacht. Die Benutzerauthentifizierung wird von Kubernetes delegiert. Und Autorisierung auch. Helmrechte werden als Kubernetes-Rechte (über RBAC) definiert, und Cluster-Administratoren können Helmrechte auf jeder erforderlichen Detailebene einschränken.
Releases, ReleaseVersions und State Storage
In Abwesenheit von Tiller benötigen wir eine neue Art der Interaktion aller Clients (zum Release-Management), um den Status verschiedener Releases innerhalb des Clusters aufrechtzuerhalten.
Zu diesem Zweck haben wir zwei neue Einträge eingeführt:
Release
- für eine bestimmte Installation eines bestimmten Diagramms. Wenn wir helm install my-wordpress stable/wordpress
ausführen, wird eine Version namens my-wordpress
erstellt und während der gesamten Lebensdauer dieser WordPress-Installation gepflegt.ReleaseVersion
- Jedes Mal, wenn Sie das Helm-Diagramm aktualisieren, müssen Sie berücksichtigen, was sich geändert hat und ob die Änderung erfolgreich war. ReleaseVersion
an ein Release gebunden und speichert nur Datensätze mit Informationen zum Aktualisieren, ReleaseVersion
und Löschen. Wenn wir das helm upgrade my-wordpress stable/wordpress
ReleaseVersion
bleibt das ursprüngliche Release
Objekt gleich, es wird jedoch ein ReleaseVersion
Objekt mit Informationen zum Aktualisierungsvorgang ReleaseVersion
.
Releases
und
ReleaseVersions
werden in denselben Namespaces wie die Diagrammobjekte gespeichert.
Mit diesen Funktionen können Helm-Benutzerteams die Aufzeichnungen der Helm-Installationen im Cluster verfolgen, ohne dass Tiller erforderlich ist.
Aber warte, das ist noch nicht alles!
In diesem Artikel habe ich versucht, über einige der wichtigsten Änderungen in Helm 3 zu sprechen. Diese Liste ist jedoch überhaupt nicht vollständig.
Der Helm 3-Plan enthält auch andere Änderungen, z. B. Verbesserungen im Diagrammformat, Leistungsverbesserungen für Diagrammrepositorys und ein neues Ereignissystem, das Diagrammentwickler verwenden können. Wir machen Eric Raymond auch zur
Code-Archäologie, indem wir die Codebasis bereinigen und Komponenten aktualisieren, die in den letzten drei Jahren an Relevanz verloren haben.
Hinweis perev. : Es ist ein Paradoxon, aber der Helm 2-Paketmanager, wenn die install
oder das upgrade
erfolgreich ist, d. H. Eine Freigabe im success
garantiert nicht, dass die Anwendungsressourcen erfolgreich eingeführt wurden (z. B. gibt es keine Fehler wie ImagePullError
). Vielleicht können Sie mit dem neuen Ereignismodell zusätzliche Hooks für Ressourcen hinzufügen und den Rollout-Prozess besser steuern - wir werden es bald herausfinden.Mit dem Beitritt von Helm zur CNCF lassen wir uns nicht nur von Helm 3 inspirieren, sondern auch vom
Chart Museum , dem wunderbaren Dienstprogramm zum
Testen von Charts , dem
offiziellen Chart-Repository und anderen Projekten unter der Schirmherrschaft von Helm in CNCF. Wir sind zuversichtlich, dass ein gutes Paketmanagement für Kubernetes für das Cloud-native Ökosystem genauso wichtig ist wie ein gutes Paketmanagement für Linux.
PS vom Übersetzer
Lesen Sie auch in unserem Blog: