Основы Kubernetes и развертывание кластера через kubeadm

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

1. Введение в Kubernetes: Архитектура, основные компоненты и требования к узлам

Введение в Kubernetes: Архитектура, основные компоненты и требования к узлам

Добро пожаловать в курс «Основы Kubernetes и развертывание кластера через kubeadm». Это первая статья, в которой мы заложим фундамент для понимания того, как работает самая популярная система оркестрации контейнеров в мире.

Если вы уже знакомы с Docker, то знаете, как запустить один контейнер. Но что делать, если контейнеров сотни? Как следить за тем, чтобы они не падали? Как распределить их по разным серверам? Именно эти задачи решает Kubernetes.

Что такое Kubernetes?

Kubernetes (часто сокращают как K8s) — это платформа с открытым исходным кодом для автоматизации развертывания, масштабирования и управления контейнеризированными приложениями. Изначально она была разработана компанией Google (на основе их внутренней системы Borg), а сейчас поддерживается Cloud Native Computing Foundation.

Представьте себе оркестр. Каждый музыкант — это контейнер. Чтобы музыка звучала гармонично, нужен дирижер, который говорит, кому и когда вступать, и следит за темпом. Kubernetes — это и есть этот дирижер для ваших контейнеров.

Архитектура Kubernetes: Вид с высоты птичьего полета

