【问题标题】:EnvoyProxy Rate Limit Not Working in Istio 1.7EnvoyProxy 速率限制在 Istio 1.7 中不起作用
【发布时间】:2020-09-08 17:48:16
【问题描述】:

通过应用以下脚本,我无法看到在 istio 1.7 中应用的速率限制。

---
apiVersion: v1
kind: Namespace
metadata:
  name: sock-shop
  labels:
    istio-injection: enabled
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: filter-ratelimit
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: "envoy.http_connection_manager"
              subFilter:
                name: "envoy.router"
      patch:
        operation: INSERT_BEFORE
        value:
         name: envoy.rate_limit
         config:
           domain: sock-shop-ratelimit
           rate_limit_service:
             grpc_service:
               envoy_grpc:
                 cluster_name: rate_limit_service
               timeout: 0.25s
    - applyTo: CLUSTER
      match:
        cluster:
          service: ratelimit.rate-limit.svc.cluster.local
      patch:
        operation: ADD
        value:
          name: rate_limit_service
          type: STRICT_DNS
          connect_timeout: 0.25s
          lb_policy: ROUND_ROBIN
          http2_protocol_options: {}
          hosts:
            - socket_address:
                address: ratelimit.rate-limit.svc.cluster.local
                port_value: 8081
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: filter-ratelimit-svc
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
    - applyTo: VIRTUAL_HOST
      match:
        context: GATEWAY
        routeConfiguration:
          vhost:
            name: "*:80"
            route:
              action: ANY
      patch:
        operation: MERGE
        value:
          # rate limit service descriptors config relays on the order of the request headers (desriptor_key)
          rate_limits:
            - actions:
                - request_headers:
                    header_name: "x-plan"
                    descriptor_key: "plan"               
                - request_headers:
                    header_name: "x-account"
                    descriptor_key: "account" 
apiVersion: v1
kind: Namespace
metadata:
  name: rate-limit
  labels:
    istio-injection: enabled
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: rate-limit
  labels:
    app: redis
spec:
  ports:
  - name: redis
    port: 6379
  selector:
    app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: rate-limit
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - image: redis:alpine
        imagePullPolicy: Always
        name: redis
        ports:
        - name: redis
          containerPort: 6379
      restartPolicy: Always
      serviceAccountName: ""
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: ratelimit-config
  namespace: rate-limit
data:
  # check this example: https://github.com/envoyproxy/ratelimit#example-4
  config.yaml: |
    domain: sock-shop-ratelimit
    descriptors:
      - key: plan
        value: BASIC
        descriptors:
          - key: account
            rate_limit:
              unit: minute
              requests_per_unit: 1
      - key: plan
        value: PLUS
        descriptors:
          - key: account
            rate_limit:
              unit: minute
              requests_per_unit: 2
---
apiVersion: v1
kind: Service
metadata:
  name: ratelimit
  namespace: rate-limit
  labels:
    app: ratelimit
spec:
  ports:
  - name: "8080"
    port: 8080
    targetPort: 8080
    protocol: TCP
  - name: "8081"
    port: 8081
    targetPort: 8081
    protocol: TCP
  - name: "6070"
    port: 6070
    targetPort: 6070
    protocol: TCP
  selector:
    app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ratelimit
  namespace: rate-limit
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ratelimit
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: ratelimit
    spec:
      containers:
      - image: envoyproxy/ratelimit:v1.4.0
        imagePullPolicy: Always
        name: ratelimit
        command: ["/bin/ratelimit"]
        env:
        - name: LOG_LEVEL
          value: debug
        - name: REDIS_SOCKET_TYPE
          value: tcp
        - name: REDIS_URL
          value: redis:6379
        - name: USE_STATSD
          value: "false"
        - name: RUNTIME_ROOT
          value: /data
        - name: RUNTIME_SUBDIRECTORY
          value: ratelimit
        ports:
        - containerPort: 8080
        - containerPort: 8081
        - containerPort: 6070
        volumeMounts:
        - name: config-volume
          mountPath: /data/ratelimit/config/config.yaml
          subPath: config.yaml
      volumes:
        - name: config-volume
          configMap:
            name: ratelimit-config
---

除此之外,我还部署了 istio bookinfo 示例应用程序

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

配置到此应用的 istio 入口网关路由

kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

当我通过应用相关的速率限制标头通过入口网关访问应用程序时

    curl -I "http://"$GATEWAY_URL/productpage" --header 'x-plan: BASIC' --header 'x-account: user'

它一直给我 200 OK 响应,不管我应用它多少次,尽管应用的限制是每分钟 2 个请求。

此外,当我尝试在 redis 中查看数据时,我看不到那里的数据。

export REDIS_POD=$(kubectl get pod -n rate-limit | grep redis | awk '{ print $1 }')

kubectl -n rate-limit exec -it $REDIS_POD -c redis /bin/sh

redis-cli

keys *

任何人的帮助将不胜感激。

【问题讨论】:

  • 首先要检查的是 istio 如何设置“failure_mode_deny”?默认情况下,Envoy 将此设置为“false”,这意味着连接到速率限制器服务失败不会拒绝请求。检查此设置的第一步是将其设置为 true: (envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/…) 并查看是否被拒绝。这将告诉您您的配置正在尝试访问该服务,但没有得到响应。

标签: redis istio rate-limiting envoyproxy


【解决方案1】:

你的网关设置是什么?

您需要添加与网关中使用的完全相同的 fqdn:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: example-gateway
  namespace: example
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - example.com
    port:
      name: http
      number: 80
      protocol: HTTP
    tls:
      httpsRedirect: true

所以在这种情况下,虚拟主机应该是:

 configPatches:
    - applyTo: VIRTUAL_HOST
      match:
        context: GATEWAY
        routeConfiguration:
          vhost:
            name: "example.com:80"
            route:
              action: ANY

【讨论】:

  • 不知道为什么,但在 istio 1.7 中仍然无法使用我切换到 isito 1.6.2 并且它可以无缝运行而没有任何更改
【解决方案2】:

切换到 istio 1.6.2 为我工作,脚本没有任何变化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 2019-06-18
    相关资源
    最近更新 更多