Dieses Dokument wurde mithilfe automatisierter maschineller Übersetzungstechnologie übersetzt. Wir bemühen uns um korrekte Übersetzungen, übernehmen jedoch keine Gewähr für die Vollständigkeit, Richtigkeit oder Zuverlässigkeit der übersetzten Inhalte. Im Falle von Abweichungen ist die englische Originalversion maßgebend und stellt den verbindlichen Text dar.

Cluster Autoscaler mit AWS EC2 Auto Scaling-Gruppen

Dieser Leitfaden zeigt Ihnen, wie Sie Kubernetes cluster-autoscaler auf benutzerdefinierten Rancher-Clustern mit AWS EC2 Auto Scaling-Gruppen installieren und verwenden.

Wir werden ein benutzerdefiniertes Rancher RKE2-Cluster mit einer festen Anzahl von Knoten mit den Rollen etcd und controlplane sowie einer variablen Anzahl von Knoten mit der Rolle worker installieren, verwaltet von cluster-autoscaler.

Voraussetzungen

Diese Elemente sind erforderlich, um diesem Leitfaden zu folgen:

  • Der Rancher-Server ist betriebsbereit

  • Sie haben einen AWS EC2-Benutzer mit den entsprechenden Berechtigungen zum Erstellen von virtuellen Maschinen, Auto Scaling-Gruppen und IAM-Profilen und -Rollen

1. Erstellen Sie ein benutzerdefiniertes Cluster

Auf dem Rancher-Server sollten wir ein benutzerdefiniertes k8s-Cluster erstellen. Verweisen Sie hier, um die Versionskompatibilität zu überprüfen.

Stellen Sie sicher, dass der Name des Cloud-Anbieters auf amazonec2 gesetzt ist. Sobald das Cluster erstellt ist, müssen wir Folgendes erhalten:

  • clusterID: c-xxxxx wird auf dem EC2 kubernetes.io/cluster/<clusterID> Instanz-Tag verwendet

  • clusterName: wird auf dem EC2 k8s.io/cluster-autoscaler/<clusterName> Instanz-Tag verwendet

  • nodeCommand: wird in den EC2 Instanz user_data hinzugefügt, um neue Knoten zum Cluster hinzuzufügen

      sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:<RANCHER_VERSION> --server https://<RANCHER_URL> --token <RANCHER_TOKEN> --ca-checksum <RANCHER_CHECKSUM> <roles>

2. Konfigurieren Sie den Cloud-Anbieter

