如何在 Istio 中制作断路器?

How to make a circuit-breaker in Istio?

我正在尝试在 Istio 中配置断路器。这是yaml。

trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
      tcp:
        maxConnections: 1
    outlierDetection:
      baseEjectionTime: 1m
      consecutive5xxErrors: 1
      interval: 1s

我在 JMeter 中有一个线程组列表,这些线程组将不断命中与上述断路器关联的服务。收到错误响应后,它应该使服务不可用 1 分钟。但是,这并没有发生。

我是不是误解了它的工作原理?有什么办法可以实现吗?

根据您提供的信息,我认为问题可能是您的 DestiationRule 中未设置参数 maxEjectionPercent:

maxEjectionPercent - Maximum % of hosts in the load balancing pool for the upstream service that can be ejected. Defaults to 10%.

由于它默认为 10%,这意味着只有 10% 的部署会被断路器弹出。出于测试目的,您可以尝试将其设置为 100%,类似于 documentiation to demonstrate this:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 1s
      baseEjectionTime: 3m
      maxEjectionPercent: 100 

我已经测试了文档中的示例,它对我来说工作正常。

另一个可能的问题可能是 sidecar 注入。请验证您的 pod 是否确实有一个(您应该看到 pod 内准备好了 2 个容器中的 2 个):

 ~  kgp                                                                                                                                    ✔  cluster-1 ⎈
NAME                             READY   STATUS    RESTARTS   AGE
fortio-deploy-576dbdfbc4-9crcf   2/2     Running   0          46m
httpbin-74fb669cc6-mg9rh         2/2     Running   0          48m

我认为您混淆了 outlier detectioncircuit breaker based on connectionPool settings

您在 connectionPool 中应用的设置将配置一个断路器,如果违反任何限制,则电路将被触发,新请求将从 istio 代理获得即时 503 响应。因为在新的请求中不会被发送到应用程序。 但是,代理将尽快接受新请求(当接受新请求不违反限制时)。 在这个上下文中没有熔断1分钟的事情。

异常值检测不同。这通过从负载平衡池中触发特定的容易出错的 POD 来实现。 假设您的部署有 4 个副本 pods 运行。假设 PODs 之一给出 5xx 错误(The 503 errors sent by proxy, like in the connection pool breach case, are not counted here. 此计数是您的应用程序错误)。在这种情况下,istio 将等待 consecutive5xxErrors(在您的情况下为 1),一旦违反,它将首次从 baseEjectionTime 的负载平衡中删除该 pod。 也就是说,它将等待 baseEjectionTime (在您的情况下为 1m)。到那时,不会向容易出错的 POD 发送新请求。 1 分钟后,它会再次将 POD 添加到负载平衡池中。但是,如果此 POD 再次违反连续 5xxErrors(在您的情况下为 1),那么 istio 会将其从负载平衡中删除 2xbaseEjectionTime,在您的情况下为 2 分钟。 这将继续进行,直到您的 POD 返回非 5XX 错误。