<div><img src="https://top-fwz1.mail.ru/counter?id=3548135;js=na" style="position:absolute;left:-9999px;" alt="Top.Mail.Ru" /></div>
Публичное облако на базе VMware с управлением через vCloud Director
Вход / Регистрация

Kubernetes Service — разбираем типы сервисов k8s и их применение

Александр Бархатов
Александр Бархатов
Технический писатель
03 июля 2025 г.
6
12 минут чтения
Средний рейтинг статьи: 5

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

Предварительные требования

Так как мы будем рассматривать практическую часть, нам понадобится кластер Kubernetes. Арендовать готовый кластер можно с помощью сервиса Kubernetes в облаке.

Аренда кластера Kubernetes

Для начала арендуем кластер Kubernetes.

1) Авторизируемся в аккаунте при помощи логина или адреса электронной почты и пароля.

2) После успешной авторизации отобразится панель управления текущего проекта. Переходим в раздел «Kubernetes» в меню слева и нажимаем на кнопку «Создать».

3) Выбираем необходимый регион из списка доступных:

Image16

4) Далее необходимо выбрать тип кластера. На выбор доступно 3 типа — Dev, Base и Custom. В нашем случае нам будет достаточно Dev-конфигурации:

Image18

5) В качестве конфигурации для воркер-нод выберем минимальную, а именно одноядерный процессор, 2 ГБ оперативной памяти и 30 ГБ места на NVMe-диске:

Image8

6) Все остальные параметры можно оставить без изменений:

Image1

7) Для заказа кластера нажимаем на кнопку «Заказать»:

Image20

После заказа кластера он будет готов к использованию в течение пары минут. kubeconfig для подключения к кластеру будут сгенерирован и доступен в раздел «Дашборд».

Что такое сервис в Kubernetes?

Сервис в Kubernetes — это объект, который используется для определения логических групп подов и правил доступа к ним. Поды в Kubernetes имеют временный (эфирный) характер: их можно создавать, удалять, перезапускать или перемещать между узлами кластера. Это делает прямой доступ к подам по их IP-адресам ненадежным. Сервисы решают эту проблему, предоставляя стабильный сетевой интерфейс для взаимодействия с подами. Каждый сервис получает виртуальный IP-адрес (ClusterIP) или DNS-имя, через которые можно обращаться к группе подов, даже если сами поды меняются.

Сервисы в Kubernetes классифицируются на несколько видов, каждый из которых разработан для конкретных задач и сценариев применения. Всего в Kubernetes присутствует пять типов сервисов:

  • ClusterIP
  • NodePort
  • LoadBalancer
  • ExternalName
  • Headless Service

Далее рассмотрим каждый тип сервиса более подробно, включая его описание, назначение особенности и конфигурацию.

ClusterIP

Тип сервиса, который используется в Kubernetes по умолчанию. Сервис создает виртуальный IP-адрес внутри кластера, который используется для доступа к подам, соответствующим селектору сервиса. ClusterIP обеспечивает внутреннюю маршрутизацию трафика, то есть доступ возможен только внутри кластера без доступа во внешнюю сеть. Данный тип сервиса подходит для приложений, которые взаимодействуют только с другими компонентами внутри кластера, например, СУБД PostgreSQL или брокер сообщений Apache Kafka.

Особенности

  • Используется виртуальный IP-адрес для сетевого взаимодействия только внутри кластера.

  • Балансировка трафика происходит между подами, которые соответствуют селектору сервиса.

  • Подходит для работы со внутренними сервисами — СУБД, API, брокеры сообщений.

Пример использования

В качестве примера создадим файл типа Deployment, в котором будет указан сервис ClusterIP вместе с контейнером, где будет запущен веб-сервер Nginx. Конфигурация приведена ниже:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-clusterip-deployment
  namespace: service-clusterip
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26.0
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: "0.5"
            memory: "512Mi"
          requests:
            cpu: "0.2"
            memory: "256Mi"
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
      - name: test-curl
        image: curlimages/curl:8.12.0
        command: ["/bin/sh", "-c", "while true; do curl http://nginx-clusterip-service; sleep 10; done"]
        resources:
          limits:
            cpu: "0.2"
            memory: "128Mi"
          requests:
            cpu: "0.1"
            memory: "64Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-clusterip-service
  namespace: service-clusterip
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

