Meedoeed14 часов назадОбъяснить с
Kubernetes просто, часть 5: зачем нужен Ingress и как маршрутизировать HTTP‑трафик
Уровень сложностиПростойВремя на прочтение7 минОхват и читатели4.9KKubernetes*Системное администрирование*DevOps*Облачные сервисы*Сетевые технологии*ТуториалПредыдущие статьи:
Kubernetes просто, часть 4: как трафик попадает в кластер, NodePort и LoadBalancerKubernetes просто, часть 3: зачем нужен Service и как трафик доходит до конкретного PodKubernetes просто, часть 2: что происходит после kubectl applyKubernetes просто, часть 1: зачем Kubernetes, устройство кластера
В прошлой части мы успели разобрать, как трафик попадает в кластер извне, из Интернета и локальных сетей.
Теперь у нас есть три типа Service
ClusterIP
NodePort
LoadBalancer
И для внешнего доступа мы пришли к следующей схеме:
Internet
↓
Load Balancer
↓
Service
↓
PodsДля одного приложения всё довольно закономерно. Но давайте представим, что наш кластер постепенно растёт. Теперь в нём работают несколько приложений:
shop.example.com
admin.example.com
api.example.com
Каждому из них нужен внешний доступ. И, конечно, можно просто собрать для каждого из них Service типа LoadBalancer для его осуществления.
В итоге получаем:
Тут возникает закономерный вопрос:
Обязательно ли каждому HTTP‑приложению создавать собственную внешнюю точку входа?Этот подход кажется нерациональным — неужто его нельзя оптимизировать?
Хочется принимать трафик в одном месте, а уже потом решать:
shop.example.com ↓ shop-service
api.example.com ↓ api-service
admin.example.com ↓ admin-serviceА может, даже так:
example.com/shop ↓ shop-service
example.com/api
↓
api-serviceИменно для такой маршрутизации в зависимости от HTTP‑адреса в Kubernetes используется Ingress. Его изучению и посвятим эту статью.
Что это такое?
Начнём с простого:
Ingress описывает правила маршрутизации HTTP/HTTPS‑трафика к Services внутри Kubernetes.Фактически, с этим мы уже определились ранее.
До этого мы имели:
Internet
↓
Load Balancer
↓
Service
↓
PodsА теперь появляется новый уровень:
Internet
↓
Ingress
├──→ Service A → Pods
└──→ Service B → PodsIngress умеет «смотреть» на HTTP‑запрос и определять, какому Service его передать.
К примеру, пришёл запрос на
https://shop.example.com
Он закономерно попадёт в shop‑service.
А запрос на
https://api.example.com
Отправится в api‑service.
В итоге имеем:
Ingress ≠ Service
Давайте продублируем задачи каждого уровня, чтобы не путать их.
Мы знаем, задача Service — вести учёт работоспособных подов и распределять по ним входящий трафик.
К примеру:
backend-service
├── Pod A
├── Pod B
└── Pod CЗадача Ingress похожа, но уже относительно сервисов, а не подов. Он работает на уровень выше и распределяет трафик по сервисам.
Маршрутизация по домену
Посмотрим на первый сценарий, о котором мы говорили:
Имеется два адреса и два сервиса, которые им соответствуют:
api.example.com -> api-service
shop.example.com -> shop-service
Соответственно, мы хотим получить соответствующую маршрутизацию, чтобы запросы на первый адрес попадали в api‑service и аналогично для shop.
Ingress позволяет легко описать такие правила:
apiVersion: networking.k8s.io/v1 kind: Ingress
metadata: name: example-ingress
spec:
rules:
- host: shop.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: shop-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80На первый взгляд — YAML большой и непонятный, но идея здесь довольно лаконичная и простая.
Есть правило:
host: <адрес, к примеру api.example.com>
И backend, который его должен обслуживать:
service:
name: <имя сервиса>
port:
number: <порт, на котором принимает запросы сервис>Соответственно:
если host = shop.example.com
↓
отправить в shop-service:80Аналогично для api.example.com.
Маршрутизация по пути
Ingress умеет принимать решения не только по домену, вспомните типичные адреса сайтов, на которые вы заходите, обычно они имеют вид
marketplace.com/catalog
marketplace.com/profile
И подобные. Часть после «/» обычно называется путём запроса.
Соответственно, хотелось бы иметь возможность маршрутизировать трафик именно в зависимости от пути.
marketplace.com/catalog -> catalog-service
marketplace.com/profile -> profile-service
В manifest это может быть отображено так:
rules:
- host: marketplace.com
http:
paths:
- path: /catalog
pathType: Prefix
backend:
service:
name: catalog-service
port:
number: 80
- path: /profile
pathType: Prefix
backend:
service:
name: profile-service
port:
number: 80Теперь Ingress смотрит не только на домен запроса, но и на path (его путь).
pathType
В манифесте выше появилось:
pathType: Prefix
Сейчас достаточно понимать его как:
Путь считается префиксом для маршрутизации запросов.Иначе говоря, запросы на
marketplace/catalog
marketplace/catalog/technic
marketplace/catalog/technic/phones
Все будут маршрутизироваться по правилу префикса /catalog сервисом catalog-service.
Есть и другие варианты pathType, но сейчас углубляться в них не будем.
Ingress — набор правил
Вполне возможно, что Ingress уже усвоился в вашей голове как набор правил по маршрутизации трафика. Так и есть!
Мы создали:
kind: Ingress
В нём написали, какие маршруты на какие сервисы ссылаются. Фактически, сам объект Ingress — просто набор правил. Но кто эти правила реализует? Кто следит за тем, чтобы они выполнялись?
Здесь появляется Ingress Controller.
Упрощённо имеем:
Ingress
│ содержит правила
↓
Ingress Controller
│ реализует их
↓
ServicesЭто похоже на уже знакомый нам принцип, с desired и actual state кластера.
Мы описываем желаемое состояние кластера, а соответствующий контроллер следит за тем, чтобы актуальное состояние стремилось к желаемому.
Так и здесь:
Мы описываем набор правил, а контроллер следит за объектами Ingress и настраивает соответствующую маршрутизацию трафика.
Собираем всё вместе
Представим, что у нас есть Интернет‑магазин.
В Kubernetes работают:
Frontend Pods
API Pods
Admin Pods
Для каждой группы подов создан свой Service.
shop-service
api-service
admin-service
Наружу мы хотим отдать:
shop.example.com
api.example.com
admin.example.com
Имеем в итоге:
И здесь уже хорошо видно разделение ответственности.
DNS
↓
Где находится внешний адрес?
----------------------------
Load Balancer
↓
Как попасть в кластер?
----------------------------
Ingress
↓
К какому HTTP backend
отправить запрос?
----------------------------
Service
↓
Какие Pods стоят
за этим backend?
----------------------------
Pods
↓
Где работает приложение?
Что запомнить
После этой части главное не запоминать большой Ingress YAML.
Гораздо важнее держать в голове цепочку:
Internet
↓
Ingress Controller
↓
Ingress rules
↓
Service
↓
PodsIngress описывает правила HTTP/HTTPS‑маршрутизации.
Например:
shop.example.com -> shop-service
api.example.com -> api-service
Ingress Controller — компонент, который реализует эти правила и фактически обрабатывает соответствующий входящий трафик.
А Service по‑прежнему решает уже знакомую задачу:
Service ↓ backend PodsКак итог:
Ingress ≠ Service
Ingress ≠ Ingress Controller
Проверьте себя
1. Какую проблему решает Ingress, если у нас уже есть Service типа LoadBalancer?
2. Чем отличаются задачи Ingress и Service?
3. Есть правила:
shop.example.com -> shop-service
api.example.com -> api-service
Куда должен попасть запрос:
https://api.example.comТеги:• kubernetes
• k8s
• хабр
• ingress
• service
• системное администрирование
• devops
• трафик
• сети
• контейнерыХабы:• Kubernetes
• Системное администрирование
• DevOps
• Облачные сервисы
• Сетевые технологии
Получайте больше инсайтов о систематизации бизнеса
Подписывайтесь на Telegram-канал Business Operations — ежедневные материалы о бизнес-процессах, операционном управлении и повышении эффективности
💬 Подписаться на канал→ Оригинальная статья