我们在 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 代理端的任何连接。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
。
希望能帮助到你。