Архитектура Kubernetes: управление узлами

В отличие от модулей (pods) и служб (services), узел по сути не создается Kubernetes: он создается извне облачными провайдерами, такими как Google Compute Engine, или существует в вашем пуле физических или виртуальных машин. Поэтому, когда Kubernetes создает узел, он создает объект, который представляет узел. После создания Kubernetes проверяет, является ли узел действительным или нет. Например, если вы попытаетесь создать узел из следующего содержимого:

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

Kubernetes создает объект узла внутри себя (представление) и проверяет узел путем проверки работоспособности на основе поля metadata.name. Если узел действителен - то есть, если все необходимые службы (services) запущены - он может запускать модуль (pod). В противном случае он игнорируется для любой активности кластера, пока не станет действительным.

Примечание: Kubernetes сохраняет объект для недопустимого узла и продолжает проверять, становится ли он действительным. Вы должны явно удалить объект Node, чтобы остановить этот процесс.

В настоящее время есть три компонента, которые взаимодействуют с интерфейсом узла Kubernetes: контроллер узла (node controller), kubelet и kubectl.

Контроллер узла (Node Controller)

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

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

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

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

В версиях Kubernetes до 1.13 NodeStatus является heartbeat от узла. Начиная с Kubernetes 1.13, функция аренды узла (node lease feature) представлена как альфа-функция (функция gate NodeLease). Когда функция аренды узла включена, каждый узел имеет связанный объект Lease в пространстве имен kube-node-lease, который периодически обновляется узлом, и NodeStatus и аренда узла обрабатываются как пульсы (heartbeats) от узла. Аренда узла (Node lease) часто обновляется, в то время как NodeStatus передается от узла к мастеру только тогда, когда произошли некоторые изменения или прошло достаточно времени (по умолчанию 1 минута, что больше, чем тайм-аут по умолчанию в 40 секунд для недоступных узлов). Поскольку аренда узла намного легче, чем NodeStatus, эта функция значительно сокращает пульс узла с точки зрения масштабируемости и производительности.

В Kubernetes 1.4 была обновлена логика контроллера узла, чтобы лучше обрабатывать случаи, когда у большого количества узлов возникают проблемы с достижением мастера (например, из-за того, что мастер имеет проблемы с сетью). Начиная с версии 1.4, контроллер узла просматривает состояние всех узлов в кластере при принятии решения о выселении модуля (pod).

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

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

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

Начиная с Kubernetes 1.6, NodeController также отвечает за выселение модулей (pods), работающих на узлах с NoExecute taints (не позволяет содержать не здоровые pod'ы). Кроме того, в качестве альфа-функции, которая по умолчанию отключена, NodeController отвечает за добавление taint объектов, соответствующих проблемам узла, таким как узел недоступен или не готов.

Начиная с версии 1.8, контроллер узла может быть привлечен к ответственности за создание ошибок, представляющих условия узла. Это альфа-функция версии 1.8.

Самостоятельная регистрация узлов

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

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

  • --kubeconfig - путь к учетным данным для аутентификации на сервере.
  • --cloud-provider - как общаться с облачным провайдером, чтобы прочитать метаданные о себе.
  • --register-node - автоматически регистрироваться на сервере API.
  • --register-with-taints - Зарегистрировать узел с заданным списком taints (разделенный запятыми <key>=<value>:<effect> (<ключ>=<значение>:<эффект>)). Не используется, если параметр register-node равен false.
  • --node-ip - IP-адрес узла.
  • --node-label - метки, добавляемые при регистрации узла в кластере.
  • --node-status-update -quency - указывает, как часто kubelet отправляет статус узла мастеру.

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

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

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

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

Администратор может изменять ресурсы узла (независимо от значения параметра --register-node). Модификации включают установку меток на узле и маркировку его как не подлежащего планированию.

Метки на узлах могут использоваться вместе с селекторами узлов на pod'ах для управления расписанием, например, ограничить pod, чтобы иметь право работать только на подмножестве узлов.

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

kubectl cordon $NODENAME

Примечание. Блоки, созданные контроллером DaemonSet, обходят планировщик Kubernetes и не учитывают атрибут unschedulable на узле. Это предполагает, что демоны принадлежат машине, даже если на нее не загружаются приложения, пока она готовится к перезагрузке.

Емкость узла

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

Планировщик Kubernetes обеспечивает достаточное количество ресурсов для всех модулей (pod'ов) на узле. Он проверяет, что сумма запросов контейнеров на узле не превышает емкость узла. Он включает в себя все контейнеры, запущенные kubelet, но не контейнеры, запускаемые непосредственно во время выполнения контейнера, и не любые процессы, выполняющиеся вне контейнеров.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Контроллеры в Kubernetes: DaemonSet

Контроллеры в Kubernetes: ReplicaSet

Контроллеры в Kubernetes: StatefulSet