添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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

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

创建 frontend-v2

为了展示路由分配的能力,我们首先创建一个名为 frontend-v2 Deployment ,这个 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
        - 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}
      curl -s svc-frontend/index.php | grep Version
    

    执行效果:

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

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

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

    前面提到,我们生成了一个delay.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:
            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