Posted at

Istio IngressGateway周辺を理解する


はじめに

Istioでどのようにトラフィックを制御しているのかについて、公式チュートリアルをローカル環境で実験した際に学んだ事のメモ。

■公式チュートリアル

https://istio.io/docs/examples/bookinfo/


前提

Kubernetes上にデプロイするのは、BookInfoというサンプルアプリケーションで構成は以下の通り。

image.png

EnvoyプロキシをPodにインジェクトすると下図のように、各PodにEnvoyがサイドカーとして内包され、全トラフィックをEnvoy経由でやり取りする事でサービスメッシュを構築する。

image.png


Istio IngressGateway周りの流れ

image.png

1. クラスタ外部からトラフィックが来る

2. トラフィックをロードバランサーが受ける

3. ロードバランサーが転送するポートで待ち受けてるIstio-IngressGateway Serviceにルーティングされる

4. Istio-IngressGateway Serviceは、リクエストをIstio-IngressGateway Podに転送

5. VirtualServiceリソースの設定を元に、Istio-IngressGateway PodはリクエストをアプリケーションのServiceへ送る

のような流れだと思われる:cat2:

■下記参考

https://blog.jayway.com/2018/10/22/understanding-istio-ingress-gateway-in-kubernetes/


IngressGateway

Istioをセットアップすると、serviceリソースとしてnamespace=istio-systemistio-ingressgatewayがクラスタ内にセットアップされる。

$ kubectl get service istio-ingressgateway -n istio-system

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.99.217.20 localhost 15020:31305/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:32722/TCP,15030:30551/TCP,15031:30212/TCP,15032:31148/TCP,15443:32476/TCP 4h

上記ServiceからIstio-IngressGateway Podにリクエストを転送し、後述のVirtualServiceの設定を元にトラフィックを制御している。

$ kubectl get pod istio-ingressgateway-5966c86d4-sb9cb -n istio-system

NAME READY STATUS RESTARTS AGE
istio-ingressgateway-5966c86d4-sb9cb 1/1 Running


Gateway

Kubernetesクラスタの外部からトラフィックを受け付けるために、サービスメッシュの境界に存在するistio-ingessgatewayの設定を行うためのリソース

下記は80番ポートでHTTPリクエストを待ち受ける設定。

Gatewayリソースはトラフィックを受ける設定をするだけで、どこにどうやって流すかはVirtualServiceリソースが担当する。


bookinfo-gateway.yaml

apiVersion: networking.istio.io/v1alpha3

kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"

hostsは「*」で全てを受け入れるように設定されているが、例えば下記のように設定すると、dev.example.comやprod.example.comを持つVirtualServiceが該当する事になる。

hosts:

- "*.example.com"

参考:Istio-Gateway


VirtualService

istio-ingressgatewayで受けたトラフィックをどこにどうやって流すかのルールを設定するためのリソース

後述のDestinationRuleリソースで定義するsubsetsと合わせる事でトラフィック分割を実現する事が可能。

尚、subsetsを定義しなくても異なるサービスにトラフィックを分割することも可能な模様(実験してないけど)

※参考:Istio-HTTPRouteDestination


bookinfo-gateway.yaml

apiVersion: networking.istio.io/v1alpha3

kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080

参考:Istio-VirtualService


トラフィック分割の例

■DestinationRule

DestinationRuleリソースは、トラフィックに適応されるポリシーを定義する。

reviewsという名前のServiceに3つのバージョンが存在し、それぞれv1v2v3というLabelで識別可能である事を設定している。

Service = reviews配下のPodはversionラベルを持っており、それぞれv1〜v3まで設定されている状態⬇️こんな感じ

image.png


DestinationRule-sample.yaml

apiVersion: networking.istio.io/v1alpha3

kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3

■VirtualService

DestinationRuleで設定したバージョンに対して、それぞれv1に5%、v2に5%、v3に90%の割合でトラフィック分散させるようにVirtualServiceリソースで設定している例。


VirtualService-sample.yaml

apiVersion: networking.istio.io/v1alpha3

kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 5
- destination:
host: reviews
subset: v2
weight: 5
- destination:
host: reviews
subset: v3
weight: 90

destination.host(string) = Service名を指定

destination.subset(string) = DestinationRuleで定義されたsubset名を指定

参考:Istio/VirtualService

実行してみると、確かにほぼv3が反映されるようになった(Book Reviews部分)

image.png


ハマった事

DestinationRuleリソースに相互TLSの設定(trafficPolicy)を何も記述していなかった(Default=DISABLE)のだが、DestinationRuleをApplyした瞬間にupstream connect error or disconnect/reset before headersと言われて一瞬詰んだ・・・†

下記を参考に相互TLSについて把握し、trafficPolicy.tls.modeを設定。

参考:TLSSettings.TLSmode

参考:503 errors after setting destination rule


所感

Istio初心者ですがチュートリアルを進める事で、Istio IngressGateway周りでどんな挙動をしているのか、雰囲気理解する事ができた気がします。

まだ試せていないの機能だらけなので、実際に動かしてIstioに対する理解を深めると共に、次は自分のアプリケーションをKubernetesにデプロイしてIstioを適応してみようと思いましたまる

docker< Fight!!