TransportServer

Ресурс TransportServer позволяет настраивать балансировку нагрузки по протоколам TCP, UDP и TLS Passthrough. Он реализован как пользовательский ресурс.

Это справочная документация по ресурсу TransportServer.

Предварительные требования

  • Для TCP и UDP ресурс TransportServer должен использоваться совместно с ресурсом GlobalConfiguration, который должен быть создан отдельно.

  • Для TLS Passthrough обязательно включите параметр командной строки -enable-tls-passthrough в Ingress Controller.

Спецификация TransportServer

Ресурс TransportServer определяет конфигурацию балансировки нагрузки для трафика TCP, UDP или TLS Passthrough. Ниже приведено несколько примеров:

  • Балансировка нагрузки TCP:

    apiVersion: k8s.angie.software/v1alpha1
    kind: TransportServer
    metadata:
    name: dns-tcp
    spec:
    listener:
        name: dns-tcp
        protocol: TCP
    tls:
        secret: cafe-secret
    upstreams:
    - name: dns-app
      service: dns-service
      port: 5353
      action:
      pass: dns-app
    
  • Балансировка нагрузки UDP:

    apiVersion: k8s.angie.software/v1alpha1
    kind: TransportServer
    metadata:
    name: dns-udp
    spec:
    listener:
        name: dns-udp
        protocol: UDP
    upstreams:
    - name: dns-app
      service: dns-service
      port: 5353
      upstreamParameters:
      udpRequests: 1
      udpResponses: 1
      action:
      pass: dns-app
    
  • Балансировка нагрузки TLS Passthrough:

    apiVersion: k8s.angie.software/v1alpha1
    kind: TransportServer
    metadata:
    name: secure-app
    spec:
    listener:
        name: tls-passthrough
        protocol: TLS_PASSTHROUGH
    host: app.example.com
    upstreams:
    - name: secure-app
      service: secure-app
      port: 8443
      action:
      pass: secure-app
    

Поле

Описание

Тип

Обязательно

listener

Прослушиватель, через который Angie будет принимать входящие соединения и датаграммы.

Listener

Да

host

Хост (доменное имя) сервера. Это должен быть допустимый поддомен, как определено в RFC 1123, например my-app или hello.example.com. Домены с подстановочными знаками, такие как *.example.com, не допускаются. Требуется для балансировки нагрузки TLS Passthrough.

строка

Нет

tls

Конфигурация завершения TLS. Не поддерживается для балансировки нагрузки TLS Passthrough.

TLS

Нет

upstreams

Список апстримов.

[]upstream

Да

upstreamParameters

Параметры апстрима.

UpstreamParameters

Нет

action

Действие, выполняемое для клиентского соединения или датаграммы.

Action

Да

ingressClassName

Указывает, какой Ingress Controller должен обрабатывать ресурс TransportServer.

string

Нет

streamSnippets

Задает пользовательский фрагмент в контексте stream.

string

Нет

serverSnippets

Задает пользовательский фрагмент в контексте server.

string

Нет

Listener

Ссылается на прослушиватель, через который Angie будет принимать входящий трафик к TransportServer. Для TCP и UDP прослушиватель должен быть определен в ресурсе GlobalConfiguration. При ссылке на прослушиватель должны совпадать как имя, так и протокол. Для TLS Passthrough используйте встроенный прослушиватель с именем tls-passthrough и протоколом TLS_PASSTHROUGH.

Пример:

listener:
  name: dns-udp
   protocol: UDP

Поле

Описание

Тип

Требуется

name

Имя прослушивателя.

string

Да

protocol

Протокол прослушивателя.

string

Да

TLS

Поле tls определяет конфигурацию TLS для TransportServer. Обратите внимание, что текущая реализация поддерживает завершение TLS на нескольких портах, где каждому приложению принадлежит выделенный порт. При этом Ingress Controller завершает TLS-соединения на каждом порту, где каждое приложение использует свой собственный сертификат или ключ, и направляет соединения соответствующему приложению (сервису) на основе этого входящего порта (т. е. любое TLS-соединение независимо от настроек SNI на порту будет перенаправлено в приложение, соответствующее этому порту). Пример конфигурации показан ниже:

secret: cafe-secret

Поле

Описание

Тип

Обязательно

secret

Имя секрета с сертификатом TLS и ключом. Секрет должен принадлежать тому же пространству имен, что и транспортный сервер. Секрет должен иметь тип kubernetes.io/tls и содержать ключи с именами tls.crt и tls.key, содержащие сертификат и закрытый ключ, как описано здесь.

string

Нет

Upstream

Определяет конечное место назначения для TransportServer. Например:

name: secure-app
service: secure-app
port: 8443
maxFails: 3
maxConns: 100
failTimeout: 30s
loadBalancingMethod: least_conn

Поле

Описание

Тип

