はじめに
本記事はIstio入門シリーズの第二弾です!
前回の Istio入門 その1 -Istioとは?- では、Istioのざっくりとしたアーキテクチャを解説しました。ぼんやりと全体像が見えてきたかと思いますので、今回は公式サンプルアプリケーションを試しつつ実際の動きを見ていきたいと思います。
Istio入門シリーズ
- [その1 -Istioとは?-][istio1]
- [その2 -Istio構築とサンプルアプリのデプロイ-][istio2]
- [その3 -Blue/Greenデプロイメントによるカナリアリリース-][istio3]
- [その4 -基礎から振り返る-][istio4]
[istio4]: https://qiita.com/Ladicle/items/4ba57078128d6affadd5
[istio1]: https://qiita.com/Ladicle/items/979d59ef0303425752c8
[istio2]: https://qiita.com/Ladicle/items/e949b0f68ac18b7a95d8
[istio3]: https://qiita.com/Ladicle/items/5a68ff85e15e86781453
Hello Istio!
bookinfoを試す前に、まずはIstioの構築です。フル機能のIstioを使えるプラットフォームは現時点でKubernetesのみ1なので、Minikube2を使って構築したいと思います。
環境情報
- 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/
2. 続いてメモリを4G確保してMinikubeを起動します
```bash
$ 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
4. KubernetesにダウンロードしてきたIstioのManifestを適用します
```bash
$ 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 443/TCP 34m
istio-system svc/istio-egress ClusterIP 10.0.0.60 80/TCP 15m
istio-system svc/istio-ingress LoadBalancer 10.0.0.175 80:32706/TCP,443:32034/TCP 15m
istio-system svc/istio-mixer ClusterIP 10.0.0.184 9091/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP 15m
istio-system svc/istio-pilot ClusterIP 10.0.0.189 8080/TCP,443/TCP 15m
kube-system svc/kube-dns ClusterIP 10.0.0.10 53/UDP,53/TCP 34m
kube-system svc/kubernetes-dashboard NodePort 10.0.0.76 80:30000/TCP 34m
### お疲れ様でした:beer:
以上でIstioの構築は完了です。環境差分など何か問題がありましたら公式の[Setup](https://istio.io/docs/setup/)ガイドをご参照ください。
## サンプルアプリケーションを試す
前章でIstioが立ち上げることができました。しかし、これだけではどの様な機能が使えるのかわかりません。この章では、[公式サンプルアプリケーション](https://github.com/istio/istio/tree/master/samples)を使ってIstioを組み込む方法を見ていきます。
### アプリケーションにIstioを組み込む
Istioを構成するコンポーネントの一つであるEnvoy[^3]は、アプリケーションのサイドカーとして組み込まれるためアプリケーションコードを修正する必要がありません。
1. まずは前章でダウンロードしたIstioのディレクトリに移動します
```bash
$ cd path/to/istio-0.2.7
-
アプリケーションのManifestに対してistioctlのkube-injectを実行します。すると、Istioの設定が組み込まれたManifestが生成されます。
$ istioctl kube-inject -f samples/bookinfo/kube/bookinfo.yaml > out
3. `kube-inject`で生成されたManifestと元のManifestのdiffをみると、annotationやサイドカーの設定が追加されていることがわかります![Pasted image at 2017_12_07 10_40 AM.png](https://qiita-image-store.s3.amazonaws.com/0/26683/ebaa40bb-c8ba-6dff-6349-314cd2040d5e.png)
> 全てのdiffが見たい方は[gists](https://gist.github.com/Ladicle/8ea73d991f074c80adf7c9b8d8eceb7f)をご参照ください。
#### Automatic sidecar injection
今回は差分をみるためistioctlで明示的にIstioをアプリケーションに対して組み込みました。
より簡単にデプロイする方法として、DeploymentのPodにサイドカーを自動で組み込む機能[^4]も提供されています。ただし、この機能はKubernetesの[Initializer](https://kubernetes.io/docs/admin/extensible-admission-controllers/#what-are-initializers)を利用しているので、Kubernetesクラスタの立ち上げ時にフラグをオンにする必要があります。その上でistio-initializerをデプロイすることで利用することができます。
実は、前章の構築で既にこの機能を有効にしています。minikube立ち上げ時に付与していた`extra-config`、Istio Manifest適用時に指定していた`istio-initializer.yml`が自動組み込み機能の有効化方法です。
### Istioを組み込んだManifestをKubernetesに適用する
<img width="1254" alt="degital gerimanda - 4.png" src="https://qiita-image-store.s3.amazonaws.com/0/26683/528ab317-f586-068e-5ba2-0ce69bb1c399.png">
**図1** IstioをBookinfoに組み込んだ前と後の比較
実際にアプリケーションを立ち上げる前に、軽くBookinfoのアーキテクチャをみていきましょう。このBookinfoは、本の情報を掲載しているマイクロサービスなアプリケーションです。図1のような構成を取っており、機能は以下のようになっています。
* **商品ページ (Python)**: 他のコンポーネントから取得した本の情報を提供する。
* **レビュー (Java)**: 本のレビュー情報を提供する。1~3までのバージョンがある。
* **詳細情報 (NodeJS)**: 本の詳細情報を提供する。商品ページから呼び出される。
* **レーティング (Ruby)**: 本のレートを提供する。レビューのv2から呼び出される。
では、前章で作成したIstio組み込み済みのManifestを使ってBookinfoをKubernetes上に立ちあげましょう。
1. はじめに、作成したManifestをKubernetesに適用します
```bash
$ 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 9080/TCP 5s
kubernetes ClusterIP 10.0.0.1 443/TCP 1h
productpage ClusterIP 10.0.0.207 9080/TCP 5s
ratings ClusterIP 10.0.0.116 9080/TCP 5s
reviews ClusterIP 10.0.0.92 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にアクセスして正しいレスポンスが返ってくることを確認します。
```bash
$ 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をより高度にコントロールする方法を見ていきたいと思います。それではお楽しみに 👋