Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.
Кластерная Архитектура
- 1: Узлы
- 2: Связь между плоскостью управления и узлом
- 3: Контроллеры
- 4: Диспетчер облачных контроллеров
- 5: Container Runtime Interface (CRI)
- 6: Сборщик мусора
1 - Узлы
Kubernetes запускает ваши приложения, помещая контейнеры в Поды для запуска на Узлах (Nodes). В зависимости от кластера, узел может быть виртуальной или физической машиной. Каждый узел содержит сервисы, необходимые для запуска Подов, управляемых плоскостью управления.
Обычно у вас есть несколько узлов в кластере; однако в среде обучения или среде с ограниченными ресурсами у вас может быть только один.
Компоненты на узле включают kubelet, среду выполнения контейнера и kube-proxy.
Управление
Существует два основных способа добавления Узлов в API сервер:
- Kubelet на узле саморегистрируется в плоскости управления
- Вы или другой пользователь вручную добавляете объект Узла
После того как вы создадите объект Узла или kubelet на узле самозарегистируется, плоскость управления проверяет, является ли новый объект Узла валидным (правильным). Например, если вы попробуете создать Узел при помощи следующего JSON манифеста:
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
Kubernetes создает внутри себя объект Узла (представление). Kubernetes проверяет,
что kubelet зарегистрировался на API сервере, который совпадает со значением поля metadata.name
Узла.
Если узел здоров (если все необходимые сервисы запущены),
он имеет право на запуск Пода. В противном случае этот узел игнорируется для любой активности кластера
до тех пор, пока он не станет здоровым.
Kubernetes сохраняет объект для невалидного Узла и продолжает проверять, становится ли он здоровым.
Вы или контроллер должны явно удалить объект Узла, чтобы остановить проверку доступности узла.
Имя объекта Узла должно быть валидным именем поддомена 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
Статус Узла
Статус узла содержит следующие данные:
- Адреса (Addresses)
- Условия (Conditions)
- Емкость и Выделяемые ресурсы (Capacity and Allocatable)
- Информация (Info)
Вы можете использовать kubectl
для просмотра статуса Узла и других деталей:
kubectl describe node <insert-node-name-here>
Каждая секция из вывода команды описана ниже.
Адреса (Addresses)
Использование этих полей варьируется в зависимости от вашего облачного провайдера или конфигурации физических серверов (bare metal).
- HostName: Имя хоста, сообщаемое ядром узла. Может быть переопределено через kubelet
--hostname-override
параметр. - ExternalIP: Обычно, IP адрес узла, который является внешне маршрутизируемым (доступен за пределами кластера).
- InternalIP: Обычно, IP адрес узла, который маршрутизируется только внутри кластера.
Условия (Conditions)
Поле conditions
описывает статус всех Running
узлов. Примеры условий включают в себя:
Условие Узла | Описание |
---|---|
Ready |
True если узел здоров и готов принять поды, False если узел нездоров и не принимает поды, и Unknown если контроллер узла не получал информацию от узла в течение последнего периода node-monitor-grace-period (по умолчанию 40 секунд) |
DiskPressure |
True если присутствует давление на размер диска - то есть, если емкость диска мала; иначе False |
MemoryPressure |
True если существует давление на память узла - то есть, если памяти на узле мало; иначе False |
PIDPressure |
True если существует давление на процессы - то есть, если на узле слишком много процессов; иначе False |
NetworkUnavailable |
True если сеть для узла настроена некорректно, иначе False |
SchedulingDisabled
. SchedulingDisabled
не является Условием в Kubernetes API;
вместо этого блокированные узлы помечены как Не назначаемые в их спецификации.
Состояние узла представлено в виде 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
ограничениями, за исключением тех подов, которые сопротивляются этим ограничениям.
Контроллер узла так же добавляет ограничения
соответствующие проблемам узла, таким как узел недоступен или не готов. Это означает,
что планировщик не будет размещать поды на нездоровых узлах.
kubectl cordon
помечает узел как 'не назначаемый', что имеет побочный эффект от контроллера сервисов,
удаляющего узел из любых списков целей LoadBalancer узла, на которые он ранее имел право,
эффективно убирая входящий трафик балансировщика нагрузки с блокированного узла(ов).
Емкость узла
Объекты узла отслеживают информацию о емкости ресурсов узла (например, объем доступной памяти и количество CPU). Узлы, которые самостоятельно зарегистрировались, сообщают о своей емкости во время регистрации. Если вы вручную добавляете узел, то вам нужно задать информацию о емкости узла при его добавлении.
Планировщик Kubernetes гарантирует, что для всех Подов на Узле достаточно ресурсов. Планировщик проверяет, что сумма requests от контейнеров на узле не превышает емкость узла. Эта сумма requests включает все контейнеры, управляемые kubelet, но исключает любые контейнеры, запущенные непосредственно средой выполнения контейнера, а также исключает любые процессы, запущенные вне контроля kubelet.
Топология узла
Kubernetes v1.16 [alpha]
Если вы включили TopologyManager
feature gate, то kubelet
может использовать подсказки топологии при принятии решений о выделении ресурсов.
Смотрите Контроль Политик Управления Топологией на Узле
для дополнительной информации.
Что дальше
- Подробнее прокомпоненты из которых состоит узел.
- Подробнее про Определение API для Узла.
- Подробнее про Узлы of the architecture design document.
- Подробнее про ограничения и допуски.
- Подробнее про авто масштабирование кластера.
2 - Связь между плоскостью управления и узлом
Этот документ описывает связь между плоскостью управления (apiserver) и кластером Kubernetes. Цель состоит в том, чтобы позволить пользователям настраивать свою установку для усиления сетевой конфигурации, чтобы кластер мог работать в ненадежной сети (или на полностью общедоступных IP-адресах облачного провайдера).
Связь между плоскостью управления и узлом
В Kubernetes имеется API шаблон «ступица и спица» (hub-and-spoke). Все используемые API из узлов (или которые запускают pod-ы) завершает apiserver. Ни один из других компонентов плоскости управления не предназначен для предоставления удаленных сервисов. Apiserver настроен на прослушивание удаленных подключений через безопасный порт HTTPS (обычно 443) с одной или несколькими включенными формами аутентификации клиента.
Должна быть включена одна или несколько форм авторизации, особенно, если разрешены анонимные запросы или ServiceAccount токены.
Узлы должны быть снабжены публичным корневым сертификатом для кластера, чтобы они могли безопасно подключаться к apiserver-у вместе с действительными учетными данными клиента. Хороший подход заключается в том, чтобы учетные данные клиента, предоставляемые kubelet-у, имели форму клиентского сертификата. См. Информацию о загрузке kubelet TLS bootstrapping для автоматической подготовки клиентских сертификатов kubelet.
Pod-ы, которые хотят подключиться к apiserver, могут сделать это безопасно, используя ServiceAccount, чтобы Kubernetes автоматически вводил общедоступный корневой сертификат и действительный токен-носитель в pod при его создании.
Служба kubernetes
(в пространстве имен default
) настроена с виртуальным IP-адресом, который перенаправляет (через kube-proxy) на HTTPS эндпоинт apiserver-а.
Компоненты уровня управления также взаимодействуют с кластером apiserver-а через защищенный порт.
В результате режим работы по умолчанию для соединений от узлов и модулей, работающих на узлах, к плоскости управления по умолчанию защищен и может работать в ненадежных и/или общедоступных сетях.
Узел к плоскости управления
Существуют два пути связи плоскости управления (apiserver) с узлами. Первый - от apiserver-а до kubelet процесса, который выполняется на каждом узле кластера. Второй - от apiserver к любому узлу, pod-у или службе через промежуточную функциональность apiserver-а.
apiserver в kubelet
Соединение из apiserver-а к kubelet используются для:
- Извлечения логов с pod-ов.
- Прикрепление (через kubectl) к запущенным pod-ам.
- Обеспечение функциональности переадресации портов kubelet.
Эти соединения завершаются на HTTPS эндпоинте kubelet-a. По умолчанию apiserver не проверяет сертификат обслуживания kubelet-ов, что делает соединение подверженным к атаке «человек посередине» (man-in-the-middle) и небезопасным к запуску в ненадежных и/или общедоступных сетях.
Для проверки этого соединения используется флаг --kubelet-certificate-authority
чтобы предоставить apiserver-у набор корневых (root) сертификатов для проверки сертификата обслуживания kubelet-ов.
Если это не возможно, используйте SSH-тунелирование между apiserver-ом и kubelet, если это необходимо, чтобы избежать подключения по ненадежной или общедоступной сети.
Наконец, должны быть включены аутентификация или авторизация kubelet для защиты kubelet API.
apiserver для узлов, pod-ов, и служб
Соединения с apiserver к узлу, поду или сервису по умолчанию осуществляются по-обычному HTTP-соединению и поэтому не аутентифицируются, и не шифруются. Они могут быть запущены по защищенному HTTPS-соединению, после добавления префикса https:
к имени узла, пода или сервиса в URL-адресе API, но они не будут проверять сертификат предоставленный HTTPS эндпоинтом, как и не будут предоставлять учетные данные клиента. Таким образом, хотя соединение будет зашифровано, оно не обеспечит никаких гарантий целостности. Эти соединения в настоящее время небезопасны для запуска в ненадежных или общедоступных сетях.
SSH-туннели
Kubernetes поддерживает SSH-туннели для защиты плоскости управления узлов от путей связи. В этой конфигурации apiserver инициирует SSH-туннель для каждого узла в кластере (подключается к ssh-серверу, прослушивая порт 22) и передает весь трафик предназначенный для kubelet, узлу, pod-у или службе через туннель. Этот туннель гарантирует, что трафик не выводится за пределы сети, в которой работает узел.
SSH-туннели в настоящее время устарели, поэтому вы не должны использовать их, если не знаете, что делаете. Служба подключения является заменой этого канала связи.
Служба подключения
Kubernetes v1.18 [beta]
В качестве замены SSH-туннелям, служба подключения обеспечивает уровень полномочия TCP для плоскости управления кластерной связи. Служба подключения состоит из двух частей: сервер подключения к сети плоскости управления и агентов подключения в сети узлов. Агенты службы подключения инициируют подключения к серверу подключения и поддерживают сетевое подключение. После включения службы подключения, весь трафик с плоскости управления на узлы проходит через эти соединения.
Следуйте инструкциям Задача службы подключения, чтобы настроить службу подключения в кластере.
3 - Контроллеры
В робототехнике и автоматизации, цикл управления - это непрерывный цикл, который регулирует состояние системы.
Вот один из примеров контура управления: термостат в помещении.
Когда вы устанавливаете температуру, это говорит термостату о вашем желаемом состоянии. Фактическая температура в помещении - это текущее состояние. Термостат действует так, чтобы приблизить текущее состояние к желаемому состоянию, путем включения или выключения оборудования.
Контроллеры в Kubernetes - управляющие циклы, которые отслеживают состояние вашего кластера, затем вносят или запрашивают изменения там, где это необходимо. Каждый контроллер пытается привести текущее состояние кластера ближе к желаемому состоянию.Шаблон контроллера
Контроллер отслеживает по крайней мере один тип ресурса Kubernetes. Эти объекты имеют поле спецификации, которое представляет желаемое состояние. Контроллер (ы) для этого ресурса несут ответственность за приближение текущего состояния к желаемому состоянию
Контроллер может выполнить это действие сам; чаще всего в Kubernetes, контроллер отправляет сообщения на сервер API которые имеют полезные побочные эффекты. Пример этого вы можете увидеть ниже.
Управление с помощью сервера API
Контроллер Job является примером встроенного контроллера Kubernetes. Встроенные контроллеры управляют состоянием, взаимодействуя с кластером сервера API.
Задание - это ресурс Kubernetes, который запускает Pod, или возможно несколько Pod-ов, выполняющих задачу и затем останавливающихся.
(После планирования, Pod объекты становятся частью желаемого состояния для kubelet).
Когда контроллер задания видит новую задачу, он убеждается что где-то в вашем кластере kubelet-ы на множестве узлов запускают нужное количество Pod-ов для выполнения работы. Контроллер задания сам по себе не запускает никакие Pod-ы или контейнеры. Вместо этого контроллер задания сообщает серверу API о создании или удалении Pod-ов. Другие компоненты в плоскости управления действуют на основе информации (имеются ли новые запланированные Pod-ы для запуска), и в итоге работа завершается.
После того как вы создадите новое задание, желаемое состояние для этого задания будет завершено. Контроллер задания приближает текущее состояние этой задачи к желаемому состоянию: создает Pod-ы, выполняющие работу, которую вы хотели для этой задачи, чтобы задание было ближе к завершению.
Контроллеры также обновляют объекты которые их настраивают.
Например: как только работа выполнена для задания, контроллер задания обновляет этот объект задание, чтобы пометить его как Завершенный
.
(Это немного похоже на то, как некоторые термостаты выключают свет, чтобы указать, что теперь ваша комната имеет установленную вами температуру).
Прямое управление
В отличие от Задания, некоторым контроллерам нужно вносить изменения в вещи за пределами вашего кластера.
Например, если вы используете контур управления, чтобы убедиться, что в вашем кластере достаточно Узлов, тогда этому контроллеру нужно что-то вне текущего кластера, чтобы при необходимости запустить новые узлы.
Контроллеры, которые взаимодействуют с внешним состоянием, находят свое желаемое состояние с сервера API, а затем напрямую взаимодействуют с внешней системой, чтобы приблизить текущее состояние.
(На самом деле существует контроллер, который горизонтально масштабирует узлы в вашем кластере.)
Важным моментом здесь является то, что контроллер вносит некоторые изменения, чтобы вызвать желаемое состояние, а затем сообщает текущее состояние обратно на сервер API вашего кластера. Другие контуры управления могут наблюдать за этими отчетными данными и предпринимать собственные действия.
В примере с термостатом, если в помещении очень холодно, тогда другой контроллер может также включить обогреватель для защиты от замерзания. В кластерах Kubernetes, плоскость управления косвенно работает с инструментами управления IP-адресами, службами хранения данных, API облачных провайдеров и другими службами для реализации расширения Kubernetes.
Желаемое против текущего состояния
Kubernetes использует систему вида cloud-native и способен справляться с постоянными изменениями.
Ваш кластер может изменяться в любой по мере выполнения работы и контуры управления автоматически устраняют сбой. Это означает, что потенциально Ваш кластер никогда не достигнет стабильного состояния.
Пока контроллеры вашего кластера работают и могут вносить полезные изменения, не имеет значения, является ли общее состояние стабильным или нет.
Дизайн
В качестве принципа своей конструкции Kubernetes использует множество контроллеров, каждый из которых управляет определенным аспектом состояния кластера. Чаще всего конкретный контур управления (контроллер) использует один вид ресурса в качестве своего желаемого состояния и имеет другой вид ресурса, которым он управляет, чтобы это случилось. Например, контроллер для заданий отслеживает объекты заданий (для обнаружения новой работы) и объекты модулей (для выполнения заданий, а затем для того, чтобы видеть, когда работа завершена). В этом случае что-то еще создает задания, тогда как контроллер заданий создает Pod-ы.
Полезно иметь простые контроллеры, а не один монолитный набор взаимосвязанных контуров управления. Контроллеры могут выйти из строя, поэтому Kubernetes предназначен для этого.
Существует несколько контроллеров, которые создают или обновляют один и тот же тип объекта. За кулисами контроллеры Kubernetes следят за тем, чтобы обращать внимание только на ресурсы, связанные с их контролирующим ресурсом.
Например, у вас могут быть развертывания и задания; они оба создают Pod-ы. Контроллер заданий не удаляет Pod-ы созданные вашим развертыванием, потому что имеется информационные (метки) которые могут быть использованы контроллерами тем самым показывая отличие Pod-ов.
Способы запуска контроллеров
Kubernetes поставляется с набором встроенных контроллеров, которые работают внутри kube-controller-manager. Эти встроенные контроллеры обеспечивают важные основные функции.
Контроллер развертывания и контроллер заданий - это примеры контроллеров, которые входят в состав самого Kubernetes («встроенные» контроллеры). Kubernetes позволяет вам запускать устойчивую плоскость управления, так что в случае отказа одного из встроенных контроллеров работу берет на себя другая часть плоскости управления.
Вы можете найти контроллеры, которые работают вне плоскости управления, чтобы расширить Kubernetes. Или, если вы хотите, можете написать новый контроллер самостоятельно. Вы можете запустить свой собственный контроллер в виде наборов Pod-ов, или внешнее в Kubernetes. Что подойдет лучше всего, будет зависеть от того, что делает этот конкретный контроллер.
Что дальше
- Прочтите о плоскости управления Kubernetes
- Откройте для себя некоторые из основных объектов Kubernetes
- Узнайте больше о Kubernetes API
- Если вы хотите написать собственный контроллер, см Шаблоны расширения в расширении Kubernetes.
4 - Диспетчер облачных контроллеров
Kubernetes v1.11 [beta]
Технологии облачной инфраструктуры позволяют запускать Kubernetes в общедоступных, частных и гибридных облаках. Kubernetes верит в автоматизированную, управляемую API инфраструктуру без жесткой связи между компонентами.
Диспетчер облачных контроллеров компонент панель управления Kubernetes - это встраиваемый в логику управления облочная спецификация. Диспетчер облачных контроллеров позволяет связать кластер с API поставщика облачных услуг и отделить компоненты, взаимодействующие с этой облачной платформой, от компонентов, взаимодействующих только с вашим кластером.
Отделяя логику взаимодействия между Kubernetes и базовой облачной инфраструктурой, компонент cloud-controller-manager позволяет поставщикам облачных услуг выпускать функции в другом темпе по сравнению с основным проектом Kubernetes.
Диспетчер облачных контроллеров спроектирован с использованием механизма плагинов, которые позволяют различным облачным провайдерам интегрировать свои платформы с Kubernetes.
Дизайн
Диспетчер облачных контроллеров работает в панели управления как реплицированный набор процессов (обычно это контейнер в Pod-ах). Каждый диспетчер облачных контроллеров реализует множество контроллеров в единственном процессе.
Функции диспетчера облачных контроллеров
Контроллеры внутри диспетчера облачных контроллеров включают в себя:
Контроллер узла
Контроллер узла отвечает за создание объектов узла при создании новых серверов в вашей облачной инфраструктуре. Контроллер узла получает информацию о работающих хостах внутри вашей арендуемой инфраструктуры облачного провайдера. Контроллер узла выполняет следующие функции:
- Инициализация объектов узла для каждого сервера, которые контроллер получает через API облачного провайдера.
- Аннотирование и маркировка объектов узла специфичной для облака информацией, такой как регион узла и доступные ему ресурсы (процессор, память и т.д.).
- Получение имени хоста и сетевых адресов.
- Проверка работоспособности узла. В случае, если узел перестает отвечать на запросы, этот контроллер проверяет с помощью API вашего облачного провайдера, был ли сервер деактивирован / удален / прекращен. Если узел был удален из облака, контроллер удаляет объект узла из вашего Kubernetes кластера.
Некоторые облачные провайдеры реализуют его разделение на контроллер узла и отдельный контроллер жизненного цикла узла.
Контроллер маршрута
Контроллер маршрута отвечает за соответствующую настройку маршрутов в облаке, чтобы контейнеры на разных узлах кластера Kubernetes могли взаимодействовать друг с другом.
В зависимости от облачного провайдера, контроллер маршрута способен также выделять блоки IP-адресов для сети Pod-ов.
Контроллер сервисов
Сервисы интегрируются с компонентами облачной инфраструктуры, такими как управляемые балансировщики нагрузки, IP-адреса, фильтрация сетевых пакетов и проверка работоспособности целевых объектов. Контроллер сервисов взаимодействует с API вашего облачного провайдера для настройки требуемых балансировщиков нагрузки и других компонентов инфраструктуры, когда вы объявляете ресурсы сервисов.
Авторизация
В этом разделе разбирается доступ к различным объектам API, который нужен облачным контроллерам для выполнения своих операций.
Контроллер узла
Контроллер узла работает только с объектом узла. Он требует полного доступа на чтение и изменение объектов узла.
v1/Node
:
- Get
- List
- Create
- Update
- Patch
- Watch
- Delete
Контроллер маршрута
Контроллер маршрута прослушивает создание объектов узла и соответствующим образом настраивает маршруты. Для этого требуется получить доступ к объектам узла.
v1/Node
:
- Get
Контроллер сервисов
Контроллер сервисов прослушивает события Create, Update и Delete объектов служб, а затем соответствующим образом настраивает конечные точки для соответствующих сервисов.
Для доступа к сервисам требуется доступ к событиям List и Watch. Для обновления сервисов требуется доступ к событиям Patch и Update.
Чтобы настроить ресурсы конечных точек для сервисов, требуется доступ к событиям Create, List, Get, Watch и Update.
v1/Service
:
- List
- Get
- Watch
- Patch
- Update
Другие
Реализация ядра диспетчера облачных контроллеров требует доступ для создания объектов событий, а для обеспечения безопасной работы требуется доступ к созданию сервисных учетных записей (ServiceAccounts).
v1/Event
:
- Create
- Patch
- Update
v1/ServiceAccount
:
- Create
RBAC ClusterRole для диспетчера облачных контроллеров выглядит так:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cloud-controller-manager
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- ""
resources:
- nodes
verbs:
- '*'
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
- apiGroups:
- ""
resources:
- services
verbs:
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
- get
- list
- watch
- update
Что дальше
Администрирование диспетчера облачных контроллеров содержит инструкции по запуску и управлению диспетчером облачных контроллеров.
Хотите знать, как реализовать свой собственный диспетчер облачных контроллеров или расширить проект?
Диспетчер облачных контроллеров использует интерфейсы Go, которые позволяют реализовать подключение из любого облака. В частности, он использует интерфейс CloudProvider
, который определен в cloud.go
из kubernetes/cloud-provider.
Реализация общих контроллеров, описанных в этом документе (Node, Route, и Service), а также некоторые другие вспомогательные конструкции, вместе с общим интерфейсом облачного провайдера являются частью ядра Kubernetes. Особые реализации для облачных провайдеров находятся вне ядра Kubernetes и реализуют интерфейс CloudProvider
.
Дополнительные сведения о разработке плагинов см. в разделе Разработка диспетчера облачных контроллеров.
5 - Container Runtime Interface (CRI)
Интерфейс CRI позволяет kubelet работать с различными исполняемыми средами контейнеров без необходимости перекомпиляции компонентов кластера.
Исполняемая среда контейнеров должна работать на всех узлах кластера, чтобы kubelet мог запускать Pod'ы и их контейнеры.
Интерфейс Kubernetes Container Runtime Interface (CRI) container Runtime Interface (CRI) — это основной протокол для связи между kubelet'ом и исполняемой средой контейнеров.
Интерфейс Kubernetes Container Runtime Interface (CRI) задает основной gRPC-протокол, на базе которого осуществляется коммуникация между компонентами кластера: kubelet'ом и исполняемой средой.
API
Kubernetes v1.23 [stable]
Kubelet выступает в роли клиента при подключении к исполняемой среде через gRPC. Конечные точки ImageService и RuntimeService должны быть доступны в исполняемой среде контейнеров; в kubelet их можно настроить независимо с помощью флагов командной строки --image-service-endpoint
и --container-runtime-endpoint
.
В Kubernetes v1.29 kubelet предпочитает использовать CRI v1
. Если исполняемая среда контейнера не поддерживает v1
CRI, kubelet пытается перейти на более старую поддерживаемую версию. В версии v1.29 kubelet также может работать с CRI v1alpha2
, но эта версия считается устаревшей. Если согласовать поддерживаемую версию CRI не удается, узел не регистрируется.
Обновление
При обновлении Kubernetes kubelet автоматически выбирает последнюю версию CRI при перезапуске компонента. Если это не удается, происходит откат, как описано выше. Если повторный вызов gRPC произошел из-за обновления исполняемой среды контейнера, последняя также должна поддерживать первоначально выбранную версию, иначе повторный вызов будет неудачным. Для этого требуется перезапуск kubelet'а.
Что дальше
- Дополнительная информация о протоколе CRI
6 - Сборщик мусора
Сборщик мусора - это собирательный термин для различных механизмов? используемых Kubernetes для очистки ресурсов кластера. Это позволить очистить ресурсы, такие как:
- Неудачные pod-ы
- Завершенные задания
- Объекты без ссылок на владельца Objects
- Не используемые контейнеры и образы контейнеров
- Dynamically provisioned PersistentVolumes with a StorageClass reclaim policy of Delete
- Устаревшие или просроченные запросы подписания сертификатов (CSR)
- Nodes удалено в следующих сценариях:
- В облаке, когда кластер использует диспетчер облачных контроллеров
- Локально когда кластер использует дополнение, аналогичное диспетчер облачных контроллеров
- Объекты аренды узлов
Владельцы и зависимости
Многие объекты в Kubernetes ссылаются друг на друга через ссылки владельцев. Ссылки владельцев сообщают плоскости управления какие объекты зависят от других. Kubernetes использует ссылки владельцев, чтобы предоставить плоскости управления и другим API клиентам, возможность очистить связанные ресурсы перед удалением объекта. В большинстве случаев, Kubernetes автоматический управляет ссылками владельцев.
Владелец отличается от меток и селекторов
которые также используют некоторые ресурсы. Например, рассмотрим
Службу которая создает объект
EndpointSlice
. Служба использует метки чтобы позволить плоскости управления определить какие EndpointSlice
объекты используются для этой службы. В дополнение
к меткам, каждый EndpointSlice
управляет ои имени службы, имеет
ссылку владельца. Ссылки владельцев помогают различным частям Kubernetes избегать
вмешательства в объекты, которые они не контролируют.
Ссылки на владельцев перекрестных пространств имен запрещены по дизайну. Зависимости пространства имен могут указывать на область действия кластера или владельцев пространства имен. Владелец пространства имен должен быть в том же пространстве имен, что и зависимости. Если это не возможно, ссылка владельца считается отсутствующей и зависимый объект подлежит удалению, как только будет проверено отсутствие всех владельцев.
Зависимости области действия кластер может указывать только владельцев области действия кластера. В версии v1.20+, если зависимость с областью действия кластера указывает на пространство имен как владелец, тогда он рассматривается как имеющий неразрешимую ссылку на владельца и не может быть обработан сборщиком мусора.
В версии v1.20+, если сборщик мусора обнаружит недопустимое перекрестное пространство имен ownerReference
,
или зависящие от области действия кластера ownerReference
ссылка на тип пространства имен, предупреждающее событие с причиной OwnerRefInvalidNamespace
и involvedObject
сообщающее о недействительной зависимости.
Вы можете проверить наличие такого рода событий, выполнив kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace
.
Каскадное удаление
Kubernetes проверяет и удаляет объекты, на которые больше нет ссылок владельцев, так же как и pod-ов, оставленных после удаления ReplicaSet. Когда Вы удаляете объект, вы можете контролировать автоматический ли Kubernetes удаляет зависимые объекты автоматически в процессе вызова каскадного удаления. Существует два типа каскадного удаления, а именно:
- Каскадное удаление Foreground
- Каскадное удаление Background
Вы так же можете управлять как и когда сборщик мусора удаляет ресурсы, на которые ссылаются владельцы с помощью Kubernetes finalizers.
Каскадное удаление Foreground
В Каскадном удалении Foreground, объект владельца, который вы удаляете, сначала переходить в состояние в процессе удаления. В этом состоянии с объектом-владельцем происходить следующее:
- Сервер Kubernetes API устанавливает полю объекта
metadata.deletionTimestamp
время, когда объект был помечен для удаления. - Сервер Kubernetes API так же устанавливает метку
metadata.finalizers
для поляforegroundDeletion
. - Объект остается видимым благодаря Kubernetes API пока процесс удаления не завершиться
После того как владелец объекта переходит в состояние прогресса удаления, контроллер удаляет зависимые объекты. После удаления всех зависимых объектов, контроллер удаляет объект владельца. На этом этапе, объект больше не отображается в Kubernetes API.
Во время каскадного удаления foreground, единственным зависимым, которые блокируют удаления владельца, являются те, у кого имеется поле ownerReference.blockOwnerDeletion=true
.
Чтобы узнать больше. Смотрите Использование каскадного удаления foreground.
Каскадное удаление Background
В каскадном удалении background, сервер Kubernetes API немедленно удаляет владельца объекта, а контроллер очищает зависимые объекты в фоновом режиме. По умолчанию, Kubernetes использует каскадное удаление background, если вы в ручную не используете удаление foreground или не решите отключить зависимые объекты.
Чтобы узнать больше. Смотрите Использование каскадного удаления background.
Осиротевшие зависимости
Когда Kubernetes удаляет владельца объекта, оставшиеся зависимости называются осиротевшими объектами. По умолчанию, Kubernetes удаляет зависимые объекты. Чтобы узнать, как переопределить это поведение смотрите Удаление объектов владельца и осиротевших зависимостей.
Сбор мусора из неиспользуемых контейнеров и образов
kubelet выполняет сбор мусора для неиспользуемых образов каждые пять минут и для неиспользуемых контейнеров каждую минуту. Вам следует избегать использования внешних инструментов для сборки мусора, так как они могут нарушить поведение kubelet и удалить контейнеры, которые должны существовать.
Чтобы настроить параметры для сборщика мусора для неиспользуемого контейнера и сборки мусора образа, подстройте
kubelet использую конфигурационный файл
и измените параметры, связанные со сборщиком мусора используя тип ресурса
KubeletConfiguration
.
Жизненный цикл контейнерных образов Container image lifecycle
Kubernetes управляет жизненным циклом всех образов с помощью своего менеджера образов, которые являются частью kubelet, в сотрудничестве с cadvisor. При принятии решений о сборке мусора, kubelet учитывает следующие ограничения использования диска:
HighThresholdPercent
LowThresholdPercent
Использование диска выше настроенного значения HighThresholdPercent
запускает сборку мусора, которая удаляет образы в порядке основанном на последнем использовании, начиная с самого старого. Kubelet удаляет образы до тех пор, пока использование диска не достигнет значения LowThresholdPercent
.
Сборщик мусора контейнерных образов
Kubelet собирает не используемые контейнеры на основе следующих переменных, которые вы можете определить:
MinAge
: минимальный возраст, при котором kubelet может начать собирать мусор контейнеров. Отключить, установив значение0
.MaxPerPodContainer
: максимальное количество неактивных контейнеров, которое может быть у каждой пары Pod-ов. Отключить, установив значение меньше чем0
.MaxContainers
: максимальное количество не используемых контейнеров, которые могут быть в кластере. Отключить, установив значение меньше чем0
.
В дополнение к этим переменным, kubelet собирает неопознанные и удаленные контейнеры, обычно начиная с самого старого.
MaxPerPodContainer
и MaxContainer
могут потенциально конфликтовать друг с другом в ситуациях, когда требуется максимальное количество контейнеров в Pod-е (MaxPerPodContainer
) выйдет за пределы допустимого общего количества глобальных не используемых контейнеров (MaxContainers
). В этой ситуации kubelet регулирует MaxPodPerContainer
для устранения конфликта. Наихудшим сценарием было бы понизить MaxPerPodContainer
да 1
и изгнать самые старые контейнеры.
Кроме того, владельцы контейнеров в pod-е могут быть удалены, как только они становятся старше чем MinAge
.
Настройка сборщик мусора
Вы можете настроить сборку мусора ресурсов, настроив параметры, специфичные для контроллеров, управляющих этими ресурсами. В последующих страницах показано, как настроить сборку мусора:
Что дальше
- Узнайте больше о ownership of Kubernetes objects.
- Узнайте больше о Kubernetes finalizers.
- Узнать о TTL контроллере (beta) that cleans up finished Jobs.