Istio on Ubuntu K8s — サービスメッシュの導入とmTLS設定

Kubernetes

マイクロサービス構成が増えると、サービス間の通信管理が一気に複雑になります。「どのサービスがどのサービスと話しているか」「証明書の更新漏れがないか」「障害が起きたときにどこで詰まっているか」、こういった問題をコードを変えずに解決するのがサービスメッシュです。

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 を使う前に、「サービスメッシュが何を解決するか」を整理しておきます。

マイクロサービス構成では、productpagereviewsratings のようにサービス間でHTTP通信が連鎖します。このとき次の問題が出てきます。

  • 認証:本当に正規のサービスから来ているか
  • 暗号化:通信内容がクラスター内でも盗み見されないか
  • 観測:どのサービスがどのサービスをどの頻度で呼んでいるか
  • トラフィック制御:カナリアリリース・フォールト注入など

Istio はこれらをアプリコードに手を入れずに解決します。各 Pod に Envoy Proxy コンテナ(sidecar)を自動挿入し、Pod に入出するトラフィックをすべて仲介する仕組みです。

Istio 推奨システム要件一覧(公式ドキュメント準拠)
Istio 推奨システム要件一覧(公式ドキュメント準拠)

動作確認済み環境

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

実行環境の確認(Ubuntu 24.04 + Docker + kind)
実行環境の確認(Ubuntu 24.04 + Docker + kind)
Istio/K8s バージョン一覧(2026-06-20)
Istio/K8s バージョン一覧(2026-06-20)



ubuntu@linuxlab: ~
$ docker –version
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 をダウンロードする

どちらもシングルバイナリで、パッケージマネージャーは使いません。




ubuntu@linuxlab: ~
$ curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.32.0/kind-linux-amd64
$ 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 を使います。




ubuntu@linuxlab: ~
$ cat kind-config.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 nodesReady になっていればOKです。私の環境では約2分でクラスターが起動しました。

Istio を istioctl でインストールする

手順3:istioctl をダウンロードする




ubuntu@linuxlab: ~
$ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.22.3 sh –
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 の要件を満たしているか確認します。




ubuntu@linuxlab: ~
$ istioctl x precheck
✔ 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 を使います。




ubuntu@linuxlab: ~
$ istioctl install –set profile=demo -y –set meshConfig.accessLogFile=/dev/stdout
– 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 が自動注入されます。




ubuntu@linuxlab: ~
$ kubectl label namespace default istio-injection=enabled
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 が通信を仲介しています。




ubuntu@linuxlab: ~
$ kubectl exec ratings-v1-f97c846bc-9wj9r -c ratings — curl -sI http://productpage:9080/productpage | head -5
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 を適用する




ubuntu@linuxlab: ~
$ cat peer-auth-strict.yaml
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 で設定を検証する




ubuntu@linuxlab: ~
$ istioctl analyze -n default
✔ 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
mTLS STRICT モード設定の確認(istioctl analyze)実測
mTLS STRICT モード設定の確認(istioctl analyze)実測

この証明書は Istiod が SPIFFE 仕様で自動発行するもので、TTL は24時間。証明書の更新は自動で行われます。手動で cert-manager を管理する必要はありません。

STRICT 設定後にも ratings → productpage の通信が HTTP 200 を返したことを確認済みです。mTLS になっても既存のサービス間通信は透過的に動き続けます。

Kiali でサービスメッシュを可視化する

Kiali は Istio の公式ダッシュボードです。サービス間の通信トポロジー、mTLS の状態、エラー率をリアルタイムで確認できます。

手順10:Kiali と Prometheus をインストールする




ubuntu@linuxlab: ~
$ ADDONS_BASE=”https://raw.githubusercontent.com/istio/istio/1.22.3/samples/addons”
$ 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(名前空間の全体像)

Kiali Overview ダッシュボード(default namespace の状態)
Kiali Overview ダッシュボード(default namespace の状態)

Overview ページでは名前空間ごとにサービスの健全性がカード表示されます。緑色であれば正常稼働中です。

Kiali Graph(サービス間トポロジーマップ)

Kiali Graph:bookinfo サービスのトポロジー可視化
Kiali Graph:bookinfo サービスのトポロジー可視化

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

Kiali Services 一覧

Kiali Services 一覧(mTLS 状態確認)
Kiali Services 一覧(mTLS 状態確認)

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

Kiali Workloads 一覧

Kiali Workloads 一覧(Pod 状態と sidecar 注入確認)
Kiali Workloads 一覧(Pod 状態と sidecar 注入確認)

Workloads ページでは Pod ごとの sidecar 注入状態が確認できます。チェックマークが付いていれば Envoy sidecar が正常に動いています。

sysbench で実行環境のパフォーマンスを確認する

サービスメッシュを動かすホストの CPU 性能を sysbench で実測しました。Istio の sidecar は Pod ごとに CPU・メモリを消費するため、クラスターのリソース余裕は重要です。

sysbench CPU 実測(ubuntu:24.04 Docker / threads=4 / 3回平均)
sysbench CPU 実測(ubuntu:24.04 Docker / threads=4 / 3回平均)

私の環境(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 のままになります。




ubuntu@linuxlab: ~
$ kubectl rollout restart deployment -n default
deployment.apps/productpage-v1 restarted
deployment.apps/ratings-v1 restarted

③STRICT mTLS 設定後にサービス間通信が 503 になる

DestinationRuleISTIO_MUTUAL を設定しないと、クライアント側が平文で送り続けるため 503 エラーになります。PeerAuthentication と DestinationRule はセットで設定してください。




ubuntu@linuxlab: ~
$ istioctl analyze -n default
✔ No validation issues found when analyzing namespace: default.

istioctl analyze で問題なしが確認できれば設定は正しいです。

④Kiali のグラフが空で何も表示されない

Prometheus が起動していないか、クエリ対象のトラフィックがない場合です。先に ratings Pod から productpage へ数回リクエストを送ってみてください。




ubuntu@linuxlab: ~
$ for i in $(seq 1 10); do kubectl exec ratings-v1-xxx -c ratings — curl -s http://productpage:9080/productpage -o /dev/null; done
(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 で手を動かしてみるのが最短ルートです。

UbuntuにDockerをインストールする手順 公式手順を実機検証
UbuntuにDockerを入れるとき、apt install docker.io で済ませてしまう方をよく見かけます。一方で「それは古いからダメ、必ず公式リポジトリを使え」という解説も多いですよね。では実際どれくらい違うのか、気になりませ...

コメント

タイトルとURLをコピーしました