Автор статьи: Сергей Прощаев (@sproshchaev)
Руководитель направления Java‑разработки в FinTech

Kubernetes — это фундамент современных микросервисных архитектур, оркеструющий миллионы контейнеров по всему миру. Но что происходит, когда одному сервису нужно «поговорить» с другим? Как они находят друг друга в динамической среде, где поды постоянно создаются и уничтожаются? 

Управление сервисами в Kubernetes — это мост между изолированными контейнерами, обеспечивающий надежную коммуникацию в условиях постоянных изменений. В этой статье мы разберем ключевые абстракции для управления сетевым взаимодействием в Kubernetes на примере миникуба (minikube).

Что такое Service и ServiceTypes в Kubernetes?

В мире Kubernetes поды (pods) — это эфемерные, то есть временные и заменяемые сущности. IP‑адрес пода может измениться при его пересоздании. Если бы мы пытались обращаться к приложениям напрямую по IP подов, наша система была бы крайне ненадежной. 

Сервис (Service) — это абстракция, которая определяет постоянную точку доступа к логической группе подов. Это как стабильный телефонный номер call‑центра, за которым могут стоять разные операторы (поды). Сервис обеспечивает балансировку нагрузки между этими подами. 

Тип сервиса (ServiceType) определяет, как этот сервис будет доступен. Это настройка, которая решает, будет ли сервис виден только внутри кластера или и снаружи тоже.

Давайте разберем три основных типа сервисов более подробно

1. ClusterIP: Сервис доступен только внутри кластера. Это тип по умолчанию. Он создает внутренний виртуальный IP‑адрес, который можно использовать для коммуникации между сервисами внутри Kubernetes. Идеально подходит для внутренних API, баз данных и других компонентов, не предназначенных для публичного интернета. 

2. NodePort: Делает сервис доступным снаружи кластера, открывая статический порт на каждой Node (виртуальной машине/сервере) вашего кластера. Чтобы попасть в сервис, вы обращаетесь к <IP_любой_Nodes>:<NodePort>. Этот тип используется для прямого доступа к сервисам извне в режиме разработки или для сервисов, которым нужен фиксированный порт. 

3. LoadBalancer: Наиболее мощный тип. Он автоматически запрашивает у облачного провайдера (например, AWS, GCP, Azure) создание внешнего балансировщика нагрузки, который направляет трафик на сервис. Балансировщик получает собственный внешний IP‑адрес. Это стандартный способ выхода в интернет для продакшн‑сервисов в облаке.

Таким образом, ClusterIP — это инструмент для внутренней связи, а NodePort и LoadBalancer — это инструменты для настройки внешнего доступа, где LoadBalancer — это наиболее «продакшен»‑ориентированный вариант.

Настройка проекта 

Давайте рассмотрим примеры развертывания и настройки сервисов всех трех типов. 

Для демонстрации мы будем использовать minikube — инструмент для локального запуска Kubernetes. Убедитесь, что он установлен. Для минимизации кода мы будем использовать YAML‑манифесты. 

Запустим наш кластер:

minikube start

ClusterIP (для внутреннего общения) 

Первым настроим сервис типа ClusterIP. Он будет доступен только внутри кластера Kubernetes. Создадим деплоймент с простым веб‑приложением и сервис для доступа к нему. 

Файл: deployment‑clusterip.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello-container
        image: nginxdemos/hello:plain-text
        ports:
        - containerPort: 80

Файл: service‑clusterip.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-clusterip-service
spec:
  type: ClusterIP # Это значение по умолчанию, можно не указывать
  selector:
    app: hello
  ports:
    - protocol: TCP
      port: 80      # Порт, на котором сервис принимает запросы
      targetPort: 80 # Порт контейнера, на который перенаправляется трафик

Применяем манифесты:

kubectl apply ‑f deployment‑clusterip.yaml ‑f service‑clusterip.yaml