Для начала создадим новый namespace с именем service-clusterip:

kubectl create namespace service-clusterip

Далее сохраняем конфигурацию выше в файл с именем nginx-test-deployment.yaml и применяем ее:

kubectl apply -f nginx-test-deployment.yaml

Проверяем, что все объекты были созданы:

kubectl get all -n service-clusterip

Image7

В качестве теста выполним команду curl из ранее созданного пода (в нашем примере это под с именем nginx-clusterip-deployment-54ffdb7c4b-87dsl) на имя созданного ClusterIP сервиса — http://nginx-clusterip-service:

kubectl exec -it nginx-clusterip-deployment-54ffdb7c4b-87dsl -n service-clusterip -- curl http://nginx-clusterip-service

Image15

Как можно увидеть на скриншоте выше, был получен ответ от сервиса. В этом примере сервис nginx-service направляет трафик на поды с меткой app: nginx далее сервис перенаправляет запросы на порт 80 подов. Внешний доступ отсутствует, что обеспечивает изоляцию.

NodePort

Сервис типа NodePort открывает доступ к подам через порт на каждом узле кластера. Kubernetes выделяет порт из диапазона 30000–32767 (по умолчанию) и привязывает его к сервису. Это позволяет внешним клиентам обращаться к приложению через IP-адрес любого узла кластера и назначенный порт. NodePort часто используют для тестирования или в тех случаях, где требуется прямой доступ к сервису без использования внешнего балансировщика нагрузки.

Особенности

  • Доступ к приложениям возможен через комбинацию IP-адреса узла кластера и номера порта.

  • Сервис также обладает внутренним адресом ClusterIP, что позволяет использовать его внутри кластера.

  • Подходит для временного доступа или для использования в кластерах без внешнего балансировщика нагрузки.

Пример использования

Предположим, у нас в кластере запущен под с веб-сервером Nginx. Для доступа к Nginx с локального компьютера создадим сервис типа NodePort. Используем конфигурацию ниже:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-nodeport-deployment
  namespace: service-nodeport
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26.0
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport-service
  namespace: service-nodeport
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080
  type: NodePort

Для начала создадим новый namespace с именем service-nodeport:

kubectl create namespace service-nodeport

Далее сохраняем конфигурацию выше в файл с именем nginx-nodeport-deployment.yaml и применяем ее:

kubectl apply -f nginx-nodeport-deployment.yaml

Проверяем, что все объекты были созданы:

kubectl get all -n service-nodeport

Image21

В данном примере сервис открывает порт 30080 на всех узлах кластера на внешнем IP-адресе. Чтобы узнать внешний IP-адрес кластера, необходимо выполнить команду ниже:

kubectl get nodes -o wide

Image4

Если внешний IP-адрес узла — 5.129.210.247 (столбец EXTERNAL-IP), то приложение будет доступно по адресу 5.129.210.247:30080. Выполним команду curl на внешний IP-адрес и порт 30080:

curl 5.129.210.247:30080

Image11

Трафик перенаправляется на порт 8080 подов. Этот подход удобен для быстрого тестирования, но не рекомендуется для использования в production-системах из-за ограничений безопасности и масштабируемости.

LoadBalancer

Обеспечивает доступ к приложениям в кластере через балансировщик нагрузки, созданный в облачной инфраструктуре. Этот тип сервиса автоматически присваивает внешний IP-адрес для доступа пользователей к приложению. LoadBalancer можно использовать для production-приложений, где важны высокая доступность и масштабируемость.

Особенности

  • Создает внешний IP-адрес, доступный из внешней сети.

  • Интегрируется с облачными балансировщиками нагрузки.

  • Включает функциональность ClusterIP и NodePort.

Пример использования

В качестве примера создадим конфигурацию? в которой будет использоваться под с Nginx. Доступ будет осуществляться через внешний IP-адрес балансировщика:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-loadbalancer-deployment
  namespace: service-loadbalancer
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26.0
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-loadbalancer-service
  namespace: service-loadbalancer
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

Для начала создадим новый namespace с именем service-loadbalancer:

kubectl create namespace service-loadbalancer

Далее сохраняем конфигурацию выше в файл с именем nginx-loadbalancer-deployment.yaml и применяем ее:

kubectl apply -f nginx-loadbalancer-deployment.yaml

