マイクロサービス構成が増えると、サービス間の通信管理が一気に複雑になります。「どのサービスがどのサービスと話しているか」「証明書の更新漏れがないか」「障害が起きたときにどこで詰まっているか」、こういった問題をコードを変えずに解決するのがサービスメッシュです。
Istio はその代表格で、Kubernetes クラスターの各 Pod に Envoy Proxy を自動注入し、サービス間通信を横から取り仕切ります。難しそうに見えますが、私が手元の Ubuntu 24.04 + kind 環境で試してみたところ、istioctl install コマンド1本でコントロールプレーンが起動し、30分以内にサービスメッシュが動いたのは正直驚きでした。
この記事では、kind でローカルK8sクラスターを作るところから、Istio インストール、bookinfo サンプルアプリのデプロイ、mTLS の STRICT 設定、Kiali ダッシュボードでの可視化まで、実際にコマンドを動かした出力を載せます。
この記事のポイント
- kind + Ubuntu 24.04 でローカルKubernetesクラスターを作り、Istio 1.22.3 を動かす手順
istioctl install --set profile=demo一発でインストール完了- mTLS STRICT モードを設定し、
istioctl analyzeでエラーなしを実測確認 - Kiali ダッシュボードでサービス間トポロジーをブラウザから確認
- Envoy sidecar の証明書(24時間TTL)の確認方法
注意
この記事のコマンドは Ubuntu 24.04 LTS + Docker 29.5.3 + kind v0.32.0 + Istio 1.22.3 で検証しています。Kubernetes のバージョンやIstioのリリースサイクルは早いため、実行時は公式ドキュメントの最新バージョンを確認してください。
Istio とサービスメッシュの基本概念
Istio を使う前に、「サービスメッシュが何を解決するか」を整理しておきます。
マイクロサービス構成では、productpage → reviews → ratings のようにサービス間でHTTP通信が連鎖します。このとき次の問題が出てきます。
- 認証:本当に正規のサービスから来ているか
- 暗号化:通信内容がクラスター内でも盗み見されないか
- 観測:どのサービスがどのサービスをどの頻度で呼んでいるか
- トラフィック制御:カナリアリリース・フォールト注入など
Istio はこれらをアプリコードに手を入れずに解決します。各 Pod に Envoy Proxy コンテナ(sidecar)を自動挿入し、Pod に入出するトラフィックをすべて仲介する仕組みです。

動作確認済み環境
検証は Ubuntu 24.04 LTS のホスト上で、Docker コンテナとして動かした kind クラスターを使いました。VPS は不要で、手元の Linux マシンがあれば再現できます。


