当前位置:网站首页>5个 Istio 访问外部服务流量控制最常用的例子,你知道几个?

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

2022-08-09 21:43:00 InfoQ

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 - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
 name: httpbin-ext
spec:
 hosts:
 - httpbin.org
 ports:
 - number: 80
 name: http
 protocol: HTTP
 resolution: DNS
 location: MESH_EXTERNAL
EOF

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

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

可以发现由 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 &quot;$SLEEP_POD&quot; -c sleep -- time curl -o /dev/null -sS -w &quot;%{http_code}\n&quot; http://httpbin.org/delay/5

返回结果如下:

200
real 0m 5.69s
user 0m 0.00s
sys 0m 0.00s

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

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

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: httpbin-ext
spec:
 hosts:
 - httpbin.org
 http:
 - timeout: 3s
 route:
 - destination:
 host: httpbin.org
 weight: 100
EOF

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

504
real 0m 3.01s
user 0m 0.00s
sys 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 &quot;$SLEEP_POD&quot; -c sleep -- time curl -o /dev/null -sS -w &quot;%{http_code}\n&quot; http://httpbin.org/get

返回结果如下:

200
real 0m 0.45s
user 0m 0.00s
sys 0m 0.00s

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

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

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: httpbin-ext
spec:
 hosts:
 - httpbin.org
 http:
 - fault:
 delay:
 fixedDelay: 3s
 percentage:
 value: 100
 route:
 - destination:
 host: httpbin.org
EOF

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

200
real 0m 3.43s
user 0m 0.00s
sys 0m 0.00s

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

流量转移

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

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
 name: duckling
spec:
 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/v1alpha3
kind: VirtualService
metadata:
 name: duckling
spec:
 hosts:
 - duckling.com
 http:
 - route:
 - destination:
 host: duckling.com
 subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: duckling
spec:
 host: duckling.com
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
EOF

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

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

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

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

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: duckling
spec:
 hosts:
 - duckling.com
 http:
 - route:
 - destination:
 host: duckling.com
 subset: v1
 weight: 50
 - destination:
 host: duckling.com
 subset: v2
 weight: 50
EOF

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

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

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: duckling
spec:
 hosts:
 - duckling.com
 http:
 - route:
 - destination:
 host: duckling.com
 subset: v2
EOF

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

基于请求头的路由

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

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
 name: duckling
spec:
 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/v1alpha3
kind: VirtualService
metadata:
 name: duckling
spec:
 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/v1alpha3
kind: DestinationRule
metadata:
 name: duckling
spec:
 host: duckling.com
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
EOF

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

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

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

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

kubectl exec &quot;$SLEEP_POD&quot; -c sleep -- curl -H &quot;end-user:OneMore&quot; -s http://duckling.com/
多次访问的返回结果一直是:
This is the v2 version of duckling.

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

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/649c916ad2708def9d41d1dca