Время создания внешнего балансировщика может занять 5-10 минут. Только после этого можно будет проверить, что все объекты были созданы:

kubectl get all -n service-loadbalancer

Image5

На скриншоте выше в разделе EXTERNAL-IP появился внешний IP-адрес. Если выполнить curl на данный IP-адрес, то вернется ответ от Nginx:

curl http://46.149.66.211:80

Image13

ExternalName

ExternalName — тип сервиса, который используется для создания ссылки на внешний ресурс, находящийся за пределами кластера Kubernetes, без необходимости создания локального прокси. Это позволяет направлять трафик к внешнему сервису, используя DNS-имя, без выделения ClusterIP или создания подов в кластере.

Особенности

  • Работает как DNS-алиас для внешнего ресурса.

  • Не создает виртуальный IP-адрес.

Headless Service

Headless Service — это тип сервиса, который не привязан к ClusterIP. Он обеспечивает DNS-записи для всех подов, соответствующих указанному селектору. Такой сервис применяется для прямого взаимодействия с каждым подом, например, в распределенных системах, таких как базы данных или системы обработки сообщений.

Особенности

  • Не создает виртуальный IP-адрес.

  • DNS-запрос возвращает IP-адреса всех подов.

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

Пример использования

В качестве примера создадим конфигурацию? в которой будет запущено два пода с Nginx. Ключевая особенность — установка clusterIP со значением None, при котором Kubernetes не будет выделять виртуальный IP-адрес. Вместо этого DNS будет возвращать IP-адреса всех подов, соответствующих селектору:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-headless-deployment
  namespace: service-headless
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26.0
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-headless
  namespace: service-headless
spec:
  clusterIP: None
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Для начала создадим новый namespace с именем service-headless:

kubectl create namespace service-headless

Далее сохраняем конфигурацию выше в файл с именем nginx-headless-deployment.yaml и применяем ее:

kubectl apply -f nginx-headless-deployment.yaml

Проверяем, что все объекты были созданы:

kubectl get all -n service-headless

Image3

Далее проверяем, что все поды запущены. Также получим IP-адрес узлов кластера, на которых были запущены поды:

kubectl get pods -l app=nginx -o wide -n service-headless

Image24

Запустим временный под на основе образа curl для выполнения запросов внутри кластера:

kubectl run curl-pod --image=curlimages/curl --restart=Never -n service-headless -- /bin/sh -c "sleep 3600"

Отправим запрос при помощи curl на адрес ранее созданного сервиса (nginx-headless.service). Имя сервиса записывается в формате <имя-сервиса>.<пространство-имен>.svc.cluster.local. Имя сервиса можно узнать при помощи команды:

kubectl get service -n service-headless

В нашем примере имя сервиса выглядит как nginx-headless.service-headless.svc.cluster.local.

kubectl exec -it curl-pod -n service-headless -- curl -v http://nginx-headless.service-headless.svc.cluster.local

Image23

Так как поды запущены на разных нодах, при выполнении команды IP-адреса всегда будет разными:

Image14

Сравнение типов сервисов

Для наглядности воспользуемся таблицей ниже чтобы детально сравнить все четыре типа сервисов:

 

ClusterIP

NodePort

LoadBalancer

Headless Service

Наличие виртуального IP адреса

Да

Да

Да

Нет

Доступ из внешней сети

Нет

Да

Да

Нет

Балансировка

Да

Да

Да

Нет

DNS-записи

Да

Да

Да

Да

Примеры использования

Для внутренних сервисов

Для тестирования

Для использования в production-системах

Для прямого доступа к подам

Заключение

Сервисы в Kubernetes предоставляют гибкие инструменты для управления сетевым взаимодействием внутри кластера. Каждый вид сервиса выполняет определенные функции: от организации внутренней связи между микросервисами до предоставления внешнего доступа или интеграции с внешними системами. Выбор подходящего типа сервиса определяется архитектурой приложения и требованиями к его доступности. Практические примеры, приведенные выше, демонстрируют, как настроить каждый тип сервиса для типичных сценариев. Понимание их особенностей позволяет эффективно управлять приложениями в Kubernetes и обеспечивать их надежность и масштабируемость.

03 июля 2025 г.
6
12 минут чтения
Средний рейтинг статьи: 5

Читайте также

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
Пока нет комментариев