Усунення несправностей управління топологією

Kubernetes приховує від користувача багато аспектів виконання подів на вузлах. Це зроблено навмисно. Однак деякі робочі навантаження вимагають більш надійних гарантій щодо затримки та/або продуктивності, щоб працювати прийнятно. Kubelet надає методи для реалізації більш складних політик розміщення робочих навантажень, зберігаючи при цьому абстракцію від явних директив розміщення.

Ви можете керувати топологією всередині вузлів. Це означає, що ви допомагаєте kubelet налаштувати операційну систему хоста так, щоб под і контейнери розміщувалися на правильній стороні внутрішніх меж, таких як домени NUMA. (NUMA — це абревіатура від «non-uniform memory access» (нерівномірний доступ до памʼяті) і означає, що процесори можуть бути топологічно ближчими до певних областей памʼяті через фізичне розташування апаратних компонентів і спосіб їх зʼєднання).

Джерела інформації для усунення несправностей

Ви можете використовувати наступні засоби для усунення несправностей, через які под не вдалося розгорнути або який було відхилено на вузлі, в контексті управління топологією:

  • Статус пода — вказує на помилки спорідненості топології
  • Системні журнали — містять цінну інформацію для налагодження, наприклад, про згенеровані підказки
  • Файл стану kubelet — дамп внутрішнього стану диспетчера памʼяті (включно з мапою вузлів і мапами памʼяті)
  • Ви можете використовувати API ресурсів втулка пристрою для отримання інформації про памʼять, зарезервовану для контейнерів

Усунення несправностей TopologyAffinityError

Ця помилка зазвичай виникає в таких ситуаціях:

  • вузол не має достатньо ресурсів для задоволення запиту пода
  • запит пода відхилено через певні обмеження політики Topology Manager

Помилка зʼявляється в статусі пода:

kubectl get pods
NAME         READY   STATUS                  RESTARTS   AGE
guaranteed   0/1     TopologyAffinityError   0          113s

Використовуйте kubectl describe pod <id> або kubectl events, щоб отримати детальне повідомлення про помилку:

Warning  TopologyAffinityError  10m   kubelet, dell8  Resources cannot be allocated with Topology locality

Перегляньте системні журнали

Перегляньте системні журнали щодо конкретного пода.

Набір підказок, згенерованих менеджером ЦП, повинен бути присутнім у журналах. Також у журналах можна знайти набір підказок, згенерованих менеджером памʼяті для пода.

Менеджер топології обʼєднує ці підказки, щоб обчислити єдину найкращу підказку. Найкраща підказка також повинна бути присутня в журналах.

Найкраща підказка вказує, куди розподілити всі ресурси. Topology Manager перевіряє цю підказку на відповідність поточній політиці і, виходячи з результату перевірки, або приймає под до вузла, або відхиляє його.

Також перегляньте журнали на наявність записів, повʼязаних з Memory Manager, наприклад, щоб знайти інформацію про оновлення cgroups та cpuset.mems.

Examples

Перевірка стану менеджера памʼяті на вузлі

Спочатку розгорнемо демонстраційний под Guaranteed, специфікація якого є такою:

apiVersion: v1
kind: Pod
metadata:
  name: guaranteed
spec:
  containers:
  - name: guaranteed
    image: consumer
    imagePullPolicy: Never
    resources:
      limits:
        cpu: "2"
        memory: 150Gi
      requests:
        cpu: "2"
        memory: 150Gi
    command: ["sleep","infinity"]

Далі увійдіть на вузол, де він був розгорнутий, і перевірте файл стану в /var/lib/kubelet/memory_manager_state:

{
   "policyName":"Static",
   "machineState":{
      "0":{
         "numberOfAssignments":1,
         "memoryMap":{
            "hugepages-1Gi":{
               "total":0,
               "systemReserved":0,
               "allocatable":0,
               "reserved":0,
               "free":0
            },
            "memory":{
               "total":134987354112,
               "systemReserved":3221225472,
               "allocatable":131766128640,
               "reserved":131766128640,
               "free":0
            }
         },
         "nodes":[
            0,
            1
         ]
      },
      "1":{
         "numberOfAssignments":1,
         "memoryMap":{
            "hugepages-1Gi":{
               "total":0,
               "systemReserved":0,
               "allocatable":0,
               "reserved":0,
               "free":0
            },
            "memory":{
               "total":135286722560,
               "systemReserved":2252341248,
               "allocatable":133034381312,
               "reserved":29295144960,
               "free":103739236352
            }
         },
         "nodes":[
            0,
            1
         ]
      }
   },
   "entries":{
      "fa9bdd38-6df9-4cf9-aa67-8c4814da37a8":{
         "guaranteed":[
            {
               "numaAffinity":[
                  0,
                  1
               ],
               "type":"memory",
               "size":161061273600
            }
         ]
      }
   },
   "checksum":4142013182
}

З файлу стану можна зробити висновок, що под був прикріплений до обох вузлів NUMA, тобто:

"numaAffinity":[
   0,
   1
],

Термін «закріплений» означає, що споживання памʼяті подом обмежується (через конфігурацію cgroups) цими вузлами NUMA.

Це автоматично означає, що диспетчер памʼяті створив нову групу, яка складається з цих двох вузлів NUMA, тобто вузлів NUMA з індексами 0 і 1.

Для аналізу доступних ресурсів памʼяті в групі необхідно додати відповідні записи з вузлів NUMA, що належать до групи.

Наприклад, загальний обсяг вільної «традиційної» памʼяті в групі можна обчислити, додавши вільну памʼять, доступну в кожному вузлі NUMA в групі, тобто в розділі "memory" вузла NUMA 0 ("free":0) і вузла NUMA 1 ("free":103739236352). Отже, загальний обсяг вільної «традиційної» памʼяті в цій групі дорівнює 0 + 103739236352 байтів.

Рядок "systemReserved":3221225472 вказує, що адміністратор цього вузла зарезервував 3221225472 байти (тобто 3Gi) для обслуговування kubelet і системних процесів у вузлі NUMA 0, використовуючи прапорець --reserved-memory.

Перевірка API ресурсів втулка пристрою

Kubelet надає службу gRPC PodResourceLister, яка дозволяє виявляти ресурси та повʼязані з ними метадані. Використовуючи його List gRPC endpoint, можна отримати інформацію про зарезервовану памʼять для кожного контейнера, яка міститься в повідомленні protobuf ContainerMemory.

Цю інформацію можна отримати виключно для подів у класі Guaranteed QoS.