В предыдущей статье Как развернуть и управлять Kubernetes? мы рассмотрели основы Kubernetes: его архитектуру, ключевые компоненты (такие как Pod, Deployment, Service), а также общие принципы развертывания и управления кластером. Теперь перейдем к углубленному изучению работы с подами (Pod) — минимальными исполняемыми единицами в Kubernetes. Для эффективного управления их взаимодействием и доступностью в Kubernetes используются сервисы (Services), чье общее назначение уже упоминалось ранее.
В этой статье мы детально разберем функционал сервисов на практических примерах: рассмотрим их типы (ClusterIP, NodePort, LoadBalancer), конфигурации в YAML-манифестах, а также сценарии использования для обеспечения стабильной коммуникации между компонентами приложения.
Снова о Kubernetes services
Для начала, вспомним, что такое Kubernetes services. Кратко это объекты, обеспечивающие стабильный доступ к приложениям в кластере, даже если поды (Pods) динамически меняются. Более подробно Kubernetes services — это ключевой механизм, обеспечивающий стабильную сетевую коммуникацию между компонентами приложений в условиях динамически изменяющейся среды кластера. Если кратко, Services выступают как «постоянные точки входа» к группе Pod’ов, даже если сами Pod’ы пересоздаются, масштабируются или перемещаются между узлами. На изображении ниже приведены основные типы Services в K8s:
Проблемы решаемы K8s Services:
Так как Pod’ы в Kubernetes — эфемерны: их IP-адреса меняются при перезапуске, масштабировании или обновлении. Это создает сложности для компонентов приложения (например, фронтенда и бэкенда), которым требуется стабильный способ взаимодействия.
Именно Services, решает данные проблемы через следующие несколько действий:
- Фиксированные идентификаторы – Service назначает стабильный IP-адрес (ClusterIP), DNS-имя или внешний IP, которые не зависят от «жизненного цикла» Pod’ов.
- Балансировка нагрузки – Трафик автоматически распределяется между Pod’ами, выбранными через метки (селекторы, например, `app: backend`).
- Автообновление – Service динамически отслеживает изменения в наборе Pod’ов через EndpointSlices, обновляя список доступных экземпляров.
Основные типы Kubernetes Services с примерами
ClusterIP предназначен для внутреннего доступа к Pod’ам внутри кластера.
Пример конфигурации:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Команда для создания:
Проверка:
NodePort предназначен для внешнего доступа через статический порт на nodes(30000-32767).
Пример конфигурации:
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app.kubernetes.io/name: MyApp
ports:
- port: 80
targetPort: 9376
nodePort: 30007 # Опционально (по умолчанию: случайный порт из диапазона)
Команда для создания:
Доступ:
LoadBalancer предназначен для публичного доступ через облачный балансировщик нагрузки.
Пример конфигурации:
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: MyApp
ports:
- port: 80
targetPort: 9376
Команда для создания:
Проверка внешнего IP:
ExternalName предназначен для cвязи с внешним ресурсом через DNS CNAME.
Пример конфигурации:
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: my.database.example.com
Команда для создания:
Использование:
Другие Pod’ы обращаются к external-db как к DNS-имени.
Headless Service (без ClusterIP) предназначен для прямого доступа к Pod’ам без балансировки.
Пример конфигурации:
apiVersion: v1
kind: Service
metadata:
name: my-headless
spec:
clusterIP: None
selector:
app.kubernetes.io/name: MyApp
ports:
- port: 80
targetPort: 9376
Команда для создания:
Проверка DNS:
Дополнительные примеры:
Конфигурация мультипортовый Service предназначена для упрощение конфигурации для приложений с несколькими портами
kind: Service
metadata:
name: my-multi-port
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: metrics
protocol: TCP
port: 9090
targetPort: 9090
Команда:
Конфигурация Service без селектора (ручные EndpointSlices) для интеграции с ресурсами вне Kubernetes.
Конфигурация Service:
apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
Конфигурация EndpointSlice для гибкое управление конечными точками (включая внешние системы):
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: my-service-1
labels:
kubernetes.io/service-name: my-external-service
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 9376
endpoints:
- addresses: ["10.4.5.6"]
- addresses: ["10.1.2.3"]
Команды: