Heim >Backend-Entwicklung >Golang >Der Kubernetes Cloud Controller Manager

Der Kubernetes Cloud Controller Manager

Patricia Arquette
Patricia ArquetteOriginal
2024-12-24 09:25:21697Durchsuche

Bitte beachten Sie, dass dieser Beitrag ursprünglich von mir auf medium.com gepostet wurde. Seitdem habe ich beschlossen, stattdessen zu dev.to zu wechseln!

The Kubernetes Cloud Controller Manager

In diesem Beitrag wird davon ausgegangen, dass Sie über Erfahrung mit der Bedienung/Ausführung von Kubernetes und einigen Go-Programmiersprachenkonzepten verfügen.

In den letzten anderthalb Jahren haben wir viel mit OpenStack und Kubernetes bei der Etraveli Group gearbeitet. Wir sind unser eigener Cloud-Anbieter und die Endbenutzer sind die Entwickler und die umliegenden Teams in der Entwicklungsorganisation.

Eine der Schlüsselkomponenten für die Ausführung von Kubernetes auf OpenStack ist der Cloud Controller Manager. Es ist eines der Teile, die die beiden Plattformen zusammenkleben. Für diejenigen unter Ihnen, die mit verwalteten Kubernetes-Diensten arbeiten, irgendwo in öffentlichen (oder privaten) Clouds, ist dies bereits erledigt. Die Kubernetes-Kontrollebene wird für Sie mehr oder weniger unerreichbar sein.

Warum also etwas über den Cloud Controller Manager schreiben? Der Hauptgrund waren die einfachsten Fragen eines meiner Kollegen:

„Was macht der (OpenStack) Cloud Controller Manager überhaupt?“

Ich habe versucht, die Frage zu beantworten, hatte aber im Grunde keine Ahnung, wovon ich rede. Ich wusste, dass es für die Erstellung eines Lastenausgleichs in der zugrunde liegenden Cloud verantwortlich ist, wenn ein Serviceobjekt vom Typ LoadBalancer erstellt wird.

Ich habe mich sofort dazu entschlossen, mich ein wenig damit zu befassen, und am Ende habe ich ziemlich tief gegraben und versucht, jeden Teil des Rätsels zu verstehen. In diesem Beitrag werde ich meine Erkenntnisse zusammenfassen.

In diesem Beitrag werde ich auf Folgendes verweisen:

  • Cloud Controller Manager als „CCM

  • Das Kubernetes-Hauptquellcode-Repository als „k/k

  • Kubernetes als „k8s

Als ich anfing, diesen Beitrag zu schreiben, habe ich ein kleines Projekt und Repository erstellt, in dem ich nach Vorschrift meinen eigenen Cloud Controller Manager erstellt habe und zwei winzige Kubernetes-Cluster (v1.18.2) miteinander vergleiche, von denen einer das ausführt CCM und eines, das das nicht tut. Es handelt sich um einen Proof-of-Concept und soll Ihnen zeigen, was genau Sie für den Betrieb Ihres eigenen CCM benötigen. Alles, vom Code, aus dem das CCM besteht, bis zu den k8s-Manifesten, die Sie benötigen, um es bereitzustellen.

Bevor wir beginnen, ist es gut zu wissen, dass dieser Beitrag auf verschiedene Teile der k8s-Quellcode-Repositories verweist. Ich habe das Tag v1.18.0 verwendet.

Alle Illustrationen sind meine eigenen.

Viel Spaß!

Bitte hinterlassen Sie ein oder zwei Kommentare (!), wir freuen uns über jedes Feedback!

Der Cloud Controller Manager

Der Cloud Controller Manager kann aus allgemeiner Sicht als drei verschiedene Dinge beschrieben werden:

  • Eine Binärdatei

  • Eine Reihe von Regelkreisen

  • Teil des Klebers zwischen k8s und Ihrer Cloud

