Dela via


Inaktivera cgroupsv2 på Nexus Kubernetes Node

Kontrollgrupper, eller "cgroups" tillåter att Linux-operativsystemet allokerar resurser – CPU-resurser, minne, I/O osv.– till en hierarki med operativsystemprocesser. Dessa resurser kan isoleras från andra processer och på så sätt aktivera containerisering av arbetsbelastningar.

En förbättrad version 2 av kontrollgrupper ("cgroupsv2") ingick i Linux kernel 4.5. Den primära skillnaden mellan den ursprungliga cgroups v1 och den nyare cgroups v2 är att endast en enda hierarki cgroups tillåts i cgroups v2. Förutom den här skillnaden cgroups med en enda hierarki gör v2 vissa bakåtkompatibla ändringar i pseudofilsystemet som cgroups v1 använde, till exempel att ta bort tasks pseudofilen och clone_children funktionerna.

Vissa program kan dock förlita sig på äldre cgroups v1-beteende, och den här dokumentationen förklarar hur du inaktiverar cgroups v2 på nyare Linux-operativsystemavbildningar som används för Operator Nexus Kubernetes-arbetsnoder.

Nexus Kubernetes 1.27 och senare

Kubernetes 1.25 har lagt till stöd för cgroups v2 i kubelet, men för cgroups att v2 ska kunna användas måste det vara aktiverat i Linux-kerneln.

Operatorn Nexus Kubernetes-arbetsnoder kör specialversioner av Microsoft Azure Linux (tidigare kallat CBL Mariner OS) som motsvarar Kubernetes-versionen som aktiveras av avbildningen. Linux OS-avbildningen för arbetsnoder aktiverarcgroups v2 som standard i Nexus Kubernetes version 1.27.

cgroups v2 är inte aktiverat i versioner av Nexus Kubernetes före 1.27. Därför behöver du inte utföra stegen i den här guiden för att inaktivera cgroups v2.

Förutsättningar

Innan du fortsätter med den här guiden rekommenderar vi att du:

  • I snabbstartsguiden för Nexus Kubernetes-klustret finns en omfattande översikt och steg.
  • Se till att du uppfyller de angivna förutsättningarna för att säkerställa en smidig implementering av guiden.

Tillämpa cgroupv2-inaktivering Daemonset

Varning

Om du utför det här steget på ett Kubernetes-kluster som redan har arbetsbelastningar som körs på det, avslutas alla arbetsbelastningar som körs på Kubernetes-klusternoder eftersom Daemonset värddatorn startas om. Därför rekommenderar vi att du tillämpar detta Daemonset på ett nytt Nexus Kubernetes-kluster innan arbetsbelastningar schemaläggs på det.

Kopiera följande Daemonset definition till en fil på en dator där du kan köra kubectl kommandon mot Nexus Kubernetes-klustret där du vill inaktivera 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

Och tillämpa :Daemonset

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

Ovanstående Daemonset gäller för alla Kubernetes-arbetsnoder i klustret utom sådana där en cgroup-version=v1 etikett har tillämpats. För de arbetsnoder med cgroups v2 aktiverat Daemonset ändrar startkonfigurationen för Linux-kerneln och startar om datorn.

Du kan övervaka distributionen Daemonset av och dess effekter genom att köra följande skript:

#!/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."

Ovanstående skript etiketterar noderna som har v2 cgroups inaktiverats. Den här etiketteringen tar bort de Daemonset noder som redan har startats om med cgroups v1-kernelinställningarna.