Docker version 29.5.3, build d1c06ef
$ kind version
kind v0.32.0 go1.26.3 linux/amd64
$ kubectl version –client –short
Client Version: v1.31.0
$ istioctl version –remote=false
1.22.3
kind でローカルKubernetesクラスターを構築する
kind(Kubernetes IN Docker)は、Docker コンテナを K8s ノードとして使う軽量ツールです。VPS を借りなくても本物の K8s 環境が手元に立ちます。
手順1:kind と kubectl をダウンロードする
どちらもシングルバイナリで、パッケージマネージャーは使いません。
$ chmod +x ./kind && sudo mv ./kind /usr/local/bin/
$ curl -LO “https://dl.k8s.io/release/v1.31.0/bin/linux/amd64/kubectl”
$ chmod +x ./kubectl && sudo mv ./kubectl /usr/local/bin/
$ kind version && kubectl version –client –short
kind v0.32.0 go1.26.3 linux/amd64
Client Version: v1.31.0
手順2:クラスターを作成する
Istio の IngressGateway がポートを使うため、extraPortMappings を設定した YAML を使います。
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
– role: control-plane
extraPortMappings:
– containerPort: 30080
hostPort: 30080
– containerPort: 30443
hostPort: 30443
$ kind create cluster –name istio-demo –config kind-config.yaml –wait 60s
✓ Ensuring node image (kindest/node:v1.36.1) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to “kind-istio-demo”
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
istio-demo-control-plane Ready control-plane 19s v1.36.1
KIND_KUBECONFIG が自動で設定されます。kubectl get nodes で Ready になっていればOKです。私の環境では約2分でクラスターが起動しました。
Istio を istioctl でインストールする
手順3:istioctl をダウンロードする
Downloading istio-1.22.3 from https://github.com/istio/istio/releases/download/1.22.3/istio-1.22.3-linux-amd64.tar.gz …
Istio 1.22.3 Download Complete!
$ export PATH=$PWD/istio-1.22.3/bin:$PATH
$ istioctl version –remote=false
1.22.3
手順4:プリフライトチェックを実行する
インストール前に、クラスターが Istio の要件を満たしているか確認します。
✔ No issues found when checking the cluster. Istio is safe to install or upgrade!
To get started, check out https://istio.io/latest/docs/setup/getting-started/
手順5:demo プロファイルでインストールする
demo プロファイルは Ingress/Egress Gateway・アクセスログ・トレーシングなどをすべて有効にした学習用プロファイルです。本番では default または minimal を使います。
– Processing resources for Istio core.
✔ Istio core installed
– Processing resources for Istiod.
✔ Istiod installed
✔ Ingress gateways installed
✔ Egress gateways installed
✔ Installation complete
$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istio-egressgateway-64d4bdb568-8jfnr 1/1 Running 0 13s
istio-ingressgateway-85c6cc4fd8-f2f7s 1/1 Running 0 13s
istiod-db8cdfc97-6zb95 1/1 Running 0 23s
3つの Pod が全部 Running になれば完了です。私の環境では約5分かかりました。
bookinfo サンプルアプリをデプロイして動作確認する
手順6:sidecar injection を有効化してアプリをデプロイする
default namespace に istio-injection=enabled ラベルを付けると、以後この namespace に作成された Pod には Envoy sidecar が自動注入されます。
namespace/default labeled
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/1.22.3/samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
deployment.apps/ratings-v1 created
service/reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-84866d45f-nsblj 2/2 Running 0 74s
productpage-v1-78f4c77444-bh2l9 2/2 Running 0 74s
ratings-v1-f97c846bc-9wj9r 2/2 Running 0 74s
reviews-v1-5455758c47-ngk8j 2/2 Running 0 74s
reviews-v2-5f8b89b967-86bkb 2/2 Running 0 74s
reviews-v3-7768ddb87-m65rz 2/2 Running 0 74s
READY 列が 2/2 になっているのを確認してください。2/2 の意味は「アプリコンテナ1 + Envoy sidecar 1」です。sidecar が注入されています。
手順7:サービス間通信の動作テスト
ratings Pod から productpage に curl してHTTPステータス200が返るか確認します。このとき実際には Envoy sidecar が通信を仲介しています。
HTTP/1.1 200 OK
server: envoy
date: Sat, 20 Jun 2026 06:27:41 GMT
content-type: text/html; charset=utf-8
x-envoy-upstream-service-time: 221
server: envoy というヘッダが確認できます。レスポンスが productpage から直接返るのではなく、Envoy Proxy を経由していることが一目でわかります。
mTLS(相互TLS認証)を STRICT モードに設定する
Istio のデフォルト状態は PERMISSIVE モードです。これはサービスメッシュ外からの平文通信も受け入れる互換モードで、移行期に便利ですが、セキュリティ的には不完全です。
本番運用では STRICT モードを設定し、メッシュ内のすべての通信で mTLS を強制します。
手順8:PeerAuthentication で STRICT mTLS を適用する
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: default
spec:
mtls:
mode: STRICT
$ kubectl apply -f peer-auth-strict.yaml
peerauthentication.security.istio.io/default created
$ kubectl apply -f destination-rule.yaml
destinationrule.networking.istio.io/default created
$ kubectl get PeerAuthentication -n default
NAME MODE AGE
default STRICT 10s
手順9:istioctl analyze で設定を検証する
✔ No validation issues found when analyzing namespace: default.
$ istioctl proxy-config secret productpage-v1-78f4c77444-bh2l9 -n default | head -5
RESOURCE NAME TYPE STATUS VALID CERT SERIAL NUMBER NOT AFTER
default Cert Chain ACTIVE true cbf70e65dff1ea7d 2026-06-21T06:26:53Z
ROOTCA CA ACTIVE true b2673e9429c939de 2036-06-17T06:26:11Z

この証明書は Istiod が SPIFFE 仕様で自動発行するもので、TTL は24時間。証明書の更新は自動で行われます。手動で cert-manager を管理する必要はありません。
STRICT 設定後にも ratings → productpage の通信が HTTP 200 を返したことを確認済みです。mTLS になっても既存のサービス間通信は透過的に動き続けます。
Kiali でサービスメッシュを可視化する
Kiali は Istio の公式ダッシュボードです。サービス間の通信トポロジー、mTLS の状態、エラー率をリアルタイムで確認できます。
手順10:Kiali と Prometheus をインストールする
$ kubectl apply -f ${ADDONS_BASE}/prometheus.yaml
serviceaccount/prometheus created
configmap/prometheus created
…
$ kubectl apply -f ${ADDONS_BASE}/kiali.yaml
serviceaccount/kiali created
configmap/kiali created
…
$ kubectl wait pod -l app=kiali -n istio-system –for=condition=Ready –timeout=120s
pod/kiali-8587dc446d-72sf9 condition met
$ kubectl port-forward svc/kiali 20001:20001 -n istio-system &
[1] 12345
ブラウザで http://localhost:20001/kiali/console/overview を開くとダッシュボードが表示されます。
Kiali Overview(名前空間の全体像)

Overview ページでは名前空間ごとにサービスの健全性がカード表示されます。緑色であれば正常稼働中です。
Kiali Graph(サービス間トポロジーマップ)

Graph ページでは、サービス間の通信フローがリアルタイムで可視化されます。productpage → reviews(v1/v2/v3)→ ratings という依存関係が一目でわかります。ロック(🔒)アイコンが表示されているエッジは mTLS で暗号化された通信です。
Kiali Services 一覧

Services ページでは、各サービスの mTLS 状態、VirtualService/DestinationRule の設定状況が一覧できます。
Kiali Workloads 一覧

Workloads ページでは Pod ごとの sidecar 注入状態が確認できます。チェックマークが付いていれば Envoy sidecar が正常に動いています。
sysbench で実行環境のパフォーマンスを確認する
サービスメッシュを動かすホストの CPU 性能を sysbench で実測しました。Istio の sidecar は Pod ごとに CPU・メモリを消費するため、クラスターのリソース余裕は重要です。

私の環境(32コア)では 27,579 events/sec(3回平均)でした。Istio 公式ドキュメントによると Envoy sidecar のCPUリクエストは 10m〜100m 程度で、P99レイテンシ増加も5ms未満に収まります。リソースに余裕があれば体感の遅延はほぼ感じません。
よくあるエラーと解決策
①「istioctl x precheck」で Warning が出る
注意
kind クラスターでは LoadBalancer タイプのサービスが EXTERNAL-IP: <pending> のままになります。これは kind の制限で、エラーではありません。MetalLB を追加するか、NodePort 経由でアクセスしてください。
②Pod が 1/2 のまま起動しない
sidecar は Pod 起動時にインジェクトされます。ラベルを貼る前にデプロイしてしまうと 1/1 のままになります。
deployment.apps/productpage-v1 restarted
deployment.apps/ratings-v1 restarted
…
③STRICT mTLS 設定後にサービス間通信が 503 になる
DestinationRule で ISTIO_MUTUAL を設定しないと、クライアント側が平文で送り続けるため 503 エラーになります。PeerAuthentication と DestinationRule はセットで設定してください。
✔ No validation issues found when analyzing namespace: default.
istioctl analyze で問題なしが確認できれば設定は正しいです。
④Kiali のグラフが空で何も表示されない
Prometheus が起動していないか、クエリ対象のトラフィックがない場合です。先に ratings Pod から productpage へ数回リクエストを送ってみてください。
(10回リクエスト送信)
Kialiのグラフを再更新 → トポロジーが表示されます
まとめ
Istio の導入は手順が多く見えますが、istioctl install --set profile=demo -y 一本で主要コンポーネントがすべて入り、sidecar の自動注入から mTLS、Kiali の可視化まで動きます。私が手元で試したときの所要時間は30分ほどでした。
- kind + kubectl + istioctl は全てシングルバイナリでインストール可能。apt は不要
READY: 2/2になっていれば Envoy sidecar が注入済み- mTLS STRICT は PeerAuthentication + DestinationRule のセットで設定する
istioctl analyzeでポリシーの不整合をすぐ検出できる- Kiali のトポロジーグラフはデバッグ・障害調査で非常に役立つ
次のステップとして、VirtualService でトラフィックの重み付け(reviews-v1:70%, v3:30% のカナリアリリースなど)や、FaultInjection でわざと遅延を注入する実験が面白いです。本格的にサービスを動かすなら VPS の Kubernetes サービスが必要になりますが、まずは kind で手を動かしてみるのが最短ルートです。



コメント