はじめに
App Meshも発表されたのでService Meshちゃんと動かしておこう、って感じです。
で、App Meshではなくさくっと動かせそうなGKE(慣れてる)で、親和性も高そうなIstioを試すことにします。
Istio on GKE
Setup
Istio on GKE | Istio on GKE | Google Cloud
GKEでクラスタ作成するときのオプションでIstioをデプロイすることができます。とはいっても、Istio自体のdeployはkubectl applyでできるのでそれ自体はあんまり嬉しくないけど、自動でvupとかしてくれるみたいだ。
Istio on GKE lets you easily manage the installation and upgrade of Istio as part of the GKE cluster lifecycle, automatically upgrading your system to the most recent GKE-supported version of Istio with optimal control plane settings for most needs.
Kubernetesのバージョンは1.10.9、現在のデフォルト。これ以降じゃないとあとででてくるenvoy proxyのauto injectionができないらしい。
$ gcloud container clusters list NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS istio-on-gke asia-northeast1-a 1.10.9-gke.5 35.200.74.23 n1-standard-1 1.10.9-gke.5 5 RUNNING
$ kubectl get service -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-citadel ClusterIP 10.35.243.80 <none> 8060/TCP,9093/TCP 4d istio-egressgateway ClusterIP 10.35.250.97 <none> 80/TCP,443/TCP 4d istio-galley ClusterIP 10.35.255.181 <none> 443/TCP,9093/TCP 4d istio-ingressgateway LoadBalancer 10.35.247.113 35.200.104.141 80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:32105/TCP,8060:30651/TCP,853:30293/TCP,15030:31022/TCP,15031:31609/TCP 4d istio-pilot ClusterIP 10.35.249.186 <none> 15010/TCP,15011/TCP,8080/TCP,9093/TCP 4d istio-policy ClusterIP 10.35.254.135 <none> 9091/TCP,15004/TCP,9093/TCP 4d istio-sidecar-injector ClusterIP 10.35.255.211 <none> 443/TCP 4d istio-statsd-prom-bridge ClusterIP 10.35.253.65 <none> 9102/TCP,9125/UDP 4d istio-telemetry ClusterIP 10.35.242.127 <none> 9091/TCP,15004/TCP,9093/TCP,42422/TCP 4d prometheus ClusterIP 10.35.250.123 <none> 9090/TCP 4d
grafanaがいないのが気になりつつ、、、
Enabling sidecar injection
これが最高便利だなぁと思っていて、namespaceにこのlabelをつけると、applicationをdeployしたときに自動的にsidecar proxyが注入されます。applicationのyamlに手をいれなくていいというのがいいですね。もちろんistioctlでyamlに手を入れることもできます。
$ kubectl label namespace default istio-injection=enabled
既にbookinfoのsampleをdeploy済なんですが、podを見てみるとちゃんとsidecar proxyもいることがわかります。
$ kb describe po productpage-v1-f8c8fb8-httpw (snip) Containers: productpage: Container ID: docker://8d322f8e56735d7b02899fe79a900f7b62ea12fd3be7314c1e9fc0a8d900570f Image: istio/examples-bookinfo-productpage-v1:1.8.0 Image ID: docker-pullable://istio/examples-bookinfo-productpage-v1@sha256:ed65a39f8b3ec5a7c7973c8e0861b89465998a0617bc0d0c76ce0a97080694a9 Port: 9080/TCP Host Port: 0/TCP State: Running Started: Tue, 18 Dec 2018 19:35:20 +0900 Ready: True Restart Count: 0 Requests: cpu: 100m Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-q4s8k (ro) istio-proxy: Container ID: docker://e882a24ce250b65281b16200ddca51153d888e6e918b2e0ab8d3eefeb1f58418 Image: gcr.io/gke-release/istio/proxyv2:1.0.2-gke.0 Image ID: docker-pullable://gcr.io/gke-release/istio/proxyv2@sha256:826ef4469e4f1d4cabd0dc846f9b7de6507b54f5f0d0171430fcd3fb6f5132dc Port: <none> Host Port: <none> Args: proxy sidecar --configPath /etc/istio/proxy --binaryPath /usr/local/bin/envoy --serviceCluster productpage --drainDuration 45s --parentShutdownDuration 1m0s --discoveryAddress istio-pilot.istio-system:15007 --discoveryRefreshDelay 1s --zipkinAddress zipkin.istio-system:9411 --connectTimeout 10s --statsdUdpAddress istio-statsd-prom-bridge.istio-system:9125 --proxyAdminPort 15000 --controlPlaneAuthPolicy NONE (snip)
productpage
containerの他にistio-proxy
containerがいる。
istioctlでinjectionしたときのdiffはこんな感じ。
Enabling Stackdriver tracing and logging
Service MeshといえばObservability。デフォルトでStackDriver logingとtracingと連携できるようですね。
このyamlをapplyします。
$ kubectl apply -f stackdriver-tracing.yaml stackdriver.config.istio.io "tracing-handler" created tracespan.config.istio.io "stackdriver-span" created rule.config.istio.io "stackdriver-tracing-rule" created
stackdriver
, tracespan
, rule
というkindが追加されます。tracingの設定もyamlで定義できるのはいいですね。
loggingも同様にapplyしていきます。
stackdriver
, logentry
, rule
というkindが追加されます。
$ kubectl apply -f stackdriver-logs.yaml stackdriver.config.istio.io "log-handler" created logentry.config.istio.io "server-accesslog-stackdriver" created logentry.config.istio.io "server-tcp-accesslog-stackdriver" created rule.config.istio.io "stackdriver-log" created rule.config.istio.io "stackdriver-log-tcp" created
logging, tracingともに有効になったようです。bookinfoアプリをなんとなしリロードするとなんとなし結果が見えます。さて、Googleのドキュメントはここで終わりなので、次はIstioそのものについて見ていきます。
Istio
Istioの核となる機能であるTraffic Managementを見てみましょう。
あらたなリソースが追加されています。rule configurationを見ていきます。
There are four traffic management configuration resources in Istio: VirtualService, DestinationRule, ServiceEntry, and Gateway:
追加されたリソース
- VirtualService
defines the rules that control how requests for a service are routed within an Istio service mesh.
どのようにServiceにroutingするかの設定のようです。見てみましょう。
$ kubectl describe VirtualService bookinfo Name: bookinfo (snip) API Version: networking.istio.io/v1alpha3 Kind: VirtualService (snip) Spec: Gateways: bookinfo-gateway Hosts: * Http: Match: Uri: Exact: /productpage Uri: Exact: /login Uri: Exact: /logout Uri: Prefix: /api/v1/products Route: Destination: Host: productpage Port: Number: 9080 Events: <none>
GateWayを指定して、そのgatewayからうけたリクエストを見て、pathがmatchしたら流す先はこれ、というものみたいですね。
- DestinationRule
configures the set of policies to be applied to a request after VirtualService routing has occurred.
VirtualServiceで受けたあとDestinationへ流すためのRuleSetっぽいですね。見てみましょう。
bookinfoのapplicationにはなかったので、istio-system namespaceにあったものを見てみます。
$ kb describe DestinationRule istio-policy Name: istio-policy Namespace: istio-system Labels: addonmanager.kubernetes.io/mode=Reconcile k8s-app=istio Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"networking.istio.io/v1alpha3","kind":"DestinationRule","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"Reconci... API Version: networking.istio.io/v1alpha3 Kind: DestinationRule (snip) Spec: Host: istio-policy.istio-system.svc.cluster.local Traffic Policy: Connection Pool: Http: Http 2 Max Requests: 10000 Max Requests Per Connection: 10000 Events: <none>
trrafic policy -> connection pool -> http とほって、max requestのような設定を定義してるようですね。
- ServiceEntry
is commonly used to enable requests to services outside of an Istio service mesh.
Istioの外のサービスへのリクエストを許可するためのもの。
これはbookinfoをapplyした時点では存在しなかったのであとで解説を読むとします。
- Gateway
configures a load balancer for HTTP/TCP traffic, most commonly operating at the edge of the mesh to enable ingress traffic for an application.
applicationが一番最初にトラフィックをうけるLoad Balancerの設定。
$ kb describe gateway bookinfo-gateway (snip) Kind: Gateway (snip) Spec: Selector: Istio: ingressgateway Servers: Hosts: * Port: Name: http Number: 80 Protocol: HTTP Events: <none>
さて、ドキュメントではさらに詳細にひとつひとつのリソースについて説明されているのでそこを見ていきます。
VirtualService
- Virtual Serviceはrequestを流すdestinationを複数定義でき、weightによって割合を決めることができる
- timeoutやretryも設定できる。timeoutのdefaultは15sec
- fault injectionもできる。何%の割合で、遅延を何秒間発生させたり、httpで400を返すさせたりできる
- requestを受けるsourceをlabelで限定できる
- rule/conditionは上のものが優先して適用されます。これは重要です。
DestinationRule
- VirtualServiceのあとに適用されるrule
- maxConnectionsを100とかに設定してそれを越えたら接続を切るcircuit breakerの設定ができる
- rule適用はVirtualService、DestinationRuleのhost、subsetの順で適用されるかどうかが検討される
ServiceEntry
- 外部サービスと接続するためのentry(そのまんま)
Gateway
- Virtual Serviceと対応する、ロードバランサー
おわりに
つかれたので一旦ここで終わります。次はBookinfoを動かしたり、Traffic Management設定を実際に変えてみたりしようと思います。