ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

Try "Istio on GKE"(1)公式ドキュメント編

はじめに

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はこんな感じ。

gist.github.com

Enabling Stackdriver tracing and logging

Service MeshといえばObservability。デフォルトでStackDriver logingとtracingと連携できるようですね。

https://storage.googleapis.com/gke-release/istio/release/1.0.3-gke.0/stackdriver/stackdriver-tracing.yaml

この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していきます。

https://storage.googleapis.com/gke-release/istio/release/1.0.3-gke.0/stackdriver/stackdriver-logs.yaml

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を見てみましょう。

Istio / Traffic Management

あらたなリソースが追加されています。rule configurationを見ていきます。

Istio / Traffic Management

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

おわりに

つかれたので一旦ここで終わります。次はBookinfoを動かしたり、Traffic Management設定を実際に変えてみたりしようと思います。

参考