Istio Sidecar 重试指定的状态代码 (503)

问题描述

认情况下,如果我们不定义任何 VirtualService,Istio 将生成类似于以下 Envoy 路由/重试配置的内容

{
 "cluster": "outbound|9100||quote-svc-cip.quote.svc.cluster.local","timeout": "0s","retry_policy": {
  "retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes","num_retries": 2,"retry_host_predicate": [
   {
    "name": "envoy.retry_host_predicates.prevIoUs_hosts"
   }
  ],"host_selection_retry_max_attempts": "5","retriable_status_codes": [
   503
  ]
 },"max_grpc_timeout": "0s"
}

但是如果我们指定自己的 VirtualService,例如:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
Metadata:
  name: book-svc-cip
  namespace: book
spec:
  hosts:
  - book-svc-cip.book.svc.cluster.local
  http:
  - retries:
      attempts: 3
      retryOn: connect-failure,retriable-status-codes
    route:
    - destination:
        host: book-svc-cip.book.svc.cluster.local

生成的配置将如下所示:

{
 "cluster": "outbound|9281||book-svc-cip.book.svc.cluster.local","num_retries": 3,"host_selection_retry_max_attempts": "5"
 },"max_grpc_timeout": "0s"
}

请注意缺少 retriable_status_codes

认情况下,它看起来像是在 https://github.com/istio/istio/blob/1.9.0/pilot/pkg/networking/core/v1alpha3/route/retry/retry.go#L38-L39 中定义的。但是没有选项/字段可以通过 retriable_status_codes 配置 VirtualService

我们如何在 Istio 中定义 retriable_status_codes

更新 #1:我的 Istio 版本是 1.6.9。但是如果有更新的版本可以支持的话,不胜感激。

解决方法

当前 (v1.10.2) 中没有可用于更新 retriable_status_codes 的直接 Istio 配置。

但是,我们可以通过 EnvoyFilter 来实现,例如:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: retriable-status-codes-sidecar-outbound
  namespace: istio-system
spec:
  configPatches:
  - applyTo: HTTP_ROUTE
    match:
      context: SIDECAR_OUTBOUND
    patch:
      operation: MERGE
      value:
        route:
          retry_policy:
            retriable_status_codes:
            - 503

上面将注入 retriable_status_codes 用于所有 sidecar 上的传出调用(因为我们将它放在 istio-system 命名空间中)。