Codetechnisch ist das CCM Teil des k/k-Repos, schauen Sie hier. Wie in der offiziellen k8s-Dokumentation erwähnt, kann der Code für das CCM in k/k als Grundgerüst für Ihre eigene Implementierung verwendet werden. Der Unterschied besteht im Code (Paketen), den Sie für die Interaktion mit Ihrer Cloud bereitstellen und importieren.

Der CCM wird am häufigsten über ein k8s-Manifest bereitgestellt und die Binärdatei in einen (Docker-)Container integriert, der aus einer bekannten Container-Registrierung gezogen wird.

Bemerkenswert ist, dass dem CCM Port 10258 zugewiesen wird und Sie ihn bei Bedarf freigeben müssen. Standardmäßig stellt der CCM einen /healthz-Endpunkt bereit, um den Zustand des Dienstes zu überprüfen.

Wenn Sie sich die k8s-Organisation in GitHub ansehen, werden Sie eine Reihe verschiedener CCM-Implementierungen finden. Sie werden auch externe CCMs genannt, da sie außerhalb des k/k-Repositorys leben und aus einer Reihe gut gestalteter Golang-Schnittstellen bestehen sowie das Nötigste, damit jeder sein eigenes CCM erstellen kann.

Wir werden uns das alles später im Detail ansehen.

Der Kern des CCM besteht aus vier (Cloud-)Controllern, die Regelkreise ausführen. Optional können Sie Ihre eigenen Controller neben den anderen betreiben.

The Kubernetes Cloud Controller Manager

In den nächsten Abschnitten werden wir uns die einzelnen Cloud-Controller, die im CCM ausgeführt werden, genauer ansehen.

Der Node-Controller

Der Node-Controller stellt sicher, dass Ihre Cloud-Knoten (z. B. VMs) mit anderen relevanten Informationen Ihres Cloud-Anbieters gekennzeichnet, markiert und aktualisiert werden. Der Controller führt in einer ungeordneten Liste regelmäßig Folgendes aus:

The Kubernetes Cloud Controller Manager

  • Neue Knoten, die dem Cloud-Anbieter hinzugefügt wurden, werden mit dem folgenden Taint initialisiert: node.cloudprovider.kubernetes.io/uninitialized auf „true“ und Taint-Effekt auf „NoSchedule“ gesetzt. Wenn der Knoten durch den Knotencontroller initialisiert wird, wird dieser Fehler entfernt, sodass Arbeitslasten auf dem Knoten geplant werden können. Pods, die z. B. kritisch sind Das Ausführen des Clusters verfügt natürlich über die erforderliche Toleranz, um auf bereits beschädigten Knoten geplant zu werden.

  • Aktualisieren Sie die IP-Adresse des Knotens, indem Sie die IP-Adresse im Cloud-Anbieter mit der im Node-Objekt in der k8s-API gespeicherten IP-Adresse vergleichen.

  • Fügen Sie Knotenbezeichnungen hinzu oder aktualisieren Sie sie mit Informationen aus der Cloud. Dazu gehören: Instanztyp, Zonenfehlerdomäne und Zonenregion. Zonenspezifische Informationen sind nicht obligatorisch, wie wir später sehen werden.

In Bezug auf Knotenbezeichnungen und wie die oben erwähnten Informationen zu Instanzen abgerufen und den Knotenobjekten hinzugefügt werden. Um Ihnen ein Beispiel zu geben: Der externe OpenStack-CCM führt dies durch, indem er entweder die Metadaten von der Festplatte (Konfigurationsfestplatte) liest oder den in jedem Knoten erreichbaren Metadatendienst-Endpunkt verwendet.

Service-Controller

Der Service-Controller kümmert sich um alles, was mit dem Lebenszyklus des in Ihrer Cloud erstellten Serviceobjekt-basierten Load Balancers zusammenhängt. Ein Dienst bietet eine Möglichkeit, Ihre Anwendung intern und/oder extern aus der Perspektive des k8s-Clusters verfügbar zu machen.

Dieser bestimmte Controller verarbeitet nur die Serviceobjekte vom Typ LoadBalancer. Aus Sicht des Cloud-Anbieters bedeutet dies, dass sichergestellt wird, dass eine Art Load Balancer in Ihrer Cloud erstellt, gelöscht und aktualisiert wird.