Auf AWS EC2 sollten wir einige Objekte erstellen, um unser System zu konfigurieren. Wir haben drei verschiedene Gruppen und IAM-Profile definiert, die auf AWS konfiguriert werden sollen.

  1. Autoscaling-Gruppe: Knoten, die Teil der EC2 Auto Scaling-Gruppe (ASG) sein werden. Die ASG wird von cluster-autoscaler verwendet, um hoch- und herunterzuskalieren.

    • IAM-Profil: Erforderlich für k8s-Knoten, auf denen der Cluster-Autoscaler ausgeführt wird. Es wird für Kubernetes-Masterknoten empfohlen. Dieses Profil wird K8sAutoscalerProfile genannt.

       {
           "Version": "2012-10-17",
           "Statement": [
               {
                   "Effect": "Allow",
                   "Action": [
                       "autoscaling:DescribeAutoScalingGroups",
                       "autoscaling:DescribeAutoScalingInstances",
                       "autoscaling:DescribeLaunchConfigurations",
                       "autoscaling:SetDesiredCapacity",
                       "autoscaling:TerminateInstanceInAutoScalingGroup",
                       "autoscaling:DescribeTags",
                       "autoscaling:DescribeLaunchConfigurations",
                       "ec2:DescribeLaunchTemplateVersions"
                   ],
                   "Resource": [
                       "*"
                   ]
               }
           ]
       }
  2. Master-Gruppe: Knoten, die Teil der Kubernetes etcd- und/oder Steuerungsebenen sein werden. Dies wird außerhalb der ASG sein.

    • IAM-Profil: Erforderlich für die Kubernetes-Cloud-Provider-Integration. Optional können AWS_ACCESS_KEY und AWS_SECRET_KEY anstelle von using-aws-credentials. verwendet werden. Dieses Profil wird K8sMasterProfile genannt.

       {
           "Version": "2012-10-17",
           "Statement": [
               {
                   "Effect": "Allow",
                   "Action": [
                       "autoscaling:DescribeAutoScalingGroups",
                       "autoscaling:DescribeLaunchConfigurations",
                       "autoscaling:DescribeTags",
                       "ec2:DescribeInstances",
                       "ec2:DescribeRegions",
                       "ec2:DescribeRouteTables",
                       "ec2:DescribeSecurityGroups",
                       "ec2:DescribeSubnets",
                       "ec2:DescribeVolumes",
                       "ec2:CreateSecurityGroup",
                       "ec2:CreateTags",
                       "ec2:CreateVolume",
                       "ec2:ModifyInstanceAttribute",
                       "ec2:ModifyVolume",
                       "ec2:AttachVolume",
                       "ec2:AuthorizeSecurityGroupIngress",
                       "ec2:CreateRoute",
                       "ec2:DeleteRoute",
                       "ec2:DeleteSecurityGroup",
                       "ec2:DeleteVolume",
                       "ec2:DetachVolume",
                       "ec2:RevokeSecurityGroupIngress",
                       "ec2:DescribeVpcs",
                       "elasticloadbalancing:AddTags",
                       "elasticloadbalancing:AttachLoadBalancerToSubnets",
                       "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
                       "elasticloadbalancing:CreateLoadBalancer",
                       "elasticloadbalancing:CreateLoadBalancerPolicy",
                       "elasticloadbalancing:CreateLoadBalancerListeners",
                       "elasticloadbalancing:ConfigureHealthCheck",
                       "elasticloadbalancing:DeleteLoadBalancer",
                       "elasticloadbalancing:DeleteLoadBalancerListeners",
                       "elasticloadbalancing:DescribeLoadBalancers",
                       "elasticloadbalancing:DescribeLoadBalancerAttributes",
                       "elasticloadbalancing:DetachLoadBalancerFromSubnets",
                       "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                       "elasticloadbalancing:ModifyLoadBalancerAttributes",
                       "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                       "elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer",
                       "elasticloadbalancing:AddTags",
                       "elasticloadbalancing:CreateListener",
                       "elasticloadbalancing:CreateTargetGroup",
                       "elasticloadbalancing:DeleteListener",
                       "elasticloadbalancing:DeleteTargetGroup",
                       "elasticloadbalancing:DescribeListeners",
                       "elasticloadbalancing:DescribeLoadBalancerPolicies",
                       "elasticloadbalancing:DescribeTargetGroups",
                       "elasticloadbalancing:DescribeTargetHealth",
                       "elasticloadbalancing:ModifyListener",
                       "elasticloadbalancing:ModifyTargetGroup",
                       "elasticloadbalancing:RegisterTargets",
                       "elasticloadbalancing:SetLoadBalancerPoliciesOfListener",
                       "iam:CreateServiceLinkedRole",
                       "ecr:GetAuthorizationToken",
                       "ecr:BatchCheckLayerAvailability",
                       "ecr:GetDownloadUrlForLayer",
                       "ecr:GetRepositoryPolicy",
                       "ecr:DescribeRepositories",
                       "ecr:ListImages",
                       "ecr:BatchGetImage",
                       "kms:DescribeKey"
                   ],
                   "Resource": [
                       "*"
                   ]
               }
           ]
       }
    • IAM-Rolle: K8sMasterRole: [K8sMasterProfile,K8sAutoscalerProfile].

    • Sicherheitsgruppe: K8sMasterSg. Weitere Informationen unter RKE2-Ports (Registerkarte benutzerdefinierte Knoten)

    • Tags: kubernetes.io/cluster/<clusterID>: owned

    • Benutzerdaten: K8sMasterUserData Ubuntu 18.04(ami-0e11cbb34015ff725), installiert Docker und fügt einen etcd+controlplane-Knoten zum K8s-Cluster hinzu.

      #!/bin/bash -x
      
      cat <<EOF > /etc/sysctl.d/90-kubelet.conf
      vm.overcommit_memory = 1
      vm.panic_on_oom = 0
      kernel.panic = 10
      kernel.panic_on_oops = 1
      kernel.keys.root_maxkeys = 1000000
      kernel.keys.root_maxbytes = 25000000
      EOF
      sysctl -p /etc/sysctl.d/90-kubelet.conf
      
      curl -sL https://releases.rancher.com/install-docker/19.03.sh | sh
      sudo usermod -aG docker ubuntu
      
      TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
      PRIVATE_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/local-ipv4)
      PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/public-ipv4)
      K8S_ROLES="--etcd --controlplane"
      
      sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:<RANCHER_VERSION> --server https://<RANCHER_URL> --token <RANCHER_TOKEN> --ca-checksum <RANCHER_CA_CHECKSUM> --address ${PUBLIC_IP} --internal-address ${PRIVATE_IP} ${K8S_ROLES}
  3. Worker-Gruppe: Knoten, die Teil der K8s-Worker-Ebene sein werden. Worker-Knoten werden vom Cluster-Autoscaler mithilfe der ASG skaliert.

    • IAM-Profil: Bietet die Integration des Cloud-Anbieters für Worker. Dieses Profil wird K8sWorkerProfile genannt.

       {
           "Version": "2012-10-17",
           "Statement": [
               {
                   "Effect": "Allow",
                   "Action": [
                       "ec2:DescribeInstances",
                       "ec2:DescribeRegions",
                       "ecr:GetAuthorizationToken",
                       "ecr:BatchCheckLayerAvailability",
                       "ecr:GetDownloadUrlForLayer",
                       "ecr:GetRepositoryPolicy",
                       "ecr:DescribeRepositories",
                       "ecr:ListImages",
                       "ecr:BatchGetImage"
                   ],
                   "Resource": "*"
               }
           ]
       }
    • IAM-Rolle: K8sWorkerRole: [K8sWorkerProfile].

    • Sicherheitsgruppe: K8sWorkerSg Weitere Informationen unter RKE2-Ports (Registerkarte benutzerdefinierte Knoten).

    • Tags:

      • kubernetes.io/cluster/<clusterID>: owned

      • k8s.io/cluster-autoscaler/<clusterName>: true

      • k8s.io/cluster-autoscaler/enabled: true

    • Benutzerdaten: K8sWorkerUserData Ubuntu 18.04(ami-0e11cbb34015ff725), installiert Docker und fügt den Worker-Knoten zum K8s-Cluster hinzu.

        #!/bin/bash -x
      
        cat <<EOF > /etc/sysctl.d/90-kubelet.conf
        vm.overcommit_memory = 1
        vm.panic_on_oom = 0
        kernel.panic = 10
        kernel.panic_on_oops = 1
        kernel.keys.root_maxkeys = 1000000
        kernel.keys.root_maxbytes = 25000000
        EOF
        sysctl -p /etc/sysctl.d/90-kubelet.conf
      
        curl -sL https://releases.rancher.com/install-docker/19.03.sh | sh
        sudo usermod -aG docker ubuntu
      
        TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
        PRIVATE_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/local-ipv4)
        PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/public-ipv4)
        K8S_ROLES="--worker"
      
        sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:<RANCHER_VERSION> --server https://<RANCHER_URL> --token <RANCHER_TOKEN> --ca-checksum <RANCHER_CA_CHECKCSUM> --address ${PUBLIC_IP} --internal-address ${PRIVATE_IP} ${K8S_ROLES}

Weitere Informationen finden Sie unter RKE2-Cluster auf AWS und Cluster Autoscaler auf AWS.

3. Knoten bereitstellen

Nachdem wir AWS konfiguriert haben, lassen Sie uns VMs erstellen, um unseren Cluster zu initialisieren:

  • Master (etcd+controlplane): Stellen Sie je nach Ihren Bedürfnissen drei Master-Instanzen mit der richtigen Größe bereit. Weitere Informationen finden Sie unter die Empfehlungen für produktionsbereite Cluster.

    • IAM-Rolle: K8sMasterRole

    • Sicherheitsgruppe: K8sMasterSg

    • Tags:

      • kubernetes.io/cluster/<clusterID>: owned

    • Benutzerdaten: K8sMasterUserData

  • Worker: Definieren Sie eine ASG auf EC2 mit den folgenden Einstellungen:

    • Name: K8sWorkerAsg

    • IAM-Rolle: K8sWorkerRole

    • Sicherheitsgruppe: K8sWorkerSg

    • Tags:

      • kubernetes.io/cluster/<clusterID>: owned

      • k8s.io/cluster-autoscaler/<clusterName>: true

      • k8s.io/cluster-autoscaler/enabled: true

    • Benutzerdaten: K8sWorkerUserData

    • Instanzen:

      • minimum: 2

      • gewünscht: 2

      • maximum: 10

Sobald die VMs bereitgestellt sind, sollten Sie einen benutzerdefinierten Rancher-Cluster mit drei Master- und zwei Worker-Knoten in Betrieb haben.

4. Cluster-Autoscaler installieren

An diesem Punkt sollten wir den Rancher-Cluster in Betrieb haben. Wir werden den Cluster-Autoscaler auf den Master-Knoten und im kube-system Namespace installieren, gemäß den Empfehlungen des Cluster-Autoscalers.

Parameter

Diese Tabelle zeigt die Parameter des Cluster-Autoscalers zur Feinabstimmung:

Parameter Standard Beschreibung

Cluster-Name

-

Name des automatisch skalierenden Clusters, falls verfügbar

Adresse

:8085

Die Adresse zur Bereitstellung von Prometheus-Metriken

kubernetes

-

Standort des Kubernetes-Masters. Für Standard leer lassen

kubeconfig

-

Pfad zur kubeconfig-Datei mit Autorisierungs- und Standortinformationen des Masters

cloud-config

-

Der Pfad zur Konfigurationsdatei des Cloud-Anbieters. Leerer String für keine Konfigurationsdatei

namespace

"kube-system"

Namespace, in dem der Cluster-Autoscaler läuft

Herunterskalierung aktiviert

true

Soll der CA den Cluster herunterskalieren?

Verzögerung der Herunterskalierung nach Hinzufügen

"10m"

Wie lange nach der Skalierung nach oben, bis die Bewertung der Herunterskalierung wieder aufgenommen wird

Skalierungsverzögerung nach Löschung

0

Wie lange nach der Knotenlöschung die Bewertung der Herunterskalierung wieder aufgenommen wird, standardmäßig entspricht dies dem scanInterval

Verzögerung der Herunterskalierung nach Fehler

"3m"

Wie lange nach einem Fehlschlag der Herunterskalierung wird die Bewertung der Herunterskalierung wieder aufgenommen?

Zeit, bis ein Knoten ungenutzt ist, bevor er für die Herunterskalierung in Betracht gezogen wird

"10m"

Wie lange ein Knoten ungenutzt sein sollte, bevor er für das Herunterskalieren in Frage kommt

scale-down-unready-time

"20m"

Wie lange ein nicht bereiter Knoten ungenutzt sein sollte, bevor er für das Herunterskalieren in Frage kommt

Schwellenwert für die Auslastung bei der Herunterskalierung

50 %

Summe von CPU oder Speicher aller Pods, die auf dem Knoten laufen, geteilt durch die entsprechende zuweisbare Ressource des Knotens, unterhalb derer ein Knoten für das Herunterskalieren in Betracht gezogen werden kann

scale-down-gpu-utilization-threshold

50 %

Summe der GPU-Anforderungen aller Pods, die auf dem Knoten laufen, geteilt durch die zuweisbare Ressource des Knotens, unterhalb derer ein Knoten für die Herunterskalierung in Betracht gezogen werden kann

Anzahl der nicht leeren Kandidaten für das Herunterskalieren

30

Maximale Anzahl von nicht leeren Knoten, die in einer Iteration als Kandidaten für das Herunterskalieren mit Entleerung in Betracht gezogen werden

scale-down-candidates-pool-ratio

10 %

Ein Verhältnis von Knoten, die als zusätzliche nicht leere Kandidaten für das Herunterskalieren in Betracht gezogen werden, wenn einige Kandidaten aus der vorherigen Iteration nicht mehr gültig sind

scale-down-candidates-pool-min-count

50

Mindestanzahl von Knoten, die als zusätzliche nicht leere Kandidaten für das Herunterskalieren betrachtet werden, wenn einige Kandidaten aus der vorherigen Iteration nicht mehr gültig sind

node-deletion-delay-timeout

"2m"

Maximale Zeit, die der CA wartet, um die Annotationen delay-deletion.cluster-autoscaler.kubernetes.io/ zu entfernen, bevor der Knoten gelöscht wird

scan-interval

"10s"

Wie oft der Cluster auf Skalierung nach oben oder unten neu bewertet wird

max-nodes-total

0

Maximale Anzahl von Knoten in allen Knotengruppen. Der Cluster-Autoscaler wird den Cluster über diese Anzahl hinaus nicht vergrößern

cores-total

"0:320000"

Mindest- und Höchstanzahl von Kernen im Cluster, im Format <min>:<max>. Der Cluster-Autoscaler wird den Cluster über diese Zahlen hinaus nicht skalieren

memory-total

"0:6400000"

Mindest- und Höchstanzahl von Gigabyte Speicher im Cluster, im Format <min>:<max>. Der Cluster-Autoscaler wird den Cluster über diese Zahlen hinaus nicht skalieren

cloud-provider

-

Cloud-Anbieter-Typ

max-bulk-soft-taint-count

10

Maximale Anzahl von Knoten, die gleichzeitig getaint/untaint PreferNoSchedule sein können. Auf 0 setzen, um solches Tainting auszuschalten

max-bulk-soft-taint-time

"3s"

Maximale Dauer der Tainting/Untainting von Knoten als PreferNoSchedule zur gleichen Zeit

max-empty-bulk-delete

10

Maximale Anzahl leerer Knoten, die gleichzeitig gelöscht werden können

max-graceful-termination-sec

600

Maximale Anzahl von Sekunden, die CA auf die Beendigung des Pods wartet, wenn versucht wird, einen Knoten herunterzuskalieren

max-total-unready-percentage

45

Maximaler Prozentsatz unbereiter Knoten im Cluster. Wenn dieser überschritten wird, stoppt CA die Operationen

ok-total-unready-count

3

Anzahl der erlaubten unbereiten Knoten, unabhängig vom max-total-unready-percentage

scale-up-from-zero

true

Soll CA hochskalieren, wenn es 0 bereite Knoten gibt

max-node-provision-time

"15m"

Maximale Zeit, die CA darauf wartet, dass ein Knoten bereitgestellt wird.

Knoten

-

Legt die minimale, maximale Größe und andere Konfigurationsdaten für eine Knotengruppe in einem vom Cloud-Anbieter akzeptierten Format fest. Kann mehrfach verwendet werden. Format: <min>:<max>:<other…​>

node-group-auto-discovery

-

Eine oder mehrere Definition(en) der automatischen Erkennung von Knotengruppen. Eine Definition wird ausgedrückt <name of discoverer>:[<key>[=<value>]]

Schätzer

"binpacking"

Art des Ressourcenschätzers, der beim Hochskalieren verwendet werden soll. Verfügbare Werte: ["binpacking"]

expander

"random"

Art des Node-Group-Expanders, der beim Hochskalieren verwendet werden soll. Verfügbare Werte: ["random","most-pods","least-waste","price","priority"]

ignore-daemonsets-utilization

false

Soll CA DaemonSet-Pods bei der Berechnung der Ressourcennutzung für das Herunterskalieren ignorieren?

ignore-mirror-pods-utilization

false

Soll CA Mirror-Pods bei der Berechnung der Ressourcennutzung für das Herunterskalieren ignorieren?

write-status-configmap

true

Soll CA Statusinformationen in eine ConfigMap schreiben?

max-inactivity

"10m"

Maximale Zeit seit der letzten aufgezeichneten Aktivität des Autoscalers vor dem automatischen Neustart.

max-failing-time

"15m"

Maximale Zeit seit dem letzten aufgezeichneten erfolgreichen Lauf des Autoscalers vor dem automatischen Neustart.

balance-similar-node-groups

false

Ähnliche Knotengruppen erkennen und die Anzahl der Knoten zwischen ihnen ausgleichen

Knoten-Autoprovisionierung-aktiviert

false

Soll CA Knotengruppen bei Bedarf autoprovisionieren

max-autoprovisioned-node-group-count

15

Die maximale Anzahl autoprovisionierter Knotengruppen im Cluster

unremovable-node-recheck-timeout

"5m"

Die Zeitüberschreitung, bevor wir einen Knoten erneut überprüfen, der zuvor nicht entfernt werden konnte

expendable-pods-priority-cutoff

-10

Pods mit einer Priorität unterhalb der Grenze sind verzichtbar. Sie können während des Herunterskalierens ohne Rücksicht getötet werden und verursachen kein Hochskalieren. Pods mit null Priorität (PodPriority deaktiviert) sind nicht verzichtbar

regional

false

Cluster ist regional

new-pod-scale-up-delay

"0s"

Pods, die jünger als dieser Wert sind, werden nicht für das Hochskalieren berücksichtigt.

taint-ignorieren

-

Gibt einen Taint an, der in Knotenvorlagen ignoriert werden soll, wenn man in Betracht zieht, eine Knotengruppe zu skalieren

balancing-ignore-label

-

Gibt ein Label an, das zusätzlich zu den grundlegenden und cloudanbieter-spezifischen Labels ignoriert werden soll, wenn verglichen wird, ob zwei Knoten-Gruppen ähnlich sind

aws-use-static-instance-list

false

Soll CA Instanztypen zur Laufzeit abrufen oder eine statische Liste verwenden? Nur AWS

Profilerstellung

false

Ist der Debug/pprof-Endpunkt aktiviert?

Bereitstellung

Basierend auf dem cluster-autoscaler-run-on-control-plane.yaml-Beispiel haben wir unser eigenes cluster-autoscaler-deployment.yaml erstellt, um das bevorzugte auto-discovery setup zu verwenden, indem wir Toleranzen, nodeSelector, die Bildversion und die Befehlskonfiguration aktualisieren:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
  name: cluster-autoscaler
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-autoscaler
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
rules:
  - apiGroups: [""]
    resources: ["events", "endpoints"]
    verbs: ["create", "patch"]
  - apiGroups: [""]
    resources: ["pods/eviction"]
    verbs: ["create"]
  - apiGroups: [""]
    resources: ["pods/status"]
    verbs: ["update"]
  - apiGroups: [""]
    resources: ["endpoints"]
    resourceNames: ["cluster-autoscaler"]
    verbs: ["get", "update"]
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["watch", "list", "get", "update"]
  - apiGroups: [""]
    resources:
      - "pods"
      - "services"
      - "replicationcontrollers"
      - "persistentvolumeclaims"
      - "persistentvolumes"
    verbs: ["watch", "list", "get"]
  - apiGroups: ["extensions"]
    resources: ["replicasets", "daemonsets"]
    verbs: ["watch", "list", "get"]
  - apiGroups: ["policy"]
    resources: ["poddisruptionbudgets"]
    verbs: ["watch", "list"]
  - apiGroups: ["apps"]
    resources: ["statefulsets", "replicasets", "daemonsets"]
    verbs: ["watch", "list", "get"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses", "csinodes"]
    verbs: ["watch", "list", "get"]
  - apiGroups: ["batch", "extensions"]
    resources: ["jobs"]
    verbs: ["get", "list", "watch", "patch"]
  - apiGroups: ["coordination.k8s.io"]
    resources: ["leases"]
    verbs: ["create"]
  - apiGroups: ["coordination.k8s.io"]
    resourceNames: ["cluster-autoscaler"]
    resources: ["leases"]
    verbs: ["get", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cluster-autoscaler
  namespace: kube-system
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["create","list","watch"]
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"]
    verbs: ["delete", "get", "update", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-autoscaler
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-autoscaler
subjects:
  - kind: ServiceAccount
    name: cluster-autoscaler
    namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cluster-autoscaler
  namespace: kube-system
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: cluster-autoscaler
subjects:
  - kind: ServiceAccount
    name: cluster-autoscaler
    namespace: kube-system

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cluster-autoscaler
  namespace: kube-system
  labels:
    app: cluster-autoscaler
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cluster-autoscaler
  template:
    metadata:
      labels:
        app: cluster-autoscaler
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '8085'
    spec:
      serviceAccountName: cluster-autoscaler
      tolerations:
        - effect: NoSchedule
          operator: "Equal"
          value: "true"
          key: node-role.kubernetes.io/controlplane
      nodeSelector:
        node-role.kubernetes.io/controlplane: "true"
      containers:
        - image: eu.gcr.io/k8s-artifacts-prod/autoscaling/cluster-autoscaler:<VERSION>
          name: cluster-autoscaler
          resources:
            limits:
              cpu: 100m
              memory: 300Mi
            requests:
              cpu: 100m
              memory: 300Mi
          command:
            - ./cluster-autoscaler
            - --v=4
            - --stderrthreshold=info
            - --cloud-provider=aws
            - --skip-nodes-with-local-storage=false
            - --expander=least-waste
            - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<clusterName>
          volumeMounts:
            - name: ssl-certs
              mountPath: /etc/ssl/certs/ca-certificates.crt
              readOnly: true
          imagePullPolicy: "Always"
      volumes:
        - name: ssl-certs
          hostPath:
            path: "/etc/ssl/certs/ca-certificates.crt"

Sobald die Manifestdatei vorbereitet ist, setzen Sie sie im Kubernetes-Cluster ein (die Rancher-Benutzeroberfläche kann stattdessen verwendet werden):

kubectl -n kube-system apply -f cluster-autoscaler-deployment.yaml

Die Implementierung des Cluster-Autoscalers kann auch mit manueller Konfiguration eingerichtet werden.

Tests

An diesem Punkt sollten wir einen Cluster-Scaler in unserem benutzerdefinierten Rancher-Cluster in Betrieb haben. Der Cluster-Scaler sollte K8sWorkerAsg ASG verwalten, um zwischen 2 und 10 Knoten hoch- und herunterzuskalieren, wenn eine der folgenden Bedingungen zutrifft:

  • Es gibt Pods, die im Cluster aufgrund unzureichender Ressourcen nicht ausgeführt werden konnten. In diesem Fall wird der Cluster hochskaliert.

  • Es gibt Knoten im Cluster, die über einen längeren Zeitraum unterausgelastet waren und deren Pods auf anderen vorhandenen Knoten platziert werden können. In diesem Fall wird der Cluster heruntergeskaliert.

Lastgenerierung

Wir haben ein test-deployment.yaml vorbereitet, um Last auf dem Kubernetes-Cluster zu erzeugen und zu sehen, ob der Cluster-Autoscaler ordnungsgemäß funktioniert. Die Testimplementierung fordert 1000m CPU und 1024Mi Speicher durch drei Replikate an. Passen Sie die angeforderten Ressourcen und/oder Replikate an, um sicherzustellen, dass Sie die Ressourcen des Kubernetes-Clusters erschöpfen:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: hello-world
  name: hello-world
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - image: rancher/hello-world
        imagePullPolicy: Always
        name: hello-world
        ports:
        - containerPort: 80
          protocol: TCP
        resources:
          limits:
            cpu: 1000m
            memory: 1024Mi
          requests:
            cpu: 1000m
            memory: 1024Mi

Sobald die Testimplementierung vorbereitet ist, setzen Sie sie im Standard-Namespace des Kubernetes-Clusters ein (die Rancher-Benutzeroberfläche kann stattdessen verwendet werden):

kubectl -n default apply -f test-deployment.yaml

Überprüfung der Skalierung

Sobald die Kubernetes-Ressourcen erschöpft sind, sollte der Cluster-Autoscaler die Arbeitsknoten hochskalieren, auf denen Pods nicht geplant werden konnten. Es sollte so lange hochskaliert werden, bis alle Pods geplant werden konnten. Sie sollten die neuen Knoten in der ASG und im Kubernetes-Cluster sehen. Überprüfen Sie die Protokolle im kube-system Cluster-Autoscaler-Pod.

Sobald die Hochskalierung überprüft wurde, lassen Sie uns die Herunterskalierung überprüfen. Um dies zu tun, reduzieren Sie die Anzahl der Replikate in der Testimplementierung, bis Sie genügend Kubernetes-Cluster-Ressourcen freigeben, um herunterskalieren zu können. Sie sollten sehen, wie Knoten in der ASG und im Kubernetes-Cluster verschwinden. Überprüfen Sie die Protokolle im kube-system Cluster-Autoscaler-Pod.