次に、Google の Alyssa から、 Envoy のセキュリティ面での強化(hardening) について発表がありました。Google では全てのトラフィックを受け持つ frontend proxy での Envoy 利用が進んでいるようで、そのために Envoy のセキュリティ面、特に攻撃に対する耐性の強化についての発表でした。こちらは個人的に興味関心がある分野で興味深く聞きました。
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.
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から見てもわかるようにClusterIP serviceがv1, v2, v3全てに飛ぶようになっている
なんでそんなめんどくさいことになってるのか?
答え: k8sだけではできないインテリジェンスなroutingを提供したいから
sample manifest
ここでは一番シンプルな例
sample-app
deploymentはlabelが一種類しかなく必ずそこに届くようになる。
deploymentは省略
apiVersion: v1
kind: Service
metadata:
name: sample-app
labels:
app: sample-app
spec:
ports:
- port: 3000
name: http
selector:
app: sample-app
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:
- "*"
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
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