Google Distributed Cloud-Cluster hochskalieren

Wie alle Kubernetes-Cluster hat die Skalierbarkeit von Google Distributed Cloud-Clustern viele zusammengehörige Dimensionen. Dieses Dokument soll Ihnen dabei helfen, die Schlüsseldimensionen zu verstehen, die Sie anpassen können, um Ihre Cluster ohne Beeinträchtigung Ihrer Arbeitslasten hochzuskalieren.

Informationen zu den Limits

Google Distributed Cloud ist ein komplexes System mit einer großen Integrationsfläche. Die Skalierbarkeit von Clustern wird von vielen Dimensionen beeinflusst. Die Anzahl der Knoten ist beispielsweise nur einer von vielen Dimensionen, für die Google Distributed Cloud skaliert werden kann. Weitere Dimensionen sind die Gesamtzahl der Pods und Dienste. Viele dieser Dimensionen, wie die Anzahl der Pods pro Knoten und die Anzahl der Knoten pro Cluster, sind miteinander verknüpft. Weitere Informationen zu den Dimensionen, die sich auf die Skalierbarkeit auswirken, finden Sie unter Schwellenwerte für die Kubernetes-Skalierbarkeit im Abschnitt „Scalability Special Interest Group (SIG)“ des Repositorys der Kubernetes-Community auf GitHub.

Die Skalierbarkeitslimits hängen auch von der Hardware und der Knotenkonfiguration ab, auf der Ihr Cluster ausgeführt wird. Die in diesem Dokument beschriebenen Limits werden in einer Umgebung überprüft, die wahrscheinlich von Ihrer abweicht. Daher werden möglicherweise nicht dieselben Zahlen reproduziert, wenn die zugrunde liegende Umgebung der begrenzende Faktor ist.

Weitere Informationen zu den Limits für Ihre Google Distributed Cloud-Cluster finden Sie unter Kontingente und Limits.

Skalierung vorbereiten

Berücksichtigen Sie bei der Vorbereitung der Skalierung Ihrer Google Distributed Cloud-Cluster die in den folgenden Abschnitten beschriebenen Anforderungen und Einschränkungen.

CPU- und Arbeitsspeicheranforderungen für Knoten der Steuerungsebene

Die folgende Tabelle enthält die empfohlene CPU- und Arbeitsspeicherkonfiguration für Knoten der Steuerungsebene für Cluster, auf denen Produktionsarbeitslasten ausgeführt werden:

Anzahl der Clusterknoten Empfohlene CPUs der Steuerungsebene Empfohlener Arbeitsspeicher der Steuerungsebene
1-50 8 Kerne 32 GiB
51–100 16 Kerne 64 GiB

Anzahl der Pods und Dienste

Die Anzahl der Pods und Dienste in Ihren Clustern wird durch die folgenden Einstellungen gesteuert:

Pod-CIDR und maximale Knotenanzahl

Die Gesamtzahl der für Pods in Ihrem Cluster reservierten IP-Adressen ist einer der begrenzenden Faktoren beim Hochskalieren des Clusters. Diese Einstellung bestimmt zusammen mit der Einstellung für die maximale Anzahl von Pods pro Knoten die maximale Anzahl von Knoten in Ihrem Cluster, bevor die Gefahr besteht, dass IP-Adressen für Ihre Pods aufgebraucht werden.

Beachten Sie dabei Folgendes:

  • Die Gesamtzahl der für Pods in Ihrem Cluster reservierten IP-Adressen wird mit clusterNetwork.pods.cidrBlocks angegeben. Dabei wird ein Bereich von IP-Adressen in CIDR-Notation verwendet. Beispielsweise gibt der vorab ausgefüllte Wert 192.168.0.0/16 einen Bereich von 65.536 IP-Adressen von 192.168.0.0 bis 192.168.255.255 an.

  • Die maximale Anzahl von Pods, die auf einem einzelnen Knoten ausgeführt werden können, wird mit nodeConfig.podDensity.maxPodsPerNode angegeben.

  • Basierend auf der Einstellung für die maximale Anzahl von Pods pro Knoten stellt Google Distributed Cloud etwa doppelt so viele IP-Adressen für den Knoten bereit. Die zusätzlichen IP-Adressen verhindern eine versehentliche Wiederverwendung der Pod-IP-Adressen innerhalb kurzer Zeit.

  • Wenn Sie die Gesamtzahl der Pod-IP-Adressen durch die Anzahl der auf jedem Knoten bereitgestellten Pod-IP-Adressen teilen, erhalten Sie die Gesamtzahl der Knoten, die in Ihrem Cluster vorhanden sein können.

Wenn Ihr Pod-CIDR beispielsweise 192.168.0.0/17 ist, haben Sie insgesamt 32.768 IP-Adressen (2(32 - 17) = 215 = 32.768). Wenn Sie die maximale Anzahl von Pods pro Knoten auf 250 festlegen, stellt Google Distributed Cloud einen Bereich von etwa 500 IP-Adressen bereit. Dies entspricht in etwa einem CIDR-Block /23 (2(32 - 23) = 29 = 512). Die maximale Anzahl von Knoten ist in diesem Fall also 64 (215 Adressen/Cluster geteilt durch 29 Adressen/Knoten = 2(15-9) Knoten/Cluster = 26 = 64 Knoten/Cluster.

Sowohl clusterNetwork.pods.cidrBlocks als auch nodeConfig.podDensity.maxPodsPerNode sind unveränderlich. Planen Sie daher sorgfältig für das zukünftige Wachstum Ihres Clusters, um zu vermeiden, dass die Knotenkapazität knapp wird. Die empfohlenen Höchstwerte für Pods pro Cluster, Pods pro Knoten und Knoten pro Cluster basierend auf Tests finden Sie unter Limits.

Dienst-CIDR

Ihr Dienst-CIDR kann aktualisiert werden, um beim Hochskalieren des Clusters weitere Dienste hinzuzufügen. Sie können den Dienst-CIDR-Bereich jedoch nicht reduzieren. Weitere Informationen finden Sie unter Bereich des Dienstnetzwerks erhöhen.

Für System-Daemons reservierte Ressourcen

Standardmäßig reserviert Google Distributed Cloud auf einem Knoten automatisch Ressourcen für System-Daemons wie sshd oder udev. CPU- und Arbeitsspeicherressourcen werden auf einem Knoten für System-Daemons reserviert, sodass diese Daemons die benötigten Ressourcen haben. Ohne dieses Feature können Pods potenziell die meisten Ressourcen auf einem Knoten verbrauchen, sodass System-Daemons ihre Aufgaben nicht erledigen können.

Insbesondere reserviert Google Distributed Cloud 80 Millicore CPU (80 mCPU) und 280 Mebibyte (280 MiB) Arbeitsspeicher auf jedem Knoten für System-Daemons. Beachten Sie, dass die CPU-Einheit mCPU für ein Tausendstel eines Kerns steht. Daher sind 80/1.000 bzw. 8 % eines Kerns auf jedem Knoten für System-Daemons reserviert. Die Menge der reservierten Ressourcen ist gering und hat keinen großen Einfluss auf die Pod-Leistung. Das Kubelet auf einem Knoten kann jedoch Pods entfernen, wenn ihre CPU- oder Arbeitsspeichernutzung die ihnen zugewiesenen Mengen überschreitet.

Netzwerk mit MetalLB

Sie können die Anzahl der MetalLB-Lautsprecher erhöhen, um die folgenden Aspekte zu berücksichtigen:

  • Bandbreite: Die gesamte Clusterbandbreite für Load-Balancing-Dienste hängt von der Anzahl der Lautsprecher und der Bandbreite der einzelnen Lautsprecherknoten ab. Für einen höheren Netzwerktraffic sind mehr Lautsprecher erforderlich.

  • Fehlertoleranz: Mehr Lautsprecher verringern die Auswirkungen eines Ausfalls eines Lautsprechers.

MetalLB erfordert Layer-2-Verbindungen zwischen den Load-Balancing-Knoten. In diesem Fall sind Sie möglicherweise durch die Anzahl der Knoten mit Ebene-2-Konnektivität eingeschränkt, auf denen Sie MetalLB-Lautsprecher anschließen können.

Planen Sie sorgfältig, wie viele MetalLB-Lautsprecher in Ihrem Cluster vorhanden sein sollen, und bestimmen Sie, wie viele Layer-2-Knoten Sie benötigen. Weitere Informationen finden Sie unter Skalierbarkeitsprobleme bei MetalLB.

Wenn Sie den gebündelten Load-Balancing-Modus verwenden, müssen sich die Knoten der Steuerungsebene außerdem im selben Layer-2-Netzwerk befinden. Für das manuelle Load-Balancing gilt diese Einschränkung nicht. Weitere Informationen finden Sie unter Manueller Load-Balancer-Modus.

Viele Knoten, Pods und Dienste ausführen

Durch das Hinzufügen von Knoten, Pods und Diensten können Sie Ihren Cluster skalieren. In den folgenden Abschnitten werden einige zusätzliche Einstellungen und Konfigurationen beschrieben, die Sie berücksichtigen sollten, wenn Sie die Anzahl der Knoten, Pods und Dienste im Cluster erhöhen. Informationen zu den Limits für diese Dimensionen und dazu, wie sie miteinander zusammenhängen, finden Sie unter Limits.

Cluster ohne kube-proxy erstellen

Zum Erstellen eines Hochleistungsclusters, der für die Nutzung einer großen Anzahl von Diensten und Endpunkten hochskaliert werden kann, empfehlen wir, den Cluster ohne kube-proxy zu erstellen. Ohne kube-proxy verwendet der Cluster GKE Dataplane V2 im Modus kube-proxy-replacement. Dieser Modus verhindert Ressourcenverbrauch, die für die Verwaltung eines großen Satzes von iptables-Regeln erforderlich sind.

Sie können die Verwendung von kube-proxy für einen vorhandenen Cluster nicht deaktivieren. Diese Konfiguration muss beim Erstellen des Clusters eingerichtet werden. Eine Anleitung und weitere Informationen finden Sie unter Cluster ohne kube-proxy erstellen.

CoreDNS-Konfiguration

In diesem Abschnitt werden Aspekte von CoreDNS beschrieben, die sich auf die Skalierbarkeit Ihrer Cluster auswirken.

Pod-DNS

Standardmäßig fügen Google Distributed Cloud-Cluster Pods mit einem resolv.conf ein, der so aussieht:

nameserver KUBEDNS_CLUSTER_IP
search <NAMESPACE>.svc.cluster.local svc.cluster.local cluster.local c.PROJECT_ID.internal google.internal
options ndots:5

Die Option ndots:5 bedeutet, dass Hostnamen mit weniger als 5 Punkten nicht als voll qualifizierter Domainname (FQDN) betrachtet werden. Der DNS-Server hängt alle angegebenen Suchdomains an, bevor er den ursprünglich angeforderten Hostnamen sucht. Dadurch werden beim Auflösen von google.com die folgenden Suchvorgänge durchgeführt:

  1. google.com.NAMESPACE.svc.cluster.local
  2. google.com.svc.cluster.local
  3. google.com.cluster.local
  4. google.com.c.PROJECT_ID.internal
  5. google.com.google.internal
  6. google.com

Jede der Suchvorgänge wird für IPv4 (A-Eintrag) und IPv6 (AAAA-Eintrag) durchgeführt, was zu 12 DNS-Anfragen für jede Nicht-FQDN-Abfrage führt, was den DNS-Traffic erheblich verstärkt. Um dieses Problem zu beheben, empfehlen wir, den zu suchenden Hostnamen als FQDN zu deklarieren, indem Sie einen abschließenden Punkt (google.com.) hinzufügen. Diese Deklaration muss auf der Arbeitslastebene der Anwendung erfolgen. Weitere Informationen findest du auf der resolv.conf-Manpage.

IPv6

Wenn der Cluster nicht IPv6 verwendet, ist es möglich, die DNS-Anfragen um die Hälfte zu reduzieren. Dazu entfällt die AAAA-Eintragssuche für den vorgelagerten DNS-Server. Wenn Sie Hilfe beim Deaktivieren von AAAA-Lookups benötigen, wenden Sie sich an Cloud Customer Care.

Dedizierter Knotenpool

Da DNS-Abfragen in Anwendungslebenszyklen sehr wichtig sind, empfehlen wir die Verwendung dedizierter Knoten für das coredns-Deployment. Dieses Deployment fällt in eine andere Fehlerdomäne als normale Anwendungen. Wenn Sie Hilfe beim Einrichten dedizierter Knoten für das coredns-Deployment benötigen, wenden Sie sich an Cloud Customer Care.

MetalLB-Skalierbarkeitsprobleme

MetalLB wird im Aktiv-Passiv-Modus ausgeführt. Das bedeutet, dass immer nur ein einziger MetalLB-Lautsprecher eine bestimmte LoadBalancer-VIP bedient.

Failover

Vor dem Release 1.28.0 von Google Distributed Cloud konnte das Failover von MetalLB im großen Maßstab lange dauern und ein Zuverlässigkeitsrisiko für den Cluster darstellen.

Verbindungseinschränkungen

Wenn eine bestimmte virtuelle IP-Adresse von LoadBalancer (z. B. ein Ingress-Dienst) etwa 30.000 gleichzeitige Verbindungen erwartet, ist es wahrscheinlich, dass der Lautsprecherknoten, der die VIP verarbeitet, die verfügbaren Ports ausgeschöpft hat. Aufgrund einer Architekturbeschränkung kann dieses Problem von MetalLB nicht entschärft werden. Erwägen Sie den Wechsel zum gebündelten Load-Balancing mit BGP, bevor Sie den Cluster erstellen, oder verwenden Sie eine andere Eingangsklasse. Weitere Informationen finden Sie unter Ingress-Konfiguration.

Load-Balancer-Lautsprecher

Standardmäßig verwendet Google Distributed Cloud denselben Load-Balancer-Knotenpool sowohl für die Steuerungsebene als auch für die Datenebene. Wenn Sie keinen Load-Balancer-Knotenpool (loadBalancer.nodePoolSpec) angeben, wird der Knotenpool der Steuerungsebene (controlPlane.nodePoolSpec) verwendet.

Wenn Sie die Anzahl der Sprecher erhöhen möchten, wenn Sie den Knotenpool der Steuerungsebene für das Load-Balancing verwenden, müssen Sie die Anzahl der Maschinen der Steuerungsebene erhöhen. Für Produktionsbereitstellungen empfehlen wir die Verwendung von drei Knoten der Steuerungsebene für Hochverfügbarkeit. Es ist möglicherweise keine sinnvolle Nutzung Ihrer Ressourcen, die Anzahl der Knoten der Steuerungsebene auf mehr als drei zu erhöhen, um zusätzliche Lautsprecher unterzubringen.

Konfiguration für eingehenden Traffic

Wenn Sie davon ausgehen, dass fast 30.000 gleichzeitige Verbindungen zu einer einzelnen LoadBalancer-Dienst-VIP eingehen, kann MetalLB diese möglicherweise nicht unterstützen.

Sie können die VIP über andere Mechanismen wie F5 BIG-IP verfügbar machen. Alternativ können Sie einen neuen Cluster mit gebündeltem Load-Balancing mit BGP erstellen. Dies hat nicht dieselben Einschränkungen.

Cloud Logging- und Cloud Monitoring-Komponenten optimieren

In großen Clustern reichen je nach Anwendungsprofil und Trafficmuster möglicherweise die Standardressourcenkonfigurationen für die Cloud Logging- und Cloud Monitoring-Komponenten nicht aus. Eine Anleitung zum Optimieren der Ressourcenanfragen und -limits für die Beobachtbarkeitskomponenten finden Sie unter Stackdriver-Komponentenressourcen konfigurieren.

Insbesondere können kube-state-metrics in Clustern mit einer großen Anzahl von Diensten und Endpunkten zu einer übermäßigen Arbeitsspeichernutzung sowohl für kube-state-metrics als auch für gke-metrics-agent auf demselben Knoten führen. Die Ressourcennutzung von Metrics-Server kann auch in Bezug auf Knoten, Pods und Dienste skaliert werden. Wenn Ressourcenprobleme mit diesen Komponenten auftreten, wenden Sie sich an Cloud Customer Care.

Betriebssystem mit „sysctl“ konfigurieren

Wir empfehlen Ihnen, die Betriebssystemkonfiguration für Ihre Knoten optimal auf den Anwendungsfall Ihrer Arbeitslast abzustimmen. Die Parameter fs.inotify.max_user_watches und fs.inotify.max_user_instances, die die Anzahl der Inotify-Ressourcen steuern, müssen häufig angepasst werden. Wenn Sie beispielsweise Fehlermeldungen wie die folgende sehen, sollten Sie prüfen, ob diese Parameter optimiert werden müssen:

The configured user limit (128) on the number of inotify instances has been reached
ENOSPC: System limit for number of file watchers reached...

Die Abstimmung variiert in der Regel je nach Arbeitslasttyp und Hardwarekonfiguration. Sie können die jeweiligen Best Practices für Betriebssysteme mit Ihrem Betriebssystemanbieter besprechen.

Best Practices

In diesem Abschnitt werden Best Practices zum Skalieren von Clustern beschrieben.

Eine Dimension nach der anderen skalieren

Passen Sie jeweils nur eine Dimension gleichzeitig an, um Probleme zu minimieren und das Rollback von Änderungen zu erleichtern. Die gleichzeitige Hochskalierung mehrerer Dimensionen kann selbst in kleineren Clustern Probleme verursachen. Beispielsweise wird der Versuch, die Anzahl der pro Knoten geplanten Pods auf 110 und gleichzeitig die Anzahl der Knoten im Cluster auf 250 zu erhöhen, wahrscheinlich nicht erfolgreich sein, da die Anzahl der Pods, die Anzahl der Pods pro Knoten und die Anzahl der Knoten zu stark gestreckt werden.

Cluster stufenweise skalieren

Das Hochskalieren eines Clusters kann ressourcenintensiv sein. Um das Risiko zu verringern, dass Clustervorgänge fehlschlagen oder Clusterarbeitslasten unterbrochen werden, raten wir davon ab, große Cluster mit vielen Knoten in einem einzigen Vorgang zu erstellen.

Hybrid- oder eigenständige Cluster ohne Worker-Knoten erstellen

Wenn Sie einen großen Hybrid- oder eigenständigen Cluster mit mehr als 50 Worker-Knoten erstellen, ist es besser, zuerst einen Hochverfügbarkeitscluster mit Knoten der Steuerungsebene zu erstellen und dann schrittweise hochzuskalieren. Beim Erstellen des Clusters wird ein Bootstrap-Cluster verwendet, der keine Hochverfügbarkeit hat und daher weniger zuverlässig ist. Nachdem der hybride oder eigenständige Hochverfügbarkeitscluster erstellt wurde, können Sie damit auf mehr Knoten hochskalieren.

Anzahl der Worker-Knoten in Batches erhöhen

Wenn Sie einen Cluster auf mehr Worker-Knoten erweitern, ist es besser, ihn in Phasen zu erweitern. Wir empfehlen, nicht mehr als 20 Knoten gleichzeitig hinzuzufügen. Dies gilt insbesondere für Cluster, auf denen kritische Arbeitslasten ausgeführt werden.

Parallele Image-Abrufe aktivieren

Standardmäßig ruft kubelet die Images nacheinander ab, eine nach der anderen. Wenn die Upstream-Verbindung zu Ihrem Image-Registry-Server schlecht ist, kann ein fehlerhafter Image-Abruf die gesamte Warteschlange für einen bestimmten Knotenpool zum Stillstand bringen.

Um dies zu vermeiden, sollten Sie serializeImagePulls in der benutzerdefinierten Kubelet-Konfiguration auf false festlegen. Weitere Informationen finden Sie unter Abrufeinstellungen für Kubelet-Images konfigurieren. Das Aktivieren paralleler Image-Abrufe kann zu Spitzen in der Verbrauch der Netzwerkbandbreite oder der Laufwerk-E/A führen.

Anfragen und Limits für Anwendungsressourcen optimieren

In dicht verpackten Umgebungen können Anwendungsarbeitslasten entfernt werden. Kubernetes verwendet den referenzierten Mechanismus, um Pods im Falle einer Bereinigung einzustufen.

Eine gute Vorgehensweise zum Festlegen Ihrer Containerressourcen besteht darin, die gleiche Menge an Arbeitsspeicher für Anfragen und Limits sowie ein größeres oder unbegrenztes CPU-Limit zu verwenden. Weitere Informationen finden Sie unter Cloudbasierte Kubernetes-Anwendungen vorbereiten im Cloud Architecture Center.

Speicherpartner verwenden

Für umfangreiche Bereitstellungen empfehlen wir die Zusammenarbeit mit einem der GDCV-fähigen Speicherpartner. Es ist wichtig, dass Sie sich mit dem jeweiligen Speicherpartner die folgenden Informationen bestätigen lassen:

  • Die Speicherbereitstellungen folgen Best Practices für Speicheraspekte wie Hochverfügbarkeit, Prioritätseinstellung, Knotenaffinitäten sowie Ressourcenanfragen und -limits.
  • Die Speicherversion ist mit der jeweiligen Google Distributed Cloud-Version qualifiziert.
  • Der Speicheranbieter kann die umfangreiche Unterstützung bieten, die Sie bereitstellen möchten.

Cluster für Hochverfügbarkeit konfigurieren

Es ist wichtig, dass Sie Ihre umfangreiche Bereitstellung prüfen und dafür sorgen, dass die kritischen Komponenten nach Möglichkeit für Hochverfügbarkeit konfiguriert sind. Google Distributed Cloud unterstützt Hochverfügbarkeitsoptionen für alle Clustertypen. Weitere Informationen finden Sie unter Bereitstellungsmodell auswählen. Beispiele für Clusterkonfigurationsdateien von Hochverfügbarkeitsbereitstellungen finden Sie unter Beispiele für Clusterkonfiguration.

Es ist auch wichtig, andere Komponenten zu prüfen, darunter:

  • Speicheranbieter
  • Cluster-Webhooks

Ressourcennutzung überwachen

Dieser Abschnitt enthält einige grundlegende Monitoring-Empfehlungen für große Cluster.

Auslastungsmesswerte genau beobachten

Es ist wichtig, die Auslastung sowohl der Knoten als auch der einzelnen Systemkomponenten zu überwachen und sicherzustellen, dass sie einen komfortabel sicheren Grenzwert haben. Informationen dazu, welche standardmäßigen Monitoringfunktionen standardmäßig verfügbar sind, finden Sie unter Vordefinierte Dashboards verwenden.

Bandbreitenverbrauch überwachen

Überwachen Sie die Bandbreitennutzung genau, um eine Überlastung des Netzwerks zu verhindern, was zu Leistungseinbußen des Clusters führt.

etcd-Leistung verbessern

Die Laufwerksgeschwindigkeit ist entscheidend für die Leistung und Stabilität von etcd. Ein langsames Laufwerk erhöht die Latenz von etcd-Anfragen, was zu Problemen mit der Clusterstabilität führen kann. Zur Verbesserung der Clusterleistung speichert Google Distributed Cloud Ereignisobjekte in einer separaten, dedizierten etcd-Instanz. Die etcd-Standardinstanz verwendet /var/lib/etcd als Datenverzeichnis und Port 2379 für Clientanfragen. Die Instanz "etcd-events" verwendet /var/lib/etcd-events als Datenverzeichnis und Port 2382 für Clientanfragen.

Wir empfehlen die Verwendung eines Solid State Disk (SSD) für Ihre etcd-Speicher. Für optimale Leistung sollten Sie separate Laufwerke unter /var/lib/etcd und /var/lib/etcd-events bereitstellen. Durch die Verwendung von dedizierten Laufwerken wird sichergestellt, dass die beiden etcd-Instanzen die Laufwerks-E/A nicht gemeinsam nutzen.

Die etcd-Dokumentation enthält zusätzliche Hardwareempfehlungen, mit denen Sie die beste etcd-Leistung bei der Ausführung Ihrer Cluster in der Produktion sicherstellen können.

Prüfen Sie die etcd- und Laufwerksleistung mit den folgenden etcd-E/A-Latenzmesswerten im Metrics Explorer:

  • etcd_disk_backend_commit_duration_seconds: Die Dauer sollte für das 99. Perzentil (p99) weniger als 25 Millisekunden betragen.
  • etcd_disk_wal_fsync_duration_seconds: Die Dauer sollte für das 99. Perzentil (p99) weniger als 10 Millisekunden betragen.

Weitere Informationen zur etcd-Leistung finden Sie unter Was bedeutet die etcd-Warnung „Apply-Einträge zu lange“? und Was bedeutet die etcd-Warnung „Herzschlag nicht rechtzeitig gesendet“?.

Wenn Sie weitere Unterstützung benötigen, wenden Sie sich an den Cloud Customer Care.

Nächste Schritte