Kubernetes Services: Как поды общаются друг с другом
В Kubernetes поды эфемерны: они рождаются и умирают, а их IP-адреса постоянно меняются. Service — это абстракция, которая предоставляет стабильный IP-адрес и DNS-имя для группы подов, работая как внутренний балансировщик нагрузки.
Как это работает (Схема)
Service использует селекторы, чтобы найти поды с нужными метками (labels), и направляет трафик на них через виртуальный IP (ClusterIP).
[ Клиент / Трафик ]
|
v
+-----------------+
| Service | <-- Стабильный IP (ClusterIP) и DNS
| (Selector: |
| app: nginx) |
+-------+---------+
|
+---------+---------+
| | |
v v v
[ Pod 1 ] [ Pod 2 ] [ Pod 3 ] <-- Динамические IP-адреса
(app:nginx)(app:nginx)(app:nginx)
Типы сервисов
1. ClusterIP (по умолчанию)
Сервис доступен только внутри кластера. Это стандарт для взаимодействия между микросервисами (например, когда Frontend обращается к Backend).
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
type: ClusterIP
selector:
app: backend
ports:
- protocol: TCP
port: 80 # Порт сервиса
targetPort: 8080 # Порт контейнера внутри пода
2. NodePort
Открывает статический порт на каждой ноде кластера. Трафик, приходящий на этот порт, перенаправляется на сервис. Позволяет получить доступ к приложению извне по IP ноды. Диапазон портов: 30000–32767.
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30001 # Внешний порт на ноде3. LoadBalancer
Используется в облачных провайдерах (AWS, GCP, Azure). Автоматически создает облачный балансировщик с публичным IP-адресом, который направляет трафик в кластер.
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 804. ExternalName
Просто отображает сервис на внешнее DNS-имя (например, на базу данных вне кластера). Работает на уровне DNS, без проксирования трафика.
Пример: Связка Deployment + Service
Обычно мы создаем Deployment и Service вместе, чтобы приложение было доступно.
# 1. Запускаем приложение
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
# 2. Создаем точку доступа
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx # Должен совпадать с меткой в Deployment
ports:
- port: 80
targetPort: 80
type: ClusterIP
