Ответ
Сеть в Kubernetes логически построена на нескольких ключевых абстракциях, которые создают плоское (flat) адресное пространство для подов и сервисов.
1. Pod Network (Сеть подов):
- Каждому поду назначается уникальный IP-адрес из внутренней сети кластера (например,
10.244.0.0/16). - Этот IP назначается CNI-плагином (Container Network Interface), таким как Calico, Cilium или Flannel.
- Фундаментальное правило: любой под может общаться с любым другим подом в кластере напрямую, без NAT, независимо от того, на какой ноде (физической/виртуальной машине) они находятся. Это обеспечивается overlay-сетями (VXLAN, IP-in-IP) или маршрутизацией на уровне хоста (BGP в Calico).
2. Service Network (Сеть сервисов):
- Сервис — это абстракция над динамическим набором подов (обычно определяемым селектором
selector). - Сервису назначается виртуальный IP-адрес (ClusterIP) из другого, выделенного диапазона (например,
10.96.0.0/12). Этот IP стабилен на протяжении жизни сервиса. - Как это работает: Когда трафик приходит на ClusterIP, компонент
kube-proxy, работающий на каждой ноде, перенаправляет его на один из IP-адресов бэкенд-подов. Механизм перенаправления может бытьiptables(по умолчанию) илиipvs(более эффективен для большого числа сервисов).
3. DNS (Служба имен):
- Встроенный DNS (обычно CoreDNS) автоматически создает DNS-записи для сервисов.
- Формат записи:
<service-name>.<namespace-name>.svc.cluster.local. - Например, под в том же namespace может обратиться к сервису
backendпросто по имениbackend. Из другого namespace — по полному имениbackend.app-namespace.svc.cluster.local.
4. Ingress (Входящий трафик):
- Ingress — это API-объект для управления внешним доступом к сервисам (обычно HTTP/HTTPS).
- Он не является типом сервиса, а определяет правила маршрутизации.
- Для работы Ingress требуется контроллер (например, nginx-ingress, traefik), который разворачивается как под и создает балансировщик нагрузки (часто типа LoadBalancer).
Пример логической схемы:
Внешний мир
|
v
[ Ingress Controller (Pod) ] <---> [ Ingress Resource (правила) ]
|
v (маршрутизация по хосту/пути)
[ Service (ClusterIP: 10.96.10.5) ]
|
v (балансировка через iptables/ipvs)
[ Pod (10.244.1.2) ] [ Pod (10.244.2.5) ]
Типы сервисов:
- ClusterIP: Виртуальный IP, доступный только внутри кластера.
- NodePort: Открывает статический порт на каждой ноде, перенаправляя трафик на сервис.
- LoadBalancer: Интегрируется с облачным провайдером (AWS ELB, GCP Load Balancer) для создания внешнего балансировщика.
- Headless: Сервис без ClusterIP, возвращающий напрямую IP-адреса подов. Используется для stateful-приложений (например, с StatefulSet).
Ответ 18+ 🔞
Давай разберём эту всю кухню Kubernetes, а то с виду — ёпта, сплошная магия и волшебные палочки. На самом деле, всё логично, хоть и запутано на первый взгляд, как мартышлюшка в дебрях проводов.
Представь, что у тебя есть куча контейнеров — это твои поды. Каждому такому поду, как самому уважаемому гостю, выдают свой уникальный IP-адрес из внутренней сети кластера. Типа 10.244.0.0/16. Делает это не сам Кубер, а специальные плагины — Calico, Cilium или тот же Flannel. Их задача — чтобы любой под мог набрать номер любому другому поду напрямую, без всяких прокси-телефонисток (NAT), даже если они сидят на разных физических машинах. Фундаментальное правило, блядь: связь прямая. Достигается это либо overlay-сетями (типа VXLAN), либо умной маршрутизацией. Всё плоское и прозрачное. Удивление пиздец, но это работает.
А теперь смотри, поды — штука непостоянная. Сегодня живой, завтра — пересоздался с новым айпишником. Как к ним обращаться? Напрямую по IP — это ж чих-пых тебя в сраку, каждый раз адрес менять. Вот для этого и придумали Сервисы.
Сервис — это такая стабильная точка входа, абстракция над кучей одинаковых подов. Ему дают виртуальный, но постоянный IP (ClusterIP), например, из диапазона 10.96.0.0/12. И работает это так: трафик прилетает на этот виртуальный адрес, а на каждой ноде дежурит компонент kube-proxy. Этот товарищ, как хитрая жопа, через iptables или ipvs перенаправляет запрос на один из реальных подов-бэкендов. Балансировка на уровне системы, тебе вообще париться не надо.
Но запоминать цифры — это же ебать мои старые костыли. Поэтому есть встроенный DNS (обычно CoreDNS). Он для каждого сервиса автоматом создаёт запись вида <service-name>.<namespace>.svc.cluster.local. Хочешь обратиться к бэкенду из того же неймспейса? Просто пиши backend. Из другого — ну, полное имя укажи. Удобно, как хуй с горы.
Теперь про внешний мир. Как пользователи с улицы до наших сервисов доберутся? Через Ingress. Это не сервис, а просто набор правил на бумажке (YAML-манифест). Типа "запросы на myapp.com/admin — отправляй на сервис admin-backend". А чтобы эти правила ожили, нужен Ingress Controller (nginx-ingress, traefik). Это уже реальный под, который смотрит на эти правила и сам настраивает балансировщик. Часто он ещё и внешний облачный Load Balancer себе заказывает, если тип сервиса указать LoadBalancer.
Вот как это всё вместе выглядит, короче:
Внешний мир
|
v
[ Ingress Controller (Pod) ] <--- читает правила --- [ Ingress Resource ]
|
v (смотрит на хост и путь в запросе)
[ Service (ClusterIP: 10.96.10.5) ]
|
v (балансировка через iptables/ipvs)
[ Pod (10.244.1.2) ] [ Pod (10.244.2.5) ]
И напоследок про типы сервисов, а то запутаться — не хер делать:
- ClusterIP: Виртуальный IP, только для внутреннего пользования в кластере. С улицы не видно.
- NodePort: Открывает конкретный порт на каждой ноде кластера. Заходишь на
<IP_любой_ноды>:<порт>— и тебя перенаправят на сервис. Грубо, но работает. - LoadBalancer: Для облачных пацанов. Создаёт тебе реальный, внешний балансировщик нагрузки в твоём облаке (AWS, GCP). Дорого, но красиво.
- Headless (безголовый): А это особый случай. Сервис без ClusterIP. Когда ты к нему обращаешься через DNS, он тебе в ответ сразу IP-адреса всех подов шлёт. Используется для всяких stateful-штук вроде баз данных (StatefulSet), где каждому поду своё имя и роль. Тут уже не просто балансировка, а точное попадание.
Вот и вся магия. Сначала волнение ебать, кажется, что овердохуища всего, но когда разложишь по полочкам — жить можно. Главное — CNI-плагин правильно выбрать и Ingress Controller не забыть.