LoginSignup
56
30

More than 5 years have passed since last update.

Istio IngressGateway周辺を理解する

Posted at

はじめに

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!!

56
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
56
30