← Назад к вопросам

Как запустить TCP трафик в Kubernetes

2.0 Middle🔥 151 комментариев
#Kubernetes#Сети и протоколы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Развернутый ответ: запуск TCP-трафика в Kubernetes

Запуск TCP-трафика в Kubernetes — это базовая, но критически важная задача для любого DevOps-инженера. Она охватывает несколько слоев: от развертывания приложения, которое генерирует или принимает трафик, до настройки сетевой инфраструктуры для его маршрутизации. Я разберу ключевые подходы, от простых к более продвинутым, с практическими примерами.

1. Базовый уровень: kubectl port-forward для ад-hoc доступа

Самый простой способ — это проброс порта с локальной машины прямо на Pod или Service в кластере. Этот метод идеален для отладки, но не для production-трафика, так как создает туннель через API-сервер и зависит от активной сессии kubectl.

# Проброс TCP-порта 8080 локальной машины на порт 80 пода с меткой app=nginx
kubectl port-forward pod/<pod-name> 8080:80

# Или через Service
kubectl port-forward service/<service-name> 8080:80

После выполнения команды вы можете отправлять TCP-трафик (например, с помощью curl, telnet или клиента вашего приложения) на localhost:8080, и он будет перенаправлен в кластер.

2. Production-уровень: использование Service и Ingress

Для постоянного доступа к приложениям изнутри или извне кластера используются ресурсы Service и Ingress.

Service (ClusterIP, NodePort, LoadBalancer)

Service — это абстракция, которая определяет логический набор Pods и политику доступа к ним. Тип Service определяет, как будет экспортироваться TCP-трафик.

  • ClusterIP (по умолчанию): Создает внутренний IP-адрес для доступа к Pods изнутри кластера. Внешний трафик напрямую не проходит.

    apiVersion: v1
    kind: Service
    metadata:
      name: my-tcp-service
    spec:
      type: ClusterIP
      selector:
        app: my-tcp-app
      ports:
      - protocol: TCP
        port: 80       # Порт, на котором Service доступен внутри кластера
        targetPort: 8080 # Порт контейнера в Pod, куда направляется трафик
    
  • NodePort: Открывает статический порт на каждой Node кластера. Трафик на <NodeIP>:<NodePort> перенаправляется в Service, а затем в Pod. Подходит для простого внешнего доступа, когда нет внешнего балансировщика.

    apiVersion: v1
    kind: Service
    metadata:
      name: my-nodeport-service
    spec:
      type: NodePort
      selector:
        app: my-tcp-app
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
        nodePort: 30007 # (Опционально) Порт в диапазоне 30000-32767. Если не указан, будет выбран случайный.
    
  • LoadBalancer: Стандартный способ в облачных средах (AWS, GCP, Azure). Kubernetes взаимодействует с облачным провайдером, чтобы создать внешний балансировщик нагрузки, который направляет трафик на Service. IP-адрес балансировщика становится точкой входа для внешнего TCP-трафика.

    apiVersion: v1
    kind: Service
    metadata:
      name: my-loadbalancer-service
    spec:
      type: LoadBalancer
      selector:
        app: my-tcp-app
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
    # После применения облачный провайдер назначит внешний IP (EXTERNAL-IP в выводе `kubectl get svc`).
    

Ingress и Ingress Controller

Ingress — это API-объект, который управляет внешним доступом к сервисам в кластере, обычно по HTTP/HTTPS. Однако, для "сырого" TCP (или UDP) трафика (например, для баз данных, кастомных протоколов) стандартный Ingress Resource имеет ограничения. Решение — использование Ingress Controller с поддержкой TCP/UDP проксирования, такого как NGINX Ingress Controller.

Настройка передается через ConfigMap контроллера.

  1. Развертывание NGINX Ingress Controller (например, через Helm или манифесты).
  2. Настройка ConfigMap для проксирования TCP-портов. Вы указываете, какой порт на Service контроллера будет слушать внешний TCP-трафик и на какой Service:Port внутри кластера его перенаправлять.
    # Пример ConfigMap для NGINX Ingress Controller
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: tcp-services
      namespace: ingress-nginx # Пространство имен, где работает контроллер
    data:
      "3306": "default/mysql-service:3306" # Ключ: внешний порт. Значение: <namespace>/<service-name>:<service-port>
      "5432": "default/postgres-service:5432"
    
  3. Запуск контроллера с примонтированным этим ConfigMap. Внешний трафик на порт 3306 балансировщика нагрузки контроллера будет направлен на Service mysql-service на порт 3306.

3. Продвинутый уровень: Service типа LoadBalancer с сохранением исходного IP (ExternalTrafficPolicy) и NetworkPolicy

  • ExternalTrafficPolicy: Для Service типов NodePort и LoadBalancer критически важна политика externalTrafficPolicy.
    *   `Cluster` (по умолчанию): Трафик может быть перенаправлен на Pod на любой ноде, что приводит к дополнительному хопу и потере исходного IP-адреса клиента (в Pod он будет виден как IP ноды).
    *   `Local`: Трафик направляется только на Pods, находящиеся на той же ноде, куда он пришел. Это сохраняет **исходный IP-адрес клиента** и уменьшает задержки, но требует равномерного распределения Pods.
```yaml
spec:
  externalTrafficPolicy: Local
  type: LoadBalancer
```
  • NetworkPolicy: Для управления TCP-трафиком внутри кластера (микросервисная безопасность) используйте NetworkPolicy. Это "брандмауэр" на уровне Pod.
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-db-access
    spec:
      podSelector:
        matchLabels:
          role: database
      policyTypes:
      - Ingress
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: api
        ports:
        - protocol: TCP
          port: 5432 # Разрешает входящий TCP-трафик на порт 5432 только от Pods с меткой app=api
    

Итог и рекомендации

Выбор метода зависит от контекста:

  • Отладка/разработка: kubectl port-forward.
  • Внутренняя связь микросервисов: Service типа ClusterIP.
  • Публикация stateless HTTP/HTTPS приложений: Service LoadBalancer + Ingress.
  • Публикация stateful сервисов с кастомными TCP-протоколами (БД, Redis, RabbitMQ): Service LoadBalancer с externalTrafficPolicy: Local или TCP-прокси через Ingress Controller (если нужно экономить внешние IP).
  • Полный контроль и производительность: Рассмотрите шлюзы на уровне eBPF (Cilium) или облачные шлюзы приложений (Application Gateway, ALB).

Всегда проверяйте, что Pods имеют корректные readiness/liveness пробы, а Security Groups/Firewalls облачного провайдера разрешают необходимые порты.