Istio常见问题

503 UF TLS

upstream_reset_before_response_started{connection_failure,TLS_error:_268435703:SSL_routines:OPENSSL_internal:WRONG_VERSION_NUMBER}

故障原因

默认情况下,Istio 使用 PERMISSIVE 模式配置目标工作负载。 当启用 PERMISSIVE 模式时,服务可以接受明文和双向 TLS 流量。当两边开启 istio-proxy 之后,Istio 会开启双向 TLS 流量。 检查业务部署发现添加了注解 traffic.sidecar.istio.io/includeInboundPorts: "" 入站流量不做任何拦截,导致调用方出站是 TLS 流量,但是到了被调用端没有将 TLS 卸载,直接打到了业务应用,业务应用无法识别 TLS 流量导致报错。

解决方案

关闭 TLS

可以全局关闭或者针对vs关闭

1
2
3
4
5
6
7
8
9
kubectl apply -n istio-system -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
spec:
  mtls:
    mode: DISABLE
EOF

删除注解 traffic.sidecar.istio.io/includeInboundPorts: ""

503 UC upstream_reset_before_response_started{connection_termination}

Envoy 的 HTTP Router 会在第一次和 Upstream 建立 TCP 连接并使用后将连接释放到一个连接池中,而不是直接关闭该连接。这样下次 downstream 请求相同的 Upstream host 时可以重用该连接,可以避免频繁创建/关闭连接带来的开销。

当连接被 Envoy 放入连接池后,连接中不再转发来着 downstream 数据,即连接处于空闲状态。连接对端的应用程序会检查连接的空闲状态,并在空闲期间通过 TCP keepalive packet 来侦测对端状态。由于空闲的连接也会占用资源,因此应用并不会无限制地在一个空闲连接上进行等待。几乎所有语言/框架在创建 TCP 服务器时都会设置一个 keepalive timeout 选项,如果在 keepalive timeout 的时间内没有收到新的 TCP 数据包,应用就会关闭该连接。

在应用端关闭连接后的极短时间内,Envoy 侧尚未感知到该连接的状态变化,如果此时 Envoy 收到了来着 downstream 的请求并将该连接从连接池中取出来使用,就会出现 503 UC upstream_reset_before_response_started{connection_termination} 异常。

解决方案

加大服务端 TCP keepalive timeout

增大服务器端 TCP keepalive timeout 的时间间隔可以减少该问题出现的几率。该问题在 nodejs 应用中出现得较多,原因是 nodejs 的缺省超时时间较短,只有 5 秒钟,因此在 Envoy 连接池中取出的连接有较大几率刚好被对端的 nodejs 应用关闭了。

增加重试

通过方案一可以减少 503 UC 出现的频率,但理论上无论 keepalive timeout 设置为多大,都有出现 503 UC的几率。而且我们也需要将 timeout 设置为一个合理的值,而不是无限大。要彻底解决该问题,可以采用 Virtual Service 为出现该问题的服务设置重试策略,在重试策略的 retryOn 中增加 reset 条件。

备注: Istio 缺省为服务设置了重试策略,但缺省的重试策略中并不会对连接重置这种情况进行重试。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings-route
spec:
  hosts:
  - ratings.prod.svc.cluster.local
  http:
  - route:
    - destination:
        host: ratings.prod.svc.cluster.local
        subset: v1
    retries:
      attempts: 3
      retryOn: reset,connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes

Details: socket(2) failed, got error: Too many open files

由于历史原因 docker 进程的配置的 Max open files 是1024,导致Envoy无法打开socket。 20230726110936

0%