Материал открыт для чтения

Войдите, чтобы сохранять прогресс и результаты.

Войти
Kubernetes — Основы

Архитектура кластера

чтение ~11 минУрок 2 из 30

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

module k8s intro Image02

В Docker на одной VM контейнеры запускал Docker Engine. Kubernetes решает задачу шире: нужно управлять контейнерами на нескольких машинах, следить за их состоянием, пересоздавать упавшие Pod'ы, выдавать им сеть и принимать команды от пользователя или CI.

В этом курсе мы не будем глубоко заниматься администрированием Kubernetes-кластера: установкой control plane, настройкой etcd, сертификатами, апгрейдами, резервным копированием и ремонтом системных компонентов. Это отдельная большая тема для администраторов платформы.

Но для прикладной работы всё равно важно понимать, из чего состоит кластер. Kubernetes - это не одна программа, которую просто запустили на сервере. Грубо говоря, это несколько программ, которые работают вместе: одна принимает запросы, другая хранит состояние, третья выбирает node для Pod'а, четвёртая запускает контейнеры на конкретной node.

Манифесты, Deployment, Service, ConfigMap и описание приложений - это прикладной слой работы с кластером. Именно с ним мы будем работать в этом курсе чаще всего. А архитектура ниже нужна как карта: чтобы понимать, куда попадает команда kubectl apply, почему Pod не появляется мгновенно и какие компоненты участвуют в поддержании желаемого состояния.

Чтобы не воспринимать Kubernetes как “большую чёрную коробку”, сначала разберём роли компонентов. Когда ты выполняешь kubectl apply, запрос проходит через API Server, сохраняется как желаемое состояние, а дальше контроллеры и kubelet постепенно приводят кластер к этому состоянию.

Кластер

Kubernetes-кластер — набор машин (серверов или VM), которые работают вместе. Каждая машина называется Node (узел). Узлы делятся на два типа:

Kubernetes Cluster
├── Control Plane (мозг кластера)
│   ├── API Server        — единая точка входа
│   ├── etcd              — база данных состояния
│   ├── Scheduler         — распределяет Pod'ы по узлам
│   └── Controller Manager — поддерживает желаемое состояние
└── Worker Nodes (рабочие лошадки)
    ├── kubelet           — агент на каждом узле
    ├── kube-proxy        — сетевые правила
    └── Container Runtime — запускает контейнеры (containerd)

Control Plane (Плоскость управления)

API Server

Единственная точка взаимодействия со всем кластером. Все команды (kubectl, CI/CD, другие компоненты) идут через него.

# Ты выполняешь:
kubectl apply -f deployment.yaml

# На самом деле:
# kubectl → HTTP POST → API Server → etcd → Scheduler → kubelet

API Server валидирует запросы, применяет политики авторизации и сохраняет изменения в etcd.

etcd

Распределённая key-value база данных — хранилище всего состояния кластера. Если etcd умрёт — кластер потеряет своё состояние.

etcd хранит:
├── Все Pod'ы и их состояния
├── Все Deployment'ы, Services, ConfigMaps...
├── Токены авторизации
└── Настройки сети

Это объясняет почему бэкап etcd — критически важная операция при администрировании production-кластера.

Scheduler

Смотрит на новые Pod'ы без назначенного Node и выбирает подходящий Node:

Новый Pod без Node
    ↓
Scheduler проверяет:
  - Есть ли ресурсы (CPU, RAM)?
  - Выполнены ли nodeSelector и affinity?
  - Применимы ли taints/tolerations?
    ↓
Назначает Pod на Node

Controller Manager

Запускает контроллеры — циклы, которые следят за состоянием:

  • ReplicaSet Controller: "Нужно 3 Pod'а, сейчас 2 → создать ещё один"
  • Deployment Controller: управляет rolling updates
  • Node Controller: следит за доступностью узлов
  • Job Controller: запускает одноразовые задачи

Worker Nodes

kubelet

Агент на каждом Worker Node. Получает задания от API Server и запускает контейнеры. Следит за состоянием Pod'ов и репортит обратно.

API Server: "На этом узле должен работать Pod nginx"
     ↓
kubelet → Container Runtime → запускает контейнер
kubelet → API Server: "Pod nginx Running, IP: 10.0.0.5"

kube-proxy

Сетевой proxy на каждом узле. Поддерживает сетевые правила (iptables/ipvs) для доступа к Service.

Container Runtime

Рантайм контейнеров — обычно containerd (раньше был Docker). Kubelet говорит "запусти этот образ" → containerd запускает контейнер.

Объекты Kubernetes

Всё в Kubernetes описывается объектами. У каждого объекта:
- apiVersion — версия API
- kind — тип объекта (Pod, Deployment, Service...)
- metadata — имя, namespace, labels
- spec — желаемое состояние
- status — текущее состояние (заполняется кластером)

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
  namespace: default
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:alpine
    ports:
    - containerPort: 80

Namespace — логическая изоляция

Кластер разделяется на namespace — логические пространства имён:

kubectl get namespaces
# default        — объекты без явного namespace
# kube-system    — системные компоненты k8s
# kube-public    — публично доступные ресурсы
# kube-node-lease — keepalive от узлов

В этом курсе ты работаешь в своём изолированном namespace. Ты не видишь Pod'ы других пользователей и не можешь изменить системные настройки.

kubectl: как мы общаемся с кластером

С Kubernetes обычно работают через специальную утилиту kubectl. Это CLI-клиент: ты вводишь команду в терминале, а kubectl формирует запрос к Kubernetes API Server.

kubectl не запускает контейнеры сам и не ходит напрямую на worker node. Его задача - обратиться к API Server:

  • kubectl get pods отправляет запрос "покажи Pod'ы";
  • kubectl apply -f deployment.yaml читает YAML-манифест и отправляет описание объекта;
  • kubectl delete pod web отправляет запрос на удаление объекта.

API Server уже делает следующую часть работы: проверяет права, сохраняет состояние в etcd и передаёт изменения дальше через контроллеры, scheduler и kubelet.

kubectl -> API Server -> etcd / controllers / scheduler / kubelet

Упрощённый путь запроса:

  1. kubectl читает kubeconfig.
  2. Находит адрес API Server и credentials.
  3. Отправляет HTTP-запрос в API Server.
  4. API Server проверяет аутентификацию: кто ты.
  5. API Server проверяет авторизацию через RBAC: что тебе можно делать.
  6. API Server читает или меняет состояние кластера.
  7. kubectl показывает ответ в терминале.

Kubeconfig

Чтобы kubectl знал, к какому кластеру подключаться и с какими правами, ему нужен kubeconfig.

Обычно файл лежит здесь:

~/.kube/config

Путь можно переопределить переменной окружения:

echo $KUBECONFIG

В учебной VM kubeconfig уже подготовлен. В реальной работе его обычно выдаёт администратор платформы, облачный провайдер или команда, которая управляет кластером. Например, в облаках kubeconfig часто создаётся командой CLI провайдера, а в корпоративной инфраструктуре его могут выдать через внутренний портал или секретное хранилище.

Kubeconfig не создаёт кластер. Это файл доступа: куда подключаться, каким пользователем и в какой namespace отправлять команды.

В kubeconfig обычно есть четыре важные части:

Поле Что означает
clusters адреса Kubernetes API Server и настройки доверия к сертификату
users данные пользователя: token, client certificate или другой способ входа
contexts связка cluster + user + namespace
current-context какой context используется сейчас

Упрощённо это выглядит так:

clusters:
- name: dev-cluster
  cluster:
    server: https://k8s.example.com

users:
- name: student
  user:
    token: ...

contexts:
- name: student@dev-cluster
  context:
    cluster: dev-cluster
    user: student
    namespace: default

current-context: student@dev-cluster

Context особенно важен. Он отвечает на вопрос: "в какой кластер, каким пользователем и в какой namespace сейчас пойдут команды".

Посмотреть текущие настройки можно так:

kubectl config current-context
kubectl config get-contexts
kubectl config view --minify

Если kubectl "ничего не видит", часто проблема не в Pod'ах, а в context или namespace. Поэтому перед диагностикой полезно проверить:

kubectl config view --minify --output 'jsonpath={..namespace}'
kubectl get pods
kubectl get pods -A

kubectl get pods -A — cluster-wide просмотр. Для прикладной диагностики обычно начинают с текущего namespace, а cluster-wide команды чаще относятся к platform/admin уровню.

get, describe, logs: базовый порядок просмотра

get даёт краткую таблицу:

kubectl get pods
kubectl get pods -o wide
kubectl get deployment,svc

-o wide добавляет больше полей: IP Pod'а, node, иногда дополнительные детали.

describe показывает подробности объекта и связанные Events:

kubectl describe pod web

logs показывает stdout/stderr контейнера:

kubectl logs pod/web --tail=50
kubectl logs -l app=web --tail=50
kubectl logs pod/web --previous

Перед лабами запомни порядок: сначала get, если статус непонятен - describe, если контейнер стартовал - logs.

Events - дополнительный источник диагностики. Они часто объясняют причину проблемы: image не скачался, не хватает ресурсов, probe падает, selector не находит Pod. Для отдельного просмотра событий:

kubectl get events --sort-by=.lastTimestamp

Namespace в командах

Команду можно выполнить в явном namespace:

kubectl get pods -n dev
kubectl config set-context --current --namespace=dev

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

kubectl config view --minify --output 'jsonpath={..namespace}'

Так ты не создашь ресурсы “не там”.

API resources и сокращения

Kubernetes API содержит много типов объектов. Посмотреть их можно так:

kubectl api-resources
kubectl explain pod
kubectl explain deployment.spec.replicas

kubectl explain полезен, когда ты пишешь YAML и не помнишь структуру поля. Он показывает схему ресурса из API Server.

Сокращения:

Полное имя Сокращение
pods po
deployments deploy
services svc
namespaces ns
configmaps cm
secrets secret

Примеры:

kubectl get po
kubectl get deploy,svc
kubectl describe svc web

Сокращения удобны в терминале, но в учебных объяснениях часто лучше писать полное имя, чтобы не терять смысл.

YAML из существующего объекта

Для изучения можно экспортировать объект:

kubectl get pod nginx-pod -o yaml
kubectl get deployment web -o yaml > web.yaml

Экспорт показывает и желаемую спецификацию, и runtime-поля. В Git обычно не коммитят status, uid, resourceVersion, managedFields, но для лабораторного анализа такой YAML полезен: он показывает, как Kubernetes дополнил объект defaults.

Материал изучен?

Войдите, чтобы сохранить прогресс и перейти к практической лаборатории.

Войти и продолжить