Введение: что мы будем разворачивать и зачем
В этом руководстве развернем типовое веб-приложение с базой данных в Kubernetes. Используем основные объекты: Deployment для управления подами, Service для сетевого доступа, Ingress для маршрутизации внешнего трафика, ConfigMap и Secrets для конфигурации. Все шаги проверены на практике в 2026 году и актуальны для текущих версий Kubernetes.
Вы получите рабочий деплой, который можно использовать как шаблон для production-среды. Каждый шаг сопровождается готовыми YAML-манифестами и командами kubectl. Если вы впервые разворачиваете сервис в Kubernetes, пройдите все разделы по порядку. Опытные специалисты могут использовать материал как шпаргалку.
Материал дополняет базовые руководства по архитектуре кластера и ключевым объектам API. Если вам нужны production-манифесты с расширенными настройками проб и стратегий обновления, обратитесь к полному руководству по Deployment.
Подготовка окружения
Для выполнения шагов нужен работающий кластер Kubernetes. Подойдет minikube, kind, k3s или облачный managed-кластер. Также потребуется настроенный kubectl и доступ к реестру образов. В примерах используем публичный образ nginx и образ приложения, доступный вашему кластеру.
Проверка доступа к кластеру
Убедитесь, что kubectl подключен к нужному кластеру. Выполните команду:
kubectl config current-contextВывод покажет текущий контекст. Проверьте, что он соответствует целевому кластеру. Затем запросите список узлов:
kubectl get nodesЕсли команда возвращает узлы в статусе Ready, доступ к кластеру настроен корректно. При ошибке подключения проверьте kubeconfig и права доступа.
Создание namespace
Изолируем ресурсы статьи в отдельном namespace. Это стандартная практика, которая упрощает управление и очистку.
kubectl create namespace demo-appNamespace demo-app создан. Все последующие команды выполняем с флагом -n demo-app или установим его как текущий контекст:
kubectl config set-context --current --namespace=demo-appСоздание Deployment
Deployment управляет репликами подов и обеспечивает декларативное обновление приложения. Создадим манифест deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: demo-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"Ключевые поля: replicas задает количество подов, selector связывает Deployment с подами по метке app: web-app, template описывает под. Применим манифест:
kubectl apply -f deployment.yamlПроверим статус:
kubectl get deployments
kubectl get podsПосле применения вы увидите три пода в статусе Running. Если поды не запускаются, перейдите к разделу о типичных проблемах.
Выбор стратегии обновления
Deployment поддерживает две стратегии обновления: RollingUpdate и Recreate. RollingUpdate обновляет поды поочередно, сохраняя доступность приложения. Recreate сначала удаляет все поды, затем создает новые, что вызывает простой.
Для большинства веб-приложений выбирайте RollingUpdate. Она задана по умолчанию. Параметры maxSurge и maxUnavailable управляют темпом обновления. Для stateful-приложений с жесткими требованиями к состоянию может потребоваться Recreate, но это частный случай.
Настройка ресурсов (requests/limits)
Поля requests и limits в манифесте задают минимальные и максимальные ресурсы для контейнера. Requests используются планировщиком для выбора узла. Limits ограничивают потребление и предотвращают влияние одного пода на другие.
Указывайте реальные значения, основанные на нагрузке. Заниженные limits приведут к OOMKilled, завышенные requests - к неэффективному использованию кластера. Начните с приведенных значений и корректируйте по метрикам.
Настройка конфигурации: ConfigMap и Secrets
Конфигурация отделяется от кода. Несекретные настройки хранятся в ConfigMap, чувствительные данные - в Secrets. Это упрощает обновление конфигурации без пересборки образа.
Создание ConfigMap
Создадим ConfigMap с настройками приложения:
apiVersion: v1
kind: ConfigMap
metadata:
name: web-app-config
namespace: demo-app
data:
APP_ENV: "production"
LOG_LEVEL: "info"
DATABASE_HOST: "postgres-service"Применим и проверим:
kubectl apply -f configmap.yaml
kubectl get configmap web-app-config -o yamlСоздание Secret
Secret хранит пароли, ключи API и токены. Данные кодируются в base64. Создадим Secret для пароля базы данных:
apiVersion: v1
kind: Secret
metadata:
name: web-app-secret
namespace: demo-app
type: Opaque
data:
DATABASE_PASSWORD: c3VwZXJzZWNyZXRwYXNzЗначение c3VwZXJzZWNyZXRwYXNz - это base64-кодированная строка. Закодировать значение можно командой:
echo -n 'supersecretpass' | base64В реальных кластерах включите шифрование Secrets в etcd и используйте RBAC для ограничения доступа. Для production-среды рассмотрите интеграцию с внешними системами управления секретами, например HashiCorp Vault.
Подключение ConfigMap и Secret к подам
Обновим Deployment, добавив переменные окружения из ConfigMap и Secret:
spec:
containers:
- name: web-app
image: nginx:1.27
envFrom:
- configMapRef:
name: web-app-config
- secretRef:
name: web-app-secretДиректива envFrom передает все ключи из ConfigMap и Secret как переменные окружения. Альтернативный способ - монтирование как volume. Выбор зависит от приложения: переменные окружения проще, volume позволяют обновлять конфигурацию без перезапуска пода.
Обеспечение сетевого доступа: Service
Поды в Kubernetes эфемерны, их IP-адреса меняются при перезапуске. Service предоставляет стабильный IP и DNS-имя для доступа к группе подов.
Типы Service: ClusterIP, NodePort, LoadBalancer
ClusterIP - тип по умолчанию, доступен только внутри кластера. NodePort открывает порт на каждом узле. LoadBalancer создает внешний балансировщик в облачных кластерах. Для внутреннего взаимодействия сервисов используйте ClusterIP. Для внешнего доступа - Ingress поверх ClusterIP.
Создадим Service типа ClusterIP:
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: demo-app
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 80
protocol: TCPПрименим и проверим:
kubectl apply -f service.yaml
kubectl get servicesService направляет трафик на поды с меткой app: web-app. Балансировка выполняется автоматически между всеми готовыми подами.
Настройка внешнего доступа: Ingress
Ingress маршрутизирует внешний HTTP/HTTPS-трафик к Service по правилам хоста и пути. Для работы Ingress нужен Ingress-контроллер в кластере.
Установка Ingress-контроллера
Проверьте, установлен ли контроллер:
kubectl get pods -n ingress-nginxЕсли namespace отсутствует, установите nginx-ingress через Helm:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespaceДождитесь, пока поды контроллера перейдут в статус Running.
Настройка TLS
Для HTTPS создайте Secret с сертификатом и укажите его в Ingress. Автоматизировать получение сертификатов можно с помощью cert-manager. Для тестовой среды допустимо использовать самоподписанный сертификат.
Создадим Ingress с правилом для хоста app.example.com:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: demo-app
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80Применим и проверим:
kubectl apply -f ingress.yaml
kubectl get ingressПоле ingressClassName: nginx указывает, какой контроллер обрабатывает этот Ingress. Для добавления TLS добавьте секцию tls с именем Secret и списком хостов.
Проверка доступности сервиса
После применения всех манифестов проверьте, что приложение отвечает. Начните с локальной проверки через port-forward.
Проверка через port-forward
Команда port-forward пробрасывает порт Service на локальную машину:
kubectl port-forward service/web-app-service 8080:80В другом терминале выполните запрос:
curl localhost:8080Ответ HTTP 200 с содержимым страницы подтверждает, что Service и поды работают. Для проверки Ingress добавьте запись в /etc/hosts, указывающую на IP Ingress-контроллера, и выполните curl по хосту.
Просмотр логов и событий
Логи пода показывают работу приложения:
kubectl logs <pod-name>События пода содержат информацию о жизненном цикле:
kubectl describe pod <pod-name>В выводе ищите секцию Events. Ошибки при старте, проблемы с образами и сбои проб отображаются там. Это первый шаг при диагностике.
Типичные проблемы и их решение
При деплое в Kubernetes возникают повторяющиеся ошибки. Разберем три частые проблемы и способы их устранения.
ImagePullBackOff
Статус ImagePullBackOff означает, что кластер не может загрузить образ контейнера. Причины: неверный тег образа, отсутствие доступа к приватному реестру, превышение лимита запросов к Docker Hub.
Проверьте имя образа в манифесте. Для приватных реестров настройте imagePullSecrets в Deployment. Проверьте, что Secret с учетными данными создан в том же namespace.
CrashLoopBackOff
Контейнер запускается и сразу завершается с ошибкой. Причины: ошибка в коде приложения, неверная конфигурация, нехватка памяти.
Смотрите логи пода: kubectl logs <pod-name> --previous. Проверьте readiness/liveness пробы, если они настроены. Убедитесь, что limits по памяти достаточны для приложения.
Pod в состоянии Pending
Под не может быть запланирован на узел. Причины: недостаточно ресурсов в кластере, проблемы с PersistentVolumeClaim, селекторы узлов без совпадений.
Выполните kubectl describe pod <pod-name> и изучите события. Если не хватает ресурсов, уменьшите requests или добавьте узлы. При проблемах с PVC проверьте StorageClass и доступность томов.
Для более глубокой диагностики используйте руководство по меткам и селекторам, которое помогает отслеживать версии приложений при обновлениях.
Заключение: что дальше?
Вы развернули веб-приложение в Kubernetes: создали Deployment с тремя репликами, настроили ConfigMap и Secrets, обеспечили внутренний доступ через Service и внешний через Ingress. Проверили доступность и разобрали типичные ошибки.
Этот базовый сценарий - основа для production-деплоя. Следующие шаги: автоматизация через Helm, настройка CI/CD пайплайнов, мониторинг с Prometheus и Grafana, усиление безопасности через RBAC и Network Policies. Для проектирования production-ready кластеров изучите руководство по проектированию промышленных кластеров.
Для размещения кластера Kubernetes в облаке подойдет Timeweb Cloud с гибкой инфраструктурой и managed-решениями. Если вы работаете с микросервисной архитектурой, обратитесь к гайду по структуре манифестов для корректного версионирования YAML-файлов.