Leistung optimieren

Wenn Sie bestimmte Voraussetzungen für die Leistungsoptimierung haben, können Sie die Standardeinstellungen für manche Clusterkomponenten in IBM Cloud® Kubernetes Service ändern.

Wenn Sie die Standardeinstellungen ändern, tun Sie dies auf eigenes Risiko. Sie sind für die Ausführung der erforderlichen Tests für alle geänderten Einstellungen und für eventuelle Unterbrechungen, die durch die geänderten Einstellungen in Ihrer Umgebung verursacht werden, verantwortlich.

Standard-Workerknoteneinstellungen

Standardmäßig verfügen Ihre Worker-Knoten über das Betriebssystem und die Rechenhardware der Worker-Knoten-Variante, die Sie bei der Erstellung des Worker-Pools ausgewählt haben.

Betriebssystem anpassen

Eine Liste der unterstützten Betriebssysteme nach Clusterversion finden Sie in den Versionsinformationen unter Kubernetes. Ihr Cluster kann keine Betriebssysteme kombiniert verwenden oder andere Betriebssysteme verwenden.

Beachten Sie die folgenden Informationen, wenn Sie Ihre Workerknoten optimieren.

  • Image- und Versionsaktualisierungen: Workerknotenaktualisierungen, wie z. B. Sicherheitspatches für die Image- oder Kubernetes-Versionen, werden von IBM für Sie bereitgestellt. Die Entscheidung über den Zeitpunkt für die Anwendung der Aktualisierungen auf die Workerknoten liegt jedoch bei Ihnen. Weitere Informationen finden Sie unter Cluster, Workerknoten und Clusterkomponenten aktualisieren.
  • Temporäre Änderungen: Wenn Sie sich bei einem Pod anmelden oder einen anderen Prozess zum Ändern einer Workerknoteneinstellung verwenden, sind die Änderungen temporär. Bei Lebenszyklusoperationen des Workerknotens, wie z. B. automatische Wiederherstellung, erneutes Laden, Aktualisieren oder Ersetzen eines Workerknotens, werden alle Änderungen auf die Standardeinstellungen zurückgesetzt.
  • Dauerhafte Änderungen: Damit Änderungen über den gesamten Lebenszyklus der Worker-Knoten hinweg bestehen bleiben, erstellen Sie ein Daemon-Set, das einen Container init verwendet. Weitere Informationen finden Sie unter Workerknoten-Standardeinstellungen zur Leistungsoptimierung ändern.

Änderungen am Betriebssystem werden nicht unterstützt. Wenn Sie die Standardeinstellungen ändern, sind Sie für das Debugging und die Behebung von eventuell auftretenden Problemen verantwortlich.

Hardwareänderungen

Zum Ändern der Computerhardware, z. B. der CPU oder des Speichers für die einzelnen Workerknoten, wählen Sie eine der folgenden Optionen.

Anpassen der Kernel-Einstellungen von Worker-Knoten zur Leistungsoptimierung

Cluster-Workerknoten werden für ein Maß an Stabilität, Optimierung und Leistung konfiguriert, von dem erwartet wird, dass sie die Anforderungen der meisten Workloads erfüllen. Normalerweise wird es nicht empfohlen, die Kerneleinstellungen Ihres Workerknotens zu ändern, da solche Änderungen zu ungewöhnlichen und unbeabsichtigten Problemen führen können. Wenn Ihre Workload jedoch sehr eindeutige Anforderungen an die Leistungsoptimierung hat, die Änderungen an Ihren Kerneleinstellungen erfordern, können Sie ein angepasstes Kubernetes-DaemonSet anwenden, um die Kernelkonfiguration zu ändern. Stellen Sie fest, dass diese Änderungen erhebliche negative Folgen haben können und dass Sie Änderungen an der Konfiguration der Kerneleinstellungen auf eigenes Risiko implementieren.

Wenn Sie die Konfiguration Ihrer Kernel-Einstellungen ändern, stellen Sie sicher, dass Sie die genauen Änderungen, die Sie vornehmen, dokumentieren und speichern. Wenn Sie ein Support-Ticket für Probleme im Zusammenhang mit dem Cluster öffnen, müssen Sie diese Änderungen angeben. Diese Konfigurationsänderungen können für das Problem verantwortlich sein und Sie werden möglicherweise aufgefordert, die Änderungen im Rahmen der Problemuntersuchung zurückzusetzen. In diesem Fall sind Sie für das Zurücksetzen von Änderungen an der Kernelkonfiguration verantwortlich, die Sie implementieren.

Das Ändern der Standardkerneleinstellungen kann sich negativ auf Ihren Cluster auswirken. Nehmen Sie diese Änderungen auf eigenes Risiko vor.

Sie können die Standardkerneleinstellungen ändern, indem Sie ein angepasstes Kubernetes DaemonSet mit einem init-Container auf Ihren Cluster anwenden. Die Dämongruppe (DaemonSet) ändert die Einstellungen für alle vorhandenen Workerknoten und wendet die Einstellungen auf alle neuen Workerknoten an, die im Cluster eingerichtet werden. Der Container init stellt sicher, dass diese Änderungen vorgenommen werden, bevor andere Pods auf dem Worker-Knoten eingeplant werden. Es sind keine Pods betroffen.

Sie müssen über die Servicezugriffsrolle Manager in IBM Cloud IAM für alle Namensbereiche verfügen, in denen der privilegierte Beispielinitialisierungscontainer initContainer ausgeführt wird. Nachdem die Container für die Bereitstellungen initialisiert wurden, werden die Privilegien gelöscht.

Vorbereitende Schritte: Melden Sie sich bei Ihrem Konto an. If applicable, target the appropriate resource group. Legen Sie den Kontext für den Cluster fest.

  1. Speichern Sie die folgende Dämongruppe (DaemonSet) in einer Datei mit dem Namen worker-node-kernel-settings.yaml. Fügen Sie im Abschnitt spec.template.spec.initContainers die Felder und Werte für die sysctl-Parameter hinzu, die Sie optimieren möchten. Dieses Beispiel für eine Dämongruppe ändert den Standardwert für die Anzahl Verbindungen, die maximal in der Umgebung zulässig sind, über die Einstellung net.core.somaxconn und den Bereich ephemerer Ports über die Einstellung net.ipv4.ip_local_port_range.

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: kernel-optimization
      namespace: kube-system
      labels:
        tier: management
        app: kernel-optimization
    spec:
      selector:
        matchLabels:
          name: kernel-optimization
      template:
        metadata:
          labels:
            name: kernel-optimization
        spec:
          hostNetwork: true
          hostPID: true
          hostIPC: true
          initContainers:
            - command:
                - sh
                - -c
                - sysctl -w net.ipv4.tcp_syn_retries="5"; sysctl -w net.ipv4.tcp_fin_timeout="15";
              image: us.icr.io/armada-master/network-alpine:latest
              imagePullPolicy: Always
              name: sysctl
              resources: {}
              securityContext:
                privileged: true
                capabilities:
                  add:
                    - NET_ADMIN
              volumeMounts:
                - name: modifysys
                  mountPath: /sys
          containers:
            - resources:
                requests:
                  cpu: 0.01
              image: us.icr.io/armada-master/network-alpine:latest
              name: sleepforever
              command: ["/bin/sh", "-c"]
              args:
                - >
                  while true; do
                    sleep 100000;
                  done
          volumes:
            - name: modifysys
              hostPath:
                path: /sys
    
  2. Wenden Sie die Dämongruppe auf Ihre Workerknoten an. Die Änderungen werden sofort angewendet.

    kubectl apply -f worker-node-kernel-settings.yaml
    

Um die Parameter sysctl Ihrer Worker-Knoten auf die Standardwerte zurückzusetzen, führen Sie die folgenden Schritte aus.

  1. Löschen Sie die Dämongruppe. Die initContainers, die die angepassten Einstellungen angewendet haben, werden entfernt.
    kubectl delete ds kernel-optimization
    
  2. Führen Sie für alle Workerknoten im Cluster einen Warmstart durch. Die Workerknoten werden mit den angewendeten Standardwerten wieder gestartet.

Podleistung optimieren

Wenn Sie bestimmte Anforderungen an die Workloadleistung haben, können Sie die Standardeinstellungen für die sysctl-Parameter für den Linux-Kernel in Pod-Netznamensbereichen ändern.

Um die Kernel-Einstellungen für App-Pods zu optimieren, können Sie für jede Bereitstellung einen Patch initContainer in die pod/ds/rs/deployment YAML-Datei einfügen. Der initContainer wird jeder App-Bereitstellung hinzugefügt, die sich in dem Pod-Netznamensbereich befindet, für den Sie die Leistung optimieren möchten.

Beversichere dich vor dem Start, dass du über die IAM-Zugriffsrolle ManagerIBM Cloud für alle Namespaces verfügst, um das Beispiel mit erhöhten Rechten auszuführen initContainer. Nachdem die Container für die Bereitstellungen initialisiert wurden, werden die Privilegien gelöscht.

  1. Speichern Sie das folgende initContainer-Patch in einer Datei mit dem Namen pod-patch.yaml und fügen Sie die Felder und Werte für die sysctl-Parameter hinzu, die Sie optimieren möchten. Dieses Beispiel für den initContainer ändert den Standardwert für die Anzahl Verbindungen, die maximal in der Umgebung zulässig sind, über die Einstellung net.core.somaxconn und den Bereich ephemerer Ports über die Einstellung net.ipv4.ip_local_port_range.

    spec:
      template:
        spec:
          initContainers:
            - command:
                - sh
                - -c
                - sysctl -e -w net.core.somaxconn=32768;  sysctl -e -w net.ipv4.ip_local_port_range="1025 65535";
              image: alpine:3.6
              imagePullPolicy: IfNotPresent
              name: sysctl
              resources: {}
              securityContext:
                privileged: true
    
  2. Wenden Sie Patches auf alle Ihre Bereitstellungen an.

    kubectl patch deployment <deployment_name> --patch pod-patch.yaml
    
  3. Wenn Sie den Wert für net.core.somaxconn in den Kerneleinstellungen geändert haben, können die meisten Apps automatisch den aktualisierten Wert verwenden. Einige Apps erfordern jedoch unter Umständen, dass Sie den entsprechenden Wert in Ihrem App-Code manuell ändern, damit er mit dem Kernelwert übereinstimmt. Wenn Sie beispielsweise die Leistung eines Pods optimieren, in dem eine NGINX-App ausgeführt wird, müssen Sie den Wert des Felds backlog im NGINX-App-Code ändern, damit er übereinstimmt. Weitere Informationen finden Sie in diesem Blogbeitrag auf NGINX.

sysctl-Einstellungen für Netz-Keepalive optimieren

Wenn ein Pod lange laufende TCP Verbindungen hat, die gelegentlich getrennt werden, wenn sie eine Zeit lang im Leerlauf sind, kann es hilfreich sein, die sysctl keepalive-Einstellungen für den Pod zu ändern.

Es gibt derzeit keine Möglichkeit, diese sysctl-Keepalive-Einstellungen standardmäßig für alle Pods in einem Cluster festzulegen. Die beste Methode, die Einstellungen für alle Pods zu ändern, ist die Verwendung einer privilegierten initContainer. Sehen Sie sich das folgende Beispiel an, wie ein initContainer für eine Bereitstellung in einem test-ns-Namensbereich eingerichtet wird.

Implementieren Sie das folgende Beispiel initContainer. Denken Sie daran, den Abschnitt containers: in Ihre eigenen Anwendungscontainer zu ändern. initContainer legt dann die sysctl-Einstellungen für alle regulären Container im Pod fest, da sie alle denselben Netznamensbereich gemeinsam nutzen.

kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
	name: test-sysctl
	namespace: test-ns
	labels:
	run: test-sysctl
spec:
	replicas: 2
	selector:
	matchLabels:
		run: test-sysctl
	template:
	metadata:
		labels:
		run: test-sysctl
	spec:
		initContainers:
		- command:
		- sh
		- -c
		- sysctl -e -w net.ipv4.tcp_keepalive_time=40; sysctl -e -w net.ipv4.tcp_keepalive_intvl=15; sysctl -e -w net.ipv4.tcp_keepalive_probes=6;
		image: us.icr.io/armada-master/alpine:latest
		imagePullPolicy: IfNotPresent
		name: sysctl-init
		resources: {}
		securityContext:
			privileged: true
		containers:
		- name: test-sysctl
		image: us.icr.io/armada-master/alpine:latest
		command: ["sleep", "2592000"]
	EOF

Ressourcen des Providers von Clustermetriken anpassen

Ihr Cluster verfügt über einen Metrikservice, der von der metrics-server-Bereitstellung im Namensbereich kube-system bereitgestellt wird. Die metrics-server-Ressourcenanforderungen basieren auf der Anzahl der Knoten im Cluster und sind für Cluster mit bis zu 30 Pods pro Workerknoten optimiert. Der Metrikservice entspricht den Speicher- und CPU-Grenzwerten der Ressourcenanforderungen.

Die Metrik-Service-Container können "abnormale Speicherbedingungen" sein, wenn die Speicheranforderungen zu niedrig sind. Aufgrund von CPU-Drosselung können sie sehr langsam reagieren oder die Verfügbarkeits- und Bereitschaftsprüfungen nicht bestehen, wenn die CPU-Anforderungen zu gering sind.

Die Speicherbelegung wird durch die Anzahl der Pods im Cluster gesteuert. Die CPU-Auslastung wird durch die Anzahl der Anforderungen für Metriken (HPAs, kubectl top nodes / pods usw.) und durch API-Erkennungsanforderungen gesteuert. metrics-server stellt eine Kubernetes-API bereit, damit Clients wie kubectl, die API-Erkennung verwenden, auch dann einen Teil der Arbeitslast auf metrics-server verlagern, wenn sie keine Metriken verwenden.

Die folgenden Symptome können darauf hindeuten, dass die metrics-server-Ressourcen angepasst werden sollten:

  • metrics-server wird häufig neu gestartet.

  • Das Löschen eines Namensbereichs führt dazu, dass der Namensbereich in einem Status Terminating blockiert wird und eine Fehlerbedingung in kubectl describe namespace einen Erkennungsfehler für die Metrik-API meldet.

  • kubectl top pods, kubectl top nodes, andere Befehle kubectl oder Anwendungen, die mithilfe der Kubernetes-API Kubernetes-Fehler wie die folgenden protokollieren:

The server is currently unable to handle the request (get pods.metrics.k8s.io)
Discovery failed for some groups, 1 failing: unable to retrieve the complete list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to handle the request
  • Horizontal Pod Autoscalers (HPAs) skalieren keine Bereitstellungen.

  • Das Ausführungsergebnis von kubectl get apiservices v1beta1.metrics.k8s.io ist ein Status wie der folgende:

NAME                     SERVICE                      AVAILABLE                      AGE
v1beta1.metrics.k8s.io   kube-system/metrics-server   False (FailedDiscoveryCheck)   139d

metrics-server-config-Konfigurationszuordnung ändern

Sowohl CPU als auch Speicher verfügen über optimierbare grundlegende und knotenspezifische Einstellungen, die zum Berechnen einer Gesamtanforderung verwendet werden.

  • baseCPU
  • cpuPerNode
  • baseMemory
  • memoryPerNode

Dabei gilt:

cpuRequest = baseCPU + cpuPerNode * number_of_nodes
memoryRequest = baseMemory + memoryPerNode * number_of_nodes

Die Anzahl der Knoten in diesen Berechnungen stammt aus einer Reihe von 'Bucketgrößen' und hat eine Mindestgröße von 16 Knoten.

Die CPU wird in Kernen mit Werten wie 1 oder mit Bruchwerten wie 100m (100 Millicores) angefordert.

Der Speicher wird in Byte mit dem folgenden optionalen Suffix angefordert:

  • basis 2 1Ki = 1024): Ki (Kilobytes), Mi (Megabytes), Gi (Gigabytes).
  • metrisch 1k = 1000): k, M, G.

Wenn zu erwarten ist, dass die Anzahl der Knoten in einem Cluster im Laufe der Zeit zunimmt (oder sich ändert), können Sie in Erwägung ziehen, die Einstellung 'pro Knoten' anzupassen. Wenn die Anzahl der Knoten statisch ist, passen Sie die grundlegende Einstellung an. Die Gesamtwerte für CPU und Speicher werden letztlich in den Ressourcenanforderungen für metrics-server-Bereitstellungen festgelegt.

Sie können die Standardressourcen ändern, indem Sie die Konfigurationszuordnung des Providers von Metriken bearbeiten. Ändern Sie die Ressourcenanforderungen oder Grenzwerte nicht unmittelbar in der metrics-server-Bereitstellung. Diese Werte werden vom metrics-server-nanny-Container überschrieben.

Die Standardkonfigurationszuordnung für metrics-server-config ist:

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
  name: metrics-server-config
  namespace: kube-system
data:
  NannyConfiguration: |-
    apiVersion: nannyconfig/v1alpha1
    kind: NannyConfiguration

Dieses Beispiel zeigt eine Konfigurationszuordnung mit allen definierten Werten.

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
  name: metrics-server-config
  namespace: kube-system
data:
  NannyConfiguration: |-
    apiVersion: nannyconfig/v1alpha1
    kind: NannyConfiguration
    baseCPU: 200m
    cpuPerNode: 1m
    baseMemory: 40Mi
    memoryPerNode: 6Mi

Die Standardwerte lauten wie folgt:

baseCPU: 200m
cpuPerNode: 1m
baseMemory: 40Mi
memoryPerNode: 6Mi

Konfigurationszuordnung bearbeiten

Die Konfigurationszuordnung können Sie mit dem Befehl kubectl edit bearbeiten:

kubectl edit cm metrics-server-config -n kube-system

Fügen Sie die zu ändernden Felder hinzu oder bearbeiten Sie sie. Speichern Sie anschließend die Konfigurationszuordnung und beenden Sie den Editor.

Der von IBM Cloud bereitgestellte metrics-server überwacht die Konfigurationszuordnung auf Änderungen und aktualisiert die Anforderungen für Bereitstellungsressourcen automatisch. Es kann bis zu 10 Minuten dauern, bis der metrics-server die Änderung erkennt und eine neue Gruppe von Pods startet, die auf den aktualisierten Einstellungen basieren.

Standardeinstellungen wiederherstellen

Um die Standardeinstellungen für metrics-server wiederherzustellen, löschen Sie die Konfigurationszuordnung. Sie wird in wenigen Minuten erneut erstellt.

kubectl delete cm metrics-server-config -n kube-system

Zu optimierende Ressourcen bestimmen

Verwenden Sie den Befehl kubectl describe pod, um die Pod-Definition, Statusinformationen und kürzlich aufgetretene Ereignisse abzurufen:

kubectl get pod -n kube-system -l k8s-app=metrics-server
NAME                             READY   STATUS    RESTARTS   AGE
metrics-server-9fb4947d6-s6sgl   3/3     Running   0          2d4h
kubectl describe pod -n kube-system metrics-server-9fb4947d6-s6sgl

Beispielausgabe

Containers:
  metrics-server:
    Container ID:  containerd://fe3d07c9a2541242d36da8097de3896f740c1363f6d2bfd01b8d96a641192b1b
    Image:         us.icr.io/armada-master/metrics-server:v0.4.4
    Image ID:      us.icr.io/armada-master/metrics-server@sha256:c2c63900d0e080c2413b5f35c5a59b5ed3b809099355728cf47527aa3f35477c
    Port:          4443/TCP
    Host Port:     0/TCP
    Command:
      /metrics-server
      --metric-resolution=45s
      --secure-port=4443
      --tls-cert-file=/etc/metrics-server-certs/tls.crt
      --tls-private-key-file=/etc/metrics-server-certs/tls.key
    State:          Running
      Started:      Fri, 10 Sep 2021 17:31:39 +0000
    Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    137
      Started:      Fri, 10 Sep 2021 05:59:51 +0000
      Finished:     Fri, 10 Sep 2021 17:31:37 +0000
    Ready:          True
    Restart Count:  36

Wenn Last State für OOMKilled den Wert Reason anzeigt, erhöhen Sie die Speicheranforderungen in der Konfigurationszuordnung (ConfigMap) metrics-server-config in Schritten von 100 Mi oder größer, bis der Metrikserver stabil ist und mehrere Stunden oder länger ausgeführt wird, ohne in den Status OOMkilled zu wechseln.

Last State:     Terminated
  Reason:       OOMKilled
  Exit Code:    137

Wenn Last state für Reason den Wert Error und Ereignisse wie im folgenden Beispiel anzeigt, erhöhen Sie die CPU-Anforderungen in der Konfigurationszuordnung metrics-server-config in Schritten von 100 m oder mehr, bis der Metrikserver stabil ist und mehrere Stunden oder länger ausgeführt und nicht durch Zeitlimitüberschreitungen bei Tests abgebrochen wird.

Last State:     Terminated
  Reason: Error
  Exit Code: 137
Events:
Warning Unhealthy 46m (x5 over 80m) kubelet Liveness probe failed: Get "https://198.18.68.236:4443/livez": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 26m (x65 over 89m) kubelet Liveness probe failed: Get "https://198.18.68.236:4443/livez": net/http: TLS handshake timeout
Warning Unhealthy 21m (x10 over 76m) kubelet Readiness probe failed: Get "https://198.18.68.236:4443/readyz": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 115s (x93 over 90m) kubelet Readiness probe failed: Get "https://198.18.68.236:4443/readyz": net/http: TLS handshake timeout

Sie müssen diesen Prozess möglicherweise einige Male wiederholen, bis eine stabile Konfiguration erreicht ist. Passen Sie dabei zuerst Speicheranforderungen und danach CPU-Anforderungen an.

Huge Pages aktivieren

Klassische Infrastruktur Virtuelle Private Cloud

Sie können die KubernetesHugePages-Planung in Clustern aktivieren, auf denen Kubernetes in der Version 1.19 oder höher ausgeführt wird. Die einzige unterstützte Seitengröße ist 2 MB pro Seite. Dies ist die Standardgröße des Kubernetes-Feature-Gates.

Huge Pages Scheduling ist ein Beta-Feature in IBM Cloud Kubernetes Service. Änderungen sind vorbehalten.

Standardmäßig ordnet die CPU Ihrer Workerknoten RAM in Blöcken oder Seiten von 4 KB zu. Wenn Ihre App mehr RAM erfordert, muss das System nach zusätzlichen Seiten suchen, was die Verarbeitung verlangsamen kann. Mit Huge Pages können Sie die Seitengröße auf 2 MB erhöhen, um die Leistung für Ihre RAM-intensiven Apps wie Datenbanken für künstliche Intelligenz (KI), Internet der Dinge (Internet of Things, IoT) oder Machine-Learning-Workloads zu steigern. Weitere Informationen zu Huge Pages finden Sie in der Kernel-Dokumentation unter Linux.

Wenn Sie einen Warmstart des Workerknotens durchführen, bleiben die Huge Pages erhalten. Die Konfiguration der Huge Pages bleibt jedoch bei keinem anderen Lebenszyklusvorgang eines Worker-Knotens erhalten. Sie müssen die Aktivierungsschritte jedes Mal wiederholen, wenn Sie Workerknoten aktualisieren, neu laden, ersetzen oder hinzufügen.

  • Plattformzugriffsrolle Operator und Servicezugriffsrrolle Manager für den Cluster in IBM Cloud IAM

Vorbereitende Schritte: Melden Sie sich bei Ihrem Konto an. If applicable, target the appropriate resource group. Legen Sie den Kontext für den Cluster fest.

  1. Erstellen Sie eine Konfigurationsdatei hugepages-ds.yaml, um Huge Pages zu aktivieren. Die folgende YAML-Beispieldatei verwendet eine Dämongruppe, um den Pod auf jedem Workerknoten in Ihrem Cluster auszuführen. Sie können die Zuordnung der Huge Pages, die auf dem Workerknoten verfügbar sind, mithilfe des Parameters vm.nr_hugepages festlegen. In diesem Beispiel werden 512 Seiten mit 2 MB pro Seite zugeordnet, für insgesamt 1 GB, die ausschließlich für Huge Pages zugeordnet werden.

    Möchten Sie Huge Pages nur für bestimmte Workerknoten aktivieren - z. B. für einen Worker-Pool, den Sie für RAM-intensive Apps verwenden? Weisen Sie Ihrem Worker-Pool Labels und Taints zu und fügen Sie anschließend Affinitätsregeln zum Daemon-Set hinzu, damit die Pods nur auf den von Ihnen angegebenen Worker-Knoten im Worker-Pool bereitgestellt werden.

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: hugepages-enablement
      namespace: kube-system
      labels:
        tier: management
        app: hugepages-enablement
    spec:
      selector:
        matchLabels:
          name: hugepages-enablement
      template:
        metadata:
          labels:
            name: hugepages-enablement
        spec:
          hostPID: true
          initContainers:
            - command:
                - sh
                - -c
                # Customize allocated Hugepages by providing the value
                - "echo vm.nr_hugepages=512 > /etc/sysctl.d/90-hugepages.conf"
              image: alpine:3.6
              imagePullPolicy: IfNotPresent
              name: sysctl
              resources: {}
              securityContext:
                privileged: true
              volumeMounts:
                - name: modify-sysctld
                  mountPath: /etc/sysctl.d
          containers:
            - resources:
                requests:
                  cpu: 0.01
              image: alpine:3.6
              # once the init container completes, keep the pod running for worker node changes
              name: sleepforever
              command: ["/bin/sh", "-c"]
              args:
                - >
                  while true; do
                      sleep 100000;
                  done
          volumes:
            - name: modify-sysctld
              hostPath:
                path: /etc/sysctl.d
    
  2. Wenden Sie die Datei an, die Sie zuvor erstellt haben.

    kubectl apply -f hugepages-ds.yaml
    
  3. Überprüfen Sie, ob sich die Pods im Status Running befinden.

    kubectl get pods
    
  4. Starten Sie das Kubelet erneut, das auf jedem Workerknoten ausgeführt wird, indem Sie die Workerknoten neu starten. Laden Sie nicht den Workerknoten erneut, um das Kubelet erneut zu starten. Wenn Sie den Workerknoten erneut laden, bevor das Kubelet die Huge-Pages-Aktivierung wahrnimmt, schlägt die Aktivierung fehl.

    1. Listen Sie die Workerknoten in Ihrem Cluster auf.
        ibmcloud ks worker ls -c CLUSTER_NAME_OR_ID
        ```
    2. Führen Sie einen Warmstart für die Workerknoten durch. Sie können mehrere Worker-Knoten neu starten, indem Sie mehrere `-w` Optionen angeben. Achten Sie jedoch darauf, dass genügend Worker-Knoten gleichzeitig für Ihre Anwendungen in Betrieb bleiben, um einen Ausfall zu vermeiden.
    ```sh {: pre}
        ibmcloud ks worker reboot -c CLUSTER_NAME_OR_ID -w WORKER1_ID -w WORKER2_ID
        ```
    
  5. Erstellen Sie einen Testpod hugepages-test.yaml, der Huge Pages als Datenträger anhängt und der Ressourcengrenzwerte und -anforderungen verwendet, um festzulegen, wie viele Huge-Pages-Ressourcen der Pod verwenden soll. Hinweis: Wenn Sie Bezeichnungen, Taints und Affinitätsregeln verwendet haben, um Huge Pages nur auf ausgewählten Workerknoten zu aktivieren, nehmen Sie diese Regeln in Ihren Testpod auf.

    apiVersion: v1
    kind: Pod
    metadata:
      name: hugepages-example
    spec:
      containers:
        - name: hugepages-example
          image: fedora:34
          command:
            - sleep
            - inf
          volumeMounts:
            - mountPath: /hugepages-2Mi
              name: hugepage-2mi
          resources:
            limits:
              hugepages-2Mi: 100Mi
              memory: 100Mi
            requests:
              memory: 100Mi
      volumes:
        - name: hugepage-2mi
          emptyDir:
            medium: HugePages-2Mi
    
  6. Wenden Sie die Poddatei an, die Sie zuvor erstellt haben.

    kubectl apply -f hugepages-pod.yaml
    
  7. Stellen Sie sicher, dass Ihr Pod die Huge-Pages-Ressourcen verwendet.

    1. Überprüfen Sie, ob sich Ihr Pod im Status Running befindet. Der Pod wird nicht ausgeführt, wenn keine Workerknoten mit Huge Pages verfügbar sind.
        kubectl get pods
        ```
    2. Melden Sie sich beim Pod an.
    ```sh {: pre}
        kubectl exec -it <pod> /bin/sh
        ```
    3. Überprüfen Sie, ob Ihr Pod die Größe der Huge Pages anzeigen kann.
    ```sh {: pre}
        ls /sys/kernel/mm/hugepages
        ```
        Beispielausgabe
        ```sh {: screen}
        hugepages-1048576kB  hugepages-2048kB
        ```
    
  8. Optional: Entfernen Sie die Aktivierungsdämongruppe. Beachten Sie, dass Sie die Dämongruppe neu erstellen müssen, wenn Sie die Workerknoten mit Huge Pages zu einem späteren Zeitpunkt aktualisieren, neu laden, ersetzen oder hinzufügen müssen.

    kubectl -n kube-system delete daemonset hugepages-enablement
    
  9. Wiederholen Sie diese Schritte, wenn Sie Workerknoten aktualisieren, neu laden, ersetzen oder hinzufügen möchten.

Um Fehler bei Workerknoten mit Huge Pages zu beheben, können Sie nur den Workerknoten neu starten. Die Huge-Pages-Konfiguration bleibt nicht über alle anderen Lebenszyklusoperationen des Workerknotens hinweg bestehen, zum Beispiel, wenn Workerknoten aktualisiert, neu geladen, ersetzt oder hinzugefügt werden. Um die Huge-Pages-Konfiguration aus Ihrem Cluster zu entfernen, können Sie alle Workerknoten aktualisieren, neu laden oder ersetzen.

Ändern der maximalen Übertragungseinheit (MTU) für Cluster mit Calico

Sie können die maximale Übertragungseinheit (MTU) der Worker-Knoten und des Plug-ins Calico erhöhen oder verringern, um den Anforderungen an den Netzwerkdurchsatz Ihrer Umgebung gerecht zu werden.

Alle VPC-Arbeitsknoten unterstützen eine MTU von bis zu 9000, und klassische Bare-Metal-Arbeitsknoten unterstützen ebenfalls eine MTU von bis zu 9000. Klassische virtuelle Server unterstützen nur die Standard-MTU von 1500. Wenn Ihr Cluster also über klassische virtuelle Server-Arbeitsknoten verfügt, sollten Sie weder den Arbeitsknoten noch die Calico MTU erhöhen.

Die Änderung von MTU-Werten (Maximum Transmission Unit) kann zu unerwarteten Ergebnissen führen, insbesondere in komplexen Netzwerkumgebungen. Um eine Unterbrechung Ihres Arbeitsablaufs zu vermeiden, wird dringend empfohlen, diese Änderungen auf einem Entwicklungscluster zu testen, bevor Sie Änderungen an Ihren Produktionsclustern vornehmen.

Standardmäßig hat das Calico in Ihrem IBM Cloud Kubernetes Service eine MTU von 1450 Byte für Satellite und 1480 Byte für Satellite. In den meisten Fällen ist dieser Standard-MTU-Wert von Calico ausreichend, um Paketverluste und Fragmentierung zu vermeiden. Da die meisten Hosts einen MTU-Wert von 1500 verwenden, bieten diese Standardwerte Satellite 50 zusätzliche Bytes für VXLAN-Header und Satellite 20 zusätzliche Bytes für die IP-Header, die in einigen Pod-zu-Pod-Cluster-Netzwerkverkehren verwendet werden. Beachten Sie, dass alle Arbeitsknoten im Cluster denselben Calico verwenden müssen.

Sehen Sie sich die folgenden Fälle an, in denen Sie möglicherweise die Standard-Calico-MTU ändern müssen:

  • Wenn Sie den Netzwerkdurchsatz zwischen den Pods verbessern müssen und Ihre Clusterknoten eine höhere Host-MTU verwenden können, können Sie sowohl die Host- als auch die Calico erhöhen. Dies wird als "Jumbo-Frames" bezeichnet. Die typische Jumbo Frame MTU beträgt 9000. In diesem Fall können Sie die private Netzwerkschnittstelle des Hosts auf einen MTU-Wert von 9000 und die Calico auf einen etwas niedrigeren Wert einstellen - 8950 für Satellite und 8980 für Satellite. Beachten Sie, dass einige Hardware oder Ressourcen von Cloud-Anbietern, wie z. B. virtuelle Azure, möglicherweise keine Jumbo-Frames oder nur einen MTU-Wert von bis zu 4000 unterstützen.
  • Wenn Sie über eine VPN-Verbindung für Ihren Cluster verfügen, benötigen einige VPN-Verbindungen eine kleinere Calico-MTU als den Standardwert. Überprüfen Sie beim Provider des VPN-Service, ob eine kleinere Calico-MTU erforderlich ist.
Vorbereitende Schritte
Falls Ihre Worker-Knoten noch mit dem Standard-MTU-Wert laufen, erhöhen Sie zunächst den MTU-Wert für Ihre Worker-Knoten, bevor Sie den MTU-Wert für das Calico-Plug-in erhöhen. Sie können beispielsweise das folgende Daemon-Set anwenden, um die MTU für Ihre Worker-Knoten auf 9.000 Byte zu ändern. Beachten Sie, dass die im Befehl ip link verwendeten Schnittstellennamen abhängig vom Typ Ihrer Workerknoten variieren.
  • Beispielbefehl für Bare-Metal-Workerknoten: ip link set dev bond0 mtu 9000;ip link set dev bond1 mtu 9000;
  • Beispielbefehl VPC-Arbeitsknoten: ip link set dev ens3 mtu 9000;
  1. Führen Sie die folgenden Befehle aus, um sich bei einem Cluster-Worker-Knoten anzumelden und von einem Knoten zum anderen zu pingen. Da die MTU Ihres Knotens nur auf 1500 oder 1480 eingestellt ist, wird dieser Versuch voraussichtlich fehlschlagen. In den folgenden Schritten können Sie diese Befehle erneut ausführen, um zu überprüfen, ob die Änderungen erfolgreich waren.

    1. Listen Sie die Knoten in Ihrem Cluster auf. Speichern Sie die Namen und IP-Adressen von zwei gesunden Knoten.
        kubectl get nodes -o wide
        ```
    1. Melden Sie sich bei einem der Knoten an. Geben Sie den Namen des Knotens an.
    
    
    
    ```sh {: pre}
        kubectl debug --image=us.icr.io/armada-master/network-alpine -it node/<NODE_NAME> -- sh
        ```
    
    
    1. Führen Sie den Befehl aus, um von einem Knoten zum anderen zu pingen. Geben Sie die IP-Adresse des Knotens an, auf den Sie im vorherigen Schritt nicht verwiesen haben.
    ```sh {: pre}
        ping -c1 -Mdo -s 8972 <OTHER_HOST_IP>
        ```
    
  2. Ändern Sie die Knoten-MTU mit dem folgenden Beispiel-Daemonset. Dieser MTU-Wert gilt für den Verkehr von Knoten zu Knoten. Ändern Sie die Zeile - ip link set dev ens3 mtu <MTU_VALUE> so, dass sie Ihren MTU-Wert enthält (im Beispiel wird ein MTU-Wert von 9000 verwendet). Beachten Sie, dass Sie möglicherweise auch den Schnittstellennamen " ens3 ändern müssen, wenn ens3 für Ihre Knoten nicht geeignet ist.

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      labels:
        app: set-host-mtu
      name: set-host-mtu
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          name: set-host-mtu
      template:
        metadata:
          labels:
            name: set-host-mtu
        spec:
          containers:
            - args:
                - |
                  while true; do
                    sleep 100000;
                  done
              command:
                - /bin/sh
                - -c
              image: us.icr.io/armada-master/network-alpine:latest
              imagePullPolicy: IfNotPresent
              name: sleepforever
              resources:
                requests:
                  cpu: 10m
          hostNetwork: true
          initContainers:
            - command:
                - sh
                - -c
                - ip link set dev ens3 mtu 9000
              image: us.icr.io/armada-master/network-alpine:latest
              imagePullPolicy: IfNotPresent
              name: set-host-mtu
              securityContext:
                capabilities:
                  add:
                    - NET_ADMIN
                privileged: true
              volumeMounts:
                - mountPath: /sys
                  name: modifysys
          restartPolicy: Always
          terminationGracePeriodSeconds: 2
          tolerations:
            - operator: Exists
          volumes:
            - hostPath:
                path: /sys
                type: ""
              name: modifysys
      updateStrategy:
        rollingUpdate:
          maxSurge: 0
          maxUnavailable: 1
        type: RollingUpdate
    
  3. Wenden Sie das Daemonset an, um den MTU-Wert des Knotens zu ändern.

      kubectl apply -f <file_name>
    
  4. Führen Sie die Befehle erneut aus, um sich bei einem Knoten anzumelden und einen Ping von einem Host zu einem anderen zu senden, wobei Sie eine große Paketgröße verwenden. Da Sie nun den MTU-Wert des Knotens erhöht haben, sollte der Befehl " ping erfolgreich sein.

    kubectl debug --image=us.icr.io/armada-master/network-alpine -it node/<NODE_NAME> -- sh
    
    ping -c1 -Mdo -s 8972 <OTHER_HOST_IP>
    
  5. Nehmen Sie sich die Zeit, Ihren Cluster mit dem neuen Knoten-MTU-Wert zu testen. Bevor Sie mit der Änderung des Calico MTU-Wertes fortfahren, sollten Sie überprüfen, ob Ihre Anwendungen noch wie erwartet funktionieren.

  6. Führen Sie den Befehl aus, um die Calico zu aktualisieren, damit der Pod-zu-Pod-Verkehr auch die größere MTU verwenden kann. Bei Satellite Core OS-Clustern sollte der Calico 50 Byte kleiner sein als der Knoten-MTU-Wert. Bei allen anderen Clustern sollte der Calico 20 Byte niedriger sein. Wenn Sie beispielsweise 9000 für die Knoten-MTU angegeben haben, sollte Ihre Calico 8950 für Satellite Core OS-Cluster oder 8980 für alle anderen Cluster betragen.

    kubectl patch installation.operator.tigera.io default --type='merge' -p '{"spec":{"calicoNetwork":{"mtu":<MTU_VALUE>}}}'
    

    Sie können die Ressource auch direkt bearbeiten, indem Sie ' kubectl edit installation.operator.tigera.io default ausführen.

  7. Wenden Sie diese Änderungen auf alle Ihre Knoten an, indem Sie alle Knoten vorsichtig neu starten. Stellen Sie sicher, dass Sie diesen Prozess auf einem Entwicklungscluster getestet haben, bevor Sie mit diesem Schritt fortfahren, da diese Änderungen zu Unterbrechungen Ihrer Arbeitslast führen können. Um die Knoten neu zu starten, wird empfohlen, die Knoten nacheinander abzusperren, zu entleeren und neu zu starten.

Wenn Sie diese Schritte auf einem Produktionscluster durchführen, sollten Sie denselben Prozess anwenden, den Sie für die Aktualisierung oder den Austausch von Produktionsknoten verwenden. Es wird dringend empfohlen, diesen gesamten Prozess auf einem Testcluster zu testen, bevor Sie diese Schritte auf einem Produktionscluster durchführen.

Während des Neustarts verwenden einige Pods die neue, größere MTU und einige Pods haben noch die ursprüngliche, kleinere MTU. Normalerweise verursacht dieses Szenario keine Probleme, da beide Seiten die korrekte maximale Paketgröße aushandeln. Wenn Sie jedoch ICMP-Pakete blockieren, kann es sein, dass die Aushandlung nicht funktioniert und Ihr Cluster Probleme mit der Pod-Verbindung bekommt, bis alle Neustarts abgeschlossen sind. Es ist von entscheidender Bedeutung, dass dieser Prozess zunächst in einem Entwicklungscluster getestet wird.

Deaktivierung des Port Map Plug-Ins in Calico

Der Plug-in portmap für die Containernetzschnittstelle (Container Network Interface, CNI) von Calico ermöglicht Ihnen, einen Host-Port (hostPort) zu verwenden, um Ihre App-Pods über einen bestimmten Port auf dem Workerknoten zugänglich zu machen. Verhindern Sie Leistungsprobleme für 'iptables', indem Sie das Plug-in für Portzuordnungen aus der Calico-CNI-Konfiguration Ihres Clusters entfernen.

Wenn Sie über viele Services in Ihrem Cluster verfügen, z. B. mehr als 500 Services, oder viele Ports auf Services, z. B. mehr als 50 Ports pro Service für 10 oder mehr Services, werden viele iptables-Regeln für die Calico- und Kubernetes-Netzrichtlinien für diese Services generiert. Die Verwendung vieler iptables-Regeln kann zu Leistungsproblemen beim Port-Map-Plug-in führen und möglicherweise zukünftige Aktualisierungen der iptables-Regeln verhindern oder einen Neustart des Containers calico-node verursachen, wenn innerhalb einer bestimmten Zeit keine Sperre für die Aktualisierung der iptables-Regeln empfangen wird. Zur Vermeidung solcher Leistungsprobleme können Sie das Plug-in für Portzuordnungen inaktivieren, indem Sie es aus der Calico-CNI-Konfiguration Ihres Clusters entfernen.

Wenn Sie hostPorts verwenden müssen, inaktivieren Sie das Plug-in für die Portzuordnung nicht.

  1. Bearbeiten Sie die Calico-Installationsressource default.

    kubectl edit installation default -n calico-system
    
  2. Ändern Sie im Abschnitt spec.calicoNetwork den Wert für das Feld hostPorts in Disabled.

    ...
    spec:
      calicoNetwork:
        hostPorts: Disabled
        ipPools:
          - cidr: 172.30.0.0/16
            encapsulation: IPIPCrossSubnet
            natOutgoing: Enabled
            nodeSelector: all()
        mtu: 1480
        nodeAddressAutodetectionV4:
          interface: (^bond0$|^eth0$|^ens6$|^ens3$)
      kubernetesProvider: OpenShift
      registry: us.icr.io/armada-master/
      variant: Calico
    status:
      variant: Calico
    
  3. Speichern und schließen Sie die Datei. Daraufhin werden Ihre Änderungen automatisch angewendet.