Optimisation des performances pour les noeuds worker Red Hat CoreOS

Satellite

Systèmes d'exploitation de noeud worker pris en charge
Red Hat CoreOS (RHCOS)

Vous pouvez optimiser les performances de votre nœud de travail Red Hat CoreOS en activant l'épinglage de l'unité centrale, l'accès non uniforme à la mémoire (NUMA) et les pages volumineuses. Ces configurations peuvent être utiles aux applications qui ont des exigences strictes en matière de performances. Toutefois, ces personnalisations peuvent entraîner des problèmes de planification de la charge de travail.

Au lieu de régler les performances des nœuds de travail avec des fichiers MachineConfig dans Red Hat OpenShift, vous pouvez modifier l'hôte avec un fichier daemonset. Pour plus d'informations, voir Modifier le MTU de Calico ou Optimiser les performances des nœuds de travail de Red Hat CoreOS.

Déploiement de l'opérateur Node Feature Discovery

Satellite

Avant de pouvoir activer NUMA, l'épinglage d'UC et les pages très volumineuses sur vos noeuds worker, vous devez déployer l'opérateur Node Feature Discovery Operator. Pour plus d'informations, voir Node Feature Discovery Operator.

Activation de l'accès à la mémoire non uniforme (NUMA), de l'épinglage d'UC et des pages très volumineuses sur vos noeuds worker

Satellite

Avant de commencer, vérifiez que vous avez déployé l'opérateur Node Feature Discovery Operator.

  1. Sauvegardez le fichier DaemonSet suivant dans un fichier appelé customize.yaml.

    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: ibm-user-custom-configurator-privileged
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:openshift:scc:privileged
    subjects:
      - kind: ServiceAccount
        name: ibm-user-custom-configurator
        namespace: kube-system
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ibm-user-custom-configurator
      namespace: kube-system
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ibm-user-custom-configurator
      namespace: kube-system
    data:
      89-hugepages.conf: |
        vm.nr_hugepages=<<NUMBER_OF_HUGEPAGES>>
      configure.sh: |
        #!/usr/bin/env bash
        set -x
        cp -f /scripts/ibm-user-custom-configuration.sh /host-usr-local-bin/ibm-user-custom-configuration.sh
        chmod 0755 /host-usr-local-bin/ibm-user-custom-configuration.sh
        cp -f /scripts/ibm-user-custom-configuration.service /host-etc-systemd-dir/ibm-user-custom-configuration.service
        chmod 0644 /host-etc-systemd-dir/ibm-user-custom-configuration.service
        if [[ -f /scripts/89-hugepages.conf ]]; then
          cp -f /scripts/89-hugepages.conf /host-etc-systctld-dir/89-hugepages.conf
        fi
        nsenter -t 1 -m -u -i -n -p -- systemctl daemon-reload
        nsenter -t 1 -m -u -i -n -p -- systemctl enable ibm-user-custom-configuration.service
        nsenter -t 1 -m -u -i -n -p -- systemctl start ibm-user-custom-configuration.service
      ibm-user-custom-configuration.sh: |
        #!/usr/bin/env bash
        set -x
        GIGABYTES_RESERVED_MEMORY=$(echo $SYSTEM_RESERVED_MEMORY | awk -F 'Gi' '{print $1}')
        GIGABYTES_RESERVED_MEMORY_ROUNDED_UP=$(echo $GIGABYTES_RESERVED_MEMORY | awk '{print int($1+0.999)}')
        sed -i "s/SYSTEM_RESERVED_MEMORY=.*/SYSTEM_RESERVED_MEMORY=${GIGABYTES_RESERVED_MEMORY_ROUNDED_UP}Gi/g" /etc/node-sizing.env
        TOTAL_NUMA_MEMORY_TO_ALLOCATE=$(echo "$GIGABYTES_RESERVED_MEMORY_ROUNDED_UP" "1024" | awk '{print $1 * $2 + 100}')
        if cat /etc/kubernetes/kubelet.conf | jq -r .; then
          cat >/tmp/ibm-user-config.conf.json <<EOF
          {
            "topologyManagerPolicy": "<<TOPOLOGY_MANAGER_POLICY_VALUE>>",
            "memoryManagerPolicy": "Static",
            "cpuManagerPolicy": "static",
            "reservedMemory": [
              {
                "numaNode": 0,
                "limits": {
                "memory": "${TOTAL_NUMA_MEMORY_TO_ALLOCATE}Mi"
                  }
              }
            ]
          }
        EOF
          if ! cat /tmp/ibm-user-config.conf.json | jq -r .; then
            exit 1
          fi
          if ! jq -s '.[0] * .[1]' /tmp/ibm-user-config.conf.json /etc/kubernetes/kubelet.conf > /etc/kubernetes/tmp-kubelet.conf; then
            exit 1
          fi
          mv -f /etc/kubernetes/tmp-kubelet.conf /etc/kubernetes/kubelet.conf
          else
            cat >/tmp/ibm-user-config.conf <<EOF
        #START USER CONFIG
        topologyManagerPolicy: <<TOPOLOGY_MANAGER_POLICY_VALUE>>
        memoryManagerPolicy: Static
        cpuManagerPolicy: static
        reservedMemory:
          - numaNode: 0
            limits:
              memory: ${TOTAL_NUMA_MEMORY_TO_ALLOCATE}Mi
        #END USER CONFIG
        EOF
          sed -i '/#START USER CONFIG/,/#END USER CONFIG/d' /etc/kubernetes/kubelet.conf
          cat /tmp/ibm-user-config.conf >>/etc/kubernetes/kubelet.conf
        fi
      ibm-user-custom-configuration.service: |
        [Unit]
        Description=Add custom user config to kubelet
        Before=kubelet.service
        After=kubelet-auto-node-size.service
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        EnvironmentFile=/etc/node-sizing.env
        ExecStart=/usr/local/bin/ibm-user-custom-configuration.sh
        [Install]
        WantedBy=multi-user.target
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      labels:
        app: ibm-user-custom-configurator
      name: ibm-user-custom-configurator
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          app: ibm-user-custom-configurator
      template:
        metadata:
          labels:
            app: ibm-user-custom-configurator
        spec:
          nodeSelector:
            feature.node.kubernetes.io/memory-numa: "true"
            ibm-cloud.kubernetes.io/os: RHCOS
          tolerations:
            - operator: "Exists"
          hostPID: true
          serviceAccount: ibm-user-custom-configurator
          initContainers:
            - name: configure
              image: "registry.access.redhat.com/ubi8/ubi:8.6"
              command: ['/bin/bash', '-c', 'mkdir /cache && cp /scripts/configure.sh /cache && chmod +x /cache/configure.sh && /bin/bash /cache/configure.sh']
              securityContext:
                privileged: true
              volumeMounts:
                - mountPath: /scripts
                  name: script-config
                - mountPath: /host-etc-systemd-dir
                  name: etc-systemd-dir
                - mountPath: /host-usr-local-bin
                  name: usr-local-bin
                - mountPath: /host-etc-systctld-dir
                  name: etc-systctld-dir
          containers:
            - name: pause
              image: us.icr.io/armada-master/pause:3.2
          volumes:
            - name: etc-systemd-dir
              hostPath:
                path: /etc/systemd/system
            - name: etc-systctld-dir
              hostPath:
                path: /etc/sysctl.d
            - name: usr-local-bin
              hostPath:
                path: /usr/local/bin
            - name: script-config
              configMap:
                name: ibm-user-custom-configurator
    
  2. Editez les valeurs DaemonSet pour optimiser les performances.

