Istioを学ぶ、minikubeで。
はじめに
Istio を導入している社内のKubernetesにサービスを展開するにあたり、自サービス用にネットワーク設定やセキュリティの対策などを行う必要があったので最低限の知識は抑えておこうと思い学習してみる。
前提知識
Kubernetes (k8s) とは
前提として Kubernetes (k8s) がどのような仕組みなのか、どんなリソースがあるのかは簡単に理解しておいた方がよさそう。
過去に書いた下記の記事があるので参照してみてください
Istioとは
ここからが本番。まずは前提知識としてIstio
とは何かを簡単に調査。
従来のマイクロサービスの課題
Kubernetesを環境構築しているということは、下記のようにマイクロサービスを採用してたくさんの様々なサービスを連携させてユーザーに機能提供をしているとことがほとんどだと思われる。
そうしたときに課題になるのが下記のようなものである。
- サービス間のネットワークトラフィックの制御
- サービス間の認証認可や通信方法の暗号化などセキュリティ対策
- LogやMetricsなどのオブザーバビリティの管理
例えば、上記のマイクロサービスの例では一つの機能を提供するだけでも様々サービスを呼び出す必要がある。どこかのサービス間通信で時間かかってしまった場合や、どこかのサービスが落ちた場合には全体に影響を与えかねない。そのためタイムアウトや落ちたサービスにこれ以上リクエストを送らないようにするサーキットブレイクなどでトラフィックの制御を行う必要が出てくる。
一つ一つのアプリケーションがこの対策のための実装を行うのはあまり現実的ではない。
サービスメッシュ
この問題に対しサービスメッシュと呼ばれるレイヤーを導入することで解決することができる。サービスメッシュはマイクロサービス間のネットワーク通信を管理、コントロールするレイヤーを指す。
サービスメッシュは上記のように各サービス間の通信の間に入り込んでトラフィック管理を行い、ルーティングやロードバランス、フェイルオーバー、認証認可、通信暗号化、通信状況の可視化などの機能を提供してくれる。
これにより複雑な通信に関する処理をサービスメッシュに任せることができて、エンジニアはアプリ開発に集中することができる。
Istio
このサービスメッシュを実現するためのオープンソースがIstio
である。Istioは、k8sに対してサービス間通信を管理するサービスメッシュとして導入される。サービスメッシュ内のすべてのサービスに Envoy
と呼ばれるサイドカープロキシを展開し、コントロールプレーンで集中管理を行ってくれます。
Istio導入
チュートリアルに従って、minikubeにistioを導入してみる。
導入環境
- OS: Mac (Intel)
- メモリ: 8GB
minikubeの起動
ここで問題、自分のMacがチュートリアルに要件を満たさない。。とりあえずメモリを調整してこのまま進める。
minikube start --memory=5500 --cpus=4 --kubernetes-version=v1.30.0
(Optional) k9sのインストール
k8sのリソース郡を見やすくしてくれるのでおすすめ
brew install derailed/k9s/k9s
Istioのインストール
Kubernetesにデプロイするためのmanifestやコマンドラインツール(istioctl)、サンプルアプリなどをパッケージ化してzipファイルとして提供してくれているので下記でダウンロード
curl -L https://istio.io/downloadIstio | sh -
Pathの追加 (毎回Path追加するのが面倒であれば、.zshrc
に追加しておく)
export PATH="$PATH:/Users/{USERNAME}/istio-1.23.0/bin"
Istioctlの動作確認
$ istioctl version
Istio is not present in the cluster: no running Istio pods in namespace "istio-system"
client version: 1.23.0
minikubeにistioをインストール
istionctl install --context minikube
インストールするとistioのリソースが展開されていることを確認できる
$ kubectl get all -n istio-system
NAME READY STATUS RESTARTS AGE
pod/istio-ingressgateway-75fcb94949-xd8s4 1/1 Running 0 32m
pod/istiod-5f7944b777-qz25m 1/1 Running 0 32m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/istio-ingressgateway LoadBalancer 10.98.216.163 127.0.0.1 15021:32206/TCP,80:32377/TCP,443:31222/TCP 32m
service/istiod ClusterIP 10.103.177.215 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 32m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-ingressgateway 1/1 1 1 32m
deployment.apps/istiod 1/1 1 1 32m
NAME DESIRED CURRENT READY AGE
replicaset.apps/istio-ingressgateway-75fcb94949 1 1 1 32m
replicaset.apps/istiod-5f7944b777 1 1 1 32m
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/istio-ingressgateway Deployment/istio-ingressgateway cpu: <unknown>/80% 1 5 1 32m
horizontalpodautoscaler.autoscaling/istiod Deployment/istiod cpu: <unknown>/80% 1 5 1 32m
もちろんk9sでも確認できる
k9s -n istio-system
Kubernetes Gateway API CRDs をインストール
ほとんどの場合インストールされていない。IstioはこのAPIを通して、ルーティングやトラフィックの管理を行う。
下記コマンドではインストールされているかどうかチェックし、されていなかったらインストールしてくれる。
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.1.0" | kubectl apply -f -; }
アプリのデプロイ with Envoy
Envoy Proxy自動追加設定
このあとアプリをデプロイしていく際に自動的にEnvoy ProxyがPodに展開されるようにする。下記は指定したnamespace配下のものにEnvoyが自動的に展開されるようにしている。
kubectl label namespace default istio-injection=enabled
サンプルアプリのデプロイ
アプリを指定のnamespaceにデプロイする。Istioのチュートリアルのアプリのマニフェストを用いて、default
というnamespaceにデプロイする。
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.23/samples/bookinfo/platform/kube/bookinfo.yaml
上記でマニフェストを適用するとPodが出来上がる
kubectl get pods
さらにPodを指定してみるとアプリのコンテナだけでなく、Envoyもデプロイされていることがわかる
kubectl get pod details-v1-558b8b4b76-2llld