Проверим, что сервис создан и у него есть внутренний IP (CLUSTER‑IP):

kubectl get svc hello‑clusterip‑service

Возможный вывод в консоль: hello‑clusterip‑service ClusterIP 10.96.XX.XX <none> 80/TCP

Мы можем проверить его работу, зайдя в под и выполнив запрос изнутри кластера, но проще будет посмотреть на него в действии позже.

NodePort (для внешнего доступа в dev‑среде) 

Вторым примером будет сервис типа NodePort. Он откроет наш веб‑сервис на порту ноды (виртуальной машины minikube), сделав его доступным с нашей локальной машины. 

Файл: service‑nodeport.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-nodeport-service
spec:
  type: NodePort
  selector:
    app: hello # Нацелен на те же поды, что и предыдущий сервис
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      # nodePort: 30007 - можно указать вручную, иначе Kubernetes выберет случайный в диапазоне 30000-32768

Применяем:

kubectl apply -f service-nodeport.yaml

Узнаем порт, который был назначен сервису (порт в колонке PORT(S) после 80:):

kubectl get svc hello-nodeport-service

Команда вернет что‑то вроде: http://192.168.49.2:30123 Откройте эту ссылку в браузере, и вы увидите ответ от приложения.

LoadBalancer (для продакшена в облаке) 

Для настройки этого типа сервиса в minikube его нужно сначала включить. «Под капотом» minikube создаст эмулятор облачного балансировщика. 

Включаем туннель, который эмулирует работу облачного балансировщика (запустите в отдельном терминале):

minikube tunnel

Файл: service‑loadbalancer.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-loadbalancer-service
spec:
  type: LoadBalancer
  selector:
    app: hello
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Применяем:

kubectl apply -f service-loadbalancer.yaml

Возможный вывод в консоль: hello‑loadbalancer‑service LoadBalancer 10.111.ZZ.ZZ 10.111.ZZ.ZZ 80:30789/TCP Пока EXTERNAL‑IP в статусе <pending>, но благодаря команде minikube tunnel он должен получить значение (часто это IP ноды minikube).

Теперь вы можете обратиться к сервису по этому IP‑адресу в браузере: http://<EXTERNAL‑IP>

Заключение 

В этих учебных примерах мы рассмотрели три основных способа управления доступом к приложениям в Kubernetes. Как мы видим, сервис типа ClusterIP обеспечивает надежную внутреннюю коммуникацию, полностью изолированную от внешнего мира. NodePort открывает «окно» в кластер для целей разработки и отладки, но не является идеальным решением для продакшена из‑за необходимости ручного управления портами и адресами. LoadBalancer — это мощный и автоматизированный способ предоставить доступ к сервису извне, тесно интегрированный с инфраструктурой облачных провайдеров. 

На практике в продакшене часто используется связка Ingress (еще одна абстракция для управления внешним HTTP‑трафиком) и сервисов типа ClusterIP, что обеспечивает большую гибкость и контроль. Выбор подходящего типа сервиса позволяет найти баланс между изоляцией, простотой и требованиями к доступности вашего приложения.


Если разбор исключений и базовый синтаксис Java для вас уже привычная территория, следующий шаг — научиться собирать из этого полноценные продакшен-сервисы. Курс Java Developer. Professional прокачивает работу с JVM «изнутри» (байткод, сборка мусора), многопоточность, современные фреймворки и паттерны, а заодно даёт много практики с код-ревью от сильных Java-разработчиков. В итоге вы выходите на уровень, где можно уверенно решать задачи Middle+ и расширять стек без ощущения «магии» под капотом.

Пройдите вступительный тест, чтобы узнать, подойдет ли вам программа курса.

Для знакомства с форматом обучения и экспертами приходите на бесплатные демо-уроки:

  • 2 декабря — Spring Boot + Elasticsearch: как за 10 минут сделать поиск, который летает? Записаться

  • 16 декабря — Что такое: Scoped Values. Записаться

Комментарии (0)