Kapazitätsreserven konfigurieren

Kapazitätspuffer 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) namens „CapacityBuffer“ verwendet. Mit Kapazitätspuffern 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 Bereitstellung von Knoten 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ätspuffern beschrieben: ein Puffer mit fester Anzahl von Replikaten, ein Puffer mit Ressourcenlimits und ein prozentualer Puffer.

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 diesen Task 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 update Befehl ab. Ältere Versionen der gcloud CLI 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 Puffer und Version 1.36.0-gke.2253000 oder höher für Standby-Puffer 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 Puffer empfohlen und ist für Standby-Puffer 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 Pufferkapazitä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ätspuffer unterstützen jedoch alle folgenden Ressourcentypen:

    • Bereitstellung
    • ReplicaSet
    • StatefulSet
    • ReplicationController
    • Job
    • CustomResourceDefinitions (CRDs), die die Unterressource scale implementieren.

In diesem Abschnitt finden Sie Beispiele für diese Objekte. Wenn Sie bereits eine Arbeitslast haben, die Sie mit einem Kapazitätspuffer konfigurieren möchten, fahren Sie mit Kapazitätspuffer anwenden fort.

So erstellen Sie eine Beispielarbeitslast für Kubernetes:

  1. Speichern Sie das folgende Manifest als namespace.yaml:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: capacity-buffer-example
      labels:
        name: capacity-buffer-example
    

    Dieses Manifest erstellt einen Namespace namens capacity-buffer-example.

  2. Optional: Wenn Sie Kapazitätspuffer 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: true
    

    Dieses 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.

  3. 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-example
    

    Dieses Manifest erstellt eine PodTemplate, die die Ressourcenanforderungen für eine einzelne Einheit der Pufferkapazität (1 CPU und 1Gi Arbeitsspeicher) definiert. Diese Konfiguration gibt die Größe der Kapazitätseinheiten an, die GKE für den Puffer bereitstellt. Mit dieser PodTemplate berücksichtigt GKE beispielsweise keine Knoten mit weniger als 1 CPU und 1 GiB verfügbarer Ressourcen als Teil des Puffers, wenn der Cluster skaliert wird.

  4. 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-example
    

    Dieses Manifest erstellt ein Beispiel-Deployment mit 10 Replikaten. Es ist das Referenzobjekt für das prozentuale Pufferbeispiel im nächsten Abschnitt.

  5. 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.yaml
    
  6. Prüfen Sie, ob GKE die Objekte erstellt hat:

    kubectl get podtemplate -n capacity-buffer-example
    kubectl get deployment critical-workload-ref -n capacity-buffer-example
    

    Die 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ätspuffer anwenden

In diesem Abschnitt finden Sie Beispiele für die verschiedenen Arten von Kapazitätspuffern, die Sie auf Ihre Arbeitslasten anwenden können.

Puffer 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 Puffereinheiten basierend auf einer PodTemplate an.

So erstellen Sie einen Puffer mit einer festen Anzahl von Replikaten:

  1. 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 Puffereinheiten anzufordern.

  2. Wenden Sie das Manifest an:

    kubectl apply -f cb-fixed-replicas.yaml
    
  3. Prüfen Sie, ob GKE den Kapazitätspuffer angewendet hat:

    kubectl get capacitybuffer fixed-replica-buffer -n NAMESPACE
    

    Im Feld replicas des Status sollte 3 angezeigt werden. Dies entspricht der Anzahl der Replikate, die Sie im Manifest definiert haben. Im Feld STATUS sollte ReadyForProvisioning angezeigt werden.

Puffer mit Ressourcenlimits konfigurieren

Mit dem Feld limits können Sie eine maximale Menge an Ressourcen definieren, die der Puffer verbrauchen soll. Diese wird basierend auf der Größe Ihrer PodTemplate berechnet.

So erstellen Sie einen Puffer mit Ressourcenlimits:

  1. 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 1 CPU und 1Gi Arbeitsspeicher. Das Ergebnis sollten 5 Puffereinheiten sein.

  2. Wenden Sie das Manifest an:

    kubectl apply -f cb-resource-limits.yaml
    
  3. Prüfen Sie, ob GKE den Kapazitätspuffer angewendet hat:

    kubectl get capacitybuffer resource-limit-buffer -n NAMESPACE
    

    Prüfen Sie den Status des CapacityBuffer. Im Feld replicas sollte ein Wert angezeigt werden, der aus den von Ihnen definierten Limits abgeleitet wurde. Wenn Sie das PodTemplate Beispiel aus dem vorherigen Abschnitt verwenden, sollten 5 Puffereinheiten angezeigt werden. Das ist die maximale Anzahl von Einheiten, die innerhalb der definierten Limits liegen.

Prozentualen Puffer konfigurieren

Wenn Sie einen prozentualen Puffer konfigurieren, wird die Größe des Puffers dynamisch basierend auf einem Prozentsatz einer vorhandenen skalierbaren Arbeitslast angepasst. Prozentuale Kapazitätspuffer werden nur für skalierbare Kubernetes-Objekte unterstützt, die die Unterressource „scale“implementieren, z. B. Deployments, StatefulSets, ReplicaSets oder Jobs. Sie können keinen prozentualen Puffer 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 Puffern. Prozentuale Puffer 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 einen prozentualen Puffer:

  1. 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 10 festgelegt.

  2. Wenden Sie das Manifest an:

    kubectl apply -f cb-percentage-based.yaml
    
  3. Prüfen Sie, ob GKE den Kapazitätspuffer angewendet hat:

    kubectl get capacitybuffer percentage-buffer -n NAMESPACE
    

    Prüfen Sie den Status des CapacityBuffer. Im Feld replicas sollte ein Wert aus der Prozentberechnung angezeigt werden. Wenn Sie das Deployment-Beispiel aus dem vorherigen Abschnitt verwenden, sollten 2 Puffereinheiten angezeigt werden. Das sind 20% der 10 Replikate, die im Deployment definiert sind.

  4. Testen Sie die dynamische Skalierung, indem Sie das Deployment manuell auf 20 Replikate skalieren:

    kubectl scale deployment critical-workload-ref -n NAMESPACE --replicas=20
    

    Der CapacityBuffer-Controller reagiert und skaliert den Puffer automatisch auf 4 Replikate.

Verhalten von Standby-Puffern anpassen

Mit Annotationen können Sie anpassen, wie Standby-Puffer 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. 5m oder 1h). Der Standardwert ist 5m.
  • buffer.gke.io/standby-capacity-refresh-frequency: Wie oft angehaltene Knoten aktualisiert werden. Der Standardwert ist 1d.

Das folgende Beispiel zeigt ein Manifest mit diesen optionalen Feldern zum Anpassen des Verhaltens von Standby-Puffern:

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"

Bilder in Standby-Puffer 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 Bilder mit dem DaemonSet vorab:

  1. 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.9
    

    Ersetzen Sie Folgendes:

    • NAMESPACE: Der Namespace für das DaemonSet, z. B. capacity-buffer-example.
    • IMAGE_NAME: Der Name des vorab zu ladenden Bildes, z. B. your-app-image:latest.
  2. Wenden Sie das DaemonSet-Manifest auf Ihren Cluster an:

    kubectl apply -f image-puller-daemonset.yaml
    
  3. Prüfen Sie, ob das DaemonSet erstellt wurde:

    kubectl get daemonset image-prefetch-daemonset -n NAMESPACE
    
  4. Prüfen Sie, ob Ihr Kapazitätspuffer erstellt wurde und für die Bereitstellung bereit ist:

    kubectl get capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
    

    Prüfen Sie den Status. Im Feld STATUS sollte ReadyForProvisioning angezeigt werden.

Status und Leistung von Kapazitätspuffern überwachen

Sie können den Status und die Leistung Ihrer Kapazitätspuffer mit kubectl-Befehlen und Cloud Monitoring-Messwerten überwachen.

Status der CapacityBuffer-Ressource prüfen

So prüfen Sie den Zustand Ihrer Kapazitätspuffer und vergewissern sich, dass sie bereit sind, Arbeitslasten zu empfangen:

  1. Rufen Sie den Status aller Kapazitätspuffer im Cluster ab:

    kubectl get capacitybuffer -A
    
  2. Prüfen Sie den detaillierten Status, die Bedingungen und die Ereignislogs eines bestimmten Puffers:

    kubectl describe capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
    

Angehaltene Standby-Pufferknoten identifizieren

Standby-Puffer-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'

Ein Status von True gibt an, dass eine Standby-VM angehalten ist. Ein Status von False oder <none> gibt einen aktiven, ausgeführten Knoten an.

Leistung mit Cloud Monitoring überwachen

Um die Leistung von Kapazitätspuffern zu überwachen, beobachten Sie die folgenden Ressourcen in Cloud Monitoring:

  • Reaktionslatenz (cluster_autoscaler/reaction_time_milliseconds) : Erfasst die Zeit, 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 Puffer-Pods zu beobachten.

Kapazitätspuffer entfernen

Wenn Sie keinen Kapazitätspuffer mehr für Ihre Arbeitslasten 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ätspuffern.

Kapazitätspuffer aufgrund des Abrechnungsmodells nicht bereit

Wenn Sie einen CapacityBuffer für eine Arbeitslast erstellen, die das Pod-basierte Abrechnungsmodell (Pay-per-Pod) verwendet, ist der Kapazitätspuffer 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.

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.

Nächste Schritte