はじめに
本記事はIstio入門シリーズの第二弾です!
前回の [Istio入門 その1 -Istioとは?-][0] では、Istioのざっくりとしたアーキテクチャを解説しました。ぼんやりと全体像が見えてきたかと思いますので、今回は公式サンプルアプリケーションを試しつつ実際の動きを見ていきたいと思います。
Istio入門シリーズ
* その1 -Istioとは?-
* その2 -Istio構築とサンプルアプリのデプロイ-
* その3 -Blue/Greenデプロイメントによるカナリアリリース-
* その4 -基礎から振り返る-
Hello Istio!
bookinfoを試す前に、まずはIstioの構築です。フル機能のIstioを使えるプラットフォームは現時点でKubernetesのみ[^1]なので、Minikube[^2]を使って構築したいと思います。
環境情報
- OS: macOS Sierra
- Hypervisor: VirtualBox
KubernetesにIstioをデプロイする
-
はじめにMinikubeをダウンロードしてパスを通します
$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.23.0/minikube-darwin-amd64 $ chmod +x minikube $ sudo mv minikube /usr/local/bin/
-
続いてメモリを4G確保してMinikubeを起動します
$ minikube start --memory 4096 --extra-config=apiserver.Admission.PluginNames="Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,GenericAdmissionWebhook,ResourceQuota"
注意
Istio本体の起動には2Gで十分なのですが、BookInfoの動作には4G以上のメモリが必要なことに注意してください。 -
ここから、本題のIstioをダウンロードしてistioctlのパスを通します
$ curl -L https://git.io/getLatestIstio | sh - $ cd istio-0.2.7 $ sudo mv bin/istioctl /usr/local/bin
-
KubernetesにダウンロードしてきたIstioのManifestを適用します
$ kubectl apply -f install/kubernetes/istio-auth.yaml $ kubectl apply -f install/kubernetes/istio-initializer.yaml
-
最後にkubectlを使って、作成されたIstioのリソースを確認します
$ kubectl get --all-namespaces all NAMESPACE NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE istio-system deploy/istio-ca 1 1 1 1 15m istio-system deploy/istio-egress 1 1 1 1 15m istio-system deploy/istio-ingress 1 1 1 1 15m istio-system deploy/istio-initializer 1 1 1 1 12m istio-system deploy/istio-mixer 1 1 1 1 15m istio-system deploy/istio-pilot 1 1 1 1 15m kube-system deploy/kube-dns 1 1 1 1 34m NAMESPACE NAME DESIRED CURRENT READY AGE istio-system rs/istio-ca-57f9bd7ddb 1 1 1 15m istio-system rs/istio-egress-6c6b84cd5d 1 1 1 15m istio-system rs/istio-ingress-79cf84458b 1 1 1 15m istio-system rs/istio-initializer-865bc594c 1 1 1 12m istio-system rs/istio-mixer-6fdc6784c7 1 1 1 15m istio-system rs/istio-pilot-5f4865659b 1 1 1 15m kube-system rs/kube-dns-6fc954457d 1 1 1 34m NAMESPACE NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE istio-system deploy/istio-ca 1 1 1 1 15m istio-system deploy/istio-egress 1 1 1 1 15m istio-system deploy/istio-ingress 1 1 1 1 15m istio-system deploy/istio-initializer 1 1 1 1 12m istio-system deploy/istio-mixer 1 1 1 1 15m istio-system deploy/istio-pilot 1 1 1 1 15m kube-system deploy/kube-dns 1 1 1 1 34m NAMESPACE NAME DESIRED CURRENT READY AGE istio-system rs/istio-ca-57f9bd7ddb 1 1 1 15m istio-system rs/istio-egress-6c6b84cd5d 1 1 1 15m istio-system rs/istio-ingress-79cf84458b 1 1 1 15m istio-system rs/istio-initializer-865bc594c 1 1 1 12m istio-system rs/istio-mixer-6fdc6784c7 1 1 1 15m istio-system rs/istio-pilot-5f4865659b 1 1 1 15m kube-system rs/kube-dns-6fc954457d 1 1 1 34m NAMESPACE NAME READY STATUS RESTARTS AGE istio-system po/istio-ca-57f9bd7ddb-4j7h5 1/1 Running 0 15m istio-system po/istio-egress-6c6b84cd5d-dzgxx 1/1 Running 0 15m istio-system po/istio-ingress-79cf84458b-s4wx6 1/1 Running 0 15m istio-system po/istio-initializer-865bc594c-kw2xx 1/1 Running 0 12m istio-system po/istio-mixer-6fdc6784c7-hl8sf 2/2 Running 0 15m istio-system po/istio-pilot-5f4865659b-hbw5d 1/1 Running 0 15m kube-system po/kube-addon-manager-minikube 1/1 Running 0 34m kube-system po/kube-dns-6fc954457d-qfczj 3/3 Running 0 34m kube-system po/kubernetes-dashboard-55t8g 1/1 Running 0 34m NAMESPACE NAME DESIRED CURRENT READY AGE kube-system rc/kubernetes-dashboard 1 1 1 34m NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default svc/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 34m istio-system svc/istio-egress ClusterIP 10.0.0.60 <none> 80/TCP 15m istio-system svc/istio-ingress LoadBalancer 10.0.0.175 <pending> 80:32706/TCP,443:32034/TCP 15m istio-system svc/istio-mixer ClusterIP 10.0.0.184 <none> 9091/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP 15m istio-system svc/istio-pilot ClusterIP 10.0.0.189 <none> 8080/TCP,443/TCP 15m kube-system svc/kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 34m kube-system svc/kubernetes-dashboard NodePort 10.0.0.76 <none> 80:30000/TCP 34m
お疲れ様でした
以上でIstioの構築は完了です。環境差分など何か問題がありましたら公式のSetupガイドをご参照ください。
サンプルアプリケーションを試す
前章でIstioが立ち上げることができました。しかし、これだけではどの様な機能が使えるのかわかりません。この章では、公式サンプルアプリケーションを使ってIstioを組み込む方法を見ていきます。
アプリケーションにIstioを組み込む
Istioを構成するコンポーネントの一つであるEnvoy[^3]は、アプリケーションのサイドカーとして組み込まれるためアプリケーションコードを修正する必要がありません。
-
まずは前章でダウンロードしたIstioのディレクトリに移動します
$ cd path/to/istio-0.2.7
-
アプリケーションのManifestに対してistioctlのkube-injectを実行します。すると、Istioの設定が組み込まれたManifestが生成されます。
$ istioctl kube-inject -f samples/bookinfo/kube/bookinfo.yaml > out
kube-inject
で生成されたManifestと元のManifestのdiffをみると、annotationやサイドカーの設定が追加されていることがわかります
全てのdiffが見たい方はgistsをご参照ください。
Automatic sidecar injection
今回は差分をみるためistioctlで明示的にIstioをアプリケーションに対して組み込みました。
より簡単にデプロイする方法として、DeploymentのPodにサイドカーを自動で組み込む機能[^4]も提供されています。ただし、この機能はKubernetesのInitializerを利用しているので、Kubernetesクラスタの立ち上げ時にフラグをオンにする必要があります。その上でistio-initializerをデプロイすることで利用することができます。
実は、前章の構築で既にこの機能を有効にしています。minikube立ち上げ時に付与していたextra-config
、Istio Manifest適用時に指定していたistio-initializer.yml
が自動組み込み機能の有効化方法です。
Istioを組み込んだManifestをKubernetesに適用する
実際にアプリケーションを立ち上げる前に、軽くBookinfoのアーキテクチャをみていきましょう。このBookinfoは、本の情報を掲載しているマイクロサービスなアプリケーションです。図1のような構成を取っており、機能は以下のようになっています。
- 商品ページ (Python): 他のコンポーネントから取得した本の情報を提供する。
- レビュー (Java): 本のレビュー情報を提供する。1~3までのバージョンがある。
- 詳細情報 (NodeJS): 本の詳細情報を提供する。商品ページから呼び出される。
- レーティング (Ruby): 本のレートを提供する。レビューのv2から呼び出される。
では、前章で作成したIstio組み込み済みのManifestを使ってBookinfoをKubernetes上に立ちあげましょう。
-
はじめに、作成したManifestをKubernetesに適用します
$ kubectl apply -f out service "details" created deployment "details-v1" created service "ratings" created deployment "ratings-v1" created service "reviews" created deployment "reviews-v1" created deployment "reviews-v2" created deployment "reviews-v3" created service "productpage" created deployment "productpage-v1" created ingress "gateway" created
-
次に、正しく立ち上がっていることをkubectlで確認します
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE details ClusterIP 10.0.0.190 <none> 9080/TCP 5s kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 1h productpage ClusterIP 10.0.0.207 <none> 9080/TCP 5s ratings ClusterIP 10.0.0.116 <none> 9080/TCP 5s reviews ClusterIP 10.0.0.92 <none> 9080/TCP 5s $ kubectl get po NAME READY STATUS RESTARTS AGE details-v1-cf8bdb7f7-dwpqw 2/2 Running 0 1m productpage-v1-6bb58b5bd5-r6mkf 2/2 Running 0 1m ratings-v1-598779769-s6msj 2/2 Running 0 1m reviews-v1-6f49f7dbd7-dznm7 2/2 Running 0 1m reviews-v2-8659c664ff-xh29g 2/2 Running 0 1m reviews-v3-bcbd4f7f9-kcm7z 2/2 Running 0 1m
BookInfoにアクセスする
最後に、立ち上げたBookinfoにアクセスしてみましょう。まずは取得したゲートウェイのURLにアクセスして正しいレスポンスが返ってくることを確認します。
$ export GATEWAY_URL=$(kubectl get po -n istio-system -l istio=ingress -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingress -n istio-system -o 'jsonpath={.spec.ports[0].nodePort}')
$ curl -o /dev/null -s -w "%{http_code}\n" http://$GATEWAY_URL/productpage
200
200が返ってきたでしょうか? 問題なければ次はブラウザからアクセスしてみます。
open http://$GATEWAY_URL/productpage
ブラウザが立ち上がったら、ページを何回かリロードしてみてください。レビュー機能を持つコンポーネントに対してラウンドロビンでルーティングされるので、図2-4のような画面複数のバージョンページが表示されるかと思います。
おわりに
今回はIstioの構築とアプリケーションにIstioを組み込む方法について見ていきました。アーキテクチャは少々複雑でしたが、Kubernetesへの組み込みは簡単だったのではないでしょうか?
次回は、Istioの機能を使ってBookInfoをより高度にコントロールする方法を見ていきたいと思います。それではお楽しみに 👋
[0]: https://qiita.com/Ladicle/items/979d59ef0303425752c8
[1]: https://istio.io/docs/guides/bookinfo.html
[^1]: Istioとは参照
[^2]: Localで簡単にKubernetesクラスタを動かすためのツール
[^3]: システム構成参照
[^4]: automatic-sidecar-injection参照