Обязательно

name

Имя апстрима. Это должна быть допустимая метка DNS, как определено в RFC 1035. Например, допустимы значения hello и upstream-123. Имя должно быть уникальным среди всех апстримов ресурса.

string

Да

service

Название сервиса. Сервис должен принадлежать к тому же пространству имен, что и ресурс. Если сервиса не существует, Angie предположит, что у него нет конечных точек, и будет закрывать клиентские соединения и игнорировать датаграммы.

string

Да

port

Порт службы. Если у сервиса этот порт не задан, Angie предположит, что у него нет конечных точек, и будет закрывать клиентские соединения и игнорировать датаграммы. Значение должно находиться в диапазоне 1..65535.

int

Да

maxFails

Задает число неудачных попыток установить связь с сервером, которые должны произойти в течение времени, заданного параметром failTimeout, чтобы сервер считался недоступным. Значение по умолчанию: 1.

int

Нет

maxConns

Задает максимальное число подключений к проксируемому серверу. Значение по умолчанию равно нулю, что означает отсутствие ограничений. Значение по умолчанию равно 0.

int

Нет

failTimeout

Задает время, в течение которого должно произойти указанное количество неудачных попыток установить связь с сервером, чтобы считать сервер недоступным, и период времени, в течение которого сервер будет считаться недоступным. Значение по умолчанию равно 10 секундам.

string

Нет

loadBalancingMethod

Метод балансировки нагрузки между серверами апстрима. По умолчанию соединения распределяются между серверами по методу взвешенной циклической балансировки. Доступные методы и подробности смотрите в разделе Апстрим.

string

Нет

UpstreamParameters

Различные параметры апстрима:

upstreamParameters:
  udpRequests: 1
  udpResponses: 1
  connectTimeout: 60s
  nextUpstream: true
  nextUpstreamTimeout: 50s
  nextUpstreamTries: 1

Поле

Описание

Тип

Обязательно

udpRequests

Количество датаграмм, после получения которых следующая датаграмма от того же клиента запускает новый сеанс. См. директиву proxy_requests. Значение по умолчанию равно 0.

int

Нет

udpResponses

Количество датаграмм, ожидаемых от проксируемого сервера в ответ на клиентскую датаграмму. См. директиву proxy_responses. По умолчанию количество датаграмм не ограничено.

int

Нет

connectTimeout

Тайм-аут установки соединения с проксируемым сервером. См. директиву proxy_connect_timeout. Значение по умолчанию - 60 секунд.

string

Нет

nextUpstream

Если соединение с проксируемым сервером установить не удается, определяет, будет ли клиентское соединение передано на следующий сервер. См. директиву proxy_next_upstream. Значение по умолчанию равно true.

bool

Нет

nextUpstreamTries

Количество попыток до передачи соединения к следующему серверу. См. директиву proxy_next_upstream_tries. Значение по умолчанию равно 0.

int

Нет

nextUpstreamTimeout

Время, отведенное для передачи соединения к следующему серверу. См. директиву proxy_next_upstream_timeout. Значение по умолчанию - 0.

string

Нет

SessionParameters

Различные параметры для TCP-соединений и UDP-сеансов.

sessionParameters:
  timeout: 50s

Поле

Описание

Тип

Обязательно

timeout

Тайм-аут между двумя последовательными операциями чтения или записи в соединениях с клиентом или проксируемым сервером. См. директиву proxy_timeout. Значение по умолчанию равно 10m.

string

Нет

Action

Действие, которое необходимо выполнить для клиентского соединения или датаграммы.

В приведенном ниже примере клиентские подключения и датаграммы передаются на апстрим в dns-app:

action:
  pass: dns-app

Поле

Описание

Тип

Требуется

pass

Передает соединения и датаграммы апстриму. Апстрим с таким именем должен быть определен в ресурсе.

string

Да

Использование TransportServer

Для работы с ресурсами TransportServer можно использовать обычные команды kubectl, аналогично ресурсам Ingress.

Например, следующая команда создает ресурс TransportServer, определенный в transport-server-passthrough.yaml, с именем secure-app:

kubectl apply -f transport-server-passthrough.yaml

transportserver.k8s.angie.software/secure-app created

Вы можете получить ресурс, выполнив:

kubectl get transportserver secure-app

NAME         AGE
secure-app   46sm

В kubectl get и подобных командах также можно использовать короткое имя ts вместо transportserver.

Использование фрагментов

Фрагменты позволяют вставлять элементы конфигурации Angie в различные контексты конфигурации Angie. В приведенном ниже примере мы используем фрагменты для настройки контроля доступа на TransportServer:

apiVersion: k8s.angie.software/v1alpha1
kind: TransportServer
metadata:
  name: cafe
