IstioのVirtualServiceの動きをyamlから読み解く

全然理解できなかったVirtualServiceがどのように動いてくれるのか、自分が理解した範囲で書いておきます。
## VirtualServiceのyaml
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local
  http:
  - name: "reviews-v2-routes"
    match:
    - uri:
        prefix: "/wpcatalog"
    - uri:
        prefix: "/consumercatalog"
    rewrite:
      uri: "/newcatalog"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v2
  - name: "reviews-v1-route"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v1
```
Istio1.5の公式からそのままコピペしたものですね。
一行ずつ自分の解釈を書いていきます。

### apiVersion:

```yaml
apiVersion: networking.istio.io/v1alpha3
```
「istioのAPIを叩きますよ」という宣言。
そうえいばIstio1.5になってからMixerやGalleyやPilotなどバラバラだったPodは全て`Istiod`に統合されました。
これはIstioのリリースノートにも書いてあるのでバージョンアップしたら読んだほうがいいですね。

### kind:
```yaml
kind: VirtualService
```
これで「IstioのVirtualServiceとして設定するよ」と宣言します。


### metadata:
```yaml
metadata:
  name: reviews-route
```
もう既に一行じゃないですね。すみません。
VirtualServiceを`reviews-route`という名前で作ります。
ここで指定する名前は他のserviceなどと一緒になっていても問題無いようです。
`kubectl get virtualservice` を実行すると出力される名前になります。
nameの他に`namespace:hogehoge`で`hogehoge`というNameSpaceに適用することが可能です。

### hosts:
```yaml
spec:
  hosts:
  - reviews.prod.svc.cluster.local
```
出ました。
ここでは、`トラフィックの宛先がどこなのか`を指定します。
言い換えればVirtualSerivceさんがどこ宛のトラフィックを見るか。です。

上記の例では`reviews.prod.svc.cluster.local`でよくわからんです状態になりますが、
この書き方は簡単に言うとフルパスみたいな物で、`prod`というNamespaceの
`reviews`というServiceを表しています。Serviceは`kubectl get svc`で表示されるServiceです。
`Service名.Namespace名.svc.cluster.local`とすることで明示的に書いているんですね。
おそらく、複数のNamespaceに同じような構成を作った時に
誤った設定をしないようにこういう書き方ができるんだと思います。

「もっと簡単に書きたい！まともに使っているNamespaceは一個だ！」
そういう場合は以下のように書けるようです。

```yaml
spec:
  hosts:
  - reviews
```
この場合はVirtualServiceを適用するNamespace内に
`reviews`というSerivceが存在することが条件です。

動作について既にご存知の方もいらっしゃるかと思いますが、
基本的にVirtualServiceはServiceに向かって流れていくトラフィックを
横から掴んで自分のルールに従ってルーティングしてくれるんですね。

回転寿司でタッチパネルから注文すると自動で自分のところに向かってくるシステムがあるじゃないですか。
それで例えれば、Aさんが注文をした時に、本来ならAさんに届くはずのお寿司を、
勝手に横取りして自分の隣の人に渡してあげるんです。

ここのAさんがKubernetesのServiceとして、横取りするのがVirtualService。
隣の人がルーティング先。ということになります。
ルールの書き方によっては、Aさん宛のお寿司をVirtualServiceが横取りして、結局Aさんに届ける。みたいなのもできます。

### match:
```yaml
  - name: "reviews-v2-routes"
    match:
    - uri:
        prefix: "/wpcatalog"
    - uri:
        prefix: "/consumercatalog"
```
ああもう完全に一行解説じゃなくなってしまいました。

ここで定義しているのは「何が来たら横取りするか」です。
`match:`はそのままの意味で、「横取りする条件を以下に書きますよ」という宣言。
その後につらつらと条件を書いてあげます。
`prefix:`として指定すると、アクセス先が`/wpcatalog`だったら。という条件になります。

### rewrite:
```yaml
    rewrite:
      uri: "/newcatalog"
```
これは上記の`prefix:`にマッチしたトラフィックの宛先を`/newcatalog`という名前で上書き(rewrite)しちゃいます。
回転寿司でAさんが注文し、そこに向かっていくお寿司の新幹線をリモコンで操作し、
Bさんのところに届けるような感じですね。
悪質極まりない。
### destination:
```yaml
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v2
```
やっと`destination`まで来ました。
ここの`host:`でトラフィックの宛先を指定します。
先程のお寿司横取り事件で、VirtualServiceさんが隣の人に渡した時の、その「隣の人」をここで指定してあげます。
ここも`hosts:`と同じような書き方ができて、
`prod`というNamespaceにある`reviews`というServiceを宛先にしています。
VirtualServiceと宛先のServiceが同じNamespaceであれば`host: reviews`と書くことができます。

## ここまでで簡単におさらいしておきます。
```yaml
spec:
  hosts:
  - reviews.prod.svc.cluster.local
  http:
  - name: "reviews-v2-routes"
    match:
    - uri:
        prefix: "/wpcatalog"
    - uri:
        prefix: "/consumercatalog"
    rewrite:
      uri: "/newcatalog"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v2
```
Namespace`prod`にある`reviews`というServiceに対し、
`/wpcatalog`と`/consumercatalog`それぞれが先頭に付いたアドレスでアクセスがあったら
`/newcatalog`というアドレスに置き換えて、Namespace`prod`の`reviews`というServiceの
`v2`とラベリングされたサブセットにアクセスさせる。
と言い換えることができます。

`subset:`はごめんなさい。これから調べます。
DestinationRuleで頻繁に使われるようなのであとで調べます。

## あれ？残りの定義は？
```yaml
  - name: "reviews-v1-route"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v1
```
上記のいずれかにマッチしなかったらここにルーティングされます。（と思います）

## VirtualServiceって分かってくるとそんなに複雑じゃない

Kubernetes自体がもう新しい言葉ばかりで頭おかしくなると思います。
実際私も頭おかしくなってます。
でもこうして一つずつ紐解いて行ければきっとKubernetesさん（Istioさん）と仲良くなれる気がします。

もし上記内容に間違いがありましたら、修正リクエストお気軽に！私も勉強中の身です！