Назад | Перейти на главную страницу

Неправильное сохранение соединения при использовании gRPC на ISTIO

Мы видели странное поведение в нашем кластере кубернетов. У нас есть два тестовых приложения, говорящих на gRPC. Один отправляет сообщение о подписке, а другой отправляет обратно поток ответов. Предполагаемое поведение состоит в том, что этот поток остается активным до тех пор, пока не будет отменен. Однако мы встречали ситуации, когда сервер думал, что отправляет обновления, но клиент их не получал. Дальнейшее сужение этого вопроса привело к воспроизводимому тесту:

Затем наблюдаемое поведение заключалось в том, что клиент никогда не видел разрыва соединения, предположительно из-за того, что он подключен к прокси-серверу istio, а не к серверу назначения. Однако без информации о том, что соединение разорвано, восстановить соединение невозможно.

Кто-нибудь видел такое поведение? Что нам нужно настроить в ISTIO, чтобы обойти это? (Мы можем решить эту проблему, просто изменив службу так, чтобы имя порта не начиналось с "grpc-", но работало, отключив функцию ISTIO gRPC.)

Редактировать:

Kubernetes: 1.14.6 Istio: 1.3.6

Нет явной настройки DestinationRule, хотя мы пробовали разные вещи, мы не смогли найти ничего, что изменило бы это поведение.

Это может быть предотвращено idleTimeout установка в DestinationRule.

Согласно истио документация около idleTimeout:

Тайм-аут простоя для соединений пула восходящих соединений. Тайм-аут простоя определяется как период, в течение которого нет активных запросов. Если не установлен, тайм-аут простоя отсутствует. Когда истечет время ожидания простоя, соединение будет закрыто. Обратите внимание, что тайм-ауты на основе запросов означают, что HTTP / 2 PING не поддерживает соединение. Применимо к соединениям HTTP1.1 и HTTP2.

Итак, если вы сделаете DestinationRule как это:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: grpc-iddletimeout-policy
spec:
  host: grpcservice.servicenamespace.svc.cluster.local
  trafficPolicy:
    connectionPool:
      http:
        idleTimeout: 2m

Это должно закрыть любой HTTP/2 соединение со стороны прокси-сервера Istio envoy после простоя в течение 2 минут в течение grpcservice в servicenamespace пространство имен.


Istio действительно имеет tcpKeepalive также, но я не уверен, будет ли он работать с grpc подключение и Ваша конфигурация.

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: grpc-iddletimeout-policy
spec:
  host: grpcservice.servicenamespace.svc.cluster.local
  trafficPolicy:
    connectionPool:
      tcp:
        connectTimeout: 30ms
        tcpKeepalive:
          time: 7200s
          interval: 75s
      http:
        idleTimeout: 2m

Обратите внимание, что tcpKeepalive настройка применяется на уровне TCP, а idleTimeout на уровне HTTP / 2.

Вы можете проверить Вот чтобы увидеть, что конкретно TCPKeepalive варианты доступны.

Также есть статья об использовании gRPC с подключением keepalive.

Надеюсь, поможет.