在 ISTIO 上使用 gRPC 时连接保存不正确

在 ISTIO 上使用 gRPC 时连接保存不正确

我们在 Kubernetes 集群上看到了一些奇怪的行为。我们有两个使用 gRPC 的测试应用程序。一个发送订阅消息,另一个发送回响应流。预期的行为是此流保持运行直到取消。然而,我们发现服务器认为它正在发送更新但客户端没有收到的情况。进一步缩小范围导致可重现的测试用例:

  • 如果服务在 Kubernetes 中配置为 gRPC,即端口名称中为 grpc-。
  • 您设置了流媒体
  • 然后重启服务器

然后观察到的行为是客户端从未看到连接断开,大概是因为它的连接是到 istio 代理而不是目标服务器。但是,如果没有连接断开的信息,它就无法重新建立连接。

有人见过这种行为吗?我们需要在 ISTIO 中配置什么来解决这个问题?(我们可以通过将服务更改为不以“grpc-”开头的端口名称来解决问题,但通过禁用 ISTIO 的 gRPC 功能可以解决这个问题。)

编辑:

Kubernetes:1.14.6 Istio:1.3.6

没有设置明确的 DestinationRule,尽管尝试了各种方法,但我们找不到任何可以改变这种行为的方法。

答案1

idleTimeout可以通过设置来防止这种情况DestinationRule

根据 istio文档关于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闲置 2 分钟后,这将关闭来自 Istio envoy 代理端的任何连接。grpcserviceservicenamespace


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

希望能帮助到你。

相关内容