サービスメッシュを実現するIstioをEKS上で動かす - その1 まずはMinikubeでサンプルアプリケーションを動かしてみる
山崎 雅斗
Istioとは
Istioは、サービスメッシュを実現するために用いられるソフトウェアです。各マイクロサービスと一緒にSidecar Proxyと呼ばれるプロキシをデプロイし、Sidecar Proxy経由で他のマイクロサービスとの通信を行います。Istioでは、Sidecar ProxyとしてLyft社が作成したEnvoyを採用しています。
Istioは、アプリケーション側で特に修正を加えることなく使えるという特徴があります。例えばKubernetes環境の場合、サービスをデプロイすると、IstioによってPod内にSidecar Proxyが自動的に配置されます。Init Containersという機能を使い、Sidecar Proxyを経由するようにiptablesのルールが書き換えられます。こうすることで、アプリケーションの変更なしでSidecar Proxy経由でのマイクロサービス間通信を実現しています。
Istioが提供する機能の一例として、次のようなものがあります。
- HTTPやgRPC通信の負荷分散
- A/Bテストやカナリアリリース
- RetryやCircuit Breaker
- mTLSによるサービス認証・サービス間通信の暗号化
- サービスメッシュの可視化
これはあくまで一例であり、他にも多くの機能が提供されています。
この記事では、まずMinikubeで作ったKubernetesクラスタにIstioをインストールし、その概要を掴んでいこうと思います。
シリーズ一覧
- まずはMinikubeでサンプルアプリケーションを動かしてみる 👈 この記事
- EKSでサンプルを動かしてみる
- EKSでRDSなど外部サービスと接続してみる
- データの可視化について
- 実運用中のサービスをIstioにのせてみる
- Datadogと連携する
Kubernetesクラスタの準備
では、早速Istioを使うための準備をしていきます。
なお、Minikubeのバージョンは 0.28.1
より新しいものを使用してください。
$ minikube version
minikube version: v0.35.0
まずはKubernetesクラスタを作成していきます。通常のアプリケーションと合わせてIstioをインストールする場合、メモリ8192MB、CPU4つを割り当てることが推奨されています。
なお、この記事ではMinikubeで利用するVM driverをVirtualBoxとして進めていきます。
$ minikube start --memory=8192 --cpus=4 --kubernetes-version=v1.13.0
Istioのインストール
Kubernetesクラスタの準備ができたら、次はIstioをインストールしていきます。
まず、必要なファイル群をダウンロードする必要があります。
次のコマンドを実行すると、必要なファイルを一式ダウンロードしてきてくれます。
$ curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.1.1 sh -
ダウンロードが完了したら istio-1.1.1
というディレクトリができていると思うので、そこに移動しておきます。
$ cd istio-1.1.1
それでは、実際にIstioのコンポーネントをインストールしていきます。
今回はテストが目的なので、検証用として手軽にインストールできる方法を使っていきます。
$ for i in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl apply -f $i; done
$ kubectl apply -f install/kubernetes/istio-demo.yaml
インストールできたら、念の為正しくできているか確認しておきます。
出力に多少違いはあるかもしれませんが、だいたい同じような感じでリソースが作られていればOKです。
$ kubectl get service --namespace istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grafana ClusterIP 10.101.64.221 <none> 3000/TCP 41s
istio-citadel ClusterIP 10.105.151.0 <none> 8060/TCP,15014/TCP 41s
istio-egressgateway ClusterIP 10.107.234.187 <none> 80/TCP,443/TCP,15443/TCP 42s
istio-galley ClusterIP 10.111.216.196 <none> 443/TCP,15014/TCP,9901/TCP 42s
istio-ingressgateway LoadBalancer 10.98.185.191 <pending> 80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:32421/TCP,15030:32019/TCP,15031:30492/TCP,15032:31708/TCP,15443:31437/TCP,15020:31055/TCP 41s
istio-pilot ClusterIP 10.109.64.14 <none> 15010/TCP,15011/TCP,8080/TCP,15014/TCP 41s
istio-policy ClusterIP 10.105.193.134 <none> 9091/TCP,15004/TCP,15014/TCP 41s
istio-sidecar-injector ClusterIP 10.102.66.58 <none> 443/TCP 41s
istio-telemetry ClusterIP 10.111.70.37 <none> 9091/TCP,15004/TCP,15014/TCP,42422/TCP 41s
jaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP 40s
jaeger-collector ClusterIP 10.97.209.25 <none> 14267/TCP,14268/TCP 40s
jaeger-query ClusterIP 10.103.246.63 <none> 16686/TCP 40s
kiali ClusterIP 10.98.38.163 <none> 20001/TCP 41s
prometheus ClusterIP 10.106.254.153 <none> 9090/TCP 41s
tracing ClusterIP 10.102.197.252 <none> 80/TCP 40s
zipkin ClusterIP 10.101.17.94 <none> 9411/TCP 40s
$ kubectl get pods --namespace istio-system
NAME READY STATUS RESTARTS AGE
grafana-57586c685b-6bkwh 1/1 Running 0 8m30s
istio-citadel-5f886dc9b4-mdz4w 1/1 Running 0 8m29s
istio-cleanup-secrets-1.1.1-tffzx 0/1 Completed 0 8m31s
istio-egressgateway-6555655585-glxhl 1/1 Running 0 8m30s
istio-galley-689b548d98-nn8xs 1/1 Running 0 8m30s
istio-grafana-post-install-1.1.1-sqt7k 0/1 Completed 0 8m32s
istio-ingressgateway-74484b55f4-vl8g6 1/1 Running 0 8m30s
istio-pilot-6d9b655646-r9lmr 2/2 Running 0 8m29s
istio-policy-5bcc46677b-2vrtt 2/2 Running 6 8m30s
istio-security-post-install-1.1.1-jxhx9 0/1 Completed 0 8m31s
istio-sidecar-injector-74666b458c-wxmj5 1/1 Running 0 8m29s
istio-telemetry-5f796886b4-6dpcd 2/2 Running 6 8m30s
istio-tracing-656f9fc99c-hphpn 1/1 Running 0 8m29s
kiali-69d6978b45-5vmg9 1/1 Running 0 8m30s
prometheus-66c9f5694-cs8jd 1/1 Running 0 8m29s
Istio / Downloading the Release
Istio / Quick Start Evaluation Install
サンプルのアプリケーションをインストールする
Istioのインストールまでできたら、次はサンプルアプリケーションをインストールしていきます。
ここでは、公式が提供している Bookinfo アプリケーションを使っていきます。
今回使用する Bookinfo アプリケーションは、次のような構成のマイクロサービスとなっています。
Istio / Bookinfo Application より引用
productpage サービスが一番外側でクライアントからのリクエストを受け、 reviews と details の2つのサービスと連携します。さらに、 reviews は ratings サービスと連携する、という構成となっています。
また、 reviews サービスは異なる3つのバージョンが存在し、それぞれ少しずつ機能が異なります。
アプリケーションをデプロイする前に、default namespaceに istio-injection=enabled
というlabelをつけておきます。これをつけておくことで、default namespaceにデプロイされるサービスに対し、Istioが自動的に各サービスのコンテナへSidecar Proxyをデプロイしてくれるようになります。
$ kubectl label namespace default istio-injection=enabled
それでは、アプリケーションをデプロイしていきます。
前の手順でダウンロードしてきたIstioのディレクトリに移動し、次のコマンドを実行します。
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
これで3つのマイクロサービスがデプロイされます。念の為、うまくいっていることを確認しておきます。
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.101.71.205 <none> 9080/TCP 12s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39m
productpage ClusterIP 10.97.227.92 <none> 9080/TCP 10s
ratings ClusterIP 10.96.33.37 <none> 9080/TCP 11s
reviews ClusterIP 10.104.70.91 <none> 9080/TCP 10s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-69658dcf78-t4wr5 2/2 Running 0 2m37s
productpage-v1-6b6798cb84-2txmv 2/2 Running 0 2m35s
ratings-v1-6f97d68b6-2cjzx 2/2 Running 0 2m37s
reviews-v1-7c98dcd6dc-qnd5d 2/2 Running 0 2m36s
reviews-v2-6677766d47-zqpb7 2/2 Running 0 2m36s
reviews-v3-79f9bcc54c-thzs8 2/2 Running 0 2m36s
次に、Kubernetesクラスタの外から Bookinfo アプリケーションにアクセスできるようにするため、 Gateway と呼ばれるリソースを作成します。このリソースの定義もサンプルに含まれているので、 kubectl
コマンドを実行するだけで作成できます。
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
Gatewayは、サービスメッシュのゲートウェイ(一番外側に位置するロードバランサとなる部分)を設定するためのリソースで、次のようなことを設定することができます。
- Listenするポートとそのプロトコル
- SNI(Server Name Indication)の設定
- TLSの設定 など
Gatewayリソースを作成しただけでは、どのポートで外部からの通信を受け付けるかといったことを設定しただけで、サービスメッシュの内部でどのようにリクエストがルーティングされるかということは設定していません。これを設定するために、通常はGatewayと合わせてVirtualServiceリソースを作成します。VirtualServiceリソースを使用すると、URLのパスごとのリクエストルーティング等が可能になります。
では、適用した bookinfo-gateway.yaml
の中身を見てみます。
この中では、GatewayとVirtualServiceがそれぞれ一つずつ定義されています。
先程説明したように、Gatewayリソースでは、サービスメッシュのゲートウェイでListenするポートやプロトコル等を設定します。
spec.selector
では設定対象のロードバランサ(Pod)を指定します。
今回の場合、 istio=ingressgateway
というlabelを持つPodが対象として指定されています。
spec:
selector:
istio: ingressgateway # use istio default controller
このlabelを持つPodは、次のコマンドで取得することができます。
$ kubectl get pods --selector istio=ingressgateway --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
istio-system istio-ingressgateway-58c77897cc-lmb85 1/1 Running 0 28d
spec.hosts
では、このGatewayリソースが受け付ける対象のホスト名を指定します。
ここに指定されたホスト名とマッチしたリクエストが、このGatewayリソースの設定が適用される対象となります。また、ホスト名にはワイルドカードを指定することもできます。今回作成したGatewayの spec.hosts
は次のようになっているため、あらゆるリクエストが対象となります。
hosts:
- "*"
spec.servers
以下には、外部からの通信を受け付けるために必要な設定を記述していきます。
今回作成したものだと次のようになっています。設定を見ると何となく分かるかと思いますが、HTTP用に80番ポートをListenするような設定になります。
servers:
- port:
number: 80
name: http
protocol: HTTP
ここまでできたら、実際に Bookinfo アプリケーションにアクセスしてみましょう。
Minikube環境の場合、次のようなコマンドでアクセス先のIPアドレスとポート番号を知ることができます。
$ minikube ip
192.168.99.116
$ kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'
31380
Bookinfoアプリケーションは /productpage
というパスでアクセスできるので、今回の場合は 192.168.99.116:31380/productpage
がアクセス先のURLとなります。
アクセスして下のような画面が表示されればデプロイは成功しています。
まとめ
この記事では、Minikubeを使ってIstioをインストールし、その上でサンプルの Bookinfo アプリケーションを動かすところまでを行いました。
今後何回かの記事に渡って、最終的に実運用中のサービスをEKS上のIstioにのせるまでの過程を紹介していく予定です。