Istio シリーズです。
今回は Fault Injection です。前回の VirtualService に設定を入れることでわざと 503 とか 500 エラーを返したり、delay を入れたりすることができます。
500 Internal Server Error を返す
現在の設定を確認。QueryString に v=1 があれば v1 に、それ意外は v2 に送られます。
$ kubectl get vs httpbin-virtual-service -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
...
(省略)
...
spec:
hosts:
- httpbin-service
http:
- match:
- name: v1
queryParams:
v:
exact: "1"
route:
- destination:
host: httpbin-service
subset: v1
- route:
- destination:
host: httpbin-service
subset: v2
route
のレベルに fault
を入れます。v1 のところに入れてみます。(HTTPFaultInjection.Abort)
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin-virtual-service
spec:
hosts:
- httpbin-service
http:
- match:
- name: v1
queryParams:
v:
exact: "1"
fault:
abort:
httpStatus: 500
percentage:
value: 50
route:
- destination:
host: httpbin-service
subset: v1
- route:
- destination:
host: httpbin-service
subset: v2
EOF
v1 の場合に、50% の割合で 500 Internal Server Error を返すようにしました。
root@ubuntu-deployment-cc86cc647-vsvbh:/# curl -sv http://httpbin-service/headers\?v=1
* Trying 10.109.118.31...
* TCP_NODELAY set
* Connected to httpbin-service (10.109.118.31) port 80 (#0)
> GET /headers?v=1 HTTP/1.1
> Host: httpbin-service
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< content-length: 18
< content-type: text/plain
< date: Sun, 08 Mar 2020 01:53:15 GMT
< server: envoy
<
* Connection #0 to host httpbin-service left intact
fault filter abort
curl を実行した Pod 側で istio-proxy のログを確認してみると response_flags
に FI
(Fault Injection) と入っています。また、宛先の Pod 側ではログが出ていないため、リクエストは送られていないようです。まあそうでしょう。curl 側のログも upstream の項目が空です。
{
"authority": "httpbin-service",
"bytes_received": "0",
"bytes_sent": "18",
"downstream_local_address": "10.109.118.31:80",
"downstream_remote_address": "172.17.0.9:60170",
"duration": "5",
"istio_policy_status": "-",
"method": "GET",
"path": "/headers?v=1",
"protocol": "HTTP/1.1",
"request_id": "76435924-cdea-4fdb-ae52-bc5db43946fc",
"requested_server_name": "-",
"response_code": "500",
"response_flags": "FI",
"route_name": "-",
"start_time": "2020-03-08T01:53:15.360Z",
"upstream_cluster": "-",
"upstream_host": "-",
"upstream_local_address": "-",
"upstream_service_time": "-",
"upstream_transport_failure_reason": "-",
"user_agent": "curl/7.58.0",
"x_forwarded_for": "-"
}
percentage で 50 と指定しているため全てが 500 Error になるわけではなく、リクエストの半分です。percentage の型は double で小数で 1% 未満も指定可能です。もちろんこの設定では v2 側へのアクセス時には 500 Error は返されません。本当に Upstream 側で返されれば別でしょうが。
Delay を挿入する
次に v2 側に delay を入れてみます。(HTTPFaultInjection.Delay)
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin-virtual-service
spec:
hosts:
- httpbin-service
http:
- match:
- name: v1
queryParams:
v:
exact: "1"
fault:
abort:
httpStatus: 500
percentage:
value: 50
route:
- destination:
host: httpbin-service
subset: v1
- route:
- destination:
host: httpbin-service
subset: v2
fault:
delay:
fixedDelay: 5s
percentage:
value: 50
EOF
これで v2 へリクエストを送る際に 50% の割合で5秒の delay が挿入されます。ログを確認してみます。
curl を実行している側の Pod の istio-proxy のログです。"response_flags": "DI"
となっており、Delay が挿入されていることがわかります。"start_time": "2020-03-08T02:11:04.369Z"
を宛先側のログと比較してみます。
{
"authority": "httpbin-service",
"bytes_received": "0",
"bytes_sent": "521",
"downstream_local_address": "10.109.118.31:80",
"downstream_remote_address": "172.17.0.9:47376",
"duration": "5004",
"istio_policy_status": "-",
"method": "GET",
"path": "/headers",
"protocol": "HTTP/1.1",
"request_id": "71da7efc-29a0-4e03-b23b-bfbf1638c273",
"requested_server_name": "-",
"response_code": "200",
"response_flags": "DI",
"route_name": "-",
"start_time": "2020-03-08T02:11:04.369Z",
"upstream_cluster": "outbound|80|v2|httpbin-service.default.svc.cluster.local",
"upstream_host": "172.17.0.8:80",
"upstream_local_address": "172.17.0.9:54576",
"upstream_service_time": "2",
"upstream_transport_failure_reason": "-",
"user_agent": "curl/7.58.0",
"x_forwarded_for": "-"
}
宛先側の Pod の istio-proxy のログです。"start_time": "2020-03-08T02:11:09.371Z"
と開始が5秒遅れていることが確認できます。送信元側で待ってから送っているようです。
{
"authority": "httpbin-service",
"bytes_received": "0",
"bytes_sent": "521",
"downstream_local_address": "172.17.0.8:80",
"downstream_remote_address": "172.17.0.9:54576",
"duration": "2",
"istio_policy_status": "-",
"method": "GET",
"path": "/headers",
"protocol": "HTTP/1.1",
"request_id": "71da7efc-29a0-4e03-b23b-bfbf1638c273",
"requested_server_name": "outbound_.80_.v2_.httpbin-service.default.svc.cluster.local",
"response_code": "200",
"response_flags": "-",
"route_name": "default",
"start_time": "2020-03-08T02:11:09.371Z",
"upstream_cluster": "inbound|80|http|httpbin-service.default.svc.cluster.local",
"upstream_host": "127.0.0.1:80",
"upstream_local_address": "127.0.0.1:50500",
"upstream_service_time": "1",
"upstream_transport_failure_reason": "-",
"user_agent": "curl/7.58.0",
"x_forwarded_for": "-"
}
次は OutlierDetection / 異常値検出 かな。
Istio 導入への道シリーズ
- Istio 導入への道 (1) – インストール編
- Istio 導入への道 (2) – サービス間通信編
- Istio 導入への道 (3) – VirtualService 編
- Istio 導入への道 (4) – Fault Injection 編
- Istio 導入への道 (5) – OutlierDetection と Retry 編
- Istio 導入への道 (6) – Ingress Gatway 編
- Istio 導入への道 (7) – 外部へのアクセス / ServiceEntry 編
- Istio 導入への道 (8) – 外部へのアクセスでも Fault Injection 編
- Istio 導入への道 (9) – gRPC でも Fault Injection 編
- Istio 導入への道 (10) – 図解
- Istio 導入への道 (11) – Ingress Gateway で TLS Termination 編