NUMBER_OF_HUGEPAGES

Entrez le nombre de pages très volumineuses que vous souhaitez allouer. Par exemple : 2048. Si vous ne souhaitez pas activer les pages très volumineuses, entrez 0. Plus vous allouez de pages très volumineuses, moins la mémoire globale est disponible pour vos applications.

TOPOLOGY_MANAGER_POLICY_VALUE

Saisissez la politique du gestionnaire de topologie que vous souhaitez utiliser. La politique best-effort est recommandée pour garantir une disponibilité maximale de la programmation. Toutefois, vous pouvez utiliser d'autres politiques pour une validation plus stricte des exigences tout en réduisant la disponibilité de la planification de la charge de travail. Pour plus d'informations, voir Gestionnaire de topologie.

Vous pouvez éditer la section nodeSelector pour n'appliquer la configuration qu'à un sous-ensemble de vos noeuds worker.

  1. Appliquez l' DaemonSet e en exécutant la commande suivante.
    kubectl replace --force -f customize.yaml
    
  2. Vérifiez que les pods sont à l'état Running.
    kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide
    
  3. Une fois les pods en cours d'exécution, réamorcez chaque noeud worker.
    1. Déployez un pod de débogage sur votre nœud de travail.
        oc debug node/NODE_NAME
        ```
    1. Une fois la session de débogage démarrée, exécutez la commande suivante.
    ```sh {: pre}
        nsenter -t 1 -m -u -i -n -p -- reboot
        ```
    1. Répétez ces étapes pour chaque nœud de travail que vous souhaitez redémarrer.
    
    
    

Activation de l'épinglage d'UC et des pages très volumineuses sur vos noeuds worker

Satellite

Avant de commencer, vérifiez que vous avez déployé l'opérateur Node Feature Discovery Operator.

  1. Sauvegardez le fichier DaemonSet suivant dans un fichier appelé cpu-pinning.yaml.

    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: ibm-user-custom-configurator-privileged
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:openshift:scc:privileged
    subjects:
      - kind: ServiceAccount
        name: ibm-user-custom-configurator
        namespace: kube-system
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ibm-user-custom-configurator
      namespace: kube-system
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ibm-user-custom-configurator
      namespace: kube-system
    data:
      89-hugepages.conf: |
        vm.nr_hugepages=<<NUMBER_OF_HUGEPAGES>>
      configure.sh: |
        #!/usr/bin/env bash
        set -x
        cp -f /scripts/ibm-user-custom-configuration.sh /host-usr-local-bin/ibm-user-custom-configuration.sh
        chmod 0755 /host-usr-local-bin/ibm-user-custom-configuration.sh
        cp -f /scripts/ibm-user-custom-configuration.service /host-etc-systemd-dir/ibm-user-custom-configuration.service
        chmod 0644 /host-etc-systemd-dir/ibm-user-custom-configuration.service
        if [[ -f /scripts/89-hugepages.conf ]]; then
          cp -f /scripts/89-hugepages.conf /host-etc-systctld-dir/89-hugepages.conf
        fi
        nsenter -t 1 -m -u -i -n -p -- systemctl daemon-reload
        nsenter -t 1 -m -u -i -n -p -- systemctl enable ibm-user-custom-configuration.service
        nsenter -t 1 -m -u -i -n -p -- systemctl start ibm-user-custom-configuration.service
      ibm-user-custom-configuration.sh: |
        #!/usr/bin/env bash
        set -x
        if cat /etc/kubernetes/kubelet.conf | jq -r .; then
          cat >/tmp/ibm-user-config.conf.json <<EOF
          {
            "cpuManagerPolicy": "static"
          }
        EOF
          if ! cat /tmp/ibm-user-config.conf.json | jq -r .; then
            exit 1
          fi
          if ! jq -s '.[0] * .[1]' /tmp/ibm-user-config.conf.json /etc/kubernetes/kubelet.conf > /etc/kubernetes/tmp-kubelet.conf; then
            exit 1
          fi
          mv -f /etc/kubernetes/tmp-kubelet.conf /etc/kubernetes/kubelet.conf
        else
          cat >/tmp/ibm-user-config.conf <<EOF
        #START USER CONFIG
        cpuManagerPolicy: static
        #END USER CONFIG
        EOF
          sed -i '/#START USER CONFIG/,/#END USER CONFIG/d' /etc/kubernetes/kubelet.conf
          cat /tmp/ibm-user-config.conf >>/etc/kubernetes/kubelet.conf
        fi
      ibm-user-custom-configuration.service: |
        [Unit]
        Description=Add custom user config to kubelet
        Before=kubelet.service
        After=kubelet-auto-node-size.service
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        EnvironmentFile=/etc/node-sizing.env
        ExecStart=/usr/local/bin/ibm-user-custom-configuration.sh    
        [Install]
        WantedBy=multi-user.target
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      labels:
        app: ibm-user-custom-configurator
      name: ibm-user-custom-configurator
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          app: ibm-user-custom-configurator
      template:
        metadata:
          labels:
            app: ibm-user-custom-configurator
        spec:
          nodeSelector:
            ibm-cloud.kubernetes.io/os: RHCOS
          tolerations:
            - operator: "Exists"
          hostPID: true
          serviceAccount: ibm-user-custom-configurator
          initContainers:
            - name: configure
              image: "registry.access.redhat.com/ubi8/ubi:8.6"
              command: ['/bin/bash', '-c', 'mkdir /cache && cp /scripts/configure.sh /cache && chmod +x /cache/configure.sh && /bin/bash /cache/configure.sh']
              securityContext:
                privileged: true
              volumeMounts:
                - mountPath: /scripts
                  name: script-config
                - mountPath: /host-etc-systemd-dir
                  name: etc-systemd-dir
                - mountPath: /host-usr-local-bin
                  name: usr-local-bin
                - mountPath: /host-etc-systctld-dir
                  name: etc-systctld-dir
          containers:
            - name: pause
              image: us.icr.io/armada-master/pause:3.2
          volumes:
            - name: etc-systemd-dir
              hostPath:
                path: /etc/systemd/system
            - name: etc-systctld-dir
              hostPath:
                path: /etc/sysctl.d
            - name: usr-local-bin
              hostPath:
                path: /usr/local/bin
            - name: script-config
              configMap:
                name: ibm-user-custom-configurator
    
  2. Editez les valeurs DaemonSet pour optimiser les performances.

NUMBER_OF_HUGEPAGES

Entrez le nombre de pages très volumineuses que vous souhaitez allouer. Par exemple : 2048. Si vous ne souhaitez pas activer les pages très volumineuses, entrez 0. Plus vous allouez de pages très volumineuses, moins la mémoire globale est disponible pour vos applications.

Vous pouvez éditer la section nodeSelector pour n'appliquer la configuration qu'à un sous-ensemble de vos noeuds worker.

  1. Appliquez l' DaemonSet e en exécutant la commande suivante.
    kubectl replace --force -f cpu-pinnning.yaml
    
  2. Vérifiez que les pods sont à l'état Running.
    kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide
    
  3. Une fois les pods en cours d'exécution, réamorcez chaque noeud worker.
    1. Déployez un pod de débogage sur votre nœud de travail.
        oc debug node/NODE_NAME
        ```
    1. Une fois la session de débogage démarrée, exécutez la commande suivante.
    ```sh {: pre}
        nsenter -t 1 -m -u -i -n -p -- reboot
        ```
    1. Répétez ces étapes pour chaque nœud de travail que vous souhaitez redémarrer.
    
    

Activation des packages kernel-devel

Satellite

Vous devrez peut-être activer les packages kernel-devel pour utiliser les services ou le stockage Satellite tels que Spectrum Scale Fusion.

Procédez comme suit pour activer kernel-devel en appliquant une mappe de configuration personnalisée et une configuration de machine à vos noeuds worker.

  1. Exécutez la commande suivante pour appliquer l' MachineConfig.

    ibmcloud ks cluster config --cluster CLUSTERID
    cat >"/tmp/kernel-devel-payload.yaml" <<EOF
    apiVersion: v1
    kind: List
    metadata:
      name: pvg-machine-config-tester
      annotations:
    items:
      - apiVersion: v1
        kind: Namespace
        metadata:
          name: ibm-machine-config
      - apiVersion: v1
        data:
          config: |+
            apiVersion: machineconfiguration.openshift.io/v1
            kind: MachineConfig
            metadata:
              name: 97-kerneldevel
              labels:
                machineconfiguration.openshift.io/role: worker
            spec:
              config:
                ignition:
                  version: 3.2.0
              extensions:
              - kernel-devel
        kind: ConfigMap
        metadata:
          labels:
            ibm-cloud.kubernetes.io/user-specified-config: "true"
          name: user-ignition-config-97-kerneldevel
          namespace: ibm-machine-config
    EOF
    kubectl apply -f /tmp/kernel-devel-payload.yaml
    
  2. Attendez que les ressources soient déployées. Cette opération peut prendre 5 minutes ou plus.

  3. Passez en revue les détails de la mappe de configuration pour confirmer que le déploiement a abouti.

    1. Vérifiez que la zone config-validation="valid" est présente.
        kubectl get cm -n ibm-machine-config user-ignition-config-97-kerneldevel -o yaml | grep config-validation
        ```
    1. Vérifiez que `user-ignition-config-97-kerneldevel` est présent dans la mappe de configuration.
    ```sh {: pre}
        kubectl get cm -n ibm-machine-config -l ibm-cloud.kubernetes.io/nodepoolfeedback="true" -o yaml | grep user-ignition-config-97-kerneldevel
        ```
    
  4. Ajoutez des nœuds de travail à votre cluster. kernel-devel est activé pour les noeuds worker que vous ajoutez.

  5. Vérifiez que la fonction « kernel-devel » est activée.

    1. Démarrez un pod de débogage sur l'un de vos noeuds.
        oc debug node/NODEIP
        ```
    1. Exécutez la commande suivante : ` `nsenter` `.
    ```sh {: pre}
        nsenter -t 1 -m -u -i -n -p -- rpm -qa | grep kernel-devel
        ```
    
  6. Facultatif: si vous n'avez plus besoin de kernel-devel, vous pouvez le supprimer en exécutant la commande suivante.

    kubectl delete cm -n ibm-machine-config user-ignition-config-97-kerneldevel
    

Suppression des personnalisations de performances

Satellite

Si vous souhaitez supprimer des personnalisations de vos noeuds worker et les réinitialiser aux configurations par défaut, appliquez les DaemonSet suivantes.

  1. Sauvegardez le fichier DaemonSet suivant dans un fichier appelé remove-custom.yaml.

    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: ibm-user-custom-configurator-privileged
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:openshift:scc:privileged
    subjects:
      - kind: ServiceAccount
        name: ibm-user-custom-configurator
        namespace: kube-system
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ibm-user-custom-configurator
      namespace: kube-system
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ibm-user-custom-configurator
      namespace: kube-system
    data:
      89-hugepages.conf: |
        vm.nr_hugepages=0
      configure.sh: |
        #!/usr/bin/env bash
        set -x
        cp -f /scripts/ibm-user-custom-configuration.sh /host-usr-local-bin/ibm-user-custom-configuration.sh
        chmod 0755 /host-usr-local-bin/ibm-user-custom-configuration.sh
        cp -f /scripts/ibm-user-custom-configuration.service /host-etc-systemd-dir/ibm-user-custom-configuration.service
        chmod 0644 /host-etc-systemd-dir/ibm-user-custom-configuration.service
        if [[ -f /scripts/89-hugepages.conf ]]; then
          cp -f /scripts/89-hugepages.conf /host-etc-systctld-dir/89-hugepages.conf
        fi
        nsenter -t 1 -m -u -i -n -p -- systemctl daemon-reload
        nsenter -t 1 -m -u -i -n -p -- systemctl enable ibm-user-custom-configuration.service
        nsenter -t 1 -m -u -i -n -p -- systemctl start ibm-user-custom-configuration.service
      ibm-user-custom-configuration.sh: |
        #!/usr/bin/env bash
        set -x
        if cat /etc/kubernetes/kubelet.conf | jq -r .; then
          if ! jq 'del(.topologyManagerPolicy, .memoryManagerPolicy, .cpuManagerPolicy, .reservedMemory)' /etc/kubernetes/kubelet.conf > /etc/kubernetes/tmp-kubelet.conf; then
            exit 1
          fi
          mv -f /etc/kubernetes/tmp-kubelet.conf /etc/kubernetes/kubelet.conf
        else
          sed -i '/#START USER CONFIG/,/#END USER CONFIG/d' /etc/kubernetes/kubelet.conf
        fi
      ibm-user-custom-configuration.service: |
        [Unit]
        Description=Add custom user config to kubelet
        Before=kubelet.service
        After=kubelet-auto-node-size.service
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        EnvironmentFile=/etc/node-sizing.env
        ExecStart=/usr/local/bin/ibm-user-custom-configuration.sh
        [Install]
        WantedBy=multi-user.target
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      labels:
        app: ibm-user-custom-configurator
      name: ibm-user-custom-configurator
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          app: ibm-user-custom-configurator
      template:
        metadata:
          labels:
            app: ibm-user-custom-configurator
        spec:
          nodeSelector:
            ibm-cloud.kubernetes.io/os: RHCOS
          tolerations:
            - operator: "Exists"
          hostPID: true
          serviceAccount: ibm-user-custom-configurator
          initContainers:
            - name: configure
              image: "registry.access.redhat.com/ubi8/ubi:8.6"
              command: ['/bin/bash', '-c', 'mkdir /cache && cp /scripts/configure.sh /cache && chmod +x /cache/configure.sh && /bin/bash /cache/configure.sh']
              securityContext:
                privileged: true
              volumeMounts:
                - mountPath: /scripts
                  name: script-config
                - mountPath: /host-etc-systemd-dir
                  name: etc-systemd-dir
                - mountPath: /host-usr-local-bin
                  name: usr-local-bin
                - mountPath: /host-etc-systctld-dir
                  name: etc-systctld-dir
          containers:
            - name: pause
              image: us.icr.io/armada-master/pause:3.2
          volumes:
            - name: etc-systemd-dir
              hostPath:
                path: /etc/systemd/system
            - name: etc-systctld-dir
              hostPath:
                path: /etc/sysctl.d
            - name: usr-local-bin
              hostPath:
                path: /usr/local/bin
            - name: script-config
              configMap:
                name: ibm-user-custom-configurator
    
  2. Appliquez l' DaemonSet ation à votre cluster en exécutant la commande suivante.

    kubectl replace --force -f remove-custom.yaml
    
  3. Vérifiez que les pods sont à l'état Running.

    kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide
    
  4. Une fois les pods en cours d'exécution, réamorcez chaque noeud worker.

    1. Déployez un pod de débogage sur votre nœud de travail.
        oc debug node/NODE_NAME
        ```
    1. Une fois la session de débogage démarrée, exécutez la commande suivante.
    ```sh {: pre}
        nsenter -t 1 -m -u -i -n -p -- reboot
        ```
    1. Répétez ces étapes pour chaque nœud de travail que vous souhaitez redémarrer.