istio事始め　既存のk8s clusterと何が変わるのか

>次に、Google の Alyssa から、 Envoy のセキュリティ面での強化(hardening) について発表がありました。Google では全てのトラフィックを受け持つ frontend proxy での Envoy 利用が進んでいるようで、そのために Envoy のセキュリティ面、特に攻撃に対する耐性の強化についての発表でした。こちらは個人的に興味関心がある分野で興味深く聞きました。

https://techlife.cookpad.com/entry/2018/12/18/070653

istioなにみたいなのはここでは触れない
k8s経験者がどこが変わるのかみたいな観点からとりあえず始めたい

# tl;dr

* 設定によるが基本的に全てのpodに対してenvoyがsidecarで刺さる
* istio環境下では外からくるトラフィックは必ずIngress Gatewayを通る。
* Gatewayは`VirtualService`, `DestinationRule`によって適切なpodへのルーティングを提供する
* VirtualService, DestinationRuleはk8sだけではできなかったインテリジェンスなroutingを提供する
  * Header value based routing
  * domain based routing
* VirtualServiceはingressのような機能 + envoyの設定ラッパーのような動作をする
* DestinationRuleはServiceのselector部分を抜き出したような動作をする
* 外部サイトなどのegressは明示的に指定してやらないと繋がらなくなる

# 最初に把握しておくべきこと

istio環境下において、基本的には

**cluster外からの全てのトラフィックを一度Ingress Gateway(pod)で受け取る**

一箇所で全てのトラフィックを受けたあとどのように適切なroutingを行うのかは、

istioのinstall時に提供される3つのCRD(Custom Resource Definity)によって決定される

* Gateway
* VirtualService
* DestinationRule

- - -

## kubernetes　使ったことある人向けの説明

~~~
 
Internet -->         LB(L4LB*2)           --> 　istio-ingressgateway   --> ClusterIP svc --> Sidecar Envoy --> App 
               ( k8s type:LB service)            (※1 k8s POD)              

※1 
ここでGateway, VirtualService, DestinationRuleが
うまいこと処理されて最終的な宛先が決まる。

※2 
外部からのトラフィックを受け取るのがL4LBとは限らないがistioをhelmで入れると
type: LoadBalancerで作成される

ここで言う、うまいことというのは
domain baseのrouting, HTTP headerによるrouting等、k8s nativeでは提供されていないようなrouting
~~~

ここで注意したいのは **既存のk8s ClusterIP Serviceが必要なくなるのかというとそういうわけではない** (めちゃくちゃハマった...)

`DestinationRule subset` はClusterIPは提供してくれない。 

`依然としてpodへのアクセスを提供するClusterIP serviceは必要である。`

基本的にはDestinationRuleでroutingされる可能性のある、
全てのpodに対してaccessを提供するsvcが必要なはず（要検証）

e.g.

~~~yaml

Kind: Service
...
selector:
  app: sample-app
~~~

例えば version違いの3つの同じアプリケーションsample-appが動いてるとする(違いはlabel version: n)
その場合、このserviceは `selector sample-app`しか見ていないので
round robbinで全てのversionのpodにrandomに届いてしまう、

k8s native環境では問題になるがistio環境においては、とりあえず全てのpodに飛んでも問題ない
istioが解決してくれる(おそらくenvoyの転送設定がxDSが更新される)

[公式のsample](https://github.com/istio/istio/blob/master/samples/bookinfo/platform/kube/bookinfo.yaml#L85-L156)から見てもわかるようにClusterIP serviceがv1, v2, v3全てに飛ぶようになっている

- - -

## なんでそんなめんどくさいことになってるのか?

### 答え: k8sだけではできないインテリジェンスなroutingを提供したいから

### sample manifest

ここでは一番シンプルな例　

`sample-app` deploymentはlabelが一種類しかなく必ずそこに届くようになる。

deploymentは省略

~~~yaml
apiVersion: v1
kind: Service
metadata:
  name: sample-app
  labels:
    app: sample-app
spec:
  ports:
  - port: 3000
    name: http
  selector:
    app: sample-app
~~~

~~~yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: store-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
~~~

~~~yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sample-app
spec:
  hosts:
  - "*"
  gateways:
  - store-gateway  # ↑のGateway.name と一致させること!!!
  http:
  - route:
    - destination:
        host: sample-app.default.svc.cluster.local # svc名は明示的にFullNameで書くことが推奨されています
        port:
          number: 3000
~~~

~~~yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sample-app
spec:
  host: sample-app.default.svc.cluster.local # VirtualServiceで設定したhostと同一のものを設定すること！
  subsets:
  - name: default
    labels:
      app: sample-app 

~~~

# 参考資料

オフィシャルも含め全ておすすめ！

* https://istio.io/docs/reference/config/istio.networking.v1alpha3/#Destination
* https://istio.io/docs/reference/config/istio.networking.v1alpha3/#DestinationRule
* https://www.sambaiz.net/article/185/
* https://blog.jayway.com/2018/10/22/understanding-istio-ingress-gateway-in-kubernetes/

official sample

* [基本的なmanifest(bookinfo.yamlをとりあえず見る)](https://github.com/istio/istio/blob/master/samples/bookinfo/platform/kube)
* [↑に対して応用的なroutingをしてる](https://github.com/istio/istio/tree/master/samples/bookinfo/networking)