Skip to main content

Command Palette

Search for a command to run...

Istio 的频率限制

Updated
2 min read

本来这个应该是作为第三天“零散功能点”介绍的,结果目标规则部分遇到一个 bug 一直没得到修正,就拖 着了——然后后来发现自己这个想法挺无知的——零散的功能点非常多,非常大,而且文档非常弱,很难搞,只好 逐个介绍了。

简介

调用频率限制这个功能其实也是比较常见的东西了。这里就不多做介绍了。下面简单粗暴的介绍一下测试要完 成的目标。

测试中我们将使用两个服务,服务叫 workload,客户端叫 sleep,workload 服务正常返回群众喜闻乐见 的 “Hello World”,而 sleep 仅用来做 Shell 方便测试。

测试过程将为 workload 建立规则:

  • 对于任意访问,十秒钟之内仅能访问两次;
  • 对于来自 sleep 的访问,十秒钟之内仅能访问一次

下面所有内容都在 default 命名空间进行

建立测试环境

编辑 workload.yaml 以及 sleep.yaml 之后, 我们使用如下命令运行(这两部分源码,只有些乌七八糟的标签和命名有点问题,其他很普通。 见最后页)

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

kubectl get pods 确定 Pod 成功启动,也可以使用 curl 测试 NodePort,会得到 40x 的错误 页面。

建立规则

  • quota.yaml

这部分内容规则来自:https://istio.io/docs/reference/config/mixer/template/quota.html

这个对象用于设置检测服务来源、目标的标准维度,下面我们设置的是利用服务名称来检测。

这部分可能存在 bug,官方介绍的 source 定义是 source.labels["app"] | source.service | "unknown" 我的理解是说首先获取服务 Pod 的 app 标签内容,如果没有,再获取服务名称。但是后面我们会看到, 删除source.labels["app"]的定义之后,最终生效的依旧是 app 标签,这也是为什么给 workload 加上这么多奇怪标签的原因。

apiVersion: config.istio.io/v1alpha2
kind: quota
metadata:
  name: requestcount
spec:
  dimensions:
    source: source.service | "unknown"
    sourceVersion: source.labels["version"] | "unknown"
    destination:  destination.service | "unknown"
  • handler.yaml

这一对象的定义来自:https://istio.io/docs/reference/config/mixer/adapters/memquota.html

下面的代码对应我们之前的目的,任意访问都是每 10 秒钟两次,而特定源和目标的访问则是每 10 秒钟一 次。

其中 quotas 部分,name 字段的来源是上面的 quota.yaml

这个不知道是不是 bug,必须写上半个 fqdn。

dimentions 字段则需要使用 quota.yaml 定义的维度。这里的维度可以比 quota.yaml 中定义的 维度宽松(也就是少,例如定义三个,只使用其中的两个),可以理解,这也符合匹配的规则。

apiVersion: config.istio.io/v1alpha2
kind: memquota
metadata:
  name: handler
spec:
  quotas:
  - name: requestcount.quota.default
    maxAmount: 2
    validDuration: 10s
    overrides:
    - dimensions:
        destination: workload-pod.default.svc.cluster.local
        source: sleep.default.svc.cluster.local
      maxAmount: 1
      validDuration: 10s
  • rule.yaml

这部分的定义参考:https://istio.io/docs/reference/config/mixer/policy-and-telemetry-rules.html#istio.mixer.v1.config.Rule

这个对象的作用就是,对于符合筛选条件的服务调用,使用对应的 handler 进行处理。

这里的 handler 和 requestcount 两个字段的内容,也需要是实例名称.对象类型的方式。

apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: quota
spec:
  actions:
  - handler: handler.memquota
    instances:
    - requestcount.quota

测试运行

集群外

使用 curl 重复访问 NodePort 三次,会发现第三次出现:RESOURCE_EXHAUSTED:Quota is exhausted for: RequestCount#

这说明我们设置的通用规则生效了。

集群内

在 sleep pod 中同样执行 curl 三次,发现第二次就开始出现超限说明。

上面两种情况,在超过时间窗口限制之后,都会自动恢复。

幕后

定义 quota 对象,在系统中会展现为一系列的计数器,计数器的维度就是quota 中的维度的笛卡尔积。如果在 validDuration 的时间窗口过期之前调用次数超过了 maxAmount 规定,Mixer 就会返回 RESOURCE_EXHAUSTED 给 Envoy,Envoy 则会反馈 429 代码给调用方。

结论

文档不完善的开源系统。。坑真大啊!

源码

Workload 的 Deployment 和 Service:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: workload-app
    version: http200
  name: workload-200
spec:
  replicas: 1
  selector:
    matchLabels:
      app: workload-pod
      version: http200
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: workload-pod
        version: http200
    spec:
      containers:
      - image: php:7.0-apache
        imagePullPolicy: IfNotPresent
        name: http200
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
      dnsPolicy: ClusterFirst
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: workload-service
    version: http200
  name: workload-200
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30200
  selector:
    app: workload-pod
    version: http200
  sessionAffinity: None
  type: NodePort

Sleep 的定义

apiVersion: v1
kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: sleep
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: sleep
    spec:
      containers:
      - name: sleep
        image: tutum/curl
        command: ["/bin/sleep","infinity"]
        imagePullPolicy: IfNotPresent

More from this blog

龙虾恐慌:AIOps 又要改名了?

ChatGPT 开始,把 AI 拉近到普罗大众的面前,让无数人感受到 AI 的亲民魅力。而龙虾,则把大模型驱动的自动化能力,突然间变得水灵灵、活泼泼地走进千家万户。它不只是“风口上的猪”,而是风口本身。热度高到让 Mac mini 一度断货,不知道这在不在库克的预料之内。 每代人都有每代人的鸡蛋,春节期间,我就领了我的鸡蛋。翻出古老的 MacBook Air M1,充值各种大模型。当然了,这个工具

Mar 9, 20261 min read

再见 2025

我猜不少人以为这个号废了吧?并没有,只是今年变化有点大,一直有种抄起键盘,无从说起的感觉,所以一直偷懒到今天,2025 的最后一天。 今年是我的第四个本命年,去年末一期播客里,大内说本命年不是灾年,是变化年,有危也有机。可是讲真啊,只看到危,没看到机。 各种因缘际会,从鹅厂跳槽到前东家,已经接近四年,第一个合同期已经进入尾声。除了前两年还在云原生领域嗷嗷叫,后两年基本都是些鸡零狗碎的东西了,用老东家的术语说是——偏离主航道,可谓是前景暗淡了。 一旦确定要滚蛋,反倒心思轻松起来,每天骑着我的小红车...

Jan 5, 20261 min read

辅助编程?dora 说:我知道你很急可是请你别急

从 OpenGPT 把大模型的火烧旺了之后,这三年来,相信很多组织或摩拳擦掌、或躬身入局,希望借助聪明能干的大模型,或想偿还技术宅,或想降本增效,或想弯道超车。一时间,沉寂许久的 AIxx 又活过来了,LLM Ops、Vibe Coding、中医大模型、GPT 算命等等,全都老树发新芽,焕发了勃勃生机。那么视角拉回从业者最关注的饭碗相关的领域之一——AI 辅助开发,产生了什么触动,应该如何拥抱呢? DORA 的年度报告中给出了很有意思的结论——强者恒强。 执行摘要部分总结了几个有趣的点: 问题...

Oct 6, 20251 min read

[译]dora:ai 辅助软件开发状态报告

执行摘要 在 2025 年,科技领导者面临的核心问题已不再是“是否要采用 AI”,而是“如何实现其价值”。 DORA 的研究基于超过 100 小时的定性访谈和来自全球近 5,000 名技术专业人士的问卷调查。研究揭示了一个关键事实:AI 在软件开发中的主要角色是“放大器”。它会放大高效能组织的优势,也会凸显组织的缺陷。 关键结论:AI 是放大器 AI 投资的最大回报并非来自工具本身,而是来自组织底层系统的战略性建设: 高质量的内部平台 清晰的工作流 团队的协同能力 缺少这些基础,AI ...

Oct 2, 202514 min read

僭越了,有人在用 Rust 写 Kubernetes

一个新语言问世,最爱做的事情之一,就是重写存量软件了。 云原生喝酒 SIG 重点扶持项目——rk8s(https://github.com/rk8s-dev/rk8s) 也可以归在这个范畴里,只不过这个项目重写的东西比较大,是 Kubernetes。 从 2025 年 1 月第一个 Commit 开始,到现在有了 200 多次 Commit,十几万行代码。当然距离 Kubernetes 的几百万行代码还差得远——老马就是喜欢整这种大无畏项目。 另外该项目也是国内第一个脱离 Cargo 转向使用 ...

Sep 27, 20253 min read

【伪】架构师

342 posts