Udostępnij za pośrednictwem


Wyłączanie cgroupsv2 w węźle Nexus Kubernetes

Grupy kontrolne lub "cgroups" umożliwiają systemowi operacyjnemu Linux przydzielanie zasobów — udziały procesora CPU, pamięć, we/wy itp. — do hierarchii procesów systemu operacyjnego. Te zasoby można odizolować od innych procesów i w ten sposób umożliwić konteneryzację obciążeń.

Rozszerzona wersja 2 grup kontrolnych ("cgroupsv2") została uwzględniona w jądrze systemu Linux 4.5. Podstawową różnicą między oryginalną cgroups wersją 1 a nowszą cgroups wersją 2 jest to, że tylko jedna hierarchia cgroups programu jest dozwolona w wersji cgroups 2. Oprócz tej różnicy z jedną hierarchią wersja cgroups 2 wprowadza pewne niezgodne wstecz zmiany w systemie pseudoplików, które cgroups były używane w wersji 1, na przykład usuwając tasks pseudoplik i clone_children funkcjonalność.

Niektóre aplikacje mogą jednak polegać na starszym cgroups zachowaniu w wersji 1, a w tej dokumentacji wyjaśniono, jak wyłączyć cgroups v2 na nowszych obrazach systemu operacyjnego Linux używanych dla węzłów roboczych Operatora Nexus Kubernetes.

Nexus Kubernetes 1.27 i nowsze

Chociaż platforma Kubernetes 1.25 dodała obsługę wersji cgroups 2 w ramach narzędzia kubelet, aby można cgroups było go używać w wersji 2, musi być włączona w jądrze systemu Linux.

Węzły robocze Operator Nexus Kubernetes uruchamiają specjalne wersje systemu Microsoft Azure Linux (wcześniej nazywanego systemem operacyjnym CBL Mariner), które odpowiadają wersji platformy Kubernetes włączonej przez ten obraz. Obraz systemu operacyjnego Linux dla węzłów roboczych domyślnie włączacgroups wersję 2 w systemie Nexus Kubernetes w wersji 1.27.

cgroups Wersja 2 nie jest włączona w wersjach rozwiązania Nexus Kubernetes przed wersją 1.27. W związku z tym nie musisz wykonywać kroków opisanych w tym przewodniku, aby wyłączyć cgroups 2.

Wymagania wstępne

Przed kontynuowaniem tego przewodnika z instrukcjami zaleca się wykonanie następujących czynności:

  • Zapoznaj się z przewodnikiem Szybki start dotyczącym klastra Nexus Kubernetes, aby zapoznać się z kompleksowym omówieniem i krokami.
  • Upewnij się, że zostały spełnione określone wymagania wstępne, aby zapewnić bezproblemową implementację przewodnika.

Stosowanie wyłączania cgroupv2 Daemonset

Ostrzeżenie

Jeśli wykonasz ten krok w klastrze Kubernetes, który ma już uruchomione obciążenia, wszystkie obciążenia uruchomione w węzłach klastra Kubernetes zostaną zakończone, ponieważ Daemonset komputer hosta zostanie uruchomiony ponownie. W związku z tym zdecydowanie zaleca się zastosowanie go Daemonset w nowym klastrze Nexus Kubernetes przed zaplanowaniem obciążeń.

Skopiuj następującą Daemonset definicję do pliku na komputerze, na którym można wykonywać kubectl polecenia względem klastra Nexus Kubernetes, na którym chcesz wyłączyć cgroups 2.

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..."
                sed -i 's/systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all/systemd.unified_cgroup_hierarchy=0/' /boot/grub2/grub.cfg
                reboot
              fi

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

Zastosuj element Daemonset:

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

Powyższe Daemonset dotyczy wszystkich węzłów roboczych platformy Kubernetes w klastrze z wyjątkiem tych, w których zastosowano etykietę cgroup-version=v1 . W przypadku tych węzłów roboczych z włączoną wersją cgroupsDaemonset 2 modyfikuje konfigurację rozruchu jądra systemu Linux i ponownie uruchamia maszynę.

Wdrożenie elementu i jego efektów można monitorować Daemonset , wykonując następujący skrypt:

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

Powyższy skrypt oznacza węzły, które miały cgroups wyłączoną 2. To etykietowanie Daemonset usuwa element z węzłów, które zostały już ponownie uruchomione z cgroups ustawieniami jądra w wersji 1.