写点什么

5 个 Istio 访问外部服务流量控制最常用的例子,你知道几个?

作者:万猫学社
  • 2022 年 8 月 09 日
    北京
  • 本文字数:3686 字

    阅读完需:约 12 分钟

5个 Istio 访问外部服务流量控制最常用的例子,你知道几个?

5 个 Istio 访问外部服务的流量控制常用例子,强烈建议收藏起来,以备不时之需。

环境准备

部署 sleep 服务,作为发送请求的测试源:


kubectl apply -f samples/sleep/sleep.yaml
复制代码


在 Istio 外部,使用 Nginx 搭建 duckling 服务的 v1 和 v2 两个版本,访问时显示简单的文本:


> curl -s http://192.168.1.118/This is the v1 version of duckling.> curl -s http://192.168.1.119/This is the v2 version of duckling.
复制代码

访问外部服务

执行如下命名访问外部服务 httpbin.org :


export SLEEP_POD=$(kubectl get pods -l app=sleep -o 'jsonpath={.items[0].metadata.name}')kubectl exec "$SLEEP_POD" -c sleep -- curl -s http://httpbin.org/headers
复制代码


返回结果如下:


{  "headers": {    "Accept": "*/*",     "Host": "httpbin.org",     "User-Agent": "curl/7.81.0-DEV",     "X-Amzn-Trace-Id": "Root=1-62bbfa10-3237e3b9662c65ae005148ab",     "X-B3-Sampled": "0",     "X-B3-Spanid": "9e650093bf7ae862",     "X-B3-Traceid": "1da46d7fafa5d71c9e650093bf7ae862",     "X-Envoy-Attempt-Count": "1",     "X-Envoy-Peer-Metadata": "......",     "X-Envoy-Peer-Metadata-Id": "sidecar~......"  }}
复制代码


此时的方法,没有通过 Service Entry,没有 Istio 的流量监控和控制特性。创建 Service Entry :


kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: ServiceEntrymetadata:  name: httpbin-extspec:  hosts:  - httpbin.org  ports:  - number: 80    name: http    protocol: HTTP  resolution: DNS  location: MESH_EXTERNALEOF
复制代码


再此次访问,返回结果如下:


{  "headers": {    "Accept": "*/*",     "Host": "httpbin.org",     "User-Agent": "curl/7.81.0-DEV",     "X-Amzn-Trace-Id": "Root=1-62bbfbd6-254b05344b3cde2c0c41b3b8",     "X-B3-Sampled": "0",     "X-B3-Spanid": "307c0b106c8b262e",     "X-B3-Traceid": "f684a50776c088ac307c0b106c8b262e",     "X-Envoy-Attempt-Count": "1",     "X-Envoy-Decorator-Operation": "httpbin.org:80/*",     "X-Envoy-Peer-Metadata": "......",     "X-Envoy-Peer-Metadata-Id": "sidecar~......"  }}
复制代码


可以发现由 Istio 边车添加的请求头:X-Envoy-Decorator-Operation

设置请求超时

向外部服务 httpbin.org 的 /delay 发出请求:


export SLEEP_POD=$(kubectl get pods -l app=sleep -o 'jsonpath={.items[0].metadata.name}')kubectl exec "$SLEEP_POD" -c sleep -- time curl -o /dev/null -sS -w "%{http_code}\n" http://httpbin.org/delay/5
复制代码


返回结果如下:


200real    0m 5.69suser    0m 0.00ssys     0m 0.00s
复制代码


请求大约在 5 秒后返回 200 (OK)。


创建虚拟服务,访问外部服务 httpbin.org 时, 请求超时设置为 3 秒:


kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: httpbin-extspec:  hosts:    - httpbin.org  http:  - timeout: 3s    route:      - destination:          host: httpbin.org        weight: 100EOF
复制代码


再此次访问,返回结果如下:


504real    0m 3.01suser    0m 0.00ssys     0m 0.00s
复制代码


可以看出,在 3 秒后出现了 504 (Gateway Timeout)。 Istio 在 3 秒后切断了响应时间为 5 秒的 httpbin.org 服务。

注入 HTTP 延迟故障

向外部服务 httpbin.org 的 /get 发出请求:


export SLEEP_POD=$(kubectl get pods  -l app=sleep -o 'jsonpath={.items[0].metadata.name}')kubectl exec "$SLEEP_POD" -c sleep -- time curl -o /dev/null -sS -w "%{http_code}\n" http://httpbin.org/get
复制代码


返回结果如下:


200real  0m 0.45suser  0m 0.00ssys 0m 0.00s
复制代码


请求不到 1 秒就返回 200 (OK)。


创建虚拟服务,访问外部服务 httpbin.org 时, 注入一个 3 秒的延迟:


kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: httpbin-extspec:  hosts:    - httpbin.org  http:    - fault:        delay:          fixedDelay: 3s          percentage:            value: 100      route:        - destination:            host: httpbin.orgEOF
复制代码


再此次访问 httpbin.org 的 /get ,返回结果如下:


200real  0m 3.43suser  0m 0.00ssys 0m 0.00s
复制代码


可以看出,在 3 秒后出现了 200 (OK)。

流量转移

访问duckling服务时,所有流量都路由到 v1 版本,具体配置如下:


kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: ServiceEntrymetadata:  name: ducklingspec:  hosts:  - duckling.com  ports:  - number: 80    name: http    protocol: HTTP  location: MESH_EXTERNAL  resolution: STATIC  endpoints:  - address: 172.24.29.118    ports:      http: 80    labels:      version: v1  - address: 172.24.29.119    ports:      http: 80    labels:      version: v2---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: ducklingspec:  hosts:  - duckling.com  http:  - route:    - destination:        host: duckling.com        subset: v1---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:  name: ducklingspec:  host: duckling.com  subsets:    - labels:        version: v1      name: v1    - labels:        version: v2      name: v2EOF
复制代码


执行如下命名访问外部服务 duckling.com :


export SLEEP_POD=$(kubectl get pods -l app=sleep -o 'jsonpath={.items[0].metadata.name}')kubectl exec "$SLEEP_POD" -c sleep -- curl -s http://duckling.com/
复制代码


多次访问后,返回结果一直是:This is the v1 version of duckling.


访问duckling服务时,把 50%流量转移到 v2 版本,具体配置如下:


kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: ducklingspec:  hosts:  - duckling.com  http:  - route:    - destination:        host: duckling.com        subset: v1      weight: 50    - destination:        host: duckling.com        subset: v2      weight: 50EOF
复制代码


多次访问外部服务 duckling.com ,有时返回This is the v1 version of duckling.,有时返回This is the v2 version of duckling.


访问duckling服务时,所有流量都路由到 v2 版本,具体配置如下:


kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: ducklingspec:  hosts:  - duckling.com  http:  - route:    - destination:        host: duckling.com        subset: v2EOF
复制代码


多次访问外部服务 duckling.com ,一直返回This is the v2 version of duckling.

基于请求头的路由

请求头end-user为 OneMore 的所有流量都路由到 v2 版本,其他流量都路由到 v1 版本,具体配置如下:


kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: ServiceEntrymetadata:  name: ducklingspec:  hosts:  - duckling.com  ports:  - number: 80    name: http    protocol: HTTP  location: MESH_EXTERNAL  resolution: STATIC  endpoints:  - address: 172.24.29.118    ports:      http: 80    labels:      version: v1  - address: 172.24.29.119    ports:      http: 80    labels:      version: v2---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: ducklingspec:  hosts:  - duckling.com  http:  - match:    - headers:        end-user:          exact: OneMore    route:    - destination:        host: duckling.com        subset: v2  - route:    - destination:        host: duckling.com        subset: v1---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:  name: ducklingspec:  host: duckling.com  subsets:    - labels:        version: v1      name: v1    - labels:        version: v2      name: v2EOF
复制代码


执行如下命名访问外部服务 duckling.com :


export SLEEP_POD=$(kubectl get pods -l app=sleep -o 'jsonpath={.items[0].metadata.name}')kubectl exec "$SLEEP_POD" -c sleep -- curl -s http://duckling.com/
复制代码


多次访问的返回结果一直是:This is the v1 version of duckling.


设置请求头end-user为 OneMore,访问外部服务 duckling.com :


kubectl exec "$SLEEP_POD" -c sleep -- curl -H "end-user:OneMore" -s http://duckling.com/
复制代码


多次访问的返回结果一直是:This is the v2 version of duckling.


最后,感谢你这么帅,还给我点赞

发布于: 刚刚阅读数: 3
用户头像

万猫学社

关注

资深研发工程师 2018.04.15 加入

微信搜索「万猫学社」,关注并回复「电子书」,免费获取12本必读技术书籍。

评论

发布
暂无评论
5个 Istio 访问外部服务流量控制最常用的例子,你知道几个?_云原生_万猫学社_InfoQ写作社区