Kubernetes
Теория: Первый деплой
Установка kubectl
Первый деплой в Kubernetes начинается не с Pod'а и не с манифеста, а с инструмента управления. Для работы с кластером нужен kubectl — командная строка, через которую происходит всё взаимодействие с Kubernetes. Через kubectl система получает команды, применяет конфигурации и показывает текущее состояние объектов. Без него Kubernetes фактически недоступен, даже если сам кластер уже запущен.
Kubectl — это клиент, а не часть кластера. Он не поднимает Pod'ы и не хранит состояние. Он отправляет HTTP-запросы в API-сервер Kubernetes и получает ответы. Именно поэтому kubectl устанавливается на локальную машину, а не внутрь кластера.
Прежде всего необходимо установить Kubernetes. Это можно сделать по инструкции. После установки проверим, что всё работает:
Если видите версию — kubectl готов к работе.
Подключение к кластеру
После установки kubectl сам по себе ещё ничего не умеет. Он не знает, к какому кластеру подключаться. Для этого используется конфигурационный файл ~/.kube/config. Этот файл играет роль адресной книги и пропуска одновременно. В нём хранится адрес API-сервера кластера, сертификаты или токены для аутентификации и информация о контекстах — с каким кластером и namespace вы работаете.
Minikube
Для учебных целей проще всего поднять локальный кластер через minikube. Установим его по инструкции
И запустим кластер:
Minikube создаст виртуальную машину с Kubernetes и автоматически настроит kubeconfig. Первый запуск занимает несколько минут — скачивается образ и поднимается кластер.
Проверка подключения
Если видите адрес API-сервера и CoreDNS — кластер работает, можно двигаться дальше.
Проверка текущего контекста
Если у вас несколько кластеров или kubeconfig настраивался вручную, важно понимать, куда именно сейчас отправляются команды kubectl. Иначе легко работать не с тем кластером, который вы ожидаете.
Первая команда показывает активный контекст — текущий профиль подключения. Вторая выводит список всех контекстов и отмечает активным звёздочкой.
Манифест — описание желаемого состояния
Kubernetes не всегда управляется через графический интерфейс или SSH. Большая часть работы идёт через манифесты — файлы, в которых вы описываете, что хотите получить. Kubernetes читает манифест и приводит кластер к описанному состоянию. Вы не говорите «запусти контейнер», вы говорите «должен существовать вот такой Pod».
Манифесты пишутся на YAML. Вот минимальный пример для запуска Pod с nginx:
Разберём ключевые поля:
apiVersion: v1— версия API Kubernetes, через которую создаётся объект. Pod — базовый объект, он существует с первой версии API.kind: Pod— тип объекта. Kubernetes поддерживает десятки типов: Pod, Deployment, Service, ConfigMap. Здесь работаем с Pod напрямую.metadata— метаданные объекта. Здесь обязательно только имя (metadata.name). Имя должно быть уникальным в пределах namespace.spec— спецификация, что именно должно быть внутри Pod.containers— список контейнеров. Даже если контейнер один, это всегда список.name: nginx— имя контейнера внутри Pod. Используется в логах и при обращении к конкретному контейнеру.image: nginx:1.27— образ, из которого создаётся контейнер. Kubernetes скачает его из Docker Hub, если не указан другой registry.ports— список портов, которые слушает контейнер. Это декларация для документации, она не открывает порт наружу.
Применение манифеста
Сохраните манифест в файл pod.yaml, затем выполните:
Команда apply отправляет манифест в Kubernetes. Если Pod с таким именем не существует, он будет создан. Если существует — Kubernetes сравнит текущее состояние с манифестом и применит изменения.
Пример вывода:
Pod создан, но «создан» не значит «работает». Kubernetes только начал процесс: выбирает ноду, скачивает образ, запускает контейнер.
Namespace по умолчанию
Все команды kubectl работают в каком-то namespace. Если не указать явно, используется default. Ваш Pod сейчас создан именно там.
Namespace — это логическая изоляция внутри кластера. Разные команды, окружения или проекты могут жить в разных namespace и не мешать друг другу.
Частая ошибка: Pod существует, но kubectl get pods его «не видит». Причина — Pod в одном namespace, а команда выполняется в другом. Чтобы указать namespace явно:
Пока вы работаете в default и не создавали других namespace, об этом можно не думать. Но когда что-то «пропадает» — первым делом проверяйте namespace.
Проверка статуса
READY 1/1 — внутри Pod один контейнер, и он готов. STATUS Running — Pod запущен. RESTARTS 0 — контейнер не перезапускался.
Если статус ContainerCreating — Kubernetes ещё скачивает образ. Подождите и повторите команду.
Если ImagePullBackOff или ErrImagePull — не удалось скачать образ. Проверьте имя и тег.
Подробная информация
Для деталей используйте describe:
Пример секции Events:
Здесь видно всю историю: на какую ноду попал Pod, когда качался образ, когда запустился контейнер. Если что-то пошло не так, причина почти всегда в Events.
Как обратиться к запущенному nginx
Pod работает, но если вы попробуете открыть nginx в браузере — ничего не произойдёт. containerPort: 80 в манифесте — это декларация, а не открытие порта наружу. Pod по умолчанию доступен только внутри кластера и то только если знать его IP.
Для быстрой проверки используйте port-forward:
Теперь localhost:8080 на вашей машине ведёт на порт 80 внутри Pod. Откройте в браузере или выполните:
Увидите стандартную страницу nginx. Port-forward — временное решение для отладки. Для постоянного доступа используется Service, но это тема отдельного урока.
Логи контейнера
Nginx пишет логи в stdout, Kubernetes их собирает. Пока запросов не было, логов может не быть.
Для нескольких контейнеров в Pod укажите имя:
Стриминг логов в реальном времени:
Выполнение команд внутри контейнера
Двойной дефис (--) отделяет аргументы kubectl от команды внутри контейнера.
Для интерактивного shell:
Флаги -it — interactive + tty. Для выхода введите exit. Если bash отсутствует, попробуйте /bin/sh.
Удаление Pod
Kubernetes отправляет контейнеру SIGTERM. У процесса есть 30 секунд на корректное завершение. Если не успел — SIGKILL. Удаление Pod — это уничтожение объекта: после delete этого Pod больше не существует, и Kubernetes не создаст его заново, потому что никто этого не просит.
Почему Pod нельзя обновить на месте
Измените версию nginx в манифесте на nginx:1.26 и примените:
Вы получите ошибку:
Большинство полей Pod нельзя изменить после создания. Для обновления нужно удалить и создать заново:
Это одна из причин, почему в реальной работе Pod напрямую не создают.
Почему Pod — это ещё не всё
Вы научились создавать Pod, но в реальной работе их почти никогда не создают напрямую. Pod — низкоуровневая сущность. Он не умеет себя восстанавливать, не умеет обновляться на месте, не умеет масштабироваться.
Для всего этого нужен контроллер — объект, который следит за Pod и управляет им. Самый распространённый контроллер — Deployment. Он описывает, сколько экземпляров Pod должно работать, какой образ использовать, и берёт на себя создание, обновление и пересоздание Pod при сбоях.
Если Pod — это «один процесс на одном сервере», то Deployment — это «я хочу, чтобы всегда работало три экземпляра моего приложения, и мне неважно как». Kubernetes делает остальное.
Частые ошибки
Pending— нет подходящей ноды или не хватает ресурсов. Смотрите Events вdescribe.ImagePullBackOff— неправильное имя образа, несуществующий тег или registry недоступен.CrashLoopBackOff— контейнер падает сразу после старта. Смотритеkubectl logs nginx --previous.- Pod «не виден» — проверьте namespace. Возможно, Pod создан в другом namespace, а вы смотрите в
default. execне работает — в образе нет shell. Попробуйте/bin/shвместо/bin/bash.- Контекст не тот —
kubectl config current-contextпокажет, к какому кластеру подключён kubectl.


