Kapazitätsreserven verbessern die Reaktionsfähigkeit und Zuverlässigkeit kritischer Arbeitslasten, indem sie die freie Clusterkapazität und die angehaltenen Zustände der vorab bereitgestellten und vorkonfigurierten Kapazität proaktiv verwalten. Dazu wird eine Kubernetes-CustomResourceDefinition (CRD) vom Typ CapacityBuffer verwendet. Mit Kapazitätsreserven können Sie explizit eine bestimmte Menge an ungenutzter Knotenauslastung in Ihrem Cluster definieren. Diese reservierte Kapazität trägt dazu bei, die Zeit für die Pod-Planung zu verkürzen.
Wenn eine Arbeitslast mit hoher Priorität schnell skaliert werden muss, kann die neue Arbeitslast die freie Kapazität sofort nutzen, ohne auf die Knotenbereitstellung warten zu müssen. Dieser Ansatz minimiert die Latenz und vermeidet Ressourcenkonflikte bei plötzlichen Nachfragespitzen.
Auf dieser Seite werden Methoden zum Konfigurieren von Kapazitätsreserven beschrieben: eine Reserve mit fester Anzahl von Replikaten, eine Reserve mit Ressourcenlimits und eine prozentuale Reserve.
Hinweis
Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:
- Aktivieren Sie die Google Kubernetes Engine API. Google Kubernetes Engine API aktivieren
- Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten,
installieren und dann
initialisieren Sie die
gcloud CLI. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste
Version mit dem
gcloud components updateBefehl ab. Ältere gcloud CLI-Versionen unterstützen möglicherweise nicht die Ausführung der Befehle in diesem Dokument.
- Erstellen Sie einen GKE-Cluster in Version 1.35.2-gke.1842000 für aktive Reserven und in Version 1.36.0-gke.2253000 oder höher für Standby-Reserven oder haben Sie Zugriff darauf.
- Aktivieren Sie die automatische Knotenbereitstellung in Ihren Standardclustern. In Autopilot-Clustern ist die automatische Knotenbereitstellung bereits aktiviert. Die automatische Knotenbereitstellung ist optional, wird aber für aktive Reserven empfohlen und ist für Standby-Reserven erforderlich.
Erforderliche Kubernetes-Objekte erstellen
Zum Konfigurieren eines CapacityBuffer benötigen Sie einen Namespace, der alle erforderlichen Objekte enthält: den CapacityBuffer selbst und zusätzliche Ressourcen wie eine PodTemplate oder eine Arbeitslast. Die PodTemplate und der CapacityBuffer müssen sich im selben Namespace befinden. Sie können einen Namespace erstellen oder einen vorhandenen Namespace verwenden, einschließlich des Namespace default.
Je nachdem, welchen Typ von CapacityBuffer Sie konfigurieren, benötigen Sie außerdem eines der folgenden Elemente:
- PodTemplate: definiert die Ressourcenanforderungen für eine einzelne Einheit der Reservekapazität. Die im CapacityBuffer-Objekt angegebene Konfiguration verweist auf die Pod-Vorlage.
Arbeitslast: eine vorhandene Arbeitslast, auf die Sie im CapacityBuffer Objekt verweisen. In diesem Leitfaden wird ein Deployment-Objekt als Beispielarbeitslast verwendet. Kapazitätsreserven unterstützen jedoch alle folgenden Ressourcentypen:
- Bereitstellung
- ReplicaSet
- StatefulSet
- ReplicationController
- Job
CustomResourceDefinitions (CRDs), die die Unterressource
scaleimplementieren.
In diesem Abschnitt finden Sie Beispiele für diese Objekte. Wenn Sie bereits eine Arbeitslast haben, die Sie mit einer Kapazitätsreserve konfigurieren möchten, fahren Sie mit Kapazitätsreserve anwenden fort.
So erstellen Sie eine Beispielarbeitslast für Kubernetes:
Speichern Sie das folgende Manifest als
namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: capacity-buffer-example labels: name: capacity-buffer-exampleDieses Manifest erstellt einen Namespace namens
capacity-buffer-example.Optional: Wenn Sie Kapazitätsreserven mit einer benutzerdefinierten ComputeClass verwenden möchten, speichern Sie das folgende Manifest als
custom-compute-class.yaml:apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: ccc-example namespace: capacity-buffer-example spec: # Buffers are also created according to these priorities priorities: - machineFamily: n4 - machineFamily: n4d - machineFamily: c4 - machineFamily: c4d nodePoolAutoCreation: enabled: trueDieses Manifest erstellt eine benutzerdefinierte
ComputeClass, die die Rechenprioritäten für die von GKE bereitgestellten Knoten definiert und steuert. Weitere Informationen finden Sie unter Benutzerdefinierte ComputeClasses.Speichern Sie das folgende Manifest als
buffer-pod-template.yaml:apiVersion: v1 kind: PodTemplate metadata: name: buffer-unit-template namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer template: spec: terminationGracePeriodSeconds: 0 containers: - name: buffer-container image: registry.k8s.io/pause:3.9 resources: requests: cpu: "1" memory: "1Gi" limits: cpu: "1" memory: "1Gi" # Optional: Using buffers with a custom ComputeClass / # controls the properties of the provisioned nodes. nodeSelector: cloud.google.com/compute-class: ccc-exampleDieses Manifest erstellt eine
PodTemplate, die die Ressourcenanforderungen für eine einzelne Einheit der Reservekapazität (1CPU und1GiArbeitsspeicher) definiert. Diese Konfiguration gibt die Größe der Kapazitätseinheiten an, die GKE für die Reserve bereitstellt. Mit dieser PodTemplate berücksichtigt GKE beispielsweise keine Knoten mit weniger als 1 CPU und 1 GiB verfügbarer Ressourcen als Teil der Reserve, wenn der Cluster skaliert wird.Speichern Sie das folgende Manifest als
sample-workload-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: critical-workload-ref namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer spec: replicas: 10 selector: matchLabels: app: critical-workload template: metadata: labels: app: critical-workload spec: containers: - name: busybox image: busybox command: ["sleep", "3600"] resources: requests: cpu: 100m # Optional: Using buffers with a custom ComputeClass / # controls the properties of the provisioned nodes. nodeSelector: cloud.google.com/compute-class: ccc-exampleDieses Manifest erstellt ein Beispiel-Deployment mit 10 Replikaten. Es ist das Referenzobjekt für das Beispiel für die prozentuale Reserve im nächsten Abschnitt.
Wenden Sie die Manifeste auf Ihren Cluster an:
kubectl apply -f namespace.yaml -f custom-compute-class.yaml -f buffer-pod-template.yaml -f sample-workload-deployment.yamlPrüfen Sie, ob GKE die Objekte erstellt hat:
kubectl get podtemplate -n capacity-buffer-example kubectl get deployment critical-workload-ref -n capacity-buffer-exampleDie Ausgabe sieht etwa so aus:
NAME AGE buffer-unit-template 1m NAME READY UP-TO-DATE AVAILABLE AGE critical-workload-ref 10/10 10 10 1m
Kapazitätsreserve anwenden
In diesem Abschnitt finden Sie Beispiele für die verschiedenen Arten von Kapazitätsreserven, die Sie auf Ihre Arbeitslasten anwenden können.
Reserve mit fester Anzahl von Replikaten konfigurieren
Wenn Sie einen CapacityBuffer mit einer festen Anzahl von Replikaten konfigurieren, geben Sie die genaue Anzahl der gewünschten Reserveeinheiten basierend auf einer PodTemplate an.
So erstellen Sie eine Reserve mit einer festen Anzahl von Replikaten:
Speichern Sie das folgende Manifest als
cb-fixed-replicas.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: fixed-replica-buffer namespace: NAMESPACE spec: podTemplateRef: name: POD_TEMPLATE replicas: 3 provisioningStrategy: "STRATEGY"Ersetzen Sie Folgendes:
NAMESPACE: Der Name Ihres Namespace, z. B.capacity-buffer-example.POD_TEMPLATE: Die PodTemplate, die Ihre Ressourcenanforderungen definiert, z. B.buffer-unit-template.STRATEGY: Die Bereitstellungsstrategie, entweder"buffer.x-k8s.io/active-capacity"(Standard) oder"buffer.gke.io/standby-capacity".
Dieses Manifest erstellt eine CapacityBuffer-Ressource, die auf eine PodTemplate verweist, um eine bestimmte Anzahl von Reserveeinheiten anzufordern.
Wenden Sie das Manifest an:
kubectl apply -f cb-fixed-replicas.yamlPrüfen Sie, ob GKE die Kapazitätsreserve angewendet hat:
kubectl get capacitybuffer fixed-replica-buffer -n NAMESPACEIm Feld
replicasdes Status sollte3angezeigt werden. Das entspricht der Anzahl der Replikate, die Sie im Manifest definiert haben. Im FeldSTATUSsollteReadyForProvisioningangezeigt werden.
Reserve mit Ressourcenlimits konfigurieren
Mit dem Feld limits können Sie eine maximale Menge an Ressourcen definieren, die von der Reserve verbraucht werden soll. Diese wird basierend auf der Größe Ihrer PodTemplate berechnet.
So erstellen Sie eine Reserve mit Ressourcenlimits:
Speichern Sie das folgende Manifest als
cb-resource-limits.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: resource-limit-buffer namespace: NAMESPACE spec: podTemplateRef: name: POD_TEMPLATE limits: cpu: "5" memory: "5Gi" provisioningStrategy: "STRATEGY"Ersetzen Sie Folgendes:
NAMESPACE: Der Name Ihres Namespace, z. B.capacity-buffer-example.POD_TEMPLATE: Die PodTemplate, die Ihre Ressourcenanforderungen definiert, z. B.buffer-unit-template.STRATEGY: Die Bereitstellungsstrategie, entweder"buffer.x-k8s.io/active-capacity"(Standard) oder"buffer.gke.io/standby-capacity".
Dieses Manifest erstellt eine CapacityBuffer-Ressource mit einem Limit von insgesamt 5 CPUs und 5 GiB Arbeitsspeicher. Wenn Sie das PodTemplate-Beispiel aus dem vorherigen Schritt verwenden, definieren Sie jede Einheit als
1CPU und1GiArbeitsspeicher. Das sollte zu 5 Reserveeinheiten führen.Wenden Sie das Manifest an:
kubectl apply -f cb-resource-limits.yamlPrüfen Sie, ob GKE die Kapazitätsreserve angewendet hat:
kubectl get capacitybuffer resource-limit-buffer -n NAMESPACEPrüfen Sie den Status des CapacityBuffer. Im Feld
replicassollte ein Wert angezeigt werden, der aus den von Ihnen definierten Limits abgeleitet wurde. Wenn Sie das PodTemplate Beispiel aus dem vorherigen Abschnitt verwenden, sollten5Reserveeinheiten angezeigt werden. Das ist die maximale Anzahl von Einheiten, die innerhalb der definierten Limits liegen.
Prozentuale Reserve konfigurieren
Wenn Sie eine prozentuale Reserve konfigurieren, wird die Größe der Reserve dynamisch basierend auf einem Prozentsatz einer vorhandenen skalierbaren Arbeitslast festgelegt. Prozentuale Kapazitätsreserven
werden nur für skalierbare Kubernetes-Objekte unterstützt, die die
Unterressource „scale“implementieren, z. B. Deployments, StatefulSets, ReplicaSets oder Jobs. Sie können keine prozentuale Reserve für Pod-Vorlagen definieren, da sie kein Feld replicas haben.
Wir empfehlen im Allgemeinen, mit Strategien für feste Replikate oder Ressourcenlimits zu beginnen und nicht mit prozentualen Reserven. Prozentuale Reserven reagieren weniger schnell auf plötzliche Skalierungen, wenn die Arbeitslast auf eine niedrige Anzahl oder null skaliert wird, da die Sicherheitsmarge proportional zu den aktiven Pods skaliert wird. Sie sind hauptsächlich für große Bereitstellungen nützlich, die nie auf eine sehr niedrige Anzahl von Replikaten skaliert werden.
So erstellen Sie eine prozentuale Reserve:
Speichern Sie das folgende Manifest als
cb-percentage-based.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: percentage-buffer namespace: NAMESPACE spec: scalableRef: apiGroup: apps kind: Deployment name: SCALABLE_RESOURCE_NAME percentage: 20 provisioningStrategy: "STRATEGY"Ersetzen Sie Folgendes:
NAMESPACE: Der Name Ihres Namespace.SCALABLE_RESOURCE_NAME: Der Name Ihrer skalierbaren Ressource, z. B.critical-workload-ref.STRATEGY: Die Bereitstellungsstrategie, entweder"buffer.x-k8s.io/active-capacity"(Standard) oder"buffer.gke.io/standby-capacity".
Dieses Manifest erstellt eine CapacityBuffer-Ressource, die eine Puffergröße anfordert, die 20% der Replikate der referenzierten Ressource entspricht. Wenn Sie das Deployment-Beispiel aus dem vorherigen Abschnitt verwenden, ist der Wert für die Replikate auf
10festgelegt.Wenden Sie das Manifest an:
kubectl apply -f cb-percentage-based.yamlPrüfen Sie, ob GKE die Kapazitätsreserve angewendet hat:
kubectl get capacitybuffer percentage-buffer -n NAMESPACEPrüfen Sie den Status des CapacityBuffer. Im Feld
replicassollte ein Wert aus der Prozentberechnung angezeigt werden. Wenn Sie das Deployment-Beispiel aus dem vorherigen Abschnitt verwenden, sollten2Reserveeinheiten angezeigt werden. Das entspricht 20% der 10 Replikate, die im Deployment definiert sind.Testen Sie die dynamische Skalierung, indem Sie das Deployment manuell auf 20 Replikate skalieren:
kubectl scale deployment critical-workload-ref -n NAMESPACE --replicas=20Der CapacityBuffer-Controller reagiert und skaliert die Reserve automatisch auf 4 Replikate.
Verhalten von Standby-Reserven anpassen
Mit Annotationen können Sie anpassen, wie Standby-Reserven gestartet und aktualisiert werden.
Fügen Sie diese Annotationen dem Feld metadata.annotations Ihrer CapacityBuffer-Ressource hinzu:
buffer.gke.io/standby-capacity-init-time: Die Zeit, die ein Knoten nach der Erstellung aktiv bleibt, bevor er angehalten wird. Das Format ist ein Dauerstring (z. B.5moder1h). Der Standardwert ist5m.buffer.gke.io/standby-capacity-refresh-frequency: Wie oft angehaltene Knoten aktualisiert werden. Der Standardwert ist24h.
Das folgende Beispiel zeigt ein Manifest mit diesen optionalen Feldern zum Anpassen des Verhaltens von Standby-Reserven:
apiVersion: autoscaling.x-k8s.io/v1beta1
kind: CapacityBuffer
metadata:
name: customized-standby-buffer
namespace: my-namespace
annotations:
buffer.gke.io/standby-capacity-init-time: "15m"
buffer.gke.io/standby-capacity-refresh-frequency: "12h"
spec:
podTemplateRef:
name: buffer-unit-template
replicas: 3
provisioningStrategy: "buffer.gke.io/standby-capacity"
Images in Standby-Reserven vorab laden
Um die Startzeiten von Arbeitslasten zu verkürzen, wenn ein Standby-Knoten fortgesetzt wird, können Sie Container-Images mit einem DaemonSet vorab laden. Das DaemonSet wird während der Startphase ausgeführt, bevor der Knoten angehalten wird.
So laden Sie Images mit dem DaemonSet vorab:
Speichern Sie das folgende Manifest als
image-puller-daemonset.yaml:apiVersion: apps/v1 kind: DaemonSet metadata: name: image-prefetch-daemonset namespace: NAMESPACE spec: selector: matchLabels: name: image-prefetch template: metadata: labels: name: image-prefetch spec: tolerations: - key: "buffer.gke.io/standby-node-suspended" operator: "Exists" initContainers: - name: image-puller image: IMAGE_NAME command: ["sh", "-c", "true"] containers: - name: pause image: registry.k8s.io/pause:3.9Ersetzen Sie Folgendes:
NAMESPACE: Der Namespace für das DaemonSet, z. B.capacity-buffer-example.IMAGE_NAME: Der Name des vorab zu ladenden Images, z. B.your-app-image:latest.
Wenden Sie das DaemonSet-Manifest auf Ihren Cluster an:
kubectl apply -f image-puller-daemonset.yamlPrüfen Sie, ob das DaemonSet erstellt wurde:
kubectl get daemonset image-prefetch-daemonset -n NAMESPACEPrüfen Sie, ob Ihre Kapazitätsreserve erstellt wurde und für die Bereitstellung bereit ist:
kubectl get capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACEPrüfen Sie den Status. Im Feld
STATUSsollteReadyForProvisioningangezeigt werden.
Status und Leistung von Kapazitätsreserven überwachen
Sie können den Status und die Leistung Ihrer Kapazitätsreserven mit kubectl-Befehlen und Cloud Monitoring-Messwerten überwachen.
Status der CapacityBuffer-Ressource prüfen
So prüfen Sie den Zustand Ihrer Kapazitätsreserven und vergewissern Sie sich, dass sie bereit sind, Arbeitslasten zu empfangen:
Rufen Sie den Status aller Kapazitätsreserven im Cluster ab:
kubectl get capacitybuffer -APrüfen Sie den detaillierten Status, die Bedingungen und die Ereignislogs einer bestimmten Reserve:
kubectl describe capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
Angehaltene Standby-Reserveknoten identifizieren
Standby-Reserve-VMs werden vorab bereitgestellt, aber angehalten, um Kosten zu senken. Sie erkennen diese angehaltenen Knoten an einer benutzerdefinierten Bedingung. Führen Sie den folgenden Befehl aus, um angehaltene Knoteninstanzen zu prüfen:
kubectl get nodes -o custom-columns='NAME:.metadata.name,SUSPENDED:.status.conditions[?(@.type=="Suspended")].status'
Der Status True gibt an, dass eine Standby-VM angehalten ist. Der Status False oder
<none> gibt einen aktiven, ausgeführten Knoten an.
Leistung mit Cloud Monitoring überwachen
Zur Überwachung der Leistung von Kapazitätsreserven sollten Sie die folgenden Ressourcen in Cloud Monitoring überwachen:
- Reaktionslatenz (
cluster_autoscaler/reaction_time_milliseconds) : Erfasst die Dauer, die der Cluster Autoscaler benötigt, um basierend auf der ausstehenden Nachfrage Ihres CapacityBuffer eine Skalierungsentscheidung zu treffen. - Cluster Autoscaler-Logs: Suchen Sie nach Logeinträgen wie
"Capacity pod processor injecting ...", um Ereignisse zum Ersetzen von aktiven Reserve-Pods zu beobachten.
Kapazitätsreserven entfernen
Wenn Sie eine Kapazitätsreserve für Ihre Arbeitslasten nicht mehr benötigen, löschen Sie das CapacityBuffer-Objekt. Dadurch werden die Platzhalter-Pods entfernt und der Cluster Autoscaler kann die Knoten herunterskalieren.
kubectl delete capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
Ersetzen Sie CAPACITY_BUFFER_NAME durch den Namen des CapacityBuffer, den Sie löschen möchten.
Fehlerbehebung
Im folgenden Abschnitt finden Sie Informationen zur Behebung häufiger Probleme mit Kapazitätsreserven.
Kapazitätsreserve aufgrund des Abrechnungsmodells nicht bereit
Wenn Sie einen CapacityBuffer für eine Arbeitslast erstellen, die das Pod-basierte Abrechnungsmodell (Pay-per-Pod) verwendet, ist die Kapazitätsreserve nicht bereit für die Bereitstellung.
So ermitteln Sie dieses Problem: Prüfen Sie den Status des CapacityBuffer:
kubectl describe capacitybuffer BUFFER_NAME -n NAMESPACE
Suchen Sie nach einer Bedingung vom Typ ReadyForProvisioning mit dem Status False.
Achten Sie zur Behebung dieses Problems darauf, dass Ihr CapacityBuffer auf eine Arbeitslast oder PodTemplate verweist, die mit der knotenbasierten Abrechnung kompatibel ist.
Berechtigungsfehler für benutzerdefinierte skalierbare Ressourcen
Wenn Sie einen CapacityBuffer für die Verwendung mit benutzerdefinierten skalierbaren Objekten konfigurieren (mit dem Feld scalableRef), kann der Cluster Autoscaler den Puffer möglicherweise nicht skalieren, wenn er nicht die erforderlichen Berechtigungen hat. Dieses Problem tritt nur in
GKE-Versionen vor 1.36.0-gke.2459000 auf.
Um dieses Problem zu beheben, gewähren Sie die erforderlichen Berechtigungen manuell, indem Sie
eine ClusterRole und eine ClusterRoleBinding erstellen, wie im folgenden
Beispiel:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: custom-scale-getter
rules:
- apiGroups: ["api.example.com"]
resources: ["customreplicatedresources/scale"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ca-custom-scale-getter
subjects:
- kind: User
name: "system:cluster-autoscaler"
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: custom-scale-getter
Weitere Informationen zum Konfigurieren von RBAC finden Sie in der Kubernetes RBAC-Dokumentation.
Reserve-Pods werden nicht auf Knoten geplant, die von benutzerdefinierten ComputeClasses bereitgestellt werden
Wenn Ihre CapacityBuffer-Konfigurationsabhängigkeit (z. B. eine PodTemplate) eine benutzerdefinierte ComputeClass auswählt, kann es vorkommen, dass Reserve-Pods nicht auf den neu bereitgestellten Knoten geplant werden. Dieses Problem führt dazu, dass der Cluster Autoscaler wiederholt redundante Knotenpools und Knoten erstellt, während inaktive Knoten gelöscht werden.
Dieses Problem tritt auf, wenn die benutzerdefinierte ComputeClass Knoten mit Markierungen oder bestimmten Laufzeitanforderungen bereitstellt und Ihre Reserve-Pods (oder die PodTemplate, auf die sie angewiesen sind) keine übereinstimmenden Toleranzen oder Einstellungen haben.
Aktualisieren Sie die CapacityBuffer-Konfiguration, um die erforderlichen Toleranzen, Knotenselektoren oder Laufzeitklassen anzugeben, um dieses Problem zu beheben. Wenn Ihre Abhängigkeit beispielsweise eine benutzerdefinierte ComputeClass auswählt, die mit GKE Sandbox konfiguriert ist, aktualisieren Sie die Abhängigkeit, um eine der folgenden Aktionen auszuführen:
- Geben Sie das Feld
spec.runtimeClassName: gvisoran. - Fügen Sie eine explizite Toleranz für die Markierung
sandbox.gke.io/runtime=gvisor:NoSchedulehinzu.
Weitere Informationen finden Sie in der Dokumentation zu benutzerdefinierten ComputeClasses.
Nächste Schritte
- Weitere Informationen zu Kapazitätsreserven.
- Dokumentation zur CapacityBuffer-CRD