一次不成功的 Istio 断路器尝试

Posted 伪架构师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一次不成功的 Istio 断路器尝试相关的知识,希望对你有一定的参考价值。

我认为。。这东西还是有 BUG 吧。

断路器这事情卡了我很久,总算跑通了一小部分,如果不是我学艺不精的原因,Istio 你要努力啊。

首先运行一个最新版本的 Istio 安装,目前是 0.4 版本。

  • 下载:https://github.com/istio/istio/releases

  • 安装:kubectl apply -f istio.yaml

Workload

我们使用经典的 httpbin 作为服务方,具体 yaml 可以参考附件

istioctl kube-inject -f httpbin.yaml | kubectl apply -f -

客户端服务是一个自定义镜像,其中包含一些方便使用的工具,yaml 同样的参看附件。

istioctl kube-inject -f sleep.yaml | kubectl apply -f -

注入 istio sidecar 的两个 Pod 运行起来之后,就可以尝试我们的断路器了。

缺省路由

必须有能和断路器匹配的缺省路由!

详情可以参考官方文档的Destination policy evaluation一节。

https://istio.io/docs/concepts/traffic-management/rules-configuration.html

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: route-default
spec:
  destination:
    name: httpbin
  precedence: 1
  route:
  - labels:
      app: httpbin
    weight: 100

Circuit breaker

手册:https://istio.io/docs/reference/config/traffic-rules/destination-policies.html#istio.proxy.v1.config.CircuitBreaker.SimpleCircuitBreakerPolicy

按照文档上的只言片语,拼凑一个只允许一个连接,然后就会断掉的服务规则,注意,kind 字段是DestinationPolicy

apiVersion: config.istio.io/v1alpha2
kind: DestinationPolicy
metadata:
  name: cb-sample
  namespace: default
spec:
  destination:
    name: httpbin
    labels:
      app: httpbin
  circuitBreaker:
    simpleCb:
      maxConnections: 1  # 一个连接
      httpMaxRequests: 1  # 一次请求
      httpMaxRequestsPerConnection: 1 # 每连接请求
      httpConsecutiveErrors: 1 # http 错误数限制
      sleepWindow: 15m # 根据文档,似乎是至少坚持这么久才断开
      httpDetectionInterval: 1s # 采样时间
      httpMaxEjectionPercent: 100 # 最大踢出实例数量
      httpMaxPendingRequests: 1 # 最大排队请求数量

使用kubectl apply breaker.yaml命令执行之后,可以用exec指令查询 Envoy 中的相关规则:kubectl exec  [sleep-pod-name] -it  -c sleep -- curl http://127.0.0.1:15000/clusters | grep httpbin。会看到类似下面的输出,其中的default_priority部分和我们的配置是一致的(如果没有缺省路由,就不会出现):

out.httpbin.default.svc.cluster.local|http|app=httpbin::outlier::success_rate_average::-1
out.httpbin.default.svc.cluster.local|http|app=httpbin::outlier::success_rate_ejection_threshold::-1
out.httpbin.default.svc.cluster.local|http|app=httpbin::default_priority::max_connections::1
out.httpbin.default.svc.cluster.local|http|app=httpbin::default_priority::max_pending_requests::1
out.httpbin.default.svc.cluster.local|http|app=httpbin::default_priority::max_requests::1
out.httpbin.default.svc.cluster.local|http|app=httpbin::default_priority::max_retries::3
out.httpbin.default.svc.cluster.local|http|app=httpbin::high_priority::max_connections::1024
out.httpbin.default.svc.cluster.local|http|app=httpbin::high_priority::max_pending_requests::1024
out.httpbin.default.svc.cluster.local|http|app=httpbin::high_priority::max_requests::1024
out.httpbin.default.svc.cluster.local|http|app=httpbin::high_priority::max_retries::3
out.httpbin.default.svc.cluster.local|http|app=httpbin::added_via_api::true

测试

使用 Sleep 镜像中的  Siege 进行测试:
kubectl exec  [sleep-pod] -it  -c sleep -- siege -c5 -t10S -b http://httpbin:8000

会看到其成功率极低。如果使用kubectl delete -f breaker.yaml等待规则刷新之后,重新执行测试,会重新看到 100% 的成功率。

问题

  • 目前SleepWindow,以及httpConsecutiveErrors的测试均未能成功,在 Envoy 的配置中也无法发现什么迹象。

  • 似乎没有方法可以查询负载均衡池的状态。让验证变得非常困难。

附件

sleep.yaml

kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
    version: v1
spec:
  selector:
    app: sleep
    version: v1
  ports:
    - name: ssh
      port: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: sleep
        version: v1
    spec:
      containers:
      - name: sleep
        image: dustise/sleep
        imagePullPolicy: IfNotPresent

httpbin.yaml

apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  ports:
  - name: http
    port: 8000
  selector:
    app: httpbin
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
    spec:
      containers:
      - image: citizenstig/httpbin
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 8000

以上是关于一次不成功的 Istio 断路器尝试的主要内容,如果未能解决你的问题,请参考以下文章

微服务断路器模式实现:Istio vs Hystrix

记一次不成功的redis访问

找到java selenium元素,但单击一次不起作用

Istio

云原生 | 从零开始学istio二Istio核心特性与架构

记一次不太成功的爬取dingtalk上的企业的信息