Skip to main content

Command Palette

Search for a command to run...

istio 三日谈之二 路由规则

Updated
3 min read

路由控制是 istio 的最常用功能了,经过前面的准备,我们已经基本可以进行这些内容的尝试了。

注意下面的路由规则都忽略了对来源的过滤,会显得比较呆板或者说没用,但是在加入过滤条件之后,就完全不可同日而语了。具体的过滤规则的写法可以参考官方文档或者 istio 中的 bookinfo 实例。

创建 frontend-v2

为了展示路由分配的能力,我们首先创建一个名为frontend-v2Deployment,这个deploy跟之前的 v1 共享同一个 PVC,也就是共享同一套页面。利用环境变量来控制输出。

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: frontend-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: frontend
        version: "2"
    spec:
      containers:
      - name: php
        image: 10.211.55.86:5000/php:7.1.7-apache
        ports:
        - containerPort: 80
          protocol: TCP
        volumeMounts:
        - name: wwwroot
          mountPath: /var/www/html
        env:
        - name: "SERVICE_VERSION"
          value: "2"
      volumes:
      - name: wwwroot
        persistentVolumeClaim:
          claimName: frontend-v1

同前面的 v1 一样,这个Deployment也需要使用istioctl kube-inject进行注入,最后使用kubectl apply -f 运行。

流量分配

首先创建如下路由规则

default.yaml

type: route-rule
name: frontend-default
spec:
  destination: svc-frontend.default.svc.cluster.local
  precedence: 1
  route:
  - tags:
      version: "2"
    weight: 100
  • destination:必须是服务的 fqdn

  • precedence:整数,优先级,越大越先

  • route:数组

    • tag:Pod 的标签选择器。

    • weigh: 整数,权重,分配到当前路由的比率。

创建之后,使用istioctl create -f default.yaml,创建这一规则。接下来我们使用kubectl exec -it进入 tool pod 进行测试:

$ curl svc-frontend/index.php

-----------------------------
From: frontend-797054967-r12m5
Version: 1

返回内容表明这一服务调用的是最初的 v1 版本的 frontend。

接下来修改 default.yaml 的version "1"version "2",然后用istioctl replace -f default.yaml更新路由规则。再次验证:

$ curl svc-frontend/index.php

-----------------------------
From: frontend-v2-90739004-xpmrn
Version: 2

这里可以看到,这一响应来自于 v2 版本的 Pod,并且返回的版本号也是 2。

然后我们再次修改路由规则,测试一下路由分配:

type: route-rule
name: frontend-default
spec:
  destination: svc-frontend.default.svc.cluster.local
  precedence: 1
  route:
  - tags:
      version: "2"
    weight: 10
  - tags:
      version: "1"
    weight: 90

根据上面的路由规则,对 svc-frontend 这一服务的访问,应该有 10% 流量分给版本 2,其余的 90% 分配给了版本 1。我们在 tool pod 中使用如下脚本测试这一分配:

#!/bin/bash
for i in {1..100}
do
  curl -s svc-frontend/index.php | grep Version
done

执行效果:

$  ./curl.batch.sh  | grep 2 | wc -l
10

可以看到,完全符合之前我们的路由设置。

超时策略

为了保障服务质量,我们有时会要求对某些服务的返回时间进行限制

前面提到,我们生成了一个delay.php,用于进行延时测试,文件内容如下:

<?php
header("Content-type: text/plain");
sleep(4);
echo "\n-----------------------------\n";
echo "\nFrom: ".gethostname()."\n";
echo "Version: ".$_ENV['SERVICE_VERSION']."\n";

正常执行time curl -s svc-frontend/delay.php,会返回如下结果:

-----------------------------
From: frontend-797054967-r12m5
Version: 1

real    0m4.025s
user    0m0.005s
sys     0m0.004s

我们在这里加入一个策略,两秒超时:

type: route-rule
name: front-timeout
spec:
  destination: svc-frontend.default.svc.cluster.local
  precedence: 9
  route:
  - tags:
      version: "1"
  httpReqTimeout:
    simpleTimeout:
      timeout: 2s

再次测试,则会返回超时的结果:

upstream request timeout
real    0m2.015s
user    0m0.006s
sys     0m0.003s

重试策略

在服务超时的时候,我们可能会希望请求自动重试。

这一测试要求保留前面的超时策略,以便形成失败结果:

策略文件如下:

type: route-rule
name: front-timeout
spec:
  destination: svc-frontend.default.svc.cluster.local
  precedence: 9
  route:
  - tags:
      version: "1"
  httpReqRetries:
    simpleRetry:
      attempts: 3
      perTryTimeout: 2s

这里表示每次尝试的超时时间是两秒,重试三次。使用 curl 测试:

$ time curl -s svc-frontend/delay.php
upstream request timeout
real    0m8.136s
user    0m0.005s
sys     0m0.006s

时间为 8 秒,相当于四次超时的时间。

Rewrite

和反向代理的情况类似,有时我们需要对进入服务的 URL 进行重写,下面的路由策略会将 /front 替换为 / 进行访问:

type: route-rule
name: front-timeout
spec:
  destination: svc-frontend.default.svc.cluster.local
  precedence: 9
  match:
    httpHeaders:
      uri:
        prefix: "/front/"
  rewrite:
    uri: "/"
  route:
  - tags:
      version: "1"

注意这里对uri的操作,是使用 rewrite 中的 uri 替换 match 中的 uri,二者的对应关系是强制的。

在 tool 里面进行测试访问:

$ curl http://svc-frontend/front/index.php
-----------------------------

From: frontend-797054967-r12m5
Version: 1

故障注入

微服务测试过程中,能够自动生成一些错误,无疑是个很有帮助的事情。目前 istio 支持两种故障的模拟:时延和中断

时延

下面的规则会为每个对该服务的请求都生成 7 秒的时延:

type: route-rule
name: fdelay
spec:
  destination: svc-frontend.default.svc.cluster.local
  precedence: 9
  route:
  - tags:
      version: "1"
  httpFault:
    delay:
      percent: 100
      fixedDelay: 7s
  • percent: 产生时延的比例

  • fixedDelay: 时间

使用 curl 验证,可以看到的确多出了 7 秒的处理时间。

$ time curl -s http://svc-frontend/index.php
-----------------------------

From: frontend-797054967-r12m5
Version: 1

real    0m7.028s
user    0m0.007s
sys     0m0.003s

中断

这一功能可以模拟服务中断的情景,下面的 yaml 定义了该服务 100% 会返回 403 错误。

type: route-rule
name: fdelay
spec:
  destination: svc-frontend.default.svc.cluster.local
  precedence: 9
  route:
  - tags:
      version: "1"
  httpFault:
    abort:
      percent: 100
      httpStatus: 403

curl 的验证结果如下:

$  curl -v svc-frontend/error.php
* Connected to svc-frontend (10.100.186.68) port 80 (#0)
> GET /error.php HTTP/1.1
> User-Agent: curl/7.38.0
> Host: svc-frontend
> Accept: */*
>
< HTTP/1.1 403 Forbidden
< date: Fri, 28 Jul 2017 01:27:52 GMT
* Server envoy is not blacklisted
< server: envoy
< content-length: 0
<
* Connection #0 to host svc-frontend left intact

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