Kubernetes — это система оркестрации, которая превращает множество серверов или VPS в единый и мощный вычислительный ресурс. Она самостоятельно распределяет нагрузки, масштабирует приложения и поддерживает их работу при сбоях. В нашей статье — основы работы с Kubernetes и создание кластера.
Введение
Kubernetes, или k8s, — open-source платформа для оркестрации контейнеризованных приложений. Его основная задача — абстрагировать underlying-инфраструктуру и предоставить декларативный механизм для управления распределёнными системами. Основные задачи Kubernetes: автоматическое развёртывание и масштабирование приложений, обеспечение их отказоустойчивости, организация сетевого взаимодействия между компонентами и эффективное распределение ресурсов. В этой статье мы разберём, как развернуть кластер Kubernetes, готовый к размещению приложений, на Ubuntu 24.04.
Подготовка окружения и терминология
Ключевые концепции Kubernetes
В основе всего лежит нода (node). Это физическая или виртуальная машина, на которой запущены компоненты Kubernetes и где в итоге будут работать приложения. Ноды делятся на два типа:
- Control-plane (управляющая нода, master) — здесь работают процессы, отвечающие за управление всем кластером: принятие решений (например, где запустить под), обнаружение и реагирование на события (например, если под упал).
- Worker-node (рабочая нода) — предоставляет вычислительные ресурсы (CPU, RAM) для рабочих задач. Именно на них запускаются приложения.
Ещё одно важное понятие в Kubernetes — под (pod). Под представляет собой объединение из одного или нескольких контейнеров, разделяющих общие сетевое пространство (у них один IP) и хранилище. Нельзя просто запустить контейнер — он всегда должен быть упакован в под. На одной ноде может работать множество подов.
Поды могут быть пересозданы в любой момент (например, при обновлении или сбое), для управления их жизненным циклом используется деплоймент (deployment — развёртывание). Это абстракция более высокого уровня, которая описывает желаемое состояние для вашего приложения: какой образ использовать, сколько реплик (копий) пода должно работать постоянно, как проводить обновления. Деплойменты — это предпочтительный способ развертывания stateless-приложений.
Чтобы обеспечить стабильный доступ к группе динамически меняющихся подов (например, управляемых деплойментом), используется сервис (service). Сервис предоставляет стабильный IP-адрес, DNS-имя и порт, которые не меняются на протяжении всего времени жизни сервиса. Позади него может быть один под или тысячи. Сервис автоматически направляет трафик на все здоровые поды, соответствующие его селекторам, выполняя роль встроенного балансировщика нагрузки.
Подготовка инфраструктуры
Для развёртывания даже тестового кластера нужно от двух машин (в нашем примере — под управлением Ubuntu 24.04): одна для управляющей ноды и одна для рабочей. Рекомендуемые характеристики для каждой: минимум 2 ядра ЦПУ, 2+ ГБ ОЗУ, 20+ ГБ на диске.
Подготовку нужно выполнить на всех нодах.
Первым делом обновите систему:
sudo apt update && sudo apt upgrade -yЧтобы Kubernetes работал стабильно, отключите своп и закомментируйте его запись в /etc/fstab, чтобы он не включался после перезагрузки:
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#/g' /etc/fstabДобавьте записи в /etc/hosts на всех нодах для корректного разрешения имён нод внутри кластера; откройте файл:
sudo nano /etc/hostsДобавьте строки вида:
192.168.1.100 k8s-master
192.168.1.101 k8s-worker01Замените IP и имена на актуальные для вашего окружения.
Если на серверах активирован ufw, настройте его, разрешив весь трафик кластера:
# Разрешить все входящие соединения для указанных портов и протоколов
sudo ufw allow 6443/tcp # Kubernetes API server
sudo ufw allow 2379:2380/tcp # etcd (если работает на control-plane)
sudo ufw allow 10250/tcp # Kubelet API
sudo ufw allow 8472/udp # Flannel VXLAN (если используется этот CNI)
sudo ufw allow 30000:32767/tcp # NodePort Services
sudo ufw enableЕсли вы находитесь в изолированном trusted-окружении (например, в тестовой лаборатории), его можно полностью отключить:
sudo ufw disableПосле выполнения этих шагов на всех нодах операционная система готова к установке container runtime и других компонентов.
Установка необходимых компонентов
Этот шаг нужно выполнить на всех машинах, которые будут участвовать в кластере: как на control-plane, так и на worker-нодах.
Установка container runtime
Запуская контейнеры, Kubernetes взаимодействует не напрямую с Docker, а через стандартизированный Container Runtime Interface (CRI) — containerd или CRI-O. Мы будем использовать containerd.
Сначала установите пакеты для работы с HTTPS-репозиториями и добавления новых источников пакетов:
sudo apt install -y apt-transport-https ca-certificates curlЗатем нужно добавить GPG-ключ Docker и репозиторий для получения последних версий containerd.
Добавьте GPG-ключ:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpgДобавьте APT-репозиторий:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullОбновите индекс APT и установите сам containerd.
sudo apt update
sudo apt install -y containerd.ioПосле установки containerd нужно его настроить. Стандартный метод конфигурации — использование утилиты containerd config default, которая генерирует базовый, полностью рабочий конфигурационный файл.
Создайте директорию для конфига, если её нет:
sudo mkdir -p /etc/containerdСгенерируйте дефолтный конфиг и сохраните его:
sudo containerd config default | sudo tee /etc/containerd/config.tomlТеперь нужно изменить значение параметра SystemdCgroup на true. Это обеспечивает правильную интеграцию containerd с менеджером служб systemd, что в свою очередь критически важно для работы kubelet и cgroups:
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.tomlПерезапустите службу и включите автозапуск:
sudo systemctl restart containerd
sudo systemctl enable containerdУстановка компонентов Kubernetes
Основные пакеты Kubernetes:
- kubelet — главная служба, работающая на всех нодах. kubelet следит за запуском, остановкой и поддержанием состояния подов в соответствии с полученными от control-plane манифестами. Это системный демон, которым управляет systemd.
- kubeadm — инструмент, созданный сообществом, чтобы облегчить управление кластером: он предоставляет простой и быстрый способ инициализации кластера, присоединения к нему новых нод и управления жизненным циклом подов. Это основной инструмент развертывания.
- kubectl — интерфейс командной строки для взаимодействия с API-сервером Kubernetes. С его помощью вы будете применять манифесты, просматривать состояние компонентов, управлять ресурсами. Он устанавливается в основном на control-plane ноду и на рабочие станции администраторов.
Добавление GPG-ключа:
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpgДобавление APT-репозитория:
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.listУстановка компонентов:
sudo apt update
sudo apt install -y kubelet kubeadm kubectlВ завершение запретите автообновление пакетов Kubernetes — это может привести к несовместимости версий:
sudo apt-mark hold kubelet kubeadm kubectlЗапуск и активация kubelet
Включите автозапуск kubelet при загрузке ОС:
sudo systemctl enable kubeletПока kubelet не получит конфигурацию от kubeadm, он будет постоянно перезапускаться и выводить сообщения об ошибках в логах — это нормальное поведение на данном этапе.
Инициализация control-plane ноды
Запуск инициализации кластера
Основная команда для этого — kubeadm init. Её необходимо выполнить с правами root на той машине, которую вы определили как control-plane. Одним из самых важных параметров является --pod-network-cidr, определяющий диапазон IP-адресов, которые будут назначены подам внутри кластера. Конкретный диапазон зависит от выбранного сетевого плагина (CNI). В примере мы будем использовать Calico, стандартный диапазон которого 192.168.0.0/16:
sudo kubeadm init --pod-network-cidr=192.168.0.0/16В процессе выполнения происходит следующее:
- Запускается серия предварительных проверок (preflight checks), чтобы убедиться, что система готова к инициализации (отключен своп, запущен container runtime, открыты нужные порты).
- Генерируются самоподписанные TLS-сертификаты для безопасного взаимодействия внутри кластера (для API-сервера, etcd и др.).
- Скачиваются образы системных контейнеров (kube-apiserver, kube-controller-manager, kube-scheduler, etcd, coreDNS и др.).
- Запускаются системные поды в пространстве имен kube-system. Именно эти компоненты и составляют control-plane.
- Генерируется уникальный токен; впоследствии он будет нужен worker-нодам для безопасного присоединения к кластеру.
- Формируется kubeconfig-файл для пользователя root и команда для создания конфига для обычного пользователя.
После успешного завершения инициализации будет выведено соответствующее сообщение с дальнейшими инструкциями, токеном и хешем корневого TLS-сертификата кластера для присоединения рабочих нод.
Настройка конфигурации kubectl
kubectl ищет конфигурационный файл по пути $HOME/.kube/config. Инструкции по его созданию выводятся после успешной инициализации. Выполните их от имени вашего обычного пользователя (не root), чтобы он получил возможность управлять кластером:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/configЗдесь:
- mkdir -p $HOME/.kube создаёт скрытую директорию .kube в домашнем каталоге пользователя, если её там нет;
- sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config копирует сформированный в процессе инициализации файл с административными правами доступа в домашний каталог пользователя;
- sudo chown $(id -u):$(id -g) $HOME/.kube/config меняет владельца скопированного файла на текущего пользователя, чтобы kubectl мог получить к нему доступ без прав root.
Установка сетевого плагина (CNI)
Без сетевого плагина кластер неработоспособен: поды не могут общаться друг с другом, а статус всех подов, кроме тех, что запущены на control-plane, будет pending. Мы установим Calico — один из самых популярных и функциональных плагинов.
Примените манифест для установки последней версии Calico, совместимой с диапазоном адресов, который был указан при инициализации (--pod-network-cidr=192.168.0.0/16):
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yamlkubectl apply -f берет манифест по указанному URL, загружает его и создает описанные в нем ресурсы Kubernetes (поды, сервисы, daemonsets и т. д.). Calico запустит свои поды на каждой ноде кластера, включая control-plane, чтобы обеспечить сетевое взаимодействие.
Проверка статуса нод и подов системы
После установки CNI нужно дать кластеру несколько минут на загрузку образов и запуск всех компонентов.
Проверьте статус нод, теперь control-plane нода должна быть в состоянии Ready:
kubectl get nodesПроверьте состояние системных подов в kube-system, все поды должны перейти в состояние Running:
kubectl get pods -n kube-systemНа этом этап инициализации control-plane завершен — у нас есть работающее управляющее ядро кластера и настроена сетевая подсистема. Кластер готов к добавлению worker-нод.
Присоединение worker-нод
Присоединение worker-нод является безопасным и аутентифицированным, так как для его выполнения требуется токен и хеш корневого TLS-сертификата кластера.
Генерация команды для присоединения
Команда для присоединения новой ноды была сгенерирована и выведена в терминал в конце успешной инициализации. Однако если эта информация утеряна или срок действия токена истёк (он действителен 24 часа), на control-plane ноде можно сгенерировать новую команду.
Создание нового токена:
kubeadm token create --print-join-commandЭта команда выполнит два действия:
- token create создаст новый уникальный токен для аутентификации присоединяющейся ноды;
- --print-join-command выведет полную команду kubeadm join с IP и портом API-сервера, новым токеном (флаг --token) и хешем корневого CA-сертификата (флаг --discovery-token-ca-cert-hash), необходимым для проверки подлинности control-plane.
Запуск команды на worker-нодах
Скопируйте полученную полную команду kubeadm join; подключитесь к вашей worker-ноде по SSH.
Выполните скопированную команду с правами суперпользователя на машине, которая будет выполнять роль worker-ноды:
sudo kubeadm join IP:ПОРТ --token ТОКЕН \
--discovery-token-ca-cert-hash ХЕШНа worker-ноде произойдет следующее:
- kubelet проверит подключение к container runtime.
- Нода свяжется с API-сервером по указанному адресу, используя токен для первоначальной аутентификации.
- Используя хеш CA-сертификата, нода проверит подлинность сертификата, представленного API-сервером.
- После успешной аутентификации нода получит свой уникальный клиентский сертификат (для всех дальнейших взаимодействий с control-plane).
- kubelet зарегистрирует ноду в API-сервере, и на ней начнется запуск системных подов (kube-proxy, CNI).
Проверка появления новых нод
Вернитесь на control-plane ноду или на рабочую станцию, где настроен kubectl. Если присоединение прошло успешно, то через несколько минут после выполнения команды новая worker-нода появится в списке узлов кластера.
Проверка статуса всех нод:
kubectl get nodesИзначально статус новой ноды будет NotReady. Это нормально, так как требуется время на загрузку образов и запуск сетевого плагина. Обычно через 1-2 минуты статус должен смениться на Ready.
Проверка состояния конкретной ноды:
kubectl describe node k8s-worker01Эта команда покажет подробную информацию по указанной ноде: выделенные ресурсы (CPU, память), условия готовности (Conditions), метки, информацию о системе и событиях (Events).
На этом процесс присоединения worker-нод завершён. Кластер теперь обладает вычислительными ресурсами и готов к развертыванию пользовательских приложений.
Читайте в блоге:
- Деплой и управление приложением в Kubernetes (pod, deployment, service и ingress)
- Как настроить кластер Kubernetes на нескольких VPS для запуска масштабируемых приложений
- Что такое Terraform и как он помогает управлять инфраструктурой как кодом

