Поды: базовая единица запуска

Рейтинг: 72.2% · 10 голосов
Kubernetes для разработчиков: поды, деплойменты, сервисы, ingress, конфиги и отладка. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
anton_k8s
Сообщения: 26
Зарегистрирован: 12 май 2026, 03:23

Поды: базовая единица запуска

Сообщение anton_k8s »

АкадемияKubernetes на практикеГлава 3 из 19
Оглавление курса (19)
  1. Зачем нужен Kubernetes и из чего состоит кластер
  2. Поднимаем локальный кластер: minikube и kind
  3. Поды: базовая единица запуска (вы здесь)
  4. Deployment и ReplicaSet: управляем репликами
  5. Service: сетевой доступ к подам
  6. ConfigMap и Secret: выносим конфигурацию
  7. Ingress: пускаем трафик снаружи
  8. Хранилище: Volumes и PersistentVolumeClaim
  9. Namespaces, requests и limits
  10. Health checks: liveness и readiness пробы
  11. Отладка: почему под не стартует
  12. Helm: пакетный менеджер для Kubernetes
  13. Базовая безопасность: RBAC и доступы
  14. Job и CronJob: разовые и периодические задачи
  15. StatefulSet и DaemonSet: stateful-нагрузки и системные агенты
  16. Стратегии обновления и планирование: rollout и rollback, graceful shutdown, nodeSelector, affinity, taints
  17. Автомасштабирование: HPA по метрикам, обзор VPA и Cluster Autoscaler
  18. Наблюдаемость: логи, метрики, events, обзор Prometheus и Grafana
  19. Безопасность глубже: securityContext, Pod Security Standards, NetworkPolicy, шифрование секретов
В прошлой главе вы подняли локальный кластер через minikube или kind. Пора запустить в нём первое приложение. Под (Pod) это минимальная единица, которой оперирует Kubernetes: не контейнер, а обёртка вокруг одного или нескольких контейнеров.

Что такое под и зачем он нужен:

Kubernetes не управляет контейнерами напрямую, он управляет подами. Под это группа из одного или нескольких контейнеров, которые делят между собой сеть (один IP-адрес, общий localhost) и могут делить тома с данными. В девяноста процентах случаев в поде ровно один контейнер, и это нормально. Несколько контейнеров кладут в один под, когда они не имеют смысла друг без друга: например, приложение плюс агент, который собирает его логи. Такой паттерн называют sidecar. Начиная с Kubernetes 1.33 сайдкары это нативная фича (GA): сайдкар-контейнер объявляют в initContainers с restartPolicy: Always. Тогда он гарантированно стартует раньше основного контейнера, живёт рядом с ним весь срок жизни пода, а в Job не мешает поду завершиться, когда основной контейнер закончил работу. В 2026 новые сайдкары делайте именно так, а не вторым элементом в containers, как в старых статьях.

Факт, который экономит часы при отладке: контейнеры внутри одного пода видят друг друга по localhost и всегда работают на одной ноде. Разные поды, наоборот, общаются по сети через свои IP.

Первый под:

Самый быстрый способ, команда kubectl run:

Код: Выделить всё

kubectl run nginx --image=nginx:1.27
Это годится для экспериментов, но в реальной работе поды описывают декларативно, в YAML. Создайте файл nginx-pod.yaml:

Код: Выделить всё

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.27
      ports:
        - containerPort: 80
Разберём по полям. apiVersion и kind говорят кластеру, какой объект мы описываем. metadata.name это имя пода, уникальное в рамках namespace. labels это произвольные метки, по ним поды потом находят Service и Deployment, привыкайте ставить их сразу. В spec.containers перечислены контейнеры: имя, образ, порт. containerPort сам по себе ничего не открывает, контейнер будет слушать порт 80 и без него. Но считать его чисто декоративным неверно: порту можно дать имя (name: http) и сослаться на это имя в targetPort у Service, тогда при смене номера порта правится только манифест пода. А если используете hostPort, чтобы пробросить порт ноды, containerPort обязателен. Так что указывайте его сразу.

Применяем и смотрим:

Код: Выделить всё

kubectl apply -f nginx-pod.yaml
kubectl get pods
kubectl describe pod nginx
В get pods вы увидите статус. Pending значит под ещё не привязан к ноде или качается образ, в колонке STATUS в этот момент часто видно ContainerCreating. Running значит контейнеры стартовали. Есть и конечные фазы: Succeeded, когда все контейнеры завершились с нулевым кодом (нормально для Job, не для nginx), и Failed, когда хотя бы один упал и перезапускать его не положено. describe показывает подробности, и самое ценное там внизу, секция Events: туда Kubernetes пишет, почему под не поднимается (детально займёмся этим в главе 11).

Заглянуть внутрь работающего пода:

