Kubernetes
Теория: Сервис и доступ к приложению
В Kubernetes приложения запускаются в Pod, но Pod — временные сущности. Они создаются, умирают, получают новые IP-адреса при перезапуске. Возникает вопрос: как одному приложению найти другое? Как frontend узнает, куда отправлять запросы к backend, если IP backend-Pod меняется?
Для этого в Kubernetes существует Service — объект, который создаёт стабильную точку входа для доступа к группе Pod.
Проблема: как найти Pod
Представьте: frontend должен отправлять запросы на backend. Backend — это Deployment с тремя репликами. Каждый Pod имеет свой IP: 10.244.1.5, 10.244.2.8, 10.244.1.12.
Проблемы начинаются сразу:
- Pod перезапустился — получил новый IP
- Нода упала — Pod пересоздался на другой ноде с другим IP
- Масштабировали Deployment — появились новые Pod с новыми IP
Frontend не может хардкодить эти адреса. Ему нужна стабильная точка входа, которая всегда работает, независимо от того, что происходит с Pod.
Уточнение: для StatefulSet ситуация другая — там Pod получают стабильные сетевые идентификаторы. Но для обычных Deployment проблема динамических IP актуальна.
Service: стабильная точка входа
Service — это объект Kubernetes, который создаёт постоянный IP-адрес и DNS-имя для группы Pod. Вы обращаетесь к Service, а он распределяет запросы между Pod, которые подходят под его селектор.
Разберём:
selector: app: backend— Service направляет трафик на Pod с этой меткой. Тот же механизм, что в Deployment.port: 80— порт, на котором слушает сам Service.targetPort: 8080— порт контейнера, на который Service отправляет трафик.type: ClusterIP— тип Service, об этом ниже.
Теперь frontend обращается к backend-service:80, а Service сам находит живые Pod и балансирует между ними.
Типы Service
Это частый вопрос на собеседованиях: какие типы Service бывают и когда какой использовать.
ClusterIP — тип по умолчанию
Service получает внутренний IP, доступный только внутри кластера.
Когда использовать: коммуникация между микросервисами внутри кластера. Frontend обращается к backend, backend — к базе данных. Всё внутри, ничего наружу.
NodePort — доступ через порт на нодах
Kubernetes открывает указанный порт на всех нодах кластера.
Запрос на <любая-нода>:30080 попадает в Service, оттуда — на Pod. Если nodePort не указать, Kubernetes выберет случайный из диапазона 30000-32767.
Когда использовать: тестирование, разработка, простые случаи без Ingress.
Минусы: нестандартные порты (30000+), нужно знать IP нод, порты могут конфликтовать между сервисами.
LoadBalancer — внешний балансировщик
Как это работает под капотом:
- Kubernetes создаёт ClusterIP для Service
- Kubernetes создаёт NodePort (автоматически)
- Контроллер (облачный провайдер или MetalLB на bare-metal) создаёт внешний балансировщик
- Балансировщик получает внешний IP
- Трафик идёт: внешний IP → NodePort на нодах → Pod
Поле EXTERNAL-IP покажет публичный адрес. Пока балансировщик создаётся — <pending>.
Важно про стоимость: в облаках каждый LoadBalancer — отдельный ресурс, за который вы платите. AWS ELB, GCP Load Balancer, Azure LB — всё стоит денег.
Правильный паттерн: один LoadBalancer на Ingress Controller, который маршрутизирует трафик на все внутренние ClusterIP Service.
Когда LoadBalancer всё же нужен напрямую: не-HTTP протоколы (TCP/UDP-сервисы, базы данных), когда Ingress не подходит.
ExternalName — DNS-алиас на внешний сервис
Это не балансировщик, а CNAME-запись. Обращение к external-db внутри кластера вернёт db.example.com. Полезно для интеграции внешних сервисов без изменения кода приложения.
DNS внутри кластера
Kubernetes автоматически создаёт DNS-записи для каждого Service. Это делает CoreDNS — компонент, который работает в каждом кластере.
Полное DNS-имя Service:
Если Pod и Service в одном namespace, достаточно короткого имени:
Kubernetes автоматически настраивает /etc/resolv.conf в каждом Pod, чтобы короткие имена резолвились правильно.
Endpoints: как Service находит Pod
Когда вы создаёте Service, Kubernetes автоматически создаёт объект Endpoints — список IP-адресов Pod, которые соответствуют селектору.
Service использует этот список для распределения трафика между Pod. Как именно распределяются запросы — зависит от сетевого плагина (CNI), режима kube-proxy и поведения клиента. На практике распределение может быть неравномерным: долгоживущие соединения, keep-alive, особенности iptables/IPVS — всё это влияет на то, какой Pod получит следующий запрос.
Не ожидайте идеально равномерного распределения «по очереди». Если видите, что один Pod получает больше запросов, чем другие — это нормальное поведение, а не поломка Kubernetes.
Важно: если Pod не проходит readinessProbe, его IP убирается из Endpoints. Трафик на неготовый Pod не идёт. Когда Pod снова готов — IP возвращается в список.
Headless Service
Иногда балансировка не нужна, и вы хотите получить IP всех Pod напрямую. Для этого — headless Service:
clusterIP: None — ключевое. Service не получает IP. DNS-запрос возвращает IP-адреса всех Pod:
Когда использовать: StatefulSet с базами данных, где нужен доступ к конкретному инстансу, service discovery без балансировки.
Ingress: HTTP-маршрутизация
NodePort неудобен — нестандартные порты. LoadBalancer дорог — платить за каждый сервис. Ingress решает обе проблемы для HTTP/HTTPS трафика.
Ingress — это правила маршрутизации. Один Ingress может направлять запросы на разные Service в зависимости от хоста или пути:
Запросы на myapp.example.com/api/* идут в backend-service, остальные — во frontend-service.
Важно: Ingress сам по себе ничего не делает. Нужен Ingress Controller — компонент, который читает правила и настраивает реальную маршрутизацию.
Ingress Controller: какой выбрать
Это частый вопрос на собеседованиях.
NGINX Ingress Controller — самый популярный. Но есть важный нюанс: существует две разные версии.
kubernetes/ingress-nginx (Community version)
- Поддерживается сообществом Kubernetes
- Репозиторий:
https://github.com/kubernetes/ingress-nginx - Helm chart:
ingress-nginx/ingress-nginx - Это стандартный выбор для большинства случаев
nginxinc/kubernetes-ingress (Nginx Inc version)
- Поддерживается компанией Nginx Inc (F5)
- Репозиторий:
https://github.com/nginxinc/kubernetes-ingress - Есть бесплатная версия и платная (NGINX Plus)
- Платная версия: JWT-валидация, WAF, продвинутый мониторинг, active health checks
На собеседованиях спрашивают разницу. Ключевое: community-версия от Kubernetes — бесплатная и достаточная для большинства случаев. Версия от Nginx Inc — если нужны enterprise-фичи и готовы платить.
Другие контроллеры:
- Traefik — написан на Go, автоматическое обнаружение сервисов, встроенная интеграция с Let's Encrypt. Популярен в небольших кластерах и для автоматического получения сертификатов.
- HAProxy Ingress — если нужны специфические возможности HAProxy или уже есть экспертиза в нём.
Облачные контроллеры:
- AWS: AWS Load Balancer Controller (создаёт ALB/NLB)
- GCP: GCE Ingress Controller
- Azure: Application Gateway Ingress Controller
Они используют нативные балансировщики облака, что может быть эффективнее и дешевле в конкретном облаке.
Для обучения и большинства production-случаев: kubernetes/ingress-nginx.
Установка Ingress Controller
В minikube (самый простой способ для практики):
Через Helm:
Проверка:
TLS/HTTPS в Ingress
Ingress поддерживает TLS-терминацию — принимает HTTPS, расшифровывает, отправляет HTTP на backend:
Сертификат хранится в Secret:


