Узлы

Kubernetes запускает ваши приложения, помещая контейнеры в Поды для запуска на Узлах (Nodes). В зависимости от кластера, узел может быть виртуальной или физической машиной. Каждый узел содержит сервисы, необходимые для запуска Подов, управляемых плоскостью управления.

Обычно у вас есть несколько узлов в кластере; однако в среде обучения или среде с ограниченными ресурсами у вас может быть только один.

Компоненты на узле включают kubelet, среду выполнения контейнера и kube-proxy.

Управление

Существует два основных способа добавления Узлов в API сервер:

  1. Kubelet на узле саморегистрируется в плоскости управления
  2. Вы или другой пользователь вручную добавляете объект Узла

После того как вы создадите объект Узла или kubelet на узле самозарегистируется, плоскость управления проверяет, является ли новый объект Узла валидным (правильным). Например, если вы попробуете создать Узел при помощи следующего JSON манифеста:

{
  "kind": "Node",
  "apiVersion": "v1",
  "metadata": {
    "name": "10.240.79.157",
    "labels": {
      "name": "my-first-k8s-node"
    }
  }
}

Kubernetes создает внутри себя объект Узла (представление). Kubernetes проверяет, что kubelet зарегистрировался на API сервере, который совпадает со значением поля metadata.name Узла. Если узел здоров (если все необходимые сервисы запущены), он имеет право на запуск Пода. В противном случае этот узел игнорируется для любой активности кластера до тех пор, пока он не станет здоровым.

Имя объекта Узла должно быть валидным именем поддомена DNS.

Саморегистрация Узлов

Когда kubelet флаг --register-node имеет значение true (по умолчанию), то kubelet будет пытаться зарегистрировать себя на API сервере. Это наиболее предпочтительная модель, используемая большинством дистрибутивов.

Для саморегистрации kubelet запускается со следующими опциями:

  • --kubeconfig - Путь к учетным данным для аутентификации на API сервере.

  • --cloud-provider - Как общаться с облачным провайдером, чтобы прочитать метаданные о себе.

  • --register-node - Автоматически зарегистрироваться на API сервере.

  • --register-with-taints - Зарегистрировать узел с приведенным списком ограничений (taints) (разделенных запятыми <key>=<value>:<effect>).

    Ничего не делает, если register-node - false.

  • --node-ip - IP-адрес узла.

  • --node-labels - Метки для добавления при регистрации узла в кластере (смотрите ограничения для меток, установленные плагином согласования (admission plugin) NodeRestriction).

  • --node-status-update-frequency - Указывает, как часто kubelet отправляет статус узла мастеру.

Когда режим авторизации Узла и плагин согласования NodeRestriction включены, kubelet'ы имеют право только создавать/изменять свой собственный ресурс Узла.

Ручное администрирование узла

Вы можете создавать и изменять объекты узла используя kubectl.

Когда вы хотите создать объекты Узла вручную, установите kubelet флаг --register-node=false.

Вы можете изменять объекты Узла независимо от настройки --register-node. Например, вы можете установить метки на существующем Узле или пометить его не назначаемым.

Вы можете использовать метки на Узлах в сочетании с селекторами узла на Подах для управления планированием. Например, вы можете ограничить Под, иметь право на запуск только на группе доступных узлов.

Маркировка узла как не назначаемого предотвращает размещение планировщиком новых подов на этом Узле, но не влияет на существующие Поды на Узле. Это полезно в качестве подготовительного шага перед перезагрузкой узла или другим обслуживанием.

Чтобы отметить Узел не назначаемым, выполните:

kubectl cordon $NODENAME

Статус Узла

Статус узла содержит следующие данные:

Вы можете использовать kubectl для просмотра статуса Узла и других деталей:

kubectl describe node <insert-node-name-here>

Каждая секция из вывода команды описана ниже.

Адреса (Addresses)

Использование этих полей варьируется в зависимости от вашего облачного провайдера или конфигурации физических серверов (bare metal).

  • HostName: Имя хоста, сообщаемое ядром узла. Может быть переопределено через kubelet --hostname-override параметр.
  • ExternalIP: Обычно, IP адрес узла, который является внешне маршрутизируемым (доступен за пределами кластера).
  • InternalIP: Обычно, IP адрес узла, который маршрутизируется только внутри кластера.

Условия (Conditions)

Поле conditions описывает статус всех Running узлов. Примеры условий включают в себя:

