Open4

Istioを学ぶ、minikubeで。

sakaNasakaNa

はじめに

Istio を導入している社内のKubernetesにサービスを展開するにあたり、自サービス用にネットワーク設定やセキュリティの対策などを行う必要があったので最低限の知識は抑えておこうと思い学習してみる。

前提知識

Kubernetes (k8s) とは

前提として Kubernetes (k8s) がどのような仕組みなのか、どんなリソースがあるのかは簡単に理解しておいた方がよさそう。

過去に書いた下記の記事があるので参照してみてください
https://qiita.com/naoyuki1115/items/b277822c18d88f4a0b27

sakaNasakaNa

Istioとは

ここからが本番。まずは前提知識としてIstioとは何かを簡単に調査。
https://istio.io/latest/about/service-mesh/

従来のマイクロサービスの課題

Kubernetesを環境構築しているということは、下記のようにマイクロサービスを採用してたくさんの様々なサービスを連携させてユーザーに機能提供をしているとことがほとんどだと思われる。

そうしたときに課題になるのが下記のようなものである。

  • サービス間のネットワークトラフィックの制御
  • サービス間の認証認可や通信方法の暗号化などセキュリティ対策
  • LogやMetricsなどのオブザーバビリティの管理

例えば、上記のマイクロサービスの例では一つの機能を提供するだけでも様々サービスを呼び出す必要がある。どこかのサービス間通信で時間かかってしまった場合や、どこかのサービスが落ちた場合には全体に影響を与えかねない。そのためタイムアウトや落ちたサービスにこれ以上リクエストを送らないようにするサーキットブレイクなどでトラフィックの制御を行う必要が出てくる。

一つ一つのアプリケーションがこの対策のための実装を行うのはあまり現実的ではない。

サービスメッシュ

この問題に対しサービスメッシュと呼ばれるレイヤーを導入することで解決することができる。サービスメッシュはマイクロサービス間のネットワーク通信を管理、コントロールするレイヤーを指す。

サービスメッシュは上記のように各サービス間の通信の間に入り込んでトラフィック管理を行い、ルーティングやロードバランス、フェイルオーバー、認証認可、通信暗号化、通信状況の可視化などの機能を提供してくれる。

これにより複雑な通信に関する処理をサービスメッシュに任せることができて、エンジニアはアプリ開発に集中することができる。

Istio

このサービスメッシュを実現するためのオープンソースがIstioである。Istioは、k8sに対してサービス間通信を管理するサービスメッシュとして導入される。サービスメッシュ内のすべてのサービスに Envoy と呼ばれるサイドカープロキシを展開し、コントロールプレーンで集中管理を行ってくれます。

sakaNasakaNa

Istio導入

チュートリアルに従って、minikubeにistioを導入してみる。
https://istio.io/latest/docs/setup/getting-started/#download

導入環境

  • OS: Mac (Intel)
  • メモリ: 8GB

minikubeの起動

ここで問題、自分のMacがチュートリアルに要件を満たさない。。とりあえずメモリを調整してこのまま進める。

minikube start --memory=5500 --cpus=4 --kubernetes-version=v1.30.0

(Optional) k9sのインストール

k8sのリソース郡を見やすくしてくれるのでおすすめ
https://github.com/derailed/k9s

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 -; }
sakaNasakaNa

アプリのデプロイ 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