Найти тему
Виталий Шевченко

Kubernetes. 2 часть. Архитектура.

Итак повторим: Kubelet - управляет pod-ами, общается с api-server-ом для этого. При этом именно api-server и передаём kubelet задачи: "Разверни мне pod". И api-server передаёт kubelet файл createMyApp.yaml, kubelet взаимодействует с container runtime, с сетевыми плагинами и создаёт pod на основе createMyApp.yaml файла Pod.

Api-server это компонент, который живёт на Master-ноде, и является единой точкой для общения с кластером.

Любой компонент кластера, который хочет что-либо сделать - он общается с api-server-ом (REST, https).

API server - точка входа для всех взаимодействий компонентов kubernetes.

Но это не укладывается в концепцию "отсутствия единой точки отказа". Но Master-нод может быть много, и api-server-ов таким образом может быть много.

А что делает api-server? Он проверяет конфигурации и конфигурирует api-объекты (pods, services и т.д.)

Когда kubelet общается с api-server-ом, то он получает от api-server-а информацию в виде yaml (json) файла, kubelet и отвечает также yaml (json).

Всё что компоненты сказали api-server-у, он сохраняет в etcd.

etcd - это key-value хранилище.

Ещё один важным компонент, который живёт на Master-ноде, это kube-controller-manager.

Kube-api-server, etcd, kube-controller-manager - это просто контейнеры, которые запускаются на Master ноде.

Kube-controller-manager состоит из абстракций, называемых контроллерами. Они постоянно сравнивают текущее состояние кластера с желаемым.

Откуда они берут текущее состояние? Текущее состояние им даёт kubelet.

C Worker-нод kubelet-ы передают информацию о том, что там происходит. Эта вся информация через api-server попадает в etcd, и туда же через api-server идёт controller-manager и узнаёт текущее состояние кластера.

В etcd сохраняются два знания:

  1. О том как дела у кластера.
  2. И как админ хочет, чтобы были дела у кластера.

И контроллер сравнивает эти два состояния: текущее и желаемое, и принимает решение, кому передать команду, чтобы привести состояние кластера к желаемому.

Вот в этом месте на сцену выходит ещё один компонент kube-scheduler.

Kube-scheduler - это компонент, который управляет вычислительными ресурсами.

Во-первых, он учитывает какие ресурсы есть.

  • Пришла новая нода в кластер, запустился на ней kubelet - "я новенький, загрузка слабая, оперативки не меряно".
  • Kube-scheduler - "хорошо, имеем новую ноду, с такими-то характеристиками"

Во-вторых, он ведёт учёт требований к ресурсам.

  1. Так смотри, админ запустил сейчас вот этот контейнер.
  2. Он хочет, чтобы контейнеру сразу дали 1 Гбайт оперативки с возможностью расширения до 4 Гбайт.

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

В-третьих kube-scheduler учитывает ограничения по ресурсам (affinity, anti-affinity)

Master-ноды отличается от worker-нод тем, что они имеют различные пометки, что туда нельзя класть обычную нагрузку. И Master-ноды крутят в себе только компоненты kubernetes.

А ваши контейнеры с приложениями не могут запускаться на Master-ноде. Это для того, чтобы избежать влияния Applications (ваших приложений) на Master-ноду. Высокая нагрузка на Master-ноду может приводить к печальным последствиям.

В итоге kube-scheduler решает, где запустить контейнер. При этом вариант "не могу запустить" - это тоже решение.

Не следует ожидать, что Master будет "помирать", но "тащить" нагрузку. Если вы захотите запустить контейнер, которому требуется 30 Гбайт оперативки, а в наличии только 2, то ваш контейнер нигде не запустится.

Потому, что kube-scheduler скажет, что на 30 гигов у него ничего нет. И сделает пометку, что этот контейнер запустить не может. И пойдёт по своим делам.

Это не значит, что kube-scheduler не пересмотрит своё решение. Когда появится нода с 30 Гбайтами оперативки, kube-scheduler "вспомнит" и запустит контейнер, которому требовалось 30 Гбайт.

Kube-scheduler не допустит, чтобы стало совсем плохо.