Условия узла и описание того, когда применяется каждое условие.
Условие УзлаОписание
ReadyTrue если узел здоров и готов принять поды, False если узел нездоров и не принимает поды, и Unknown если контроллер узла не получал информацию от узла в течение последнего периода node-monitor-grace-period (по умолчанию 40 секунд)
DiskPressureTrue если присутствует давление на размер диска - то есть, если емкость диска мала; иначе False
MemoryPressureTrue если существует давление на память узла - то есть, если памяти на узле мало; иначе False
PIDPressureTrue если существует давление на процессы - то есть, если на узле слишком много процессов; иначе False
NetworkUnavailableTrue если сеть для узла настроена некорректно, иначе False

Состояние узла представлено в виде JSON объекта. Например, следующая структура описывает здоровый узел:

"conditions": [
  {
    "type": "Ready",
    "status": "True",
    "reason": "KubeletReady",
    "message": "kubelet is posting ready status",
    "lastHeartbeatTime": "2019-06-05T18:38:35Z",
    "lastTransitionTime": "2019-06-05T11:41:27Z"
  }
]

Если значение параметра Status для условия Ready остается Unknown или False дольше чем период pod-eviction-timeout(аргумент, переданный в kube-controller-manager), то все Поды на узле планируются к удалению контроллером узла. По умолчанию таймаут выселения пять минут. В некоторых случаях, когда узел недоступен, API сервер не может связаться с kubelet на узле. Решение об удалении подов не может быть передано в kubelet до тех пор, пока связь с API сервером не будет восстановлена. В то же время поды, которые запланированы к удалению, могут продолжать работать на отделенном узле.

Контроллер узла не будет принудительно удалять поды до тех пор, пока не будет подтверждено, что они перестали работать в кластере. Вы можете видеть, что поды, которые могут работать на недоступном узле, находятся в состоянии Terminating или Unknown. В тех случаях, когда Kubernetes не может сделать вывод из основной инфраструктуры о том, что узел окончательно покинул кластер, администратору кластера может потребоваться удалить объект узла вручную. Удаление объекта узла из Kubernetes приводит к удалению всех объектов Подов, запущенных на узле, с API сервера и освобождает их имена.

Контроллер жизненного цикла узла автоматически создает ограничения (taints), которые представляют собой условия. Планировщик учитывает ограничения Узла при назначении Пода на Узел. Поды так же могут иметь допуски (tolerations), что позволяет им сопротивляться ограничениям Узла.

Смотрите раздел Ограничить Узлы по Условию для дополнительной информации.

Емкость и Выделяемые ресурсы (Capacity and Allocatable)

Описывает ресурсы, доступные на узле: CPU, память и максимальное количество подов, которые могут быть запланированы на узле.

Поля в блоке capacity указывают общее количество ресурсов, которые есть на Узле. Блок allocatable указывает количество ресурсов на Узле, которые доступны для использования обычными Подами.

Вы можете прочитать больше о емкости и выделяемых ресурсах, изучая, как зарезервировать вычислительные ресурсы на Узле.

Информация (Info)

Описывает общую информацию об узле, такую как версия ядра, версия Kubernetes (версии kubelet и kube-proxy), версия Docker (если используется) и название ОС. Эта информация собирается Kubelet'ом на узле.

Контроллер узла

Контроллер узла является компонентом плоскости управления Kubernetes, который управляет различными аспектами узлов.

Контроллер узла играет различные роли в жизни узла. Первая - назначение CIDR-блока узлу при его регистрации (если включено назначение CIDR).

Вторая - поддержание в актуальном состоянии внутреннего списка узлов контроллера узла согласно списку доступных машин облачного провайдера. При работе в облачной среде всякий раз, когда узел неисправен, контроллер узла запрашивает облачного провайдера, доступна ли виртуальная машина для этого узла. Если нет, то контроллер узла удаляет узел из своего списка узлов.

Третья - это мониторинг работоспособности узлов. Контроллер узла отвечает за обновление условия NodeReady для NodeStatus на ConditionUnknown, когда узел становится недоступным (т.е. контроллер узла по какой-то причине перестает получать сердцебиения (heartbeats) от узла, например, из-за того, что узел упал), и затем позже выселяет все поды с узла (используя мягкое (graceful) завершение) если узел продолжает быть недоступным. (По умолчанию таймауты составляют 40 секунд, чтобы начать сообщать ConditionUnknown, и 5 минут после, чтобы начать выселять поды.)

