Service и Ingress
| Тип | объекты API Kubernetes (core/v1 Service, networking.k8s.io/v1 Ingress) |
|---|---|
| Типы Service | ClusterIP, NodePort, LoadBalancer, ExternalName |
| Обнаружение | DNS-имя <сервис>. |
| Реализация Service | kube-proxy (iptables, IPVS, nftables) или eBPF (Cilium) |
| Ingress GA | Kubernetes 1.19 (2020) |
| Преемник Ingress | Gateway API (GA в октябре 2023) |
| Контроллеры Ingress | ingress-nginx, Traefik, HAProxy, Contour, облачные |
Service и Ingress — объекты Kubernetes, решающие задачу «как достучаться до приложения». Поды постоянно пересоздаются и каждый раз получают новый IP-адрес, поэтому обращаться к ним напрямую нельзя. Service даёт группе подов стабильное имя и виртуальный IP и распределяет между ними запросы.[1] Ingress публикует сервисы наружу по HTTP(S): направляет api.example.com в один сервис, example.com/static — в другой и завершает TLS.[2]
Service
Service выбирает поды по меткам — теми же селекторами, что использует Deployment. Список адресов готовых подов (прошедших readiness-пробу) хранится в объектах EndpointSlice и обновляется автоматически.
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80 # порт сервиса
targetPort: 8000 # порт контейнера
Внутри кластера к сервису обращаются по DNS-имени: web из того же пространства имён или полностью web.prod.svc.cluster.local.[3] За разрешение имён отвечает CoreDNS.
Типы
| Тип | Доступен | Как работает |
|---|---|---|
ClusterIP (по умолчанию) |
только внутри кластера | виртуальный IP, трафик распределяется по подам |
NodePort |
снаружи, IP_узла:порт |
порт из диапазона 30000–32767 открывается на всех узлах |
LoadBalancer |
снаружи, отдельный IP | облако или MetalLB создаёт внешний балансировщик, ведущий на NodePort |
ExternalName |
внутри | DNS-псевдоним (CNAME) на внешний хост |
Особый случай — headless-сервис (clusterIP: None): виртуального IP нет, DNS возвращает адреса всех подов. Его используют StatefulSet'ы, чтобы обращаться к конкретной реплике (db-0.db).
Как это реализовано
Виртуальный IP сервиса не принадлежит ни одному интерфейсу. На каждом узле компонент kube-proxy следит за сервисами и программирует ядро — правила iptables, IPVS или nftables, — которые подменяют адрес назначения на IP одного из подов (по сути NAT).[4] Сетевые плагины на eBPF, например Cilium, умеют делать то же самое без kube-proxy. Балансировка работает на уровне TCP/UDP-соединений, а не отдельных HTTP-запросов (см. Балансировка нагрузки).
Ingress
Создавать по LoadBalancer на каждое приложение дорого и неудобно. Ingress описывает правила маршрутизации HTTP, а реализует их Ingress-контроллер — по сути обратный прокси внутри кластера, обычно доступный через единственный LoadBalancer. Сам Kubernetes контроллер не включает — его устанавливают отдельно: ingress-nginx на базе nginx, Traefik, HAProxy, облачные варианты.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
ingressClassName: nginx
tls:
- hosts: [example.com]
secretName: example-com-tls
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service: {name: api, port: {number: 80}}
- path: /
pathType: Prefix
backend:
service: {name: web, port: {number: 80}}
Сертификат хранится в Secret (см. ConfigMap и Secret); его выпуск и продление через Let's Encrypt автоматизирует cert-manager.
Слабое место Ingress — бедная стандартная спецификация: таймауты, переписывание путей, ограничение частоты запросов задаются аннотациями, свои у каждого контроллера, и манифесты плохо переносятся.
Gateway API
Преемником Ingress стал Gateway API (версия 1.0 вышла в октябре 2023 года).[5] Он разделяет роли: оператор кластера описывает GatewayClass и Gateway (точку входа, порты, сертификаты), а команды приложений — маршруты HTTPRoute, GRPCRoute, TLSRoute. Разделение трафика по весам, сопоставление по заголовкам и межпространственные ссылки входят в стандарт, а не в аннотации. Ingress не удалён и продолжает работать, но новые возможности развиваются в Gateway API; проект ingress-nginx объявил о прекращении сопровождения в марте 2026 года.[6]
Отладка
kubectl get svc,endpointslices -l app=web
kubectl describe ingress web
kubectl run tmp --rm -it --image=busybox -- wget -qO- http://web # запрос изнутри кластера
kubectl port-forward svc/web 8080:80
Пустой список endpoints почти всегда означает, что селектор сервиса не совпадает с метками подов или поды не проходят readiness-пробу.