The Kubernetes Cloud Controller Manager

Je nachdem, wie Ihr CCM die Service-Controller-Logik implementiert hat, können Sie einen Cloud-Load-Balancer erstellen, der nur den Netzwerkverkehr intern in der Cloud ausgleicht. Dies geschieht normalerweise durch die Definition einer Reihe von Anmerkungen im Metadatenabschnitt des Serviceobjekts.

Bitte beachten Sie, dass das Standardverhalten, wie ich es z. B. festgestellt habe: OpenStack bedeutet, dass die folgenden Objekte erstellt werden, wenn ein einfaches Serviceobjekt-Manifest (vom Typ LoadBalancer) angewendet wird:

  • Ein Cloud-Load-Balancer mit einer ausgefüllten Liste von Knoten, auf die der Datenverkehr lastverteilt werden soll. Der Load Balancer zeigt auf jeden Knoten, indem er den generierten zufälligen NodePort

  • verwendet
  • Ein Serviceobjekt vom Typ NodePort

Wie oben gesehen, gibt es tatsächlich eine Reihe von Dingen, die das Service-Objekt sowohl in k8s als auch beim Cloud-Anbieter ausmachen. Für die Benutzer bedeutet dies, dass die Spalte EXTERNAL-IP mit einer Cloud-Provider-IP des Cloud Load Balancers gefüllt wird. Wird beim Auflisten der Serviceobjekte mit kubectl angezeigt:

$> kubectl get service my-app-svc
NAME       TYPE         CLUSTER-IP    EXTERNAL-IP     PORT(S)
my-app-svc LoadBalancer 172.20.10.100 123.123.123.123 80:31147/TCP

Routencontroller

Von den vier Controllern gibt es einen, der etwas Besonderes ist, und das ist der (Cloud) Route Controller. Er wird nicht gestartet, es sei denn, Sie geben die Flags --allocate-node-cidrs oder --configure-cloud-routes an das CCM. Auch wenn Sie keine Routenverarbeitungslogik implementiert haben, startet dieser Controller nicht, mehr dazu später.

The Kubernetes Cloud Controller Manager

Dieser Controller versucht regelmäßig Folgendes zu tun:

  • Listen Sie alle mit einem k8s-Cluster verknüpften Routen auf. Dies erfolgt durch Abfragen der Cloud-Anbieter-API(s).

  • Listen Sie alle Knoten auf, indem Sie die k8s-API abfragen.

  • Durchlaufen Sie jeden Knoten und das podCIDRs-Feld der Knotenspezifikation. Der Pod-CIDR und der Knotenname werden zum Erstellen von Routen über die API(s) des Cloud-Anbieters verwendet.

Außerdem löscht der Controller während des Regelkreises ungenutzte Routen. Wenn alle Routen erstellt wurden, gilt der Knoten als bereit. Das bedeutet, dass das Knotenbedingungsfeld von NetworkUnavailable auf false gesetzt wird. Wenn dem Knoten keine Routen zugeordnet sind, wird das Feld „NetworkUnavailable“ auf „true“ gesetzt. Diese Bedingungen werden vom NodeLifeCycle-Controller in Taints übersetzt, nicht zu verwechseln mit denen, für die der CCM verantwortlich ist.

Lebenszyklus-Controller

Der (Cloud Node)Lifecycle Controller stellt sicher, dass Ihre Knoten, dargestellt als Kubernetes-API-Knotenobjekte, entfernt werden, wenn die Knoten aus Ihrer Cloud entfernt werden.

The Kubernetes Cloud Controller Manager

Auch wenn sich ein Knoten in einem vom Cloud-Anbieter angegebenen Abschaltzustand befindet, wird der Knoten entsprechend mit node.cloudprovider.kubernetes.io/shutdown und dem Taint-Effekt von NoSchedule tainted.

Das ist ungefähr die gesamte Funktionalität, die Sie von einem CCM erhalten. Meistens verfügt Ihre Cloud möglicherweise über einen eigenen Controller (bereitgestellt in einer separaten Binärdatei aus einem separaten Repository), der k8s-Objekte vom Typ Ingress verarbeitet oder Ihnen hilft nativ in die zugrunde liegende Netzwerkinfrastruktur integrieren.

Das CCM wird keine One-Stop-Shop-Lösung sein, es ist nur ein Teil eines größeren Puzzles.

Wenn Sie mitverfolgt und vielleicht einen Blick auf den Quellcode der verschiedenen Controller geworfen haben, die der CCM verwaltet, ist Ihnen vielleicht aufgefallen, dass nirgends ein Cloud-Provider-spezifischer Code zu sehen ist. Es gibt lediglich eine Reihe von Aufrufen einiger mysteriöser Methoden für verschiedene Objekte.

Der spezifische Code des Cloud-Anbieters und seine Verkabelung werden das fehlende Teil dieses CCM-Puzzles sein.

The Kubernetes Cloud Controller Manager

Ein Blick in den Rückspiegel

Bevor wir uns dem Cloud-Anbieter-Paket (k8s.io/cloud-provider) zuwenden, dem fehlenden Teil des CCM-Puzzles, gehen wir einen Teil der Geschichte hinter CCM und dem/den Cloud-Anbieter(n) durch. Wie sie sich im Laufe der Jahre entwickelt haben und wie alles entstanden ist.

Von Anfang an waren die Cloud-Integrationen aus offensichtlichen Gründen eine Grundlage für einen Teil von k8s. Werfen wir einen Blick auf die Cloud-Anbieter, deren spezifischer Anbietercode im k8s-Repository (k/k) von v1.0 enthalten war, das im Juli 2015 veröffentlicht wurde:

  • AWS
  • GCE
  • Mesos
  • OpenStack
  • Ovirt
  • Rackspace
  • Vagabund

Vielleicht kennen Sie alle oben genannten „Cloud-Anbieter“, einige davon sind Virtualisierungstechnologien und passen nicht genau in das, was wir allgemein unter einem Cloud-Anbieter verstehen. Um es gelinde auszudrücken.

Bereits im Juli 2015 wurde der gesamte Cloud-Anbieter-spezifische Code importiert und vom Kubelet verwendet, einer der kritischen Knotenkomponenten, aus denen ein k8s-Clusterknoten besteht.

Es gibt eine Reihe von Problemen mit der ursprünglichen Implementierung von Cloud-Anbieter-spezifischem Code, die die k8-Community erkannt hat und an denen sie bisher arbeitet.

Hier sind einige der Probleme, die im Laufe der Jahre aufgetaucht sind:

  • Das Kubelet darf keine Cloud-Provider-spezifischen Regelkreise ausführen. Diese wurden nun in das CCM verschoben.

  • Cloud-Anbieter dürfen nicht Teil von k/k (in-tree) sein. Der Grund dafür ist, dass der Code des Cloud-Anbieters an den k8s-Release-Zyklus gebunden wäre und das Festschreiben von Code an k/k erfolgen kann eine mühsame Aufgabe.

  • Unterstützen Sie externe (Out-of-Tree) Cloud-Anbieter, indem Sie ein separates Paket mit einer steckbaren Möglichkeit zur Integration Ihrer Cloud in k8s bereitstellen. Daraus wurde das Paket k8s.io/cloud-provider.

  • Der gesamte vom CCM verwendete Cloud-Controller-Code soll in das Paket k8s.io/cloud-provider verschoben werden. Es gibt immer noch Codereste im Baum, die verschoben werden.

Aus Gründen der Abwärtskompatibilität wird der Code, der sich im Baum befand, noch eine Weile verfügbar sein, aber es ist jetzt ein eigenes Paket (k8s.io/legacy-cloud-providers).

Ich habe versucht zu verfolgen, wie das CCM und k8s.io/cloud-provider entstanden sind, indem ich in den verschiedenen Repositories der k8s-Organisation herumgestöbert habe, fast wie eine digitale Archäologie. Hier sind einige der Highlights:

  • Im September 2016 wurde das Erweiterungsproblem Nr. 88 (KEP) erstellt, um Out-of-Tree-Cloud-Anbieter (pluggable) zu unterstützen.

  • Beginn der Aufteilung des (Kube-)Controller-Managers in zwei Teile, Okt. 2016. Bitte beachten Sie, dass in dieser PR der volumeController erwähnt wird. Dies ist die Zeit vor CSI. Dieser Controller wurde seitdem aus dem CCM entfernt.

  • Diskussionen zum Cloud Controller Manager, Juli 2017. In Version 1.11 in die Betaphase gelangt.

  • Hier finden Sie eine gute Erklärung dafür, wie eng Kubelet und der Cloud-Anbieter einst miteinander verbunden waren. Es gibt drei Ansätze zur Entkopplung von Kubelet und Cloud-Anbieter.

Das Cloud-Provider-Paket

Das Cloud-Provider-Paket wird als k8s.io/cloud-provider in Ihren CCM importiert und definiert eine Reihe von (Golang-)Schnittstellen. Die wichtigste davon ist die Interface-Schnittstelle, die dieses Paket für Cloud-Anbieter steckbar macht.

The Kubernetes Cloud Controller Manager

Die Schnittstelle definiert eine Reihe von Methoden, von denen einige andere Schnittstellen zurückgeben. Diese zurückgegebenen Schnittstellen sind auch in der cloud.go-Datei des Cloud-Anbieterpakets definiert.

$> kubectl get service my-app-svc
NAME       TYPE         CLUSTER-IP    EXTERNAL-IP     PORT(S)
my-app-svc LoadBalancer 172.20.10.100 123.123.123.123 80:31147/TCP

Wie Sie oben sehen können, geben die Methodensignaturen neben den zurückgegebenen Schnittstellen einen Bool-Rückgabewert an. Dies bedeutet, dass Sie Funktionen aktivieren/deaktivieren können, wenn sie vom CCM nicht implementiert werden können oder sollten. Dies wird während der Initialisierung des Controllers überprüft, der die durch die Schnittstelle definierte Funktionalität implementiert.

Hier ist ein kurzer Überblick darüber, welche k8s.io/cloud-provider-Schnittstellenmethoden von welchem ​​Controller verwendet werden:

  • Die Schnittstellenmethoden der Instanzen werden vom Knoten und den Lifecycle-Controllern aufgerufen.

  • Die Zonen-Schnittstellenmethoden werden von den Node- und Lifecycle-Controllern aufgerufen.

  • Die Route-Schnittstellenmethoden werden vom Route-Controller aufgerufen.

  • Die LoadBalancer-Schnittstellenmethoden werden vom Service-Controller aufgerufen.

  • Die Cluster-Schnittstelle wird nur vom externen GCP-Cloud-Anbieter verwendet.

Beachten Sie, dass es im k/k-Repository an mehreren Stellen Aufrufe zu verschiedenen Methoden in den oben genannten Schnittstellen gibt, z. B. sowohl im Kubelet als auch im API-Server.

Neben den oben genannten Schnittstellen enthält das Paket k8s.io/cloud-provider auch alles, was Sie zur Registrierung und Initialisierung Ihres Cloud-Anbieters beim CCM benötigen.

Werfen wir einen Blick auf die LoadBalancer-Schnittstelle, Sie werden eine Reihe von Methoden sehen, die Sie implementieren müssen:

LoadBalancer() (LoadBalancer, bool)
Instances() (Instances, bool)
Zones() (Zones, bool)
Clusters() (Clusters, bool)
Routes() (Routes, bool)

Diese Methoden werden vom Service-Controller aufgerufen, der im CCM ausgeführt wird. Ich zeige diese Methoden als Beispiel, da Sie sehen, dass diese Methoden im Quellcode des Service-Controllers aufgerufen werden.

Was tatsächlich im gesamten CCM herumgereicht wird, ist Ihr instanziiertes Objekt, das sich wie ein Cloud-Anbieter verhält (und alle Cloud-Anbieter-Schnittstellen erfüllt).

Auf diese Weise können die von CCM verwalteten Cloud-Controller Ressourcen in Ihrer Cloud erstellen, aktualisieren und löschen.

The Kubernetes Cloud Controller Manager

Das Paket k8s.io/cloud-provider definiert keine Art der Verbindung und z. B. Authentifizieren Sie sich bei Ihrer Cloud. Diese Art von Logik müssen Sie in das CCM einbauen.

Wenn Sie alle im Paket k8s.io/cloud-provider definierten Schnittstellen erfüllt und alles miteinander verbunden haben, sind Sie erfolgreich ein Cloud-Anbieter geworden. Sie müssen nur noch Ihre CCM-Binärdatei erstellen, in einen Container packen und auf k8s bereitstellen!

Mit Blick auf die Zukunft passiert tatsächlich eine Menge Dinge, wenn man sich die Cloud-Anbieter-Teile des k/k-Repositorys ansieht. Zum Zeitpunkt des Schreibens dieses Artikels gibt es eine laufende Initiative zur Umstrukturierung und Verbesserung des k8s.io/cloud-provider mehr oder weniger unabhängig. Das bedeutet, dass z.B. Die Cloud-Controller werden Teil des Pakets k8s.io/cloud-provider sein. Das bedeutet, dass Sie als Cloud-Anbieter am Ende ein Paket importieren müssen, um Ihren eigenen CCM und externen Cloud-Anbieter erstellen und implementieren zu können.

Aus Kubernetes-Perspektive

Um Ihr neu zusammengestelltes und Docker-gepacktes CCM ausführen zu können, müssen beim Hochfahren der k8s-Steuerungsebene einige Dinge konfiguriert werden:

  • Kubelets müssen mit dem Flag --cloud-provider=external gestartet werden. Dies signalisiert dem Kubelet, dass ein anderer Controller die Knoten initialisiert.

Wie am Anfang dieses Beitrags erwähnt, gibt es dieses Repository, in dem ich die technische Seite der Dinge beim Betrieb Ihres eigenen externen Cloud-Anbieters CCM zeige und erkläre.

Wenn Sie, sagen wir, gerade auf AWS wären und Ihren eigenen k8s-Cluster auf EC2-Instanzen aufbauen würden und eine nativere Integration in AWS wünschen, hätten Sie den Cloud-Anbieter AWS CCM bereitgestellt. Sie können auch, obwohl dies nicht empfohlen wird, einfach --cloud-provider=aws auf den Kubelets angeben. Auf diese Weise signalisieren Sie k8s, dass Sie In-Tree-Cloud-Anbieter verwenden möchten, von denen nur eine Handvoll implementiert sind. Alle „neueren“ privaten/öffentlichen Clouds hätten einen externen Cloud-Anbieter CCM.

Der Code für die In-Tree-Cloud-Anbieter wird über k8s.io/legacy-cloud-providers importiert. Bitte beachten Sie, dass Sie dieses Paket von Anfang an importieren, wenn Sie den CCM-Skelettcode von k/k verwenden .

Ressourcen

Um zu verfolgen, was in Bezug auf alles rund um Cloud-Anbieter im Zusammenhang mit k8s passiert, sehen Sie sich bitte diese Ressourcen an:

  • SIG Cloud-Anbieter

  • Channel sig-cloud-provider im k8s Slack-Bereich

  • Alle mit sig/cloud-provider gekennzeichneten k8s-Erweiterungsprobleme

Hier ist eine Liste der externen Cloud-Anbieter, die sich hervorragend als Referenz eignet oder einfach nur neugierig ist, wie andere es gemacht haben:

  • OpenStack

  • DigitalOcean

  • AWS

  • GCP

  • Alibaba Cloud

  • Huawei Cloud

  • Baidu Cloud

  • vSphere

  • Azurblau

Das obige ist der detaillierte Inhalt vonDer Kubernetes Cloud Controller Manager. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn