Ajuste del rendimiento de los nodos trabajadores de Red Hat CoreOS

Satellite

Sistemas operativos de nodo trabajador soportados
Red Hat CoreOS (RHCOS)

Puede ajustar el rendimiento de su nodo de trabajo Red Hat CoreOS activando el pinning de CPU, el acceso no uniforme a memoria (NUMA) y las páginas enormes. Estas configuraciones pueden beneficiar a aplicaciones con requisitos de rendimiento estrictos. Sin embargo, estas personalizaciones pueden causar problemas de programación de la carga de trabajo.

En lugar de ajustar el rendimiento del nodo trabajador con archivos MachineConfig en Red Hat OpenShift, puede modificar el host con un archivo daemonset. Para obtener más información, consulte Cambio de la MTU de Calico o Ajuste del rendimiento de los nodos de trabajo de Red Hat CoreOS.

Despliegue del operador de descubrimiento de características de Node

Satellite

Antes de poder habilitar NUMA, la fijación de CPU y páginas grandes en los nodos trabajadores, debe desplegar el operador de descubrimiento de características de Node. Para más información, consulte Node Feature Discovery Operator.

Habilitación del acceso a memoria no uniforme (NUMA), fijación de CPU y páginas grandes en los nodos trabajadores

Satellite

Antes de empezar, asegúrese de que ha desplegado el Operador de descubrimiento de características de Node.

  1. Guarde el DaemonSet siguiente en un archivo denominado 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. Edite los valores de DaemonSet para ajustar el rendimiento.

NUMBER_OF_HUGEPAGES

Especifique el número de páginas grandes que desea asignar. Por ejemplo: 2048. Si no desea habilitar páginas grandes, especifique 0. Cuantas más páginas grandes asigne, menos memoria global estará disponible para las aplicaciones.

TOPOLOGY_MANAGER_POLICY_VALUE

Introduzca la política del gestor de topología que desea utilizar. Se recomienda la política best-effort para garantizar la máxima disponibilidad de programación. Sin embargo, puede utilizar otras políticas para una validación de requisitos más estricta, reduciendo al mismo tiempo la disponibilidad de programación de la carga de trabajo. Para más información, consulte Gestor de topología.

Puede editar la sección nodeSelector para aplicar sólo la configuración a un subconjunto de los nodos trabajadores.

  1. Aplica el servicio « DaemonSet » ejecutando el siguiente comando.
    kubectl replace --force -f customize.yaml
    
  2. Verifique que los pods han entrado en el estado Running.
    kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide
    
  3. Después de que los pods estén en ejecución, rearranque cada nodo trabajador.
    1. Implementa un pod de depuración en tu nodo de trabajo.
        oc debug node/NODE_NAME
        ```
    1. Después de que se inicie la sesión de depuración, ejecute el mandato siguiente.
    ```sh {: pre}
        nsenter -t 1 -m -u -i -n -p -- reboot
        ```
    1. Repite estos pasos para cada nodo de trabajo que quieras reiniciar.
    
    
    

Habilitación de la fijación de CPU y páginas grandes en los nodos trabajadores

Satellite

Antes de empezar, asegúrese de que ha desplegado el Operador de descubrimiento de características de Node.

  1. Guarde el DaemonSet siguiente en un archivo denominado 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. Edite los valores de DaemonSet para ajustar el rendimiento.

NUMBER_OF_HUGEPAGES

Especifique el número de páginas grandes que desea asignar. Por ejemplo: 2048. Si no desea habilitar páginas grandes, especifique 0. Cuantas más páginas grandes asigne, menos memoria global estará disponible para las aplicaciones.

Puede editar la sección nodeSelector para aplicar sólo la configuración a un subconjunto de los nodos trabajadores.

  1. Aplica el servicio « DaemonSet » ejecutando el siguiente comando.
    kubectl replace --force -f cpu-pinnning.yaml
    
  2. Verifique que los pods han entrado en el estado Running.
    kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide
    
  3. Después de que los pods estén en ejecución, rearranque cada nodo trabajador.
    1. Implementa un pod de depuración en tu nodo de trabajo.
        oc debug node/NODE_NAME
        ```
    1. Después de que se inicie la sesión de depuración, ejecute el mandato siguiente.
    ```sh {: pre}
        nsenter -t 1 -m -u -i -n -p -- reboot
        ```
    1. Repite estos pasos para cada nodo de trabajo que quieras reiniciar.
    
    

Habilitación de paquetes de kernel-devel

Satellite

Es posible que tenga que habilitar los paquetes de kernel-devel para utilizar servicios o almacenamiento de Satellite como, por ejemplo, Spectrum Scale Fusion.

Realice los pasos siguientes para habilitar kernel-devel aplicando un mapa de configuración personalizado y una configuración de máquina a los nodos trabajadores.

  1. Ejecuta el siguiente comando para aplicar la configuración de « 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. Espera a que se implementen los recursos. Esto puede tardar 5 minutos o más.

  3. Revise los detalles del mapa de configuración para confirmar que el despliegue se ha realizado correctamente.

    1. Confirme que el campo config-validation="valid" está presente.
        kubectl get cm -n ibm-machine-config user-ignition-config-97-kerneldevel -o yaml | grep config-validation
        ```
    1. Confirme que `user-ignition-config-97-kerneldevel` está presente en el mapa de configuración.
    ```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. Añade nodos de trabajo a tu clúster. Los nodos trabajadores que añada tienen habilitado kernel-devel.

  5. Comprueba que la opción « kernel-devel » esté activada.

    1. Inicie un pod de depuración en uno de los nodos.
        oc debug node/NODEIP
        ```
    1. Ejecuta el siguiente comando de « `nsenter` ».
    ```sh {: pre}
        nsenter -t 1 -m -u -i -n -p -- rpm -qa | grep kernel-devel
        ```
    
  6. Opcional: Si ya no necesita kernel-devel, puede eliminarlo ejecutando el mandato siguiente.

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

Eliminación de personalizaciones de rendimiento

Satellite

Si desea eliminar personalizaciones de los nodos trabajadores y restablecerlas a las configuraciones predeterminadas, aplique el DaemonSet siguiente.

  1. Guarde el DaemonSet siguiente en un archivo denominado 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. Aplica el servicio « DaemonSet » a tu clúster ejecutando el siguiente comando.

    kubectl replace --force -f remove-custom.yaml
    
  3. Compruebe que los pods han entrado en el estado Running.

    kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide
    
  4. Después de que los pods estén en ejecución, rearranque cada nodo trabajador.

    1. Implementa un pod de depuración en tu nodo de trabajo.
        oc debug node/NODE_NAME
        ```
    1. Después de que se inicie la sesión de depuración, ejecute el mandato siguiente.
    ```sh {: pre}
        nsenter -t 1 -m -u -i -n -p -- reboot
        ```
    1. Repite estos pasos para cada nodo de trabajo que quieras reiniciar.