Как идут запросы извне к микросервису в Kubernetes

Ответ

В моих проектах внешний трафик попадает к микросервисам в Kubernetes по четкому пути, который мы проектируем для безопасности, управляемости и отказоустойчивости.

Типичный путь запроса из интернета:

  1. Внешний балансировщик нагрузки (L4): Запрос приходит на публичный IP-адрес, управляемый облачным LoadBalancer (AWS ALB/NLB, GCP Load Balancer). Этот балансировщик создается Kubernetes Service типа LoadBalancer или, чаще, нашим Ingress-контроллером.

  2. Ingress-контроллер (L7): Балансировщик направляет HTTP/HTTPS трафик на Pod'ы Ingress-контроллера (например, ingress-nginx). Ingress-контроллер — это просто еще один Deployment в кластере.

  3. Ingress-ресурс (правила маршрутизации): Контроллер читает правила из Ingress-ресурсов Kubernetes. Эти правила определяют, какой домен/путь какому внутреннему Service'у соответствует.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: api-ingress
      annotations:
        cert-manager.io/cluster-issuer: "letsencrypt-prod" # Автоматический TLS
    spec:
      tls:
      - hosts:
        - api.mycompany.com
        secretName: api-tls-secret
      rules:
      - host: api.mycompany.com
        http:
          paths:
          - path: /users
            pathType: Prefix
            backend:
              service:
                name: user-service
                port:
                  number: 80
  4. Service (абстракция над Pod'ами): Ingress-контроллер направляет запрос на ClusterIP Service user-service. Service, используя метки (labels), находит все здоровые Pod'ы с микросервисом user-service и балансирует трафик между ними.

  5. Pod (конечная точка): Запрос достигает одного из контейнеров в Pod'е, где и обрабатывается микросервисом.

Важные детали реализации:

  • TLS-терминация обычно происходит на Ingress-контроллере, разгружая микросервисы.
  • Для gRPC или TCP-сервисов мы можем использовать Service типа LoadBalancer напрямую или специализированные Ingress-контроллеры (например, ingress-nginx с аннотацией nginx.ingress.kubernetes.io/backend-protocol: GRPC).
  • Мы используем Network Policies для ограничения трафика между неймспейсами и подами.

Ответ 18+ 🔞

Слушай, я тут на днях коллеге объяснял, как у нас этот цирк с конями устроен, когда запрос из интернета к нам в микросервисы прёт. Ты только представь, какой это пиздопроебибна многослойный бутерброд, но без него — никуда, иначе будет бардак овердохуища.

В общем, смотри, как запрос шагает, будто по тонкому льду, только всё контролируемо.

Шаг 1: Встречают по одёжке (L4-балансировщик) Всё начинается с здоровенного железного мужика на входе — это наш внешний балансировщик, типа AWS NLB или GCPшного. Он как вышибала в клубе: получает удар (запрос) на наш публичный IP и решает, куда его дальше послать. В Kubernetes он обычно всплывает магическим образом, когда ты создаёшь Service с типом LoadBalancer. Но честно? Чаще мы его используем как подставку для следующего звена.

Шаг 2: Умный распределитель (Ingress-контроллер) А дальше трафик попадает к самому хитрому парню — Ingress-контроллеру, например, ingress-nginx. Это ёперный театр! Он сам — обычный Pod в кластере, развёрнутый через Deployment. Его задача — разобрать HTTP-запрос, посмотреть на заголовки и понять, куда дальше. Вот тут-то и начинается магия L7-уровня.

Шаг 3: Правила игры (Ingress-ресурс) Контроллер — не самодур, он действует по написанным правилам. Эти правила живут в обычном YAML-файле, который называется Ingress. Смотри, как просто и гениально это выглядит:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod" # Вот эта штука сама TLS-сертификаты лепит, красота!
spec:
  tls:
  - hosts:
    - api.mycompany.com
    secretName: api-tls-secret
  rules:
  - host: api.mycompany.com
    http:
      paths:
      - path: /users
        pathType: Prefix
        backend:
          service:
            name: user-service # Смотри, он уже знает, куда слать!
            port:
              number: 80

Видишь? Если пришёл запрос на api.mycompany.com/users — вся эта каша летит на сервис user-service. А TLS (HTTPS) мы чаще всего завершаем прямо на контроллере, чтобы микросервисам не париться — пусть работают по HTTP внутри. Удивление пиздец, как удобно!

Шаг 4: Невидимый диспетчер (Service) Сервис user-service — это вообще гениальная абстракция, хуй с горы! Это не реальный под, а просто стабильный DNS-имя и IP внутри кластера. Его работа — знать по меткам (labels), какие поды с нашим микросервисом сейчас живы и здоровы, и раскидать между ними трафик. Pod упал — сервис его вычеркивает из списка и не шлёт ему больше запросы. Красота!

Шаг 5: Финальная точка (Pod) Ну а дальше запрос прилетает в один из этих самых Pod'ов, прямо в контейнер, где наш микросервис user-service его и обрабатывает. Всё, путь пройден.

А теперь про важные фишки, без которых — никуда:

  • TLS-терминация, как я уже сказал, — на контроллере. Микросервисам вообще доверия ебать ноль, пусть внутри кластера общаются без шифрования, быстрее.
  • Хочешь gRPC или свой TCP-протокол прокинуть? Можно либо сразу сервис сделать типа LoadBalancer, чтобы балансировщик снаружи тупо порт пробросил. Лишь бы твой Ingress-контроллер такое умел (у nginx, кстати, есть аннотация nginx.ingress.kubernetes.io/backend-protocol: GRPC).
  • И самое главное — безопасность. У нас же там не бордель. Мы используем Network Policies, чтобы явно сказать: «Эй, Pod из неймспейса frontend может стучаться только на порт 80 Pod'ов в неймспейсе backend». Всё остальное — иди нахуй. Иначе какой-нибудь распиздяй-микросервис начнёт шастать по всей сети, куда не надо. Так что политики — наше всё.

Вот так, чувак, и живём. Сложно? Первый раз — да, голова болит. А потом привыкаешь, и уже без этого многослойного пирога жизни не представляешь.