Код: Выделить всё

kubectl logs nginx
kubectl exec -it nginx -- sh
kubectl port-forward pod/nginx 8080:80
logs показывает stdout контейнера. exec открывает шелл внутри, как docker exec. port-forward пробрасывает порт пода на вашу машину: откройте localhost:8080 и увидите страницу nginx. Это рабочий способ потыкать приложение до того, как вы узнаете про Service в главе 5. Наигрались, удаляйте: kubectl delete pod nginx.

Типичные грабли:

Первое. Под удалили или нода упала, и он исчез навсегда. Так и задумано: голый под никто не пересоздаёт. Самовосстановление даёт Deployment, про него следующая глава. Голые поды в проде это почти всегда ошибка.

Второе. Статус ImagePullBackOff. Чаще всего опечатка в имени образа или тега, либо приватный registry без секрета доступа. Точная причина будет в Events у describe. Из СНГ docker.io временами отдаёт образы медленно и с лимитами, многие держат зеркало или прокси-registry, это нормальная практика.

Третье. CrashLoopBackOff. Контейнер стартует и сразу падает, kubelet перезапускает его с растущей паузой. За перезапуски отвечает поле restartPolicy в спеке пода: Always (по умолчанию), OnFailure или Never. Важно не путать два уровня: restartPolicy это про рестарт контейнеров внутри живого пода на той же ноде, а пересоздание самого пода после удаления или смерти ноды, как в первых граблях, никакая restartPolicy не обеспечит, это работа контроллера вроде Deployment. Отлаживать так: первым делом kubectl logs, а если контейнер уже успел перезапуститься, kubectl logs nginx --previous покажет вывод прошлого запуска.

Четвёртое. Правка спеки живого пода через kubectl edit. Почти все поля спеки неизменяемы, кластер откажет с ошибкой про forbidden fields. Но есть короткий список исключений: spec.containers[*].image и initContainers[*].image, activeDeadlineSeconds, плюс можно добавлять tolerations. То есть поменять образ у живого пода как раз можно: API-сервер примет правку, kubelet остановит контейнер и запустит его с новым образом. Для экспериментов удобно, но в проде так не делайте, реальное состояние тут же разъезжается с манифестом в git. Для всех остальных полей путь один: удалить под и применить манифест заново, либо дождаться Deployment, который умеет катить обновления сам.

Итог:

Под это атом Kubernetes: обёртка над контейнерами с общим IP и общим localhost внутри, описывается YAML-манифестом. Вы умеете создать его через apply, проверить статус и события, прочитать логи, зайти внутрь и пробросить порт. Главное ограничение пода в том, что он смертен и сам не возрождается. Как заставить кластер держать нужное число копий и переживать падения, разберём в следующей главе про Deployment и ReplicaSet.
👍1 ❤️4 🔥4 😄 🤔
Аватара пользователя
rinigan1
Сообщения: 1
Зарегистрирован: 12 май 2026, 04:49

Re: Поды: базовая единица запуска

Сообщение rinigan1 »

anton_k8s писал(а):голый под никто не пересоздаёт
а как же restartPolicy: Always? я думал она как раз для этого и существует. или это только про перезапуск контейнера внутри пода, а сам под при смерти ноды всё равно теряется?
👍2 ❤️ 🔥 😄 🤔1
Аватара пользователя
byrdie
Сообщения: 2
Зарегистрирован: 21 май 2026, 03:39

Re: Поды: базовая единица запуска

Сообщение byrdie »

вопрос про sidecar: если в поде два контейнера и оба хотят слушать порт 80, будет конфликт? они же делят один localhost, получается порты надо разводить руками?
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
vim4
Сообщения: 1
Зарегистрирован: 19 май 2026, 06:26

Re: Поды: базовая единица запуска

Сообщение vim4 »

спасибо за logs --previous, реально выручило. у меня спринговое приложение падало на старте по OOM, обычный logs показывал пустоту, я полдня грешил на кластер. с --previous сразу увидел stacktrace и поправил Xmx
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
Talon1fe
Сообщения: 2
Зарегистрирован: 23 май 2026, 09:45

Re: Поды: базовая единица запуска

Сообщение Talon1fe »

подтверждаю про docker hub из СНГ, дома через мобильный инет образы тянутся еле-еле и лимит ловится на раз. в minikube помог флаг --registry-mirror с зеркалом, разница в скорости в разы
👍2 ❤️ 🔥1 😄 🤔
Ответить
← Предыдущая глава
Поднимаем локальный кластер: minikube и kind
Следующая глава →
Deployment и ReplicaSet: управляем репликами

Все главы курса «Kubernetes на практике»

Поделиться темой: ✈ Telegram VK

Вернуться в «Kubernetes на практике»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость