Мы видели странное поведение в нашем кластере кубернетов. У нас есть два тестовых приложения, говорящих на 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
.
Надеюсь, поможет.