← Назад к вопросам

Как сервис в Kubernetes узнает с каким Pod ему взаимодействовать

2.3 Middle🔥 171 комментариев
#Docker, Kubernetes и DevOps#REST API и микросервисы

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как Service в Kubernetes узнает, с каким Pod ему взаимодействовать

Это один из ключевых механизмов Kubernetes. Service предоставляет стабильный IP адрес для доступа к группе Podов, несмотря на то, что сами Podы могут создаваться и удаляться динамически.

1. Labels и Selectors - основной механизм

Service находит нужные Podы через labels и selectors:

  • Labels - это метаданные на Podах (key=value пары)
  • Selector - это условие в Service, которое описывает какие labels ищем

Когда Service создается, он ищет все Podы с matching labels и создает Endpoints объект со списком их IP адресов.

2. Процесс Service Discovery

Шаг 1: Deployment создает Podы с labels

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
        version: v1
    spec:
      containers:
      - name: app
        image: my-app:1.0
        ports:
        - containerPort: 8080

Шаг 2: Service ищет Podы через selector

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP

Шаг 3: Kubernetes автоматически создает Endpoints

apiVersion: v1
kind: Endpoints
metadata:
  name: web-service
subsets:
- addresses:
  - ip: 10.1.0.5
    targetRef:
      kind: Pod
      name: web-app-abc123
  - ip: 10.1.0.6
    targetRef:
      kind: Pod
      name: web-app-def456
  - ip: 10.1.0.7
    targetRef:
      kind: Pod
      name: web-app-ghi789
  ports:
  - port: 8080

Шаг 4: Service получает ClusterIP (например 10.96.0.10)

Шаг 5: Мониторинг изменений - Kubernetes постоянно следит:

  • Если появляется новый Pod с label app=web → добавляется в Endpoints
  • Если Pod удаляется → удаляется из Endpoints
  • Если Pod становится недоступным → удаляется из Endpoints

3. Service Discovery в Java приложении

@RestController
public class WebController {
    private final RestTemplate restTemplate;
    
    @GetMapping("/users")
    public List<User> getUsers() {
        // Kubernetes DNS переводит имя в IP
        String url = "http://user-service:8080/api/users";
        List<User> users = restTemplate.getForObject(url, List.class);
        return users;
    }
}

@FeignClient(name = "user-service")
public interface UserServiceClient {
    @GetMapping("/api/users")
    List<User> getUsers();
}

4. Как работает Load Balancing

На каждом node'е работает kube-proxy компонент:

  1. Мониторит Service и Endpoints объекты
  2. Настраивает правила Linux Kernel (iptables или IPVS)
  3. Когда пакет приходит на Service IP:
    • kube-proxy перехватывает его
    • Выбирает один из Podов (round-robin)
    • Переписывает destination IP на IP Poda
    • Пакет идет на Pod
  4. Ответ переписывается обратно

5. DNS Resolution в Kubernetes

Кубернетес использует CoreDNS:

java приложение → http://user-service:8080
        ↓
CoreDNS резолвит имя
user-service.default.svc.cluster.local → 10.96.0.10 (ClusterIP)
        ↓
Запрос идет на Service IP 10.96.0.10
        ↓
kube-proxy Load Balance'ит на один из Podов (10.1.0.5, 10.1.0.6 или 10.1.0.7)
        ↓
Ответ возвращается

6. Типы Service'ов

ClusterIP (по умолчанию)

  • Доступен только внутри кластера
  • По имени: user-service
  • IP видны только Podам внутри кластера

NodePort

  • Доступен на всех node'ах на определенном порте
  • Доступен снаружи: <node-ip>:30000

LoadBalancer

  • Создает внешний load balancer
  • Доступен снаружи через публичный IP

ExternalName

  • Маршрутизирует на внешний сервис

7. Readiness и Liveness Probes

Это важно для Service Discovery:

readinessProbe:
  httpGet:
    path: /actuator/health
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5
  failureThreshold: 3
  • Readiness Probe - "готов ли Pod к трафику?" → влияет на Endpoints
  • Liveness Probe - "жив ли Pod?" → Kubernetes перезагружает если падает

Если readinessProbe вернет failure:

  • Pod удаляется из Endpoints
  • Service перестает отправлять трафик на этот Pod
  • Запросы идут только на здоровые Podы

8. Как Kubernetes отслеживает изменения

Контроллер Service постоянно:

  1. Ищет все Podы с matching labels
  2. Проверяет readiness status каждого Pod'а
  3. Обновляет Endpoints объект если что-то изменилось
  4. Всё это происходит автоматически и быстро (обычно в течение секунд)

Это дает:

  • Автоматическую масштабируемость - Podы могут создаваться/удаляться
  • Self-healing - упавшие Podы автоматически исключаются
  • Zero-downtime deployments - новые Podы добавляются постепенно

9. Полный жизненный цикл

  1. Deployment стартует и создает 3 Poda с label app=web
  2. Service с selector app=web находит эти 3 Poda
  3. Kubernetes создает Endpoints с IP всех 3 Podов
  4. Service получает ClusterIP 10.96.0.10
  5. DNS доступна: web-service → 10.96.0.10
  6. Когда запрос приходит на web-service:80:
    • kube-proxy Load Balance'ит на один из 3 Podов
    • Запрос перенаправляется на Pod IP и targetPort 8080
  7. Если один Pod упадет:
    • Его readiness probe будет failing
    • Kubernetes удалит его из Endpoints
    • Service перестанет слать трафик
  8. При добавлении нового Pod'а:
    • Kubernetes сразу видит его label app=web
    • Добавляет в Endpoints
    • Трафик начинает идти на новый Pod

Итого

Service Discovery работает через механизм labels и selectors:

  • Service имеет selector: какие labels ищет
  • Kubernetes ищет Podы с этими labels
  • Создает Endpoints со списком IP адресов
  • kube-proxy маршрутизирует трафик на Podы
  • Всё работает автоматически и динамически

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