モチベーション
GKE上のマイクロサービスのアプリケーションにおいて、Red/Black deploymentや release canariesを実現し、分散トレーシングによるマイクロサービスの複雑な通信環境におけるレイテンシの問題を特定したい。
istioとZipkinについて
istioは、サービスメッシュの一つで、マイクロサービスにおける問題を、各アプリケーションを修正せずに便利な機能を実現するものです。同様のものにlinkerdがあります。
今回、Red/Black deploymentやrelease canariesを実現するためにistioをインストールします
また、マイクロサービス間のレイテンシの問題を特定する仕組みのために、分散トレーシングZipkinをistioのaddonとしてデプロイします。
zipkinは、分散トレーシングの1つで、アプリケーションのレイテンシを計測して表示するものです。istioは、他の分散トレーシングであるJaegerにも対応しています。
なお、istioを導入しなくてもZipkinを導入する事は可能なのですが、各アプリケーションの計測したい箇所にZipkinを呼び出すように修正を入れなければいけません。自分で作ったアプリケーションなら可能な事だとは思うのですが面倒ですし、他担当や他社が作ったアプリケーションにZipkin対応してもらうようにするのは難しいでしょう。
今回は、istioのaddonとして導入する事で、アプリケーションに改修をする事なく、分散トレーシングが導入できます。ただし、マイクロサービスにおける各アプリケーション間のみの計測・表示という制約はでてしまいます。
Red/Black deployment
Blue/Green deploymentの一つで、新しいバージョンのコンテナを用意しロードバランサーなどを使って一斉に切り替える方式です。
release canaries
カナリアリリースとも呼ばれます。
Red/Black deploymentと異なり、一斉に切り替える事はせずに、部分的にリリースしていく方式です。
istioでは、柔軟なトラフィックコントロールが可能であり、例えば10%のみ新しいバージョンを見せたり、特定のCoookieを持つユーザーのみに新しいバージョンを見せたりする事もできます。これにより問題が見つかったら、影響を最小限にしてロールバックする事ができます。
実験環境について
基盤としてGKEを利用し、kubernetesのクラスタを構築し、istioをデプロイします。その後、istioに付属するサンプルアプリケーションであるBookInfoアプリケーションをデプロイし、Zipkinをistioのaddonとしてデプロイします。
手順は、GCPのドキュメントにあるものを使います。
GKEにクラスタの構築
istio-tutorialという名前で4ノードのGKEクラスタを構築します。
$ gcloud container clusters create istio-tutorial\
--machine-type=n1-standard-2 \
--num-nodes=4 \
--no-enable-legacy-authorization
istioのRBACルールを作るために必要ですので、cluster admin権限を付与します。
$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user="$(gcloud config get-value core/account)"
コンソールで確認してください。
istioのインストール
最新のistioをダウンロードし解凍します。
$ cd ~/
$ curl -L https://git.io/getLatestIstio | sh -
istioをダウンロードした際のメッセージにも書かれているように、PATHを追加します。
~/.bash_profileにも追加してください。
$ export PATH=$PWD/bin:$PATH
$ env|grep PATH
PATH=/Users/hirofumimatsu/istio-0.2.12/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/hirofumimatsu/google-cloud-sdk/bin
istioをインストールします。
$ cd ~/istio-0.2.12
$ kubectl apply -f install/kubernetes/istio.yaml
istioのserviceが作成されたことを確認します。
確認する時には、namespaceとしてistio-systemを指定してください。
$ kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-egress ClusterIP 10.43.244.217 <none> 80/TCP 1m
istio-ingress LoadBalancer 10.43.249.66 35.192.165.26 80:32584/TCP,443:32020/TCP 1m
istio-mixer ClusterIP 10.43.243.215 <none> 9091/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP 1m
istio-pilot ClusterIP 10.43.253.235 <none> 8080/TCP,443/TCP 1m
istioのpodが作成されたことを確認します。
ここでも、確認する時には、namespaceとしてistio-systemを指定してください。
$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istio-ca-293181461-pz0jx 1/1 Running 0 8m
istio-egress-2098918753-jc2gj 1/1 Running 0 8m
istio-ingress-3288103321-3swn4 1/1 Running 0 8m
istio-mixer-4195966866-zb5rd 2/2 Running 0 8m
istio-pilot-1168925427-75wjz 1/1 Running 0 8m
#Bookinfoのインストール
サンプルアプリケーションとして、istioにはBookInfoが付属していますので、これをデプロイします。
ここでは、istioctl kube-injectによりistioが挿入されている事に注目してください。
$ cd ~/istio-0.2.12
$ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo.yaml)
BookInfoのserviceが追加されている事を確認します。
namespaceは指定しませんので、デフォルトのnamespaceのserviceが表示されます。
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.43.249.90 <none> 9080/TCP 31s
kubernetes ClusterIP 10.43.240.1 <none> 443/TCP 18m
productpage ClusterIP 10.43.246.235 <none> 9080/TCP 28s
ratings ClusterIP 10.43.240.209 <none> 9080/TCP 30s
reviews ClusterIP 10.43.240.132 <none> 9080/TCP 30s
BookInfoのpodが追加されている事を確認します。
namespaceは指定しませんので、デフォルトのnamespaceのpodが表示されます。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-2818760093-3p6bk 2/2 Running 0 5m
productpage-v1-1172091313-jrr7f 2/2 Running 0 5m
ratings-v1-3016823457-z2xbv 2/2 Running 0 5m
reviews-v1-3334602649-w55xx 2/2 Running 0 5m
reviews-v2-2474208031-rrv59 2/2 Running 0 5m
reviews-v3-471783377-9gfjr 2/2 Running 0 5m
#ブラウザでアプリケーションを確認
正常にインストールされたことが確認できたら、イングレスを確認し、サービス利用のためのIPアドレスを確認します。
ここでは、例示のために、203.0.113.1をイングレスのアドレスとします。
$ kubectl get ingress -o wide
NAME HOSTS ADDRESS PORTS AGE
gateway * 203.0.113.1 80 6m
イングレスのアドレスを元にお手元のブラウザで確認してください。
BookInfoアプリケーションが利用できるはずです。
istioのzipkin addonの追加
istioにzipkin addonを追加します。
addonの追加はとても簡単です。
$ cd ~/istio-0.2.12
$ kubectl apply -f install/kubernetes/addons/zipkin.yaml
インストールできた事を確認してみましょう。
namespaceにistio-systemを指定してserviceを確認すると、zipkinのserviceが確認できます。
$ kubectl get services -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-egress ClusterIP 10.43.244.217 <none> 80/TCP 29m
istio-ingress LoadBalancer 10.43.249.66 35.192.165.26 80:32584/TCP,443:32020/TCP 29m
istio-mixer ClusterIP 10.43.243.215 <none> 9091/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP 29m
istio-pilot ClusterIP 10.43.253.235 <none> 8080/TCP,443/TCP 29m
zipkin ClusterIP 10.43.252.140 <none> 9411/TCP 50s
同様に、namespaceにistio-systemを指定してpodを確認すると、zipkinのpodが確認できます。
$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istio-ca-293181461-pz0jx 1/1 Running 0 29m
istio-egress-2098918753-jc2gj 1/1 Running 0 29m
istio-ingress-3288103321-3swn4 1/1 Running 0 29m
istio-mixer-4195966866-zb5rd 2/2 Running 0 30m
istio-pilot-1168925427-75wjz 1/1 Running 0 29m
zipkin-3660596538-5pvlb 1/1 Running 0 1m
zipkinを利用するためにport forwardを設定します。
$ kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=zipkin -o jsonpath='{.items[0].metadata.name}') 9411:9411 &
port forwardが設定できたら、以下のURLで確認してください。
http://localhost:9411