Кластер Kubernetes состоит из двух основных типов узлов (серверов):

  • Control Plane (Управляющий слой) — «мозг» кластера. Он принимает решения, планирует задачи и следит за состоянием системы.
  • Worker Nodes (Рабочие узлы) — «мускулы» кластера. Здесь запускаются ваши приложения (контейнеры).
  • !Общая схема архитектуры Kubernetes: разделение на управляющий слой и рабочие узлы

    Давайте разберем каждый компонент подробнее.

    Компоненты Control Plane (Master Node)

    Управляющий слой отвечает за глобальные решения в кластере (например, планирование запуска новых контейнеров) и обнаружение/реагирование на события (например, перезапуск упавшего контейнера).

    1. kube-apiserver

    Это центральный компонент, «парадная дверь» кластера. Все взаимодействия с кластером — будь то ваши команды через консоль kubectl или внутренние запросы от рабочих узлов — проходят через API Server. Он проверяет права доступа, валидирует запросы и обновляет информацию в базе данных.

    2. etcd

    Это надежное и высокопроизводительное хранилище данных типа «ключ-значение». Именно здесь хранится все состояние кластера: какие узлы есть, какие приложения запущены, какие настройки применены. Если API Server — это мозг, то etcd — это память.

    > Важно понимать: etcd — единственный компонент, который хранит состояние (stateful). Все остальные компоненты не хранят данных (stateless).

    Для обеспечения отказоустойчивости etcd часто запускают на нескольких узлах. Количество узлов для кворума (согласованности данных) рассчитывается по формуле:

    где — общее количество узлов в кластере etcd, — количество узлов, выход из строя которых кластер может пережить, а — минимально необходимый остаток для принятия решений.

    3. kube-scheduler

    Планировщик (Scheduler) следит за новыми задачами (подами), у которых еще не назначен узел. Он анализирует ресурсы (сколько памяти и CPU свободно на узлах) и решает, на какой конкретно Worker Node отправить приложение.

    4. kube-controller-manager

    Этот компонент запускает процессы контроллеров. Логически каждый контроллер — это отдельный процесс, но для упрощения они скомпилированы в один бинарный файл.

    Примеры контроллеров: Node Controller*: замечает и реагирует, если узел перестал отвечать. Job Controller*: следит за выполнением разовых задач.

    Компоненты Worker Node

    Рабочие узлы поддерживают работу подов и обеспечивают среду выполнения Kubernetes.

    1. kubelet

    Это главный агент, который работает на каждом узле кластера. Он получает инструкции от API Server (например: «Запусти этот контейнер») и гарантирует, что контейнеры запущены и работают исправно. Если контейнер падает, kubelet пытается его перезапустить.

    2. kube-proxy

    Сетевой прокси, работающий на каждом узле. Он поддерживает сетевые правила (обычно используя iptables или IPVS операционной системы). Благодаря kube-proxy возможна сетевая связь между подами и доступ к сервисам извне.

    3. Container Runtime

    Программа, ответственная за непосредственный запуск контейнеров. Kubernetes поддерживает несколько сред выполнения: * containerd * CRI-O * Docker Engine (через cri-dockerd)

    !Взаимодействие внутренних компонентов Kubernetes

    Основные понятия: Pod и Service

    Прежде чем переходить к установке, нужно знать два базовых термина:

    * Pod (Под) — минимальная единица развертывания в Kubernetes. Это «оболочка» для одного или нескольких контейнеров. Обычно один под содержит один контейнер приложения. * Service (Сервис) — абстракция, которая определяет логический набор подов и политику доступа к ним (сетевой балансировщик).

    Подготовка к развертыванию: Требования к узлам

    В этом курсе мы будем использовать утилиту kubeadm — официальный инструмент для быстрого создания кластеров. Чтобы установка прошла успешно, ваши серверы (виртуальные машины) должны соответствовать определенным требованиям.

    Аппаратные требования

    Для минимального кластера (1 Master + 1 Worker) или даже для одного узла (All-in-one) рекомендуется:

    | Компонент | Требование | | :--- | :--- | | ОС | Linux (Ubuntu 20.04/22.04, CentOS 7/8, Rocky Linux) | | CPU | Минимум 2 ядра (для Control Plane) | | RAM | Минимум 2 ГБ (желательно 4 ГБ и более) | | Сеть | Полная связность между всеми машинами |

    Программные требования и настройки ОС

    Перед запуском kubeadm необходимо выполнить несколько критически важных действий:

  • Отключение Swap. Это самое важное требование. Kubernetes (а именно kubelet) некорректно работает с файлом подкачки. Он должен быть отключен навсегда.
  • Уникальные hostname, MAC-адреса и product_uuid. Узлы должны быть различимы.
  • Открытые порты. Брандмауэр не должен блокировать трафик между компонентами.
  • Основные порты для Control Plane: * 6443 (API Server) — самый важный порт. * 2379-2380 (etcd). * 10250 (Kubelet API).

    Сетевая конфигурация

    Kubernetes требует, чтобы поды могли общаться друг с другом без NAT (трансляции сетевых адресов). Для этого мы будем устанавливать сетевой плагин (CNI - Container Network Interface) после инициализации кластера.

    Заключение

    Мы разобрали анатомию Kubernetes. Теперь вы знаете, что кластер состоит из управляющего слоя (Control Plane) и рабочих лошадок (Worker Nodes). Вы познакомились с ключевыми компонентами: API Server, etcd, Scheduler, Kubelet и Kube-proxy.

    В следующей статье мы перейдем от теории к практике: подготовим виртуальные машины, установим Container Runtime и необходимые утилиты (kubeadm, kubelet, kubectl).

    2. Подготовка окружения: Установка Container Runtime и инструментов kubeadm, kubelet, kubectl

    Подготовка окружения: Установка Container Runtime и инструментов kubeadm, kubelet, kubectl

    Рад видеть вас снова на курсе «Основы Kubernetes и развертывание кластера через kubeadm». В предыдущей статье мы изучили архитектуру Kubernetes, разобрали роль Control Plane и Worker Nodes, а также обсудили базовые требования к «железу».

    Теперь пришло время испачкать руки в терминале. Теория без практики мертва, а кластер сам себя не развернет. В этой статье мы превратим «чистые» виртуальные машины в готовые к объединению узлы Kubernetes. Мы пройдем путь от настройки ядра Linux до установки святой троицы инструментов: kubeadm, kubelet и kubectl.

    Этот процесс необходимо выполнить на всех машинах, которые будут участвовать в кластере (и на мастере, и на воркерах).

    Шаг 1: Настройка сетевых параметров ядра

    Kubernetes предъявляет специфические требования к сетевому стеку Linux. По умолчанию многие функции, необходимые для маршрутизации трафика между контейнерами (подами), отключены в целях безопасности или экономии ресурсов.

    Нам нужно загрузить два модуля ядра:

  • overlay — необходим для работы драйвера файловой системы overlayfs, который используется контейнерами.
  • br_netfilter — позволяет трафику, проходящему через сетевой мост (bridge), обрабатываться iptables. Это критически важно для работы сети внутри Kubernetes.
  • Выполните следующие команды, чтобы загрузить модули и настроить их автозагрузку:

    Теперь нам нужно включить параметры sysctl, которые позволят узлам правильно пересылать трафик. Нас интересует IP-форвардинг (пересылка пакетов) и видимость мостового трафика.

    > Если вы пропустите этот шаг, то при инициализации кластера kubeadm выдаст ошибку или предупреждение о том, что ip_forward отключен.

    Шаг 2: Установка Container Runtime (containerd)

    Раньше Kubernetes работал с Docker напрямую. Однако с версии 1.24 поддержка Docker (через компонент dockershim) была удалена. Теперь Kubernetes использует интерфейс CRI (Container Runtime Interface) для общения со средой запуска контейнеров.

    !Схема работы Container Runtime Interface (CRI)

    Мы будем использовать containerd — это промышленный стандарт, легкий и надежный рантайм, который, кстати, является «сердцем» Docker.

    Установка containerd

    Для большинства дистрибутивов Linux (Ubuntu/Debian) проще всего установить containerd из официального репозитория Docker, так как там находятся самые свежие версии.

  • Установим необходимые утилиты:
  • Добавим GPG-ключ и репозиторий Docker:
  • Установим сам пакет containerd.io:
  • Настройка Cgroup Driver

    Это самый важный момент во всей установке, на котором спотыкаются 80% новичков.

    В Linux есть механизм cgroups (control groups), который ограничивает ресурсы (CPU, память) для процессов. Этим механизмом управляет система инициализации systemd. Kubernetes (через kubelet) тоже хочет управлять cgroups для подов.

    Если systemd и kubelet будут пытаться управлять cgroups независимо друг от друга, это приведет к нестабильности системы. Нам нужно настроить containerd так, чтобы он использовал systemd как драйвер cgroup.

  • Сгенерируем конфигурацию по умолчанию:
  • Теперь нужно отредактировать файл /etc/containerd/config.toml. Найдите параметр SystemdCgroup и измените его значение с false на true.
  • Вы можете сделать это вручную редактором nano или vi, либо использовать команду sed:

  • Перезапустим containerd, чтобы применить настройки:
  • Шаг 3: Установка kubeadm, kubelet и kubectl

    Теперь, когда у нас есть работающий рантайм, установим инструменты Kubernetes. Нам понадобятся три компонента:

    * kubeadm: утилита для инициализации кластера («загрузчик»). * kubelet: компонент, который запускается на всех машинах и выполняет такие действия, как запуск подов и контейнеров. * kubectl: утилита командной строки для общения с кластером.

    > Важно: Версии этих трех компонентов должны совпадать (или отличаться незначительно). Рассинхронизация версий может привести к трудноуловимым багам.

    Добавление репозитория Kubernetes

    В августе 2023 года Google изменил местоположение репозиториев пакетов. Старые репозитории (apt.kubernetes.io) больше не обновляются. Мы будем использовать новый репозиторий pkgs.k8s.io.

  • Установим пакеты для работы с apt (если еще не установлены):
  • Загрузим публичный ключ подписи для репозиториев Kubernetes. В примере мы используем версию v1.29 (вы можете выбрать более новую, изменив цифры в URL):
  • Добавим репозиторий в список источников:
  • Установка пакетов

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

    Фиксация версий (Version Hold)

    Это крайне рекомендуемый шаг для продакшн-систем. Если вы случайно запустите apt-get upgrade, ваши компоненты Kubernetes могут обновиться, что приведет к рассинхронизации версий и потенциальному падению кластера. Обновление Kubernetes — это отдельный, контролируемый процесс.

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

    Шаг 4: Проверка установки

    Давайте убедимся, что все установлено корректно.

  • Проверьте версию kubeadm:
  • Проверьте статус сервиса kubelet:
  • Вы, скорее всего, увидите, что kubelet находится в состоянии activating (auto-restart) или циклично перезапускается с ошибкой. Не пугайтесь, это нормально!

    Kubelet ожидает конфигурацию, которую ему предоставит kubeadm только на этапе инициализации кластера. Пока кластер не инициализирован, kubelet не знает, что ему делать, и перезапускается в ожидании инструкций.

    Чек-лист перед следующей статьей

    Прежде чем переходить к созданию кластера, убедитесь, что на каждом вашем сервере (Master и Workers):

    * [ ] Отключен Swap (sudo swapoff -a). * [ ] Загружены модули ядра overlay и br_netfilter. * [ ] Включен IP-forwarding в sysctl. * [ ] Установлен и запущен containerd. * [ ] В конфиге containerd параметр SystemdCgroup установлен в true. * [ ] Установлены kubeadm, kubelet, kubectl и их версии зафиксированы.

    Если все галочки проставлены — поздравляю! Вы подготовили идеальный фундамент. В следующей статье мы наконец-то введем заветную команду kubeadm init и запустим наш Control Plane.

    До встречи на этапе инициализации!

    3. Инициализация кластера: Запуск Control Plane, настройка CNI и подключение рабочих нод

    Инициализация кластера: Запуск Control Plane, настройка CNI и подключение рабочих нод

    Добро пожаловать на третий этап нашего курса «Основы Kubernetes и развертывание кластера через kubeadm». В прошлых статьях мы разобрали теорию архитектуры и подготовили фундамент: настроили операционную систему, отключили swap и установили Container Runtime (containerd) вместе с утилитами Kubernetes.

    Сегодня наступает момент истины. Мы объединим разрозненные серверы в единый организм. Мы запустим «мозг» кластера (Control Plane), настроим «нервную систему» (сетевой плагин) и подключим «мускулы» (рабочие ноды).

    Шаг 1: Предварительная загрузка образов

    Этот шаг не является строго обязательным, но он считается хорошим тоном. При инициализации кластера kubeadm должен скачать образы контейнеров для компонентов управления (API Server, Controller Manager, Scheduler, etcd, CoreDNS).

    Чтобы процесс инициализации прошел быстрее и мы сразу увидели возможные проблемы с доступом к реестрам (registry), выполните следующую команду на Master Node:

    Эта команда проверит доступность репозитория registry.k8s.io и загрузит необходимые Docker-образы локально.

    Шаг 2: Инициализация Control Plane

    Теперь мы готовы запустить главную команду. Она сгенерирует сертификаты, создаст конфигурационные файлы и запустит статические поды.

    !Процесс работы команды kubeadm init: генерация сертификатов и запуск компонентов

    Выбор сетевого диапазона для подов

    Критически важный момент: при инициализации мы должны указать диапазон IP-адресов, который будет использоваться подами. Этот диапазон не должен пересекаться с IP-адресами ваших физических серверов.

    Мы будем использовать сетевой плагин Calico (один из самых популярных CNI). По умолчанию Calico использует подсеть 192.168.0.0/16. Нам нужно передать этот параметр флагу --pod-network-cidr.

    Запуск инициализации

    Выполните команду на Master Node:

    > Если у вашего сервера несколько сетевых интерфейсов, рекомендуется явно указать IP-адрес, на котором будет слушать API Server, добавив флаг --apiserver-advertise-address=<IP_ВАШЕГО_МАСТЕРА>.

    Что происходит «под капотом»?

    Пока вы смотрите на бегущие строки логов, kubeadm выполняет колоссальную работу:

  • Pre-flight checks: Проверяет, соответствует ли система требованиям (память, CPU, swap, модули ядра).
  • Certs generation: Создает центр сертификации (CA) и подписывает сертификаты для всех компонентов.
  • Kubeconfig generation: Создает файлы конфигурации для аутентификации сервисов.
  • Static Pods: Генерирует манифесты в папке /etc/kubernetes/manifests. Kubelet автоматически находит их и запускает API Server, etcd, Scheduler и Controller Manager.
  • Taints: Помечает мастер-ноду, чтобы на ней не запускались обычные пользовательские приложения.
  • Шаг 3: Настройка доступа для администратора

    Когда команда отработает, вы увидите сообщение: "Your Kubernetes control-plane has initialized successfully!".

    ВАЖНО: Не очищайте терминал! В конце вывода будет команда для присоединения воркеров, которая нам скоро понадобится.

    Чтобы управлять кластером через утилиту kubectl не от имени root, нужно скопировать конфигурационный файл в домашнюю директорию вашего пользователя. Выполните команды, которые вам подскажет сам kubeadm в выводе:

    bash kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml bash kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml bash kubectl get nodes bash sudo kubeadm join 10.128.0.10:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef bash kubeadm token create --print-join-command bash kubectl get nodes text NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 15m v1.29.0 k8s-worker-1 Ready <none> 2m v1.29.0 k8s-worker-2 Ready <none> 1m v1.29.0 bash kubectl get pods -A ``

    Флаг -A означает «во всех неймспейсах» (All namespaces). Вы должны увидеть поды coredns, etcd, kube-apiserver, kube-proxy и поды calico в статусе Running.

    Возможные проблемы

  • Swap: Если вы забыли отключить swap на воркере, kubeadm join зависнет или выдаст ошибку. Отключите swap (sudo swapoff -a) и попробуйте снова.
  • Firewall: Если ноды не видят друг друга, проверьте, открыты ли порты (6443, 10250, порты CNI).
  • Разные версии: Убедитесь, что версии kubeadm и kubelet` на всех узлах совпадают.
  • Заключение

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

    В следующей части курса мы научимся управлять этой мощью: разберем основные примитивы Kubernetes (Pod, Deployment, Service) и запустим наше первое веб-приложение, доступное из внешнего мира.

    4. Работа с кластером: Развертывание первых приложений, управление Pods и Services

    Работа с кластером: Развертывание первых приложений, управление Pods и Services

    Приветствую вас в четвертой части курса «Основы Kubernetes и развертывание кластера через kubeadm». В предыдущих статьях мы проделали огромную работу: подготовили инфраструктуру, установили Container Runtime и объединили виртуальные машины в полноценный кластер. Теперь, когда у нас есть работающая платформа, пришло время заставить её приносить пользу.

    В этой статье мы перейдем от администрирования инфраструктуры к эксплуатации приложений. Мы разберем, как запускать контейнеры, как обеспечивать их «бессмертие» и как открывать к ним доступ из внешнего мира.

    Pod: Атомарная единица Kubernetes

    Многие новички, приходящие из мира Docker, ожидают увидеть команду k8s run container. Однако в Kubernetes мы не управляем контейнерами напрямую. Минимальной единицей развертывания является Pod (Под).

    Pod — это логическая обертка для одного или нескольких контейнеров, которые:

  • Разделяют общее сетевое пространство (один IP-адрес на всех).
  • Имеют доступ к общим томам хранения.
  • Всегда запускаются на одной и той же ноде.
  • Запуск первого пода (Императивный способ)

    Давайте запустим наш первый веб-сервер Nginx. Для этого мы будем использовать утилиту kubectl. Существует два подхода к управлению: императивный (через команды в консоли) и декларативный (через YAML-файлы). Для быстрого старта и тестов императивный метод подходит идеально.

    Выполните команду на Master-ноде:

    Вы должны увидеть сообщение pod/my-first-pod created. Давайте проверим его статус:

    Вывод будет примерно таким:

    Если статус Running, значит, планировщик (Scheduler) успешно нашел подходящую ноду, а kubelet на этой ноде скачал образ и запустил контейнер.

    Чтобы узнать подробности (например, на какой именно ноде запущен под и какой у него IP), добавьте флаг -o wide:

    Диагностика и отладка

    Что делать, если статус не Running, а, например, ErrImagePull или CrashLoopBackOff? У нас есть два главных инструмента врача Kubernetes:

  • Describe — показывает подробную информацию о событиях объекта.
  • В самом низу вывода, в секции Events, вы увидите хронику жизни пода: назначение на ноду, скачивание образа, запуск.

  • Logs — показывает вывод (stdout/stderr) контейнера.
  • Deployment: Управление состоянием

    Запускать одиночные поды (kubectl run) — плохая практика в продакшене. Почему? Потому что поды в Kubernetes смертны. Если нода, на которой работал ваш под, сгорит, под умрет вместе с ней. Kubernetes не перезапустит его автоматически на другой ноде, потому что одиночный под — это «разовая» сущность.

    Чтобы обеспечить отказоустойчивость, мы используем контроллеры. Самый популярный из них — Deployment.

    Логика контроллера (Reconciliation Loop)

    Deployment гарантирует, что в кластере всегда запущено желаемое количество копий приложения. Это работает на основе цикла согласования. Математически логику работы контроллера можно описать простой формулой разницы состояний:

    Где: * (Дельта) — действие, которое необходимо выполнить. * — желаемое количество реплик (сколько мы хотим). * — текущее количество реплик (сколько есть сейчас).

    Если , контроллер создает новые поды. Если , контроллер удаляет лишние.

    !Иерархия объектов: Deployment следит за состоянием, ReplicaSet управляет количеством копий, Pods исполняют код

    Создание Deployment

    Давайте удалим наш старый под и создадим Deployment:

    Мы приказали кластеру: «Я хочу, чтобы всегда работало 3 экземпляра Nginx». Проверим:

    Вы увидите три пода с именами вроде my-web-7d6d97c7d-abcde. Deployment создал промежуточный объект ReplicaSet, который и наплодил нам поды.

    Магия самовосстановления

    Давайте проверим теорию на практике. «Убьем» один из подов вручную. Скопируйте имя одного из подов и выполните:

    Сразу же снова запустите kubectl get pods. Вы увидите, что удаленный под перешел в статус Terminating, но мгновенно появился новый под (с возрастом пару секунд). ReplicaSet заметил, что , а , вычислил и запустил недостающий экземпляр.

    Масштабирование

    Если ваш стартап стал популярным, и трех серверов не хватает, вы можете масштабироваться одной командой:

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

    Service: Сетевой доступ и балансировка

    У каждого пода есть свой внутренний IP-адрес. Но мы выяснили, что поды смертны. Когда под умирает и рождается новый, его IP меняется. Как же клиентам (или другим приложениям) знать, куда слать запросы?

    Здесь на сцену выходит Service (Сервис). Это абстракция, которая предоставляет единую точку входа (стабильный IP и DNS-имя) для группы подов.

    Типы сервисов

  • ClusterIP (по умолчанию): Сервис доступен только внутри кластера. Подходит для баз данных и бэкендов.
  • NodePort: Открывает порт на IP-адресе каждой ноды кластера. Позволяет получить доступ извне.
  • LoadBalancer: Использует балансировщик нагрузки облачного провайдера (AWS, Google Cloud). В нашем случае (bare-metal/VMs) этот тип не будет работать без дополнительных плагинов (например, MetalLB).
  • Публикация приложения через NodePort

    Так как мы разворачиваем кластер на виртуальных машинах, самый простой способ увидеть наш Nginx в браузере — использовать NodePort.

    Эта команда создает сервис, который перенаправляет трафик с порта сервиса на порт 80 внутри контейнеров.

    Давайте узнаем, какой порт выделил нам Kubernetes:

    Вывод:

    Обратите внимание на колонку PORT(S). Значение 80:31567 означает, что внутренний порт 80 отображен на внешний порт 31567. Диапазон NodePort по умолчанию: 30000–32767.

    Проверка доступа

    Теперь вы можете открыть браузер и ввести адрес любой из ваших нод (Master или Worker) с этим портом:

    http://<IP-ВАШЕЙ-НОДЫ>:31567

    Вы должны увидеть приветственную страницу Welcome to nginx!.

    Как это работает? Вы отправляете запрос на порт 31567 любой ноды. Служба kube-proxy (которую мы обсуждали в первой статье) перехватывает пакет и перенаправляет его на один из подов вашего Deployment, даже если этот под находится физически на другом сервере.

    Декларативный подход: Введение в YAML

    До сих пор мы использовали длинные команды в консоли. Это удобно для тестов, но ужасно для поддержки. В мире DevOps принят подход Infrastructure as Code (IaC).

    В Kubernetes мы описываем желаемое состояние в YAML-файлах (манифестах) и «скармливаем» их кластеру.

    Вот как выглядит манифест для нашего Deployment:

    Чтобы применить такой файл, используется универсальная команда:

    Если вы измените в файле replicas: 3 на replicas: 5 и снова выполните apply, Kubernetes увидит разницу и масштабирует приложение. Это и есть декларативная магия.

    Заключение

    Сегодня мы сделали огромный шаг вперед. Мы научились:

  • Запускать поды и диагностировать их состояние.
  • Использовать Deployment для самовосстановления и масштабирования приложений.
  • Понимать математику контроллеров (Reconciliation Loop).
  • Открывать доступ к приложениям через Service NodePort.
  • Теперь ваш кластер — это не просто набор серверов, а живая платформа, обслуживающая трафик. В следующей, заключительной статье базового курса, мы поговорим о хранении данных (Volumes и PersistentVolumes), чтобы наши базы данных не теряли информацию при перезапуске подов.

    5. Обслуживание кластера: Процесс обновления версии Kubernetes с помощью kubeadm и управление сертификатами

    Обслуживание кластера: Процесс обновления версии Kubernetes с помощью kubeadm и управление сертификатами

    Добро пожаловать в заключительную часть курса «Основы Kubernetes и развертывание кластера через kubeadm». Мы прошли долгий путь: от изучения архитектуры и подготовки серверов до запуска первых приложений и настройки сети.

    Однако развертывание кластера — это только начало. В реальной жизни (Day 2 Operations) администратор сталкивается с необходимостью поддерживать кластер в актуальном состоянии. Программное обеспечение устаревает, выходят патчи безопасности, а криптографические сертификаты имеют свойство истекать.

    В этой статье мы разберем два критически важных процесса: обновление версии Kubernetes без простоя (Zero Downtime Upgrade) и управление сертификатами безопасности.

    Стратегия версионирования Kubernetes

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

    Kubernetes следует семантическому версионированию , где: * — мажорная версия (Major). * — минорная версия (Minor). * — патч-версия (Patch).

    Например, в версии 1.29.2: — мажорная, — минорная, — патч.

    Правило перекоса версий (Version Skew Policy)

    В кластере компоненты могут иметь разные версии, но только в определенных пределах. Самое строгое правило касается отношения между API Server (на Control Plane) и Kubelet (на рабочих нодах).

    Математически это правило можно выразить следующим неравенством:

    Где — минорная версия агента на узле, — минорная версия API-сервера, а — максимально допустимая разница в версиях (в меньшую сторону для kubelet).

    Это означает, что если ваш API Server обновлен до версии 1.30, то Kubelet на рабочих нодах может быть версии 1.30, 1.29 или 1.28. Но Kubelet никогда не может быть новее API Server.

    > Важно: kubeadm поддерживает обновление только на одну минорную версию за раз. Вы не можете обновиться с 1.27 сразу на 1.29. Вы должны сначала обновиться до 1.28, и только потом до 1.29.

    Процесс обновления кластера

    Обновление кластера Kubernetes — это хирургическая операция. Мы должны обновить «мозг» и «конечности» системы так, чтобы запущенные приложения этого не заметили.

    Порядок действий всегда строго определен:

  • Обновление Control Plane (Master Node).
  • Обновление сетевого плагина (CNI).
  • Обновление Worker Nodes (по очереди).
  • !Пошаговая схема обновления: приоритет всегда у управляющего слоя, рабочие узлы обновляются последовательно.

    Этап 1: Обновление Control Plane

    Предположим, мы обновляем кластер с версии 1.28.x до 1.29.x. Все команды выполняются на Master Node.

    #### 1. Обновление утилиты kubeadm

    Сначала нужно обновить сам инструмент оркестрации обновления. Снимем блокировку версии (которую мы ставили в предыдущих уроках) и установим новую версию:

    Проверим версию:

    #### 2. Планирование обновления

    Kubeadm имеет встроенную команду для проверки, можно ли обновлять кластер. Она проверит доступные версии и совместимость API:

    Вывод покажет текущую версию и целевую версию. Если все проверки пройдены, вы увидите команду для запуска обновления.

    #### 3. Применение обновления

    Запускаем процесс обновления компонентов Control Plane (API Server, Controller Manager, Scheduler, etcd):

    Этот процесс займет несколько минут. В это время API Server может кратковременно перезапускаться, но контейнеры на рабочих нодах продолжат работать.

    #### 4. Обновление Kubelet и Kubectl на мастере

    После обновления Control Plane нужно обновить локальный агент kubelet на мастере:

    Перезапускаем сервис:

    Этап 2: Обновление Worker Nodes

    Теперь, когда «мозг» обновлен, нужно обновить «мускулы». Этот процесс выполняется для каждой рабочей ноды по очереди.

    #### 1. Вывод ноды из эксплуатации (Drain)

    Перед обновлением программного обеспечения на рабочей ноде мы должны корректно убрать с неё нагрузку. Для этого используется команда drain. Она делает две вещи:

  • Помечает ноду как недоступную для планирования новых подов (Cordon).
  • Аккуратно удаляет существующие поды, заставляя контроллеры перезапустить их на других нодах.
  • Выполните на Master Node (где есть kubectl):

    > Флаг --ignore-daemonsets обязателен, так как системные поды (например, сетевой плагин или kube-proxy) нельзя просто так удалить, и drain без этого флага выдаст ошибку.

    #### 2. Обновление софта на Worker Node

    Теперь заходим по SSH на Worker Node и выполняем обновление пакетов:

    #### 3. Возвращение ноды в строй (Uncordon)

    После успешного обновления возвращаемся на Master Node и сообщаем кластеру, что узел снова готов к работе:

    Повторите эти шаги для всех остальных рабочих узлов.

    Управление сертификатами (Certificate Management)

    Безопасность Kubernetes построена на PKI (Public Key Infrastructure). Каждый компонент (etcd, API Server, Kubelet) имеет свой сертификат для аутентификации.

    По умолчанию kubeadm генерирует сертификаты сроком действия на 1 год. Если вы не обновите их вовремя, кластер перестанет работать: компоненты просто перестанут доверять друг другу.

    Проверка срока действия

    Чтобы узнать, сколько времени осталось жить вашим сертификатам, используйте команду:

    Вывод будет содержать таблицу с названиями сертификатов и датой их истечения. Например:

    | CERTIFICATE | EXPIRES | RESIDUAL TIME | | :--- | :--- | :--- | | admin.conf | May 12, 2025 | 364d | | apiserver | May 12, 2025 | 364d | | etcd-server | May 12, 2025 | 364d |

    Время до истечения сертификата можно описать формулой:

    Где — остаточное время действия, — дата и время истечения сертификата, а — текущее системное время.

    Обновление сертификатов

    Хорошая новость: при обновлении версии Kubernetes (которое мы делали выше) kubeadm автоматически продлевает сертификаты. Но если вы не планируете обновлять версию кластера, а год подходит к концу, сертификаты нужно обновить вручную.

    Это делается одной командой:

    После выполнения этой команды файлы сертификатов в папке /etc/kubernetes/pki будут обновлены.

    > Критически важно: После обновления сертификатов необходимо перезапустить компоненты Control Plane, чтобы они подхватили новые файлы. Поскольку они запущены как статические поды, самый простой способ — временно переместить файлы манифестов из /etc/kubernetes/manifests/ в другую папку, подождать 20 секунд и вернуть их обратно. Kubelet увидит изменения и перезапустит процессы.

    Также не забудьте обновить файл конфигурации администратора для kubectl:

    Заключение курса

    Поздравляю! Вы завершили курс «Основы Kubernetes и развертывание кластера через kubeadm».

    Мы прошли путь от пустых виртуальных машин до полностью работоспособного, обновляемого и безопасного кластера. Вы научились: * Понимать архитектуру Control Plane и Worker Nodes. * Готовить Linux-окружение и устанавливать Container Runtime. * Инициализировать кластер и настраивать сеть через CNI. * Развертывать приложения, использовать Deployments и Services. * Обновлять кластер и следить за сертификатами.

    Kubernetes — это огромная экосистема. Впереди вас ждут темы Ingress-контроллеров, Persistent Volumes, Helm-чартов и мониторинга. Но фундамент, который вы заложили в этом курсе, позволит вам уверенно двигаться дальше.