Балансировка TCP\UDP трафика ingress-контроллером

У Ingress-контроллера nginx существует функция опубликования не только HTTP портов, но любых других TCP\UDP портов: https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/

Настройка данного функционала требует изменения нескольких компонентов кластера, которые будут рассмотрены далее.

1. Тестовая задача

Допустим, у нас есть Deployment, поды которого слушают TCP порты 1540 и 1541. У нас в кластере уже созданы сервисы для каждого пода и теперь нам нужно опубликовать данные порты наружу с помощью ingress-контроллера.

2. Реализация

Для выполнения данной задачи нам потребуется внести изменения в 2 объекта:

  • ConfigMap - nova-ingress-public-tcp-services-config

  • Service - nova-ingress-public-controller

Так как service nova-ingress-public-controller управляется с помощью FluxCD, изменения будут вноситься не напрямую в объект Service, а через объект Kustomization nova-release-ingress-public-main

  1. Откройте в браузере веб-интерфейс Nova Console и перейдите в раздел Workloads → ConfigMaps. Переключите фильтр Namespace на nova-ingress-public и из списка ConfigMaps выберите nova-ingress-public-tcp-services-config

    loadbalancing tcp udp traffic 1
  2. На открывшейся странице перейдите на вкладку YAML и вставьте следующие строки в редактор:

    data:
      1540: "1c-test/1c-1540:1540"
      1541: "1c-test/1c-1541:1541"

    В данном примере строка имеет следующий формат: <порт_который_слушает_nginx>: "<namespace>/<service>:<порт_который_слушает_service>" После внесения изменений нажмите "Cохранить":

    loadbalancing tcp udp traffic 2
  3. Перейдите в раздел Networking → Services, переключите фильтр Namespace на nova-ingress-public и из списка выберите nova-ingress-public-controller

    loadbalancing tcp udp traffic 3
  4. На открывшейся странице перейдите на вкладку YAML. Так как у данного объекта присутствуют следующие лейблы, это означает что service nova-ingress-public-controller управляется с помощью FluxCD, изменения будут вноситься не напрямую в объект Service, а через объект Kustomization nova-release-ingress-public-main:

    app.kubernetes.io/managed-by: Nova
    kustomize.toolkit.fluxcd.io/name: nova-release-ingress-public-main
    kustomize.toolkit.fluxcd.io/namespace: nova-gitops
    loadbalancing tcp udp traffic 4
  5. Откройте еще одну вкладку браузера с веб-интерфейсом Nova Console и перейдите в раздел Administration → ClusterSettings

    loadbalancing tcp udp traffic 5
  6. На открывшейся странице перейдите на вкладку "Конфигурация компонентов" и выберите из списка "Cluster Kustomizations"

    loadbalancing tcp udp traffic 6
  7. На открывшейся странице найдите имя объекта Kustomization из п.4 (nova-release-ingress-public-main)

    loadbalancing tcp udp traffic 7
  8. На открывшейся странице перейдите на вкладку YAML. Здесь нам нужно применить патч для изменения объекта Service\nova-ingress-public-controller. Существует несколько способов применения патчей к объектам Kustomization, которые подробно описаны в документации FluxCD https://fluxcd.io/flux/components/kustomize/kustomizations/#patches В данном примере мы будем использовать формат патча JSON6902. Для этого нам нужно добавить к текущему манифесту раздел patches, в котором мы опишем наш patch. В данном случае параметр op описывает действие add (добавить). Параметр path описывает место в манифесте, куда стоит внести изменения. Параметр value описывает значение, которое нужно добавить в данное место. Здесь стоит учитывать особенность работы со списками. Так как мы не указываем конкретный индекс списка, куда нужно добавить значение, то нам нужно в список значений добавить уже имеющиеся значения ports у объекта service/nova-ingress-public-controller, иначе имеющиеся значения будут потеряны при применении патча. Параметр target описывает к какому объекту будет применен патч, в нем мы указываем тип объекта, имя и namespace. В результате наш патч имеет следующий вид:

      patches:
        - patch: |
            - op: add
              path: /spec/ports
              value:
                - name: http
                  protocol: TCP
                  appProtocol: http
                  port: 80
                  targetPort: http
                - name: https
                  protocol: TCP
                  appProtocol: https
                  port: 443
                  targetPort: https
                - name: 1c-1540
                  port: 1540
                  targetPort: 1540
                  protocol: TCP
                - name: 1c-1541
                  port: 1541
                  targetPort: 1541
                  protocol: TCP
          target:
            kind: Service
            name: nova-ingress-public-controller
            namespace: nova-ingress-public

    Вставьте данный патч в редактор в секцию spec и нажмите "Сохранить"

    loadbalancing tcp udp traffic 8
  9. Вернитесь на вкладку с объектом service/nova-ingress-public-controller из п.4 и убедитесь, что в YAML манифесте объекта появилось описание новых портов (возможно понадобится нажать кнопку "Обновить"):

    loadbalancing tcp udp traffic 9

    Теперь ingress-контроллер слушает указанные порты на worker-узлах (или выделенных ingress-узлах) и перенаправляет запросы в соответствии с конфигурацией.