Как сервис в Kubernetes узнает с каким Pod ему взаимодействовать
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как 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 компонент:
- Мониторит Service и Endpoints объекты
- Настраивает правила Linux Kernel (iptables или IPVS)
- Когда пакет приходит на Service IP:
- kube-proxy перехватывает его
- Выбирает один из Podов (round-robin)
- Переписывает destination IP на IP Poda
- Пакет идет на Pod
- Ответ переписывается обратно
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 постоянно:
- Ищет все Podы с matching labels
- Проверяет readiness status каждого Pod'а
- Обновляет Endpoints объект если что-то изменилось
- Всё это происходит автоматически и быстро (обычно в течение секунд)
Это дает:
- Автоматическую масштабируемость - Podы могут создаваться/удаляться
- Self-healing - упавшие Podы автоматически исключаются
- Zero-downtime deployments - новые Podы добавляются постепенно
9. Полный жизненный цикл
- Deployment стартует и создает 3 Poda с label app=web
- Service с selector app=web находит эти 3 Poda
- Kubernetes создает Endpoints с IP всех 3 Podов
- Service получает ClusterIP 10.96.0.10
- DNS доступна: web-service → 10.96.0.10
- Когда запрос приходит на web-service:80:
- kube-proxy Load Balance'ит на один из 3 Podов
- Запрос перенаправляется на Pod IP и targetPort 8080
- Если один Pod упадет:
- Его readiness probe будет failing
- Kubernetes удалит его из Endpoints
- Service перестанет слать трафик
- При добавлении нового Pod'а:
- Kubernetes сразу видит его label app=web
- Добавляет в Endpoints
- Трафик начинает идти на новый Pod
Итого
Service Discovery работает через механизм labels и selectors:
- Service имеет selector: какие labels ищет
- Kubernetes ищет Podы с этими labels
- Создает Endpoints со списком IP адресов
- kube-proxy маршрутизирует трафик на Podы
- Всё работает автоматически и динамически
Это позволяет приложениям обращаться к другим сервисам по стабильному имени, не беспокоясь о конкретных IP адресах Podов.