Контроллер узла проверяет состояние каждого узла каждые --node-monitor-period секунд.

Сердцебиения

Сердцебиения, посылаемые узлами Kubernetes, помогают определить доступность узла.

Существует две формы сердцебиений: обновление NodeStatus и Lease объект. Каждый узел имеет связанный с ним Lease объект в kube-node-lease namespace. Lease - это легковесный ресурс, который улучшает производительность сердцебиений узла при масштабировании кластера.

Kubelet отвечает за создание и обновление NodeStatus и Lease объекта.

  • Kubelet обновляет NodeStatus либо когда происходит изменение статуса, либо если в течение настроенного интервала обновления не было. По умолчанию интервал для обновлений NodeStatus составляет 5 минут (намного больше, чем 40-секундный стандартный таймаут для недоступных узлов).
  • Kubelet создает и затем обновляет свой Lease объект каждый 10 секунд (интервал обновления по умолчанию). Lease обновления происходят независимо от NodeStatus обновлений. Если обновление Lease завершается неудачно, kubelet повторяет попытку с экспоненциальным откатом, начинающимся с 200 миллисекунд и ограниченным 7 секундами.

Надежность

В большинстве случаев контроллер узла ограничивает скорость выселения до --node-eviction-rate (по умолчанию 0,1) в секунду, что означает, что он не выселяет поды с узлов быстрее чем с одного узла в 10 секунд.

Поведение выселения узла изменяется, когда узел в текущей зоне доступности становится нездоровым. Контроллер узла проверяет, какой процент узлов в зоне нездоров (NodeReady условие в значении ConditionUnknown или ConditiononFalse) в одно и то же время. Если доля нездоровых узлов не меньше --unhealthy-zone-threshold (по умолчанию 0.55), то скорость выселения уменьшается: если кластер небольшой (т.е. количество узлов меньше или равно --large-cluster-size-threshold - по умолчанию, 50), то выселения прекращаются, в противном случае скорость выселения снижается до --secondary-node-eviction-rate (по умолчанию, 0.01) в секунду.

Причина, по которой эти политики реализуются для каждой зоны доступности, заключается в том, что одна зона доступности может стать отделенной от мастера, в то время как другие остаются подключенными. Если ваш кластер не охватывает несколько зон доступности облачного провайдера, то существует только одна зона доступности (весь кластер).

Основная причина разнесения ваших узлов по зонам доступности заключается в том, что приложения могут быть перенесены в здоровые зоны, когда одна из зон полностью становится недоступной. Поэтому, если все узлы в зоне нездоровы, то контроллер узла выселяет поды с нормальной скоростью --node-eviction-rate. Крайний случай - когда все зоны полностью нездоровы (т.е. в кластере нет здоровых узлов). В таком случае контроллер узла предполагает, что существует некоторая проблема с подключением к мастеру, и останавливает все выселения, пока какое-нибудь подключение не будет восстановлено.

Контроллер узла также отвечает за выселение подов, запущенных на узлах с NoExecute ограничениями, за исключением тех подов, которые сопротивляются этим ограничениям. Контроллер узла так же добавляет ограничения соответствующие проблемам узла, таким как узел недоступен или не готов. Это означает, что планировщик не будет размещать поды на нездоровых узлах.

Емкость узла

Объекты узла отслеживают информацию о емкости ресурсов узла (например, объем доступной памяти и количество CPU). Узлы, которые самостоятельно зарегистрировались, сообщают о своей емкости во время регистрации. Если вы вручную добавляете узел, то вам нужно задать информацию о емкости узла при его добавлении.

Планировщик Kubernetes гарантирует, что для всех Подов на Узле достаточно ресурсов. Планировщик проверяет, что сумма requests от контейнеров на узле не превышает емкость узла. Эта сумма requests включает все контейнеры, управляемые kubelet, но исключает любые контейнеры, запущенные непосредственно средой выполнения контейнера, а также исключает любые процессы, запущенные вне контроля kubelet.

Топология узла

FEATURE STATE: Kubernetes v1.16 [alpha]

Если вы включили TopologyManager feature gate, то kubelet может использовать подсказки топологии при принятии решений о выделении ресурсов. Смотрите Контроль Политик Управления Топологией на Узле для дополнительной информации.

Что дальше

Изменено March 26, 2022 at 11:03 PM PST: fix_some_typos (232c79f4e4)