Azure Kubernetes Service(AKS)でIstioを使う

Istioサービスメッシュ入門 - connpassにブログ書く枠で参加したので、レポートします。今回のテーマは、サービスメッシュの代表例であるIstioのハンズオン。スピーカーはコンテナ&サーバレス第一人者の @yokawasa さん。

Istioについて

サービスメッシュの説明はここでは割愛しますが、要するにマイクロサービスのいろいろ面倒なところ(特にサービス間通信)を引き受けますよという位置づけ。代表的なプロダクトはいくつかあるものの、最近ではIstioの勢力が増してきている模様。kubernetesとセットで使われることがほとんどだが、k8sが必須ではないらしいです。

サービスメッシュやIstioの詳細は以下のドキュメントを参照ください。

Istioの主な機能要素は以下の通り。

  • Traffic Management
  • Policies and Telemetry
  • Security

Istioの最大の利点は、サイドカーパターンを生かして、アプリ側のコンテナ(コード)に全く手を入れずに、サイドカーとしての機能をインジェクトできる点。Istioの高度なネットワーク制御機能は、基本的にProxyとしてEnvoyをPodにサイドカー注入することで実現している。

Istioのアーキテクチャ(istio.io/docsより)

HelmでIstioを導入する

ハンズオンの手順はHelmを使う方法でしたが、ローカルからのインストールだと権限エラーが発生する人が続出したため、急遽kubectlを使う方法に切り替えるなどちょっとバタバタしました。インフラ系のハンズオンあるあるという感じでした。ちなみに、Azure-CLIを使っていた人は何も問題が起きていませんでした。

あらためて、Helmを使った導入方法を整理したので、手順をメモしておきます(クライアント環境はmacOS)。

AKSクラスタを作成する

これはいろいろなところに手順が出ているので、コマンドだけ書いておきます。Azure-CLIが使えてAzureサブスクリプションを所有していることが前提です。

リソースグループを作成します。AKS専用のリソースグループを作っておくのがオススメです。

az group create -g akstest-RG -l westus2

AKSクラスタを作成します。k8sのバージョンやノードのサイズはケースバイケースですが、Istioはそれなりにリソースを使うので、多少余裕を持たせます。

az aks create --resource-group akstest-RG \
--name istio-cluster \
--kubernetes-version 1.11.1 \
--node-vm-size Standard_D2_v2 \
--node-count 3 \
--enable-addons http_application_routing \
--generate-ssh-keys

数分待ってAKSクラスタができたら、ローカルからAKSクラスタへ接続できるようにします。

az aks get-credentials --resource-group akstest-RG --name istio-cluster

AKSのノードを確認しておきます。

kubectl get nodes

NAME STATUS ROLES AGE VERSION
aks-nodepool1-36326982-0 Ready agent 3h v1.11.1
aks-nodepool1-36326982-1 Ready agent 3h v1.11.1
aks-nodepool1-36326982-2 Ready agent 3h v1.11.1

これでAKS側の準備はできたので、ローカル環境(今回はMac)からIstioを導入していきます。

Helmを使えるようにする

HelmはHomebrewから導入できます。helmインストール実行前に一応Homebrewを更新しておきます。

brew update
brew install kubernetes-helm

サービスアカウントを作成する

Istioをデプロイする前にTillerのサービスアカウントとロールバインディングを作成する必要があるので、以下のようにhelm-rbac.yamlを作成し、

apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller
namespace: kube-system

AKSクラスタに対してサービスアカウントとロールバインディングの作成を実行します

kubectl create -f helm-rbac.yaml

serviceaccount "tiller" created
clusterrolebinding "tiller" created

Istioの導入

Istioをデプロイする前に、Helmそのものとサーバ側コンポーネントであるTillerを有効化します。

helm init --service-account tiller

Happy Helming!というメッセージが出ればOKです。

Istioをダウンロードします。
パッケージマネージャであるHelmを使っているのに、ここでダウンロードが必要なのはいまいちですが、デフォルトのリポジトリにIstioがまだ入っていないので、仕方がないでしょう。

curl -L https://git.io/getLatestIstio | sh -

helmを使ってIstioをデプロイします。以下の例ではオプションとしてgrafanaprometheusなど主要なコンポーネントを有効化しています。

cd istio-1.0.2
helm install install/kubernetes/helm/istio --name istio --namespace istio-system \
--set prometheus.enabled=true \
--set tracing.enabled=true \
--set servicegraph.enabled=true \
--set grafana.enabled=true

Istioが動いていることを確認します。名前空間でistio-systemを指定してgetします。

kubectl get pods -n istio-system

kubectl get svc -n istio-system

Istioを使ったアプリの管理

これでIstioが入ったので、アプリをIstio管理下でコントロールすることができる準備ができました。これ以降の具体的な手順は、 @yokawasaのハンズオンマテリアル通りに進めれば一通りIstioの機能を確かめられます。

特にA/Bテストやカナリアリリースを実現するTraffic Control機能については、以下のようなYAMLを作成して適用するだけで、無停止で実現できてしまうのには感心しました。

v1とv3へのトラフィックを50%ずつに分散する例

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 50
- destination:
host: reviews
subset: v3
weight: 50

PaaSがかりの視点

ハンズオンを通じて、PaaSがかりとして感じたことは、「Istioこそマネージドで提供されるべきだ」ということ。
「kubernetesがようやくマネージドで提供されてきたのにIsitioもマネージドが必要なんかい!」と思うかもしれませんが、Istioの機能こそPaaSの機能として設定したいものばかり。逆にIstioそのもののインストールには、アプリ開発者の立場では何も興味はないし、価値もないと思いました。ただ、Istio(というかEnvoy)が持つ機能自体はNoOps時代に必要なものばかりなので、各社のPaaS内部で標準として採用されればいいのにと思いました。