Зарегистрируйтесь, чтобы продолжить обучение

Архитектура Kubernetes Kubernetes

Архитектура Kubernetes

Когда вы создаете Pod командой kubectl apply, что происходит внутри кластера? Как Kubernetes решает, на какой узел поместить Pod? Кто следит за тем, чтобы количество реплик соответствовало желаемому? Понимание архитектуры Kubernetes поможет вам отвечать на эти вопросы и эффективно работать с кластером.

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

Два типа узлов

Kubernetes кластер состоит из двух типов узлов, которые выполняют разные роли. Представьте оркестр: Master узел — это дирижёр, который координирует работу, а Worker узлы — это музыканты, которые исполняют музыку.

Master узлы (Control Plane) управляют кластером. Они принимают решения о том, где запускать Pod, следят за состоянием кластера и обрабатывают все запросы. Worker узлы (Data Plane) выполняют реальную работу — запускают контейнеры и обрабатывают трафик приложений.

В production обычно используется несколько Master узлов для надежности. Если один Master узел выйдет из строя, другие продолжат управлять кластером. Worker узлов может быть десятки или сотни, в зависимости от нагрузки.

Задание: посмотрите узлы вашего кластера

Проверьте, какие узлы есть в вашем кластере:

kubectl get nodes

Вы увидите список узлов. Обычно один узел помечен как control-plane (Master), остальные — Worker узлы. Посмотрите подробную информацию:

kubectl get nodes -o wide

Это покажет IP-адреса узлов, версию Kubernetes и другую информацию. В локальном кластере (minikube, kind) обычно один узел, который совмещает обе роли.

Как работает создание Pod

Давайте проследим, что происходит, когда вы создаете Pod. Это поможет понять, как взаимодействуют компоненты.

Задание: создайте Pod и проследите процесс

Создайте простой Pod:

kubectl run test-pod --image=nginx --restart=Never

Пока Pod создается, посмотрите события в реальном времени:

kubectl get events --watch

Вы увидите последовательность событий: Pod создан, Scheduler назначил узел, kubelet запустил контейнер. Это показывает, как компоненты работают вместе.

Теперь посмотрите подробную информацию о Pod:

kubectl describe pod test-pod

В секции Events вы увидите хронологию того, что происходило с Pod. Это ключ к пониманию работы Kubernetes.

Компоненты Control Plane

Control Plane — это "мозг" кластера. Все компоненты Control Plane работают на Master узлах и принимают решения о кластере.

API Server: центральная точка

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

Проверьте адрес API Server:

kubectl cluster-info

Вы увидите адрес API Server, обычно это порт 6443. API Server выполняет несколько важных функций. Он проверяет, кто вы (аутентификация) и что вам разрешено делать (авторизация). Он проверяет корректность ваших манифестов перед их применением. И самое главное — он сохраняет все изменения в etcd.

API Server не принимает решения сам. Он только обрабатывает запросы и сохраняет данные. Решения принимают другие компоненты.

etcd: хранилище состояния

etcd — это база данных, которая хранит все состояние кластера. Каждый Pod, Service, Secret, Deployment — все это хранится в etcd. Если etcd потеряет данные, кластер перестанет работать, потому что Kubernetes не будет знать, какие Pod должны быть запущены.

Посмотрите Pod etcd:

kubectl get pods -n kube-system | grep etcd

etcd использует алгоритм Raft для синхронизации данных между несколькими узлами. Если у вас несколько Master узлов, у вас будет несколько etcd, которые синхронизируются друг с другом. Это обеспечивает надежность — если один etcd упадет, другие продолжат работать.

В production рекомендуется использовать нечетное количество etcd узлов (3, 5, 7). Это нужно для кворума — минимального количества узлов, которые должны быть доступны для принятия решений. Например, в кластере из 3 узлов кворум составляет 2 узла. Если один узел выйдет из строя, система продолжит работать, потому что два оставшихся узла могут принимать решения.

Scheduler: где разместить Pod

Когда вы создаете Pod, Scheduler решает, на какой узел его поместить. Scheduler постоянно смотрит на новые Pod и выбирает для них подходящие узлы.

Посмотрите логи Scheduler:

kubectl logs -n kube-system -l component=kube-scheduler --tail=50

Вы увидите, как Scheduler анализирует Pod и выбирает узлы. Scheduler работает в два этапа. Сначала он фильтрует узлы — исключает те, которые не подходят. Например, если Pod требует 4 GB памяти, а на узле доступно только 2 GB, этот узел будет исключен. Также исключаются узлы, которые не соответствуют ограничениям размещения.