spec:
  host: cafe.example.com
  serverSnippets: |
    deny  192.168.1.1;
    allow 192.168.1.0/24;
  upstreams:
  - name: tea
    service: tea-svc
    port: 80

Фрагменты также можно указать для потока. В приведенном ниже примере мы используем фрагменты для ограничения количества подключений :

apiVersion: k8s.angie.software/v1alpha1
kind: TransportServer
metadata:
  name: cafe
spec:
  host: cafe.example.com
  streamSnippets: limit_conn_zone $binary_remote_addr zone=addr:10m;
  serverSnippets: limit_conn addr 1;
  upstreams:
  - name: tea
    service: tea-svc
    port: 80

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

Однако из-за недостатков, описанных ниже, фрагменты по умолчанию отключены. Чтобы использовать фрагменты, задайте аргумент командной строки enable-snippets.

Недостатки использования фрагментов:

  • Сложность. Чтобы использовать фрагменты, требуется:

    • Понимать примитивы конфигурации Angie и реализовать правильную конфигурацию Angie.

    • Понимать, как IC генерирует конфигурацию Angie, чтобы фрагмент не мешал другим функциям конфигурации.

  • Сниженная надежность. Неправильный фрагмент делает конфигурацию Angie недействительной, что приведет к ошибке при перезагрузке. Это помешает применить какие-либо обновления конфигурации, включая обновления для другого ресурса TransportServer, пока фрагмент не будет исправлен.

  • Последствия для безопасности. Фрагменты предоставляют доступ к примитивам конфигурации Angie, и эти примитивы не проверяются самим Ingress Controller.

Примечание

Пока конфигурация Angie содержит недопустимый фрагмент, Angie будет продолжать работать с последней допустимой конфигурацией.

Примечание

Чтобы настроить фрагменты в контексте stream, используйте ключ stream-snippets ConfigMap.

Валидация

Для ресурса TransportServer доступны два типа валидации:

  • Структурная валидация с помощью kubectl и сервера Kubernetes API.

  • Всесторонняя валидация с помощью Ingress Controller.

Структурная валидация

Пользовательское определение ресурса для TransportServer включает структурную схему OpenAPI, которая описывает тип каждого поля ресурса.

Если вы попытаетесь создать (или обновить) ресурс с нарушением структурной схемы (например, используете строковое значение для поля порта апстрима), сервер kubectl и Kubernetes API отклонят такой ресурс:

  • Пример проверки kubectl:

    kubectl apply -f transport-server-passthrough.yaml
    
      error: error validating "transport-server-passthrough.yaml": error validating data: ValidationError(TransportServer.spec.upstreams[0].port): invalid type for software.angie.k8s.v1alpha1.TransportServer.spec.upstreams.port: got "string", expected "integer"; if you choose to ignore these errors, turn validation off with --validate=false
    
  • Пример проверки сервера Kubernetes API:

    kubectl apply -f transport-server-passthrough.yaml --validate=false
    
      The TransportServer "secure-app" is invalid: []: Invalid value: map[string]interface {}{ ... }: validation failure list:
      spec.upstreams.port in body must be of type integer: "string"
    

Если ресурс не отклонен (то есть не нарушает структурную схему), Ingress Controller проверит его дополнительно.

Всесторонняя валидация

Ingress Controller проверяет поля ресурса TransportServer. Если ресурс недействителен, Ingress Controller отклонит его: ресурс продолжит существовать в кластере, но Ingress Controller будет его игнорировать.

Вы можете проверить, успешно ли Ingress Controller применил конфигурацию TransportServer. Для примера TransportServer secure-app мы можем запустить:

kubectl describe ts secure-app

. . .
Events:
  Type    Reason          Age   From                      Message
-----
Normal  AddedOrUpdated  3s    angie-ingress-controller  Configuration for default/secure-app was added or updated

Обратите внимание, что раздел «События» (Events) включает событие Normal с причиной AddedOrUpdated, которое информирует нас о том, что конфигурация была успешно применена.

Если вы создадите недопустимый ресурс, Ingress Controller отклонит его и выдаст событие Rejected. Например, если вы создадите TransportServer secure-app с действием pass, которое ссылается на несуществующий апстрим, вы получите:

kubectl describe ts secure-app

. . .
Events:
  Type     Reason    Age   From                      Message
-----
Warning  Rejected  2s    angie-ingress-controller  TransportServer default/secure-app is invalid and was rejected: spec.action.pass: Not found: "some-app"

Обратите внимание, что раздел событий включает событие Warning с причиной Rejected.

Примечание

Если вы внесете ошибку в уже существующий ресурс, контроллер входа отклонит его и удалит соответствующую конфигурацию из Angie.

Настройка с помощью ConfigMap

Ключи ConfigMap (за исключением stream-snippets, stream-log-format, resolver-addresses, resolver-ipv6, resolver-valid и resolver-timeout) не влияют на ресурсы TransportServer.