<img src="https://secure.leadforensics.com/807076.png" style="display:none;">
Zu Content springen
Deutsch
  • Es gibt keine Vorschläge, da das Suchfeld leer ist.

How to: Kubernetes Cluster Autoscaler installieren, verwenden und debuggen

Erfahren Sie in dieser Dokumentation, wie Sie den Xelon Kubernetes Autoscaler installieren, verwenden und debuggen können.

Was ist der Kubernetes Cluster Autoscaler?

Der Kubernetes Cluster Autoscaler erweitert die üblichen Möglichkeiten des Autoscalings. Standardmässig unterstützt Kubernetes nur die Skalierung von Workloads, was dem Hinzufügen oder Entfernen von Pods entspricht. Damit lassen sich die vorhandenen Cluster-Ressourcen zwar neu verteilen, die Menge der Ressourcen in einem Cluster lässt sich so aber nicht verändern. Möchten Sie die Ressourcen anhand der aktuellen Auslastung erhöhen oder verringern, müssten Sie dies manuell durch das Hinzufügen oder Entfernen von Nodes tun.

Genau hier kommt der Cluster Autoscaler ins Spiel: Gibt es aufgrund von Ressourcenengpässen nicht planbare (unschedulable) Pods, kann er einen weiteren Node hinzufügen. Ist die durchschnittliche Node-Auslastung zu niedrig und lässt es Ihr Workload zu, kann man Nodes auch wieder entfernen. Das verbessert Ihre Kosteneffizienz, weil Compute-Leistung nur während der Spitzenzeiten hinzugefügt wird.

Quell-Repository: https://github.com/Xelon-AG/autoscaler

Wie wird der Xelon Kubernetes Cluster Autoscaler installiert und konfiguriert?

Bevor Sie den Xelon Kubernetes Cluster Autoscaler installieren können, müssen Sie Ihren Cluster auf die Kubernetes-Version 1.35 oder höher aktualisieren.

Wie erhalte ich die Pool-IDs?

Sie benötigen die ID des Node Pools, den Sie skalieren möchten. Um sie zu ermitteln, können Sie wie folgt einen temporären Debug-Pod erstellen:

kubectl -n kube-system run xelon-probe --rm -it --restart=Never \
  --image=alpine:latest \
  --overrides='{
    "spec": {
      "containers": [{
        "name": "xelon-probe",
        "image": "alpine:latest",
        "stdin": true, "tty": true,
        "env": [
          {"name": "XELON_API_URL",    "value": "https://hq.xelon.ch/api/v2"},
          {"name": "XELON_CLIENT_ID", "valueFrom": {"secretKeyRef": {"name": "xelon-api-credentials", "key": "clientId"}}},
          {"name": "XELON_CLUSTER_ID","valueFrom": {"secretKeyRef": {"name": "xelon-api-credentials", "key": "kubernetesClusterId"}}},
          {"name": "XELON_TOKEN",     "valueFrom": {"secretKeyRef": {"name": "xelon-api-credentials", "key": "token"}}}
        ]
      }]
    }
  }' -- ash

Und anschliessend können Sie so die Liste der Worker Pools in Ihrem Cluster abrufen:

apk add curl jq
curl -fsS "${XELON_API_URL}/kubernetes/${XELON_CLUSTER_ID}/pools" \
  -H "Authorization: Bearer ${XELON_TOKEN}" \
  -H "X-User-Id: ${XELON_CLIENT_ID}" |
jq -r '.[] | [.identifier, .name, (.nodes | length)] | @tsv'

Wie erfolgt die Installation mit Kustomize?

Wir empfehlen die Installation mit Kustomize, damit Sie künftig durch einfaches Wechseln des Tags unkompliziert aktualisieren können. Verwenden Sie unbedingt das Autoscaler-Release, das Ihrer Kubernetes-Version am nächsten kommt.

kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - https://raw.githubusercontent.com/Xelon-AG/autoscaler/v1.35.2-xelon.2/cluster-autoscaler/cloudprovider/xelon/examples/cluster-autoscaler.yaml

patches:
  - target:
      group: apps
      version: v1
      kind: Deployment
      name: xelon-cluster-autoscaler
      namespace: kube-system
    patch: |-
      - op: replace
        path: /spec/template/spec/containers/0/args/1
        value: --nodes=3:5:pt3s8gen7g
      - op: replace
        path: /spec/template/spec/containers/0/env/0
        value:
          name: XELON_BASE_URL
          value: https://hq.xelon.ch/api/v2/

Passen Sie unbedingt den ersten Patch an Ihre Bedürfnisse an: --nodes=<min nodes>:<max nodes>:<pool ID> Das Beispiel skaliert den Node Pool "pt3s8gen7g" zwischen 3 und 5 Nodes.

Was sind Skalierungsbedingungen?

Die Skalierungsbedingungen können an Ihre Bedürfnisse angepasst werden. Die folgenden beiden Abschnitte erläutern die aktuellen Standardwerte und das Verhalten.

Hochskalieren (Scale up)

Ein neuer Node wird hinzugefügt, wenn ein Pod nicht planbar ist – weil der kube-scheduler PodScheduled=False mit Reason=Unschedulable gesetzt hat – und der Pod unter keinen der unten aufgeführten Filter fällt:

Filter Verwirft
Expendable Priorität unterhalb von --expendable-pods-priority-cutoff (Standard -10)
Bereits planbar Pods, die per Bin-Packing auf bestehende oder in Kürze verfügbare Kapazität passen
DaemonSet DS-Pods, ein neuer Node hilft ihnen nicht

Der Filter "bereits planbar" ist der Grund, weshalb ein wartender Pod manchmal kein Hochskalieren auslöst: Der CA hat Kapazität auf einem Node mitgezählt, der noch bereitgestellt wird.

Herunterskalieren (Scale down)

Ein Node wird erst entfernt, nachdem er sechs aufeinanderfolgende Prüfungen (Gates) bestanden hat. Fällt er bei einer davon durch, wird die Uhr in Gate 5 zurückgesetzt.

Gate 1: Loop aktiviert und nicht in der Cooldown-Phase
Bedingung Flag Standard
Scale-down aktiviert --scale-down-enabled true
Kein kürzliches Scale-up --scale-down-delay-after-add 10m
Kein kürzlich fehlgeschlagenes Scale-down --scale-down-delay-after-failure 3m
Kein kürzliches Löschen --scale-down-delay-after-delete 0s
Gate 2: Vorfilterung der Kandidaten
  • Der Node gehört zu einer autoskalierten Node Group.
  • Die Group liegt über ihrer MinSize(). Mit --nodes=1:4 ist der letzte Node nie ein Kandidat.
Gate 3: Eignung
  • Wird nicht bereits gelöscht (kein ToBeDeletedByClusterAutoscaler-Taint).
  • Keine Annotation cluster-autoscaler.kubernetes.io/scale-down-disabled: "true".
  • Falls nicht bereit (unready): --scale-down-unready-enabled (Standard true) muss aktiviert sein.
  • Auslastung auf oder unterhalb von --scale-down-utilization-threshold (Standard 0.5).

Auslastung bedeutet hier Ressourcen-Requests geteilt durch Allocatable – nicht die tatsächliche CPU-/Speichernutzung. Ein Node mit 5 % realer Speichernutzung, dessen Pods aber 90 % des Allocatable anfordern, wird nie heruntergesteuert. Das ist mit Abstand die häufigste Überraschung. Die entsprechende Logzeile bei -v=4 lautet:

Node prod-w-1-1 unremovable: memory requested (93.2809% of allocatable) is above the scale-down utilization threshold

 

DaemonSet- und Mirror-Pods können über --ignore-daemonsets-utilization und --ignore-mirror-pods-utilization von der Berechnung ausgeschlossen werden.

Gate 4: Simulation

Jeder Pod auf dem Node muss:

  1. Drainbar sein (kein blockierendes PodDisruptionBudget, kein kube-system-Pod ohne PDB, kein Pod ohne Controller, kein lokaler Speicher, ausser er ist mit safe-to-evict annotiert) – andernfalls Node X cannot be removed: …
  2. Anderswo Platz finden – andernfalls Node X is not suitable for removal (Grund NoPlaceToMovePods)

Die Simulation ist durch --scale-down-simulation-timeout (30s) begrenzt.

Gate 5: Lange genug nicht benötigt
Node-Status Flag Standard
Ready --scale-down-unneeded-time 10m
Unready --scale-down-unready-time 20m

Die Uhr wird jedes Mal zurückgesetzt, wenn ein Node in einem Durchlauf bei einem Gate durchfällt. Ein Node, dessen Auslastung alle paar Minuten über den Schwellenwert springt, erreicht nie zehn zusammenhängende Minuten. Nachverfolgen können Sie das mit:

kubectl logs -n kube-system deploy/xelon-cluster-autoscaler | grep "was unneeded for" 
Gate 6: Mindestgrösse und Ressourcenuntergrenze
  • Die Grösse der Group abzüglich der bereits laufenden Löschvorgänge muss über MinSize() bleiben.
  • Das Entfernen des Nodes darf den Cluster nicht unter die Mindestwerte von --cores-total / --memory-total fallen lassen.

Wie wird der Autoscaler debuggt?

Das Debugging des Autoscalers ist einfach: Verfolgen Sie einfach die Logs und prüfen Sie, was zwischen den "Starting main loop"-Meldungen passiert.

kubectl logs -f -n kube-system deploy/xelon-cluster-autoscaler 

Tipp: Wenn Sie einen Pod haben, der gefahrlos evakuiert werden kann, obwohl er nicht zu einem redundanten ReplicaSet gehört, können Sie die folgende Annotation verwenden:

cluster-autoscaler.kubernetes.io/safe-to-evict: "true"