Partager via


Désactiver cgroupsv2 sur le nœud Kubernetes Nexus

Les groupes de contrôle ou «cgroups » permettent au système d’exploitation Linux d’allouer des partages de ressources,de la mémoire, des E/S, etc.-à une hiérarchie de processus de système d’exploitation. Ces ressources peuvent être isolées d’autres processus et de cette façon permettent la conteneurisation des charges de travail.

Une version 2 améliorée des groupes de contrôle (« cgroupsv2 ») a été incluse dans le noyau Linux 4.5. La principale différence entre la version v1 d’origine cgroups et la version v2 plus récente cgroups est qu’une seule hiérarchie est cgroups autorisée dans la cgroups version 2. En plus de cette différence de hiérarchie unique, cgroups v2 apporte des modifications rétrocompatibles au pseudo-système de fichiers utilisé cgroups par v1, par exemple en supprimant le tasks pseudofichier et la clone_children fonctionnalité.

Toutefois, certaines applications peuvent s’appuyer sur un comportement plus ancien cgroups de v1, et cette documentation explique comment désactiver cgroups v2 sur des images de système d’exploitation Linux plus récentes utilisées pour les nœuds worker Kubernetes de l’opérateur Nexus.

Nexus Kubernetes 1.27 et au-delà

Bien que Kubernetes 1.25 ait ajouté la prise en charge de cgroups v2 dans kubelet, pour cgroups que v2 soit utilisé, il doit être activé dans le noyau Linux.

Les nœuds Worker Nexus Nexus Kubernetes exécutent des versions spéciales de Microsoft Azure Linux (précédemment appelées CBL Mariner OS) qui correspondent à la version Kubernetes activée par cette image. L’image du système d’exploitation Linux pour les nœuds Worker activecgroups v2 par défaut dans Nexus Kubernetes version 1.27.

cgroups v2 n’est pas activé dans les versions de Nexus Kubernetes antérieures à la version 1.27. Par conséquent, vous n’avez pas besoin d’effectuer les étapes décrites dans ce guide pour désactiver cgroups v2.

Prérequis

Avant de suivre ce guide pratique, nous vous recommandons de :

  • Reportez-vous au guide de démarrage rapide du cluster Nexus Kubernetes pour obtenir une vue d’ensemble complète et des étapes impliquées.
  • Veillez à respecter les conditions préalables décrites pour garantir l’implémentation fluide du guide.

Appliquer la désactivation de cgroupv2 Daemonset

Avertissement

Si vous effectuez cette étape sur un cluster Kubernetes qui a déjà des charges de travail en cours d’exécution, toutes les charges de travail qui s’exécutent sur des nœuds de cluster Kubernetes sont arrêtées, car le Daemonset redémarrage de la machine hôte. Par conséquent, il est fortement recommmendé que vous appliquez cela Daemonset sur un nouveau cluster Nexus Kubernetes avant que les charges de travail ne soient planifiées dessus.

Copiez la définition suivante Daemonset dans un fichier sur un ordinateur sur lequel vous pouvez exécuter kubectl des commandes sur le cluster Nexus Kubernetes sur lequel vous souhaitez désactiver cgroups v2.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: revert-cgroups
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: revert-cgroups
  template:
    metadata:
      labels:
        name: revert-cgroups
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: cgroup-version
                    operator: NotIn
                    values:
                      - v1
      tolerations:
        - operator: Exists
          effect: NoSchedule
      containers:
        - name: revert-cgroups
          image: mcr.microsoft.com/cbl-mariner/base/core:1.0
          command:
            - nsenter
            - --target
            - "1"
            - --mount
            - --uts
            - --ipc
            - --net
            - --pid
            - --
            - bash
            - -exc
            - |
              CGROUP_VERSION=`stat -fc %T /sys/fs/cgroup/`
              if [ "$CGROUP_VERSION" == "cgroup2fs" ]; then
                echo "Using v2, reverting..."
                if uname -r | grep -q "cm2"; then
                  echo "Detected Azure Linux OS version older than v3"
                  sed -i 's/systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all/systemd.unified_cgroup_hierarchy=0/' /boot/grub2/grub.cfg
                else
                  sed -i 's/systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all/systemd.unified_cgroup_hierarchy=0/' /etc/default/grub
                  grub2-mkconfig -o /boot/grub2/grub.cfg
                  if ! grep -q systemd.unified_cgroup_hierarchy=0 /boot/grub2/grub.cfg; then
                    echo "failed to update grub2 config"
                    exit 1
                  fi
                fi
                reboot
              fi

              sleep infinity
          securityContext:
            privileged: true
      hostNetwork: true
      hostPID: true
      hostIPC: true
      terminationGracePeriodSeconds: 0

Et appliquez les Daemonsetpoints suivants :

kubectl apply -f /path/to/daemonset.yaml

L’exemple ci-dessus Daemonset s’applique à tous les nœuds Worker Kubernetes du cluster, sauf ceux où une cgroup-version=v1 étiquette a été appliquée. Pour ces nœuds Worker avec cgroups v2 activé, il Daemonset modifie la configuration de démarrage du noyau Linux et redémarre la machine.

Vous pouvez surveiller le déploiement et Daemonset ses effets en exécutant le script suivant :

#!/bin/bash

set -x

# Set the DaemonSet name and label key-value pair
DAEMONSET_NAME="revert-cgroups"
NAMESPACE="kube-system"
LABEL_KEY="cgroup-version"
LABEL_VALUE="v1"
LOG_PATTERN="sleep infinity"

# Function to check if all pods are completed
check_pods_completed() {
        local pods_completed=0

        # Get the list of DaemonSet pods
        pod_list=$(kubectl get pods -n "${NAMESPACE}" -l name="${DAEMONSET_NAME}" -o jsonpath='{range.items[*]}{.metadata.name}{"\n"}{end}')

        # Loop through each pod
        for pod in $pod_list; do

                # Get the logs from the pod
                logs=$(kubectl logs -n "${NAMESPACE}" "${pod}")

                # Check if the logs end with the specified pattern
                if [[ $logs == *"${LOG_PATTERN}"* ]]; then
                        ((pods_completed++))
                fi

        done

        # Return the number of completed pods
        echo $pods_completed
}

# Loop until all pods are completed
while true; do
        pods_completed=$(check_pods_completed)

        # Get the total number of pods
        total_pods=$(kubectl get pods -n "${NAMESPACE}" -l name=${DAEMONSET_NAME} --no-headers | wc -l)

        if [ "$pods_completed" -eq "$total_pods" ]; then
                echo "All pods are completed."
                break
        else
                echo "Waiting for pods to complete ($pods_completed/$total_pods)..."
                sleep 10
        fi
done

# Once all pods are completed, add the label to the nodes
node_list=$(kubectl get pods -n "${NAMESPACE}" -l name=${DAEMONSET_NAME} -o jsonpath='{range.items[*]}{.spec.nodeName}{"\n"}{end}' | sort -u)

for node in $node_list; do
        kubectl label nodes "${node}" ${LABEL_KEY}=${LABEL_VALUE}
        echo "Added label '${LABEL_KEY}:${LABEL_VALUE}' to node '${node}'."
done

echo "Script completed."

Le script ci-dessus étiquette les nœuds qui ont été cgroups désactivés v2. Cette étiquetage supprime les Daemonset nœuds qui ont déjà été redémarrés avec les paramètres du cgroups noyau v1.