Service: сетевой доступ к подам

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

Service: сетевой доступ к подам

Сообщение anton_k8s »

АкадемияKubernetes на практикеГлава 5 из 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, шифрование секретов
В третьей главе мы выяснили, что поды смертны: у каждого свой IP, и после пересоздания он меняется. Deployment из прошлой главы спокойно убивает и поднимает реплики, поэтому ходить к подам по их адресам напрямую бессмысленно. Service решает эту проблему: один стабильный адрес и DNS-имя на группу подов плюс балансировка между ними.

Как Service находит поды:

Service ничего не знает про Deployment. Он отбирает поды по меткам через selector. Kubernetes следит за подходящими подами и ведёт список их адресов в объектах EndpointSlice, а kube-proxy на каждой ноде превращает этот список в правила iptables или IPVS. В итоге трафик на IP сервиса прозрачно уходит на один из живых подов.

Возьмём Deployment из главы 4 с меткой app: backend и контейнером, который слушает порт 8080. Сервис к нему:

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

apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 8080
Здесь port это порт самого сервиса, а targetPort это порт контейнера. Тип не указан, значит по умолчанию ClusterIP: виртуальный IP, доступный только внутри кластера.

Применяем и проверяем:

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

kubectl apply -f backend-svc.yaml
kubectl get svc backend
kubectl get endpointslices -l kubernetes.io/service-name=backend
В выводе endpointslices должны быть IP всех реплик. Если список пуст, сервис никуда не ведёт, и это почти всегда промах селектора.

DNS вместо IP:

Запоминать ClusterIP не нужно. Внутренний DNS кластера (CoreDNS) даёт каждому сервису имя. Из того же namespace под обращается просто к backend, из другого к backend.default.svc.cluster.local. Проверить можно из временного пода:

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

kubectl run tmp --rm -it --image=busybox:1.36 -- sh
wget -qO- http://backend
Именно так сервисы ходят друг к другу: фронтенд стучится на http://backend, и его не волнует, сколько там реплик и какие у них адреса.

NodePort и LoadBalancer, доступ снаружи:

ClusterIP снаружи кластера недоступен. NodePort открывает порт из диапазона 30000-32767 на каждой ноде:

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

apiVersion: v1
kind: Service
metadata:
  name: backend-ext
spec:
  type: NodePort
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30080
В minikube адрес удобно получить командой minikube service backend-ext --url. Тип LoadBalancer идёт дальше: в облаке (Yandex Cloud, VK Cloud и подобные) провайдер автоматически выдаст внешний балансировщик с публичным IP. На голой VPS без облачной интеграции LoadBalancer навсегда зависнет в состоянии pending, там ставят MetalLB или обходятся NodePort.

Для локальной отладки чаще всего хватает port-forward, без всяких NodePort:

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

kubectl port-forward svc/backend 8080:80
Типичные грабли:

Пустые endpoints. Селектор сервиса должен совпадать с метками в template Deployment, а не с метками самого объекта Deployment. Сравните вывод kubectl get pods --show-labels с selector сервиса.

Приложение слушает 127.0.0.1. Endpoints на месте, а соединение отваливается. Контейнер должен слушать 0.0.0.0, иначе трафик извне пода до него не дойдёт.

Перепутанные порты. port это вход в сервис, targetPort это порт контейнера, nodePort это порт на ноде. Если targetPort не указан, он равен port, и при несовпадении с портом приложения получите connection refused.

Долгоживущие соединения. Балансировка работает на уровне TCP-соединений, а не запросов. Один gRPC-канал или websocket прилипнет к одному поду на всё время жизни, сколько бы реплик ни было.

Что усвоили:

Service даёт стабильный адрес и DNS-имя поверх эфемерных подов, отбирает их по меткам, а тип (ClusterIP, NodePort, LoadBalancer) определяет, откуда к нему можно достучаться. Для нормального HTTP-трафика снаружи, с доменами и TLS, есть инструмент получше, чем NodePort, и это Ingress, до него дойдём в главе 7. А в следующей главе вынесем конфигурацию приложения в ConfigMap и Secret.
👍7 ❤️ 🔥3 😄 🤔2
✔ Лучший ответ сформирован автоматически — KernelNinja
anton_k8s писал(а):Один gRPC-канал или websocket прилипнет к одному поду на всё время жизни а как с этим жить? у нас все межсервисное общение на grpc. слышал что делают headless service с clusterIP: None и балансят на стороне клиента, это рабочий вариант или костыль?
Перейти к ответу →
Аватара пользователя
dockerwizard
Сообщения: 1
Зарегистрирован: 20 май 2026, 19:28

Re: Service: сетевой доступ к подам

Сообщение dockerwizard »

делал все по уроку и полчаса тупил на пустые endpoints. оказалось в Deployment у меня метка app: back-end через дефис, а в сервисе backend. совет про --show-labels золотой, надо было сразу туда смотреть, а не логи перечитывать
👍 ❤️1 🔥1 😄 🤔1
Аватара пользователя
KernelNinja
Сообщения: 2
Зарегистрирован: 19 май 2026, 01:18

Re: Service: сетевой доступ к подам

Сообщение KernelNinja »

✔ Лучший ответ — сформирован автоматически
anton_k8s писал(а):Один gRPC-канал или websocket прилипнет к одному поду на всё время жизни
а как с этим жить? у нас все межсервисное общение на grpc. слышал что делают headless service с clusterIP: None и балансят на стороне клиента, это рабочий вариант или костыль?
👍3 ❤️ 🔥 😄 🤔
Аватара пользователя
pipon
Сообщения: 1
Зарегистрирован: 22 май 2026, 06:44

Re: Service: сетевой доступ к подам

Сообщение pipon »

дополню про LoadBalancer локально: в minikube есть minikube tunnel, запускаешь его в отдельном терминале и сервис получает настоящий external ip. в kind такого нет, я туда ставил MetalLB руками, минут 20 возни но работает
👍2 ❤️ 🔥 😄 🤔
Аватара пользователя
schuff
Сообщения: 1
Зарегистрирован: 13 май 2026, 13:25

Re: Service: сетевой доступ к подам

Сообщение schuff »

а NodePort на проде это вообще норм? у нас на vps от timeweb так и торчит 30080 наружу через nginx на хосте. судя по концовке главы к 7 уроку все равно на ingress переезжать, но хочется понять насколько это сейчас плохо
👍1 ❤️ 🔥1 😄 🤔1
Ответить
← Предыдущая глава
Deployment и ReplicaSet: управляем репликами
Следующая глава →
ConfigMap и Secret: выносим конфигурацию

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

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

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

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

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