Затем Scheduler оценивает оставшиеся узлы и выбирает лучший. Он учитывает равномерное распределение нагрузки, близость данных и другие факторы. Pod назначается на узел с наивысшим баллом.

Задание: посмотрите, как Scheduler размещает Pod

Создайте Deployment с несколькими репликами:

kubectl create deployment nginx --image=nginx --replicas=3

Подождите несколько секунд, затем посмотрите, где размещены Pod:

kubectl get pods -o wide

Вы увидите, что Pod распределены по узлам. Если у вас один узел, все Pod будут на нем. Если несколько узлов, Scheduler распределит Pod равномерно.

Controller Manager: поддержание желаемого состояния

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

Например, Replication Controller следит за ReplicaSet. Если вы указали, что должно быть 3 реплики, но одна упала, контроллер создаст новую. Deployment Controller управляет обновлениями Deployment. Node Controller следит за состоянием узлов.

Контроллеры работают по принципу "наблюдай и действуй". Они постоянно проверяют текущее состояние и сравнивают его с желаемым. Если есть расхождение, они выполняют действия для его устранения.

Задание: посмотрите работу контроллеров

Создайте Deployment:

kubectl create deployment test --image=nginx --replicas=2

Подождите, пока Pod запустятся, затем удалите один Pod:

kubectl get pods
kubectl delete pod <pod-name>

Сразу же проверьте Pod снова:

kubectl get pods -w

Вы увидите, что контроллер автоматически создал новый Pod, чтобы восстановить желаемое количество реплик. Это и есть работа контроллеров — они поддерживают желаемое состояние.

Компоненты Worker узла

Worker узлы выполняют реальную работу. На каждом Worker узле работают три основных компонента.

kubelet: агент на узле

kubelet — это агент, который работает на каждом узле. Он единственный компонент, который напрямую взаимодействует с контейнерами. Когда Scheduler назначает Pod на узел, kubelet получает эту информацию от API Server и запускает контейнеры.

kubelet постоянно работает в фоне. Он периодически запрашивает у API Server список Pod, которые должны работать на его узле. Затем он сравнивает этот список с тем, что реально запущено. Если Pod должен быть запущен, но его нет, kubelet запустит его. Если Pod не должен быть запущен, но он работает, kubelet остановит его.

kubelet также выполняет пробы здоровья (Liveness, Readiness). Если Liveness Probe показывает, что приложение зависло, kubelet перезапустит контейнер. Если Readiness Probe показывает, что приложение не готово, kubelet исключит Pod из Service.

kube-proxy: сетевая связность

kube-proxy обеспечивает работу Service. Когда вы создаете Service, kube-proxy настраивает правила перенаправления трафика. Когда приложение обращается к Service IP, трафик автоматически перенаправляется на один из backend Pod.

kube-proxy работает в режиме iptables по умолчанию. Он создает правила iptables, которые перенаправляют трафик. Это происходит автоматически — когда Service или Pod изменяются, kube-proxy обновляет правила.

Посмотрите конфигурацию kube-proxy:

kubectl get configmap -n kube-system kube-proxy -o yaml

Вы увидите настройки kube-proxy. В больших кластерах можно использовать режим ipvs для лучшей производительности.

Container Runtime: запуск контейнеров

Container Runtime — это программа, которая запускает контейнеры. Kubernetes не запускает контейнеры сам, он использует Container Runtime для этого. Популярные варианты — containerd, CRI-O и Docker.

Посмотрите, какой Container Runtime используется в вашем кластере:

kubectl get nodes -o wide

В колонке CONTAINER-RUNTIME вы увидите версию runtime. Container Runtime отвечает за загрузку образов, создание контейнеров, ограничение ресурсов и мониторинг состояния.

Как все работает вместе

Давайте проследим полный цикл создания Pod, чтобы понять, как компоненты взаимодействуют.

Шаг 1: Вы выполняете kubectl apply -f pod.yaml. kubectl отправляет HTTP запрос к API Server.

Шаг 2: API Server проверяет ваши права доступа и валидирует манифест. Если все в порядке, он сохраняет информацию о Pod в etcd.

Шаг 3: Scheduler постоянно опрашивает API Server и видит новый Pod без назначенного узла. Он анализирует требования Pod и выбирает подходящий узел.

Шаг 4: Scheduler сохраняет решение через API Server, который обновляет информацию в etcd. Теперь в etcd указано, что Pod должен быть на конкретном узле.

Шаг 5: kubelet на выбранном узле периодически опрашивает API Server и видит новый Pod для своего узла. Он получает спецификацию Pod.

Шаг 6: kubelet запускает контейнеры через Container Runtime. Container Runtime скачивает образ, если его нет, и создает контейнер.

Шаг 7: kubelet отправляет статус Pod обратно в API Server, который сохраняет его в etcd. Теперь вы видите, что Pod в состоянии Running.

Шаг 8: kube-proxy видит новый Pod и обновляет сетевые правила, чтобы Service мог направлять трафик на этот Pod.

Все это происходит автоматически и асинхронно. Компоненты не ждут друг друга — они работают независимо и общаются через API Server.

Задание: проследите создание Pod

Создайте Pod и сразу смотрите события:

kubectl run trace-pod --image=nginx --restart=Never
kubectl get events --field-selector involvedObject.name=trace-pod --sort-by=.metadata.creationTimestamp

Вы увидите последовательность событий: Pod создан, Scheduler назначил узел, kubelet запустил контейнер. Это показывает работу всех компонентов.

Сетевая модель

Kubernetes использует плоскую сетевую модель. Это означает, что каждый Pod получает уникальный IP-адрес, и любой Pod может обращаться к любому другому Pod напрямую, без преобразования адресов.

Это упрощает разработку. Приложение в Pod может использовать IP-адрес другого Pod напрямую, как будто они в одной локальной сети. Не нужно настраивать проброс портов или сложные правила маршрутизации.

Задание: проверьте сетевую связность

Создайте два Pod:

kubectl run pod1 --image=nginx --restart=Never
kubectl run pod2 --image=busybox --restart=Never --command -- sleep 3600

Подождите, пока Pod запустятся, затем получите IP-адрес первого Pod:

POD1_IP=$(kubectl get pod pod1 -o jsonpath='{.status.podIP}')
echo $POD1_IP

Теперь из второго Pod проверьте связность с первым:

kubectl exec pod2 -- ping -c 3 $POD1_IP

Вы увидите, что Pod могут общаться друг с другом напрямую по IP-адресам. Это и есть плоская сетевая модель.

Сетевая связность обеспечивается CNI плагинами — программами, которые настраивают сеть на узлах. Популярные плагины — Flannel, Calico, Weave, Cilium. Они автоматически выделяют IP-адреса Pod и настраивают маршрутизацию.

Хранилище данных

Для постоянного хранения данных Kubernetes использует PersistentVolume и PersistentVolumeClaim. PersistentVolume — это физическое хранилище, которое администратор создал в кластере. PersistentVolumeClaim — это запрос приложения на хранилище.

Когда приложение говорит "мне нужно 10 GB диска", Kubernetes находит подходящий PersistentVolume или создает новый через StorageClass. Это позволяет приложениям запрашивать хранилище, не зная деталей его реализации.

Посмотрите доступные StorageClass:

kubectl get storageclass

StorageClass определяет тип хранилища и параметры его создания. В облачных кластерах StorageClass автоматически создает диски в облаке при создании PersistentVolumeClaim.

Практика: анализ кластера

Давайте проанализируем состояние вашего кластера:

# Общая информация
kubectl cluster-info

# Узлы
kubectl get nodes -o wide

# Компоненты Control Plane
kubectl get pods -n kube-system

# События
kubectl get events --all-namespaces --sort-by=.metadata.creationTimestamp | tail -20

Эти команды дают общую картину состояния кластера. Если что-то не работает, начните с этих проверок.

Задание: найдите проблемный компонент

Посмотрите все Pod в kube-system:

kubectl get pods -n kube-system

Все Pod должны быть в состоянии Running. Если какой-то Pod в состоянии Error или CrashLoopBackOff, это указывает на проблему. Посмотрите логи проблемного Pod:

kubectl logs -n kube-system <pod-name>

Логи покажут, что пошло не так. Это поможет понять, какой компонент не работает и почему.

Что дальше

Теперь вы понимаете, как устроен Kubernetes изнутри. Вы знаете, что API Server обрабатывает все запросы, etcd хранит состояние, Scheduler размещает Pod, контроллеры поддерживают желаемое состояние, а kubelet и kube-proxy работают на Worker узлах.

Это понимание поможет вам диагностировать проблемы. Если Pod не запускается, вы знаете, что проверить: логи Scheduler, состояние узлов, работу kubelet. Если Service не работает, вы знаете, что проверить kube-proxy и сетевую конфигурацию.

В следующих уроках вы глубже изучите компоненты Control Plane и Data Plane, чтобы еще лучше понимать работу кластера.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff