343 lines
27 KiB
Markdown
343 lines
27 KiB
Markdown
---
|
||
reviewers:
|
||
- caesarxuchao
|
||
- dchen1107
|
||
title: Узлы
|
||
content_template: concept
|
||
weight: 10
|
||
---
|
||
|
||
<!-- overview -->
|
||
|
||
Kubernetes запускает ваши приложения, помещая контейнеры в Поды для запуска на Узлах (_Nodes_).
|
||
В зависимости от кластера, узел может быть виртуальной или физической машиной. Каждый узел
|
||
содержит сервисы, необходимые для запуска
|
||
{{< glossary_tooltip text="Подов" term_id="pod" >}}, управляемых
|
||
{{< glossary_tooltip text="плоскостью управления" term_id="control-plane" >}}.
|
||
|
||
Обычно у вас есть несколько узлов в кластере; однако в среде обучения или среде
|
||
с ограниченными ресурсами у вас может быть только один.
|
||
|
||
[Компоненты](/ru/docs/concepts/overview/components/##компоненты-узла) на узле включают
|
||
{{< glossary_tooltip text="kubelet" term_id="kubelet" >}},
|
||
{{< glossary_tooltip text="среду выполнения контейнера" term_id="container-runtime" >}} и
|
||
{{< glossary_tooltip text="kube-proxy" term_id="kube-proxy" >}}.
|
||
|
||
<!-- body -->
|
||
|
||
## Управление
|
||
|
||
Существует два основных способа добавления Узлов в {{< glossary_tooltip text="API сервер" term_id="kube-apiserver" >}}:
|
||
|
||
1. Kubelet на узле саморегистрируется в плоскости управления
|
||
2. Вы или другой пользователь вручную добавляете объект Узла
|
||
|
||
После того как вы создадите объект Узла или kubelet на узле самозарегистируется,
|
||
плоскость управления проверяет, является ли новый объект Узла валидным (правильным). Например, если вы
|
||
попробуете создать Узел при помощи следующего JSON манифеста:
|
||
|
||
```json
|
||
{
|
||
"kind": "Node",
|
||
"apiVersion": "v1",
|
||
"metadata": {
|
||
"name": "10.240.79.157",
|
||
"labels": {
|
||
"name": "my-first-k8s-node"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
Kubernetes создает внутри себя объект Узла (представление). Kubernetes проверяет,
|
||
что kubelet зарегистрировался на API сервере, который совпадает со значением поля `metadata.name` Узла.
|
||
Если узел здоров (если все необходимые сервисы запущены),
|
||
он имеет право на запуск Пода. В противном случае этот узел игнорируется для любой активности кластера
|
||
до тех пор, пока он не станет здоровым.
|
||
|
||
{{< note >}}
|
||
Kubernetes сохраняет объект для невалидного Узла и продолжает проверять, становится ли он здоровым.
|
||
|
||
Вы или {{< glossary_tooltip term_id="controller" text="контроллер">}} должны явно удалить объект Узла, чтобы
|
||
остановить проверку доступности узла.
|
||
{{< /note >}}
|
||
|
||
Имя объекта Узла должно быть валидным
|
||
[именем поддомена DNS](/ru/docs/concepts/overview/working-with-objects/names#имена-поддоменов-dns).
|
||
|
||
### Саморегистрация Узлов
|
||
|
||
Когда kubelet флаг `--register-node` имеет значение _true_ (по умолчанию), то kubelet будет пытаться
|
||
зарегистрировать себя на API сервере. Это наиболее предпочтительная модель, используемая большинством дистрибутивов.
|
||
|
||
Для саморегистрации kubelet запускается со следующими опциями:
|
||
|
||
- `--kubeconfig` - Путь к учетным данным для аутентификации на API сервере.
|
||
- `--cloud-provider` - Как общаться с {{< glossary_tooltip text="облачным провайдером" term_id="cloud-provider" >}}, чтобы прочитать метаданные о себе.
|
||
- `--register-node` - Автоматически зарегистрироваться на API сервере.
|
||
- `--register-with-taints` - Зарегистрировать узел с приведенным списком {{< glossary_tooltip text="ограничений (taints)" term_id="taint" >}} (разделенных запятыми `<key>=<value>:<effect>`).
|
||
|
||
Ничего не делает, если `register-node` - _false_.
|
||
- `--node-ip` - IP-адрес узла.
|
||
- `--node-labels` - {{< glossary_tooltip text="Метки" term_id="label" >}} для добавления при регистрации узла в кластере (смотрите ограничения для меток, установленные [плагином согласования (admission plugin) NodeRestriction](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)).
|
||
- `--node-status-update-frequency` - Указывает, как часто kubelet отправляет статус узла мастеру.
|
||
|
||
Когда [режим авторизации Узла](/docs/reference/access-authn-authz/node/) и
|
||
[плагин согласования NodeRestriction](/docs/reference/access-authn-authz/admission-controllers/#noderestriction) включены,
|
||
kubelet'ы имеют право только создавать/изменять свой собственный ресурс Узла.
|
||
|
||
### Ручное администрирование узла
|
||
|
||
Вы можете создавать и изменять объекты узла используя
|
||
{{< glossary_tooltip text="kubectl" term_id="kubectl" >}}.
|
||
|
||
Когда вы хотите создать объекты Узла вручную, установите kubelet флаг `--register-node=false`.
|
||
|
||
Вы можете изменять объекты Узла независимо от настройки `--register-node`.
|
||
Например, вы можете установить метки на существующем Узле или пометить его не назначаемым.
|
||
|
||
Вы можете использовать метки на Узлах в сочетании с селекторами узла на Подах для управления планированием.
|
||
Например, вы можете ограничить Под, иметь право на запуск только на группе доступных узлов.
|
||
|
||
Маркировка узла как не назначаемого предотвращает размещение планировщиком новых подов на этом Узле,
|
||
но не влияет на существующие Поды на Узле. Это полезно в качестве
|
||
подготовительного шага перед перезагрузкой узла или другим обслуживанием.
|
||
|
||
Чтобы отметить Узел не назначаемым, выполните:
|
||
|
||
```shell
|
||
kubectl cordon $NODENAME
|
||
```
|
||
|
||
{{< note >}}
|
||
Поды, являющиеся частью {{< glossary_tooltip term_id="daemonset" >}} допускают
|
||
запуск на не назначаемом Узле. DaemonSets обычно обеспечивает локальные сервисы узла,
|
||
которые должны запускаться на Узле, даже если узел вытесняется для запуска приложений.
|
||
{{< /note >}}
|
||
|
||
## Статус Узла
|
||
|
||
Статус узла содержит следующие данные:
|
||
|
||
* [Адреса (Addresses)](#адреса)
|
||
* [Условия (Conditions)](#условие)
|
||
* [Емкость и Выделяемые ресурсы (Capacity and Allocatable)](#емкость)
|
||
* [Информация (Info)](#информация)
|
||
|
||
Вы можете использовать `kubectl` для просмотра статуса Узла и других деталей:
|
||
|
||
```shell
|
||
kubectl describe node <insert-node-name-here>
|
||
```
|
||
|
||
Каждая секция из вывода команды описана ниже.
|
||
|
||
### Адреса (Addresses)
|
||
|
||
Использование этих полей варьируется в зависимости от вашего облачного провайдера или конфигурации физических серверов (_bare metal_).
|
||
|
||
* HostName: Имя хоста, сообщаемое ядром узла. Может быть переопределено через kubelet `--hostname-override` параметр.
|
||
* ExternalIP: Обычно, IP адрес узла, который является внешне маршрутизируемым (доступен за пределами кластера).
|
||
* InternalIP: Обычно, IP адрес узла, который маршрутизируется только внутри кластера.
|
||
|
||
### Условия (Conditions) {#условие}
|
||
|
||
Поле `conditions` описывает статус всех `Running` узлов. Примеры условий включают в себя:
|
||
|
||
{{< table caption = "Условия узла и описание того, когда применяется каждое условие." >}}
|
||
| Условие Узла | Описание |
|
||
|----------------------|-------------|
|
||
| `Ready` | `True` если узел здоров и готов принять поды, `False` если узел нездоров и не принимает поды, и `Unknown` если контроллер узла не получал информацию от узла в течение последнего периода `node-monitor-grace-period` (по умолчанию 40 секунд) |
|
||
| `DiskPressure` | `True` если присутствует давление на размер диска - то есть, если емкость диска мала; иначе `False` |
|
||
| `MemoryPressure` | `True` если существует давление на память узла - то есть, если памяти на узле мало; иначе `False` |
|
||
| `PIDPressure` | `True` если существует давление на процессы - то есть, если на узле слишком много процессов; иначе `False` |
|
||
| `NetworkUnavailable` | `True` если сеть для узла настроена некорректно, иначе `False` |
|
||
{{< /table >}}
|
||
|
||
{{< note >}}
|
||
Если вы используете инструменты командной строки для вывода сведений об блокированном узле,
|
||
то Условие включает `SchedulingDisabled`. `SchedulingDisabled` не является Условием в Kubernetes API;
|
||
вместо этого блокированные узлы помечены как Не назначаемые в их спецификации.
|
||
{{< /note >}}
|
||
|
||
Состояние узла представлено в виде JSON объекта. Например, следующая структура описывает здоровый узел:
|
||
|
||
```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`(аргумент, переданный в
|
||
{{< glossary_tooltip text="kube-controller-manager" term_id="kube-controller-manager" >}}), то все Поды
|
||
на узле планируются к удалению контроллером узла. По умолчанию таймаут выселения **пять минут**.
|
||
В некоторых случаях, когда узел недоступен, API сервер не может связаться с kubelet на узле.
|
||
Решение об удалении подов не может быть передано в kubelet до тех пор, пока связь с API сервером не будет восстановлена.
|
||
В то же время поды, которые запланированы к удалению, могут продолжать работать на отделенном узле.
|
||
|
||
Контроллер узла не будет принудительно удалять поды до тех пор, пока не будет подтверждено,
|
||
что они перестали работать в кластере. Вы можете видеть, что поды, которые могут работать на недоступном узле,
|
||
находятся в состоянии `Terminating` или `Unknown`. В тех случаях, когда Kubernetes не может сделать вывод
|
||
из основной инфраструктуры о том, что узел окончательно покинул кластер, администратору кластера может потребоваться
|
||
удалить объект узла вручную. Удаление объекта узла из Kubernetes приводит к удалению всех объектов Подов, запущенных
|
||
на узле, с API сервера и освобождает их имена.
|
||
|
||
Контроллер жизненного цикла узла автоматически создает
|
||
[ограничения (taints)](/docs/concepts/scheduling-eviction/taint-and-toleration/), которые представляют собой условия.
|
||
Планировщик учитывает ограничения Узла при назначении Пода на Узел.
|
||
Поды так же могут иметь допуски (tolerations), что позволяет им сопротивляться ограничениям Узла.
|
||
|
||
Смотрите раздел [Ограничить Узлы по Условию](/docs/concepts/configuration/taint-and-toleration/#taint-nodes-by-condition)
|
||
для дополнительной информации.
|
||
|
||
### Емкость и Выделяемые ресурсы (Capacity and Allocatable) {#емкость}
|
||
|
||
Описывает ресурсы, доступные на узле: CPU, память и максимальное количество подов,
|
||
которые могут быть запланированы на узле.
|
||
|
||
Поля в блоке capacity указывают общее количество ресурсов, которые есть на Узле.
|
||
Блок allocatable указывает количество ресурсов на Узле,
|
||
которые доступны для использования обычными Подами.
|
||
|
||
Вы можете прочитать больше о емкости и выделяемых ресурсах, изучая, как [зарезервировать вычислительные ресурсы](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) на Узле.
|
||
|
||
### Информация (Info)
|
||
|
||
Описывает общую информацию об узле, такую как версия ядра, версия Kubernetes (версии kubelet и kube-proxy), версия Docker (если используется) и название ОС.
|
||
Эта информация собирается Kubelet'ом на узле.
|
||
|
||
### Контроллер узла
|
||
|
||
{{< glossary_tooltip text="Контроллер " term_id="controller" >}} узла является компонентом
|
||
плоскости управления Kubernetes, который управляет различными аспектами узлов.
|
||
|
||
Контроллер узла играет различные роли в жизни узла. Первая - назначение CIDR-блока узлу
|
||
при его регистрации (если включено назначение CIDR).
|
||
|
||
Вторая - поддержание в актуальном состоянии внутреннего списка узлов контроллера узла
|
||
согласно списку доступных машин облачного провайдера. При работе в облачной среде всякий раз,
|
||
когда узел неисправен, контроллер узла запрашивает облачного провайдера, доступна ли
|
||
виртуальная машина для этого узла. Если нет, то контроллер узла удаляет узел из
|
||
своего списка узлов.
|
||
|
||
Третья - это мониторинг работоспособности узлов. Контроллер узла
|
||
отвечает за обновление условия NodeReady для NodeStatus на
|
||
ConditionUnknown, когда узел становится недоступным (т.е. контроллер узла
|
||
по какой-то причине перестает получать сердцебиения (heartbeats) от узла,
|
||
например, из-за того, что узел упал), и затем позже выселяет все поды с узла
|
||
(используя мягкое (graceful) завершение) если узел продолжает быть недоступным.
|
||
(По умолчанию таймауты составляют 40 секунд, чтобы начать сообщать `ConditionUnknown`,
|
||
и 5 минут после, чтобы начать выселять поды.)
|
||
|
||
Контроллер узла проверяет состояние каждого узла каждые `--node-monitor-period` секунд.
|
||
|
||
#### Сердцебиения
|
||
|
||
Сердцебиения, посылаемые узлами Kubernetes, помогают определить доступность узла.
|
||
|
||
Существует две формы сердцебиений: обновление `NodeStatus` и
|
||
[Lease объект](/docs/reference/generated/kubernetes-api/{{< latest-version >}}/#lease-v1-coordination-k8s-io).
|
||
Каждый узел имеет связанный с ним Lease объект в `kube-node-lease`
|
||
{{< glossary_tooltip term_id="namespace" text="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` ограничениями, за исключением тех подов, которые сопротивляются этим ограничениям.
|
||
Контроллер узла так же добавляет {{< glossary_tooltip text="ограничения" term_id="taint" >}}
|
||
соответствующие проблемам узла, таким как узел недоступен или не готов. Это означает,
|
||
что планировщик не будет размещать поды на нездоровых узлах.
|
||
|
||
{{< caution >}}
|
||
`kubectl cordon` помечает узел как 'не назначаемый', что имеет побочный эффект от контроллера сервисов,
|
||
удаляющего узел из любых списков целей LoadBalancer узла, на которые он ранее имел право,
|
||
эффективно убирая входящий трафик балансировщика нагрузки с блокированного узла(ов).
|
||
{{< /caution >}}
|
||
|
||
### Емкость узла
|
||
|
||
Объекты узла отслеживают информацию о емкости ресурсов узла (например,
|
||
объем доступной памяти и количество CPU).
|
||
Узлы, которые [самостоятельно зарегистрировались](#саморегистрация-узлов), сообщают
|
||
о своей емкости во время регистрации. Если вы [вручную](#ручное-администрирование-узла)
|
||
добавляете узел, то вам нужно задать информацию о емкости узла при его добавлении.
|
||
|
||
{{< glossary_tooltip text="Планировщик" term_id="kube-scheduler" >}} Kubernetes гарантирует,
|
||
что для всех Подов на Узле достаточно ресурсов. Планировщик проверяет,
|
||
что сумма requests от контейнеров на узле не превышает емкость узла.
|
||
Эта сумма requests включает все контейнеры, управляемые kubelet,
|
||
но исключает любые контейнеры, запущенные непосредственно средой выполнения контейнера,
|
||
а также исключает любые процессы, запущенные вне контроля kubelet.
|
||
|
||
{{< note >}}
|
||
Если вы явно хотите зарезервировать ресурсы для процессов, не связанных с Подами, смотрите раздел
|
||
[зарезервировать ресурсы для системных демонов](/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved).
|
||
{{< /note >}}
|
||
|
||
## Топология узла
|
||
|
||
{{< feature-state state="alpha" for_k8s_version="v1.16" >}}
|
||
|
||
Если вы включили `TopologyManager`
|
||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/), то kubelet
|
||
может использовать подсказки топологии при принятии решений о выделении ресурсов.
|
||
Смотрите [Контроль Политик Управления Топологией на Узле](/docs/tasks/administer-cluster/topology-manager/)
|
||
для дополнительной информации.
|
||
|
||
## {{% heading "whatsnext" %}}
|
||
|
||
* Подробнее про[компоненты](/ru/docs/concepts/overview/components/#компоненты-узла) из которых состоит узел.
|
||
* Подробнее про [Определение API для Узла](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#node-v1-core).
|
||
* Подробнее про [Узлы](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node)
|
||
of the architecture design document.
|
||
* Подробнее про [ограничения и допуски](/docs/concepts/configuration/taint-and-toleration/).
|
||
* Подробнее про [авто масштабирование кластера](/docs/tasks/administer-cluster/cluster-management/#cluster-autoscaling).
|