Contents
Istio の全体像と公式ドキュメントの確認ポイント
Istio は データプレーン(Envoy) と コントロールプレーン(istiod) で構成され、サービス間通信を一元管理します。認証・認可・暗号化はすべて宣言的な CRD(Custom Resource Definition)として定義し、Kubernetes の標準ツールで運用できる点が大きな特徴です。本セクションでは、Istio が提供する主要コンポーネントと、設定を行う際に必ず参照すべき公式ドキュメントの位置付けを示します。
- データプレーン:各 Pod にサイドカーとして注入される Envoy が実際のトラフィック制御・ポリシー適用を担当。
- コントロールプレーン:istiod が証明書管理、サービスディスカバリー、ポリシー配布などを集中して行う。
- 公式ドキュメント:設定項目(例:
jwksCacheDurationや MeshConfig の構造)はバージョンごとに微妙に変化するため、必ず対応する Istio バージョンのリファレンスを確認してください。
📌 注意:本稿で示す
jwksCacheDurationやmeshConfigMap の記述は執筆時点(Istio 1.20)に基づいていますが、実際のデプロイ環境では公式リファレンス(https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/)で最新情報を確認することを強く推奨します。
CRD バージョンと今後の移行計画
Istio が提供する認証・認可系 CRD は現在 v1beta1 がデフォルトです。Kubernetes の API 安定化ロードマップに合わせ、将来的には v1 へ段階的に移行されます。この節では v1beta1 と v1 の主な違いと、移行時に留意すべき点をまとめました。
現行バージョン(v1beta1)の特徴
- Istio 1.20 以降で推奨されている API バージョン。
apiVersion: security.istio.io/v1beta1、networking.istio.io/v1beta1が使用可能。- 既存のマニフェストがほぼそのまま動作し、安定性が確認されています。
将来の v1 移行に向けたベストプラクティス
| 項目 | v1beta1(現行) | v1(予定) | 移行時の留意点 |
|---|---|---|---|
| API パス | security.istio.io/v1beta1 |
security.istio.io/v1 |
マニフェストの apiVersion を更新するだけで済むケースが多い。 |
| 必須フィールド | 一部任意だった項目が必須になる可能性あり | フィールドの必須化が進行中 | kubectl apply --dry-run=client -f <manifest> で事前検証を実施。 |
| デフォルト動作 | PERMISSIVE がデフォルトの mTLS モード(旧バージョン) |
今後は STRICT が推奨デフォルトになる可能性あり |
PeerAuthentication の明示的設定で意図しない挙動を防止。 |
実務上の対策:CRD を管理する Git リポジトリに
apiVersionのテンプレート変数(例:{{ .Values.crdVersion }})を導入し、Istio バージョンが上がった際に一括置換できるようにしておくと移行コストが大幅に削減できます。
Istio のセキュリティ機能全体像
このセクションでは、認証 → 認可 → 暗号化 というフローで統一的に扱われる Istio の主要セキュリティ機能と、それぞれがどの CRD にマッピングされるかを整理します。読者はここで全体像を把握したうえで、以降の個別設定へスムーズに移行できます。
認証(Authentication)
PeerAuthentication:mTLS の有効化・モード切替。RequestAuthentication:JWT や OIDC トークンの検証を担当し、属性情報(claims)を Envoy に注入する。
認可(Authorization)
AuthorizationPolicy:リクエスト属性(source, destination, method, path, claims など)に基づきアクセス許可/拒否を決定。- ポリシーは Namespace → Service → Workload の階層で評価され、最上位の
DENYが優先される点が重要です。
暗号化(Encryption / mTLS)
- Istio の自動証明書管理:istiod が内部 CA を保持し、90 日有効な証明書を各 Envoy に発行。
PeerAuthenticationのSTRICTモードで全トラフィックが暗号化され、外部システムとのやり取りはDestinationRuleで TLS 設定を上書き可能。
mTLS の有効化と自動ローテーション手順
本節では グローバルに mTLS を強制 する方法と、証明書の自動ローテーションが期待通りに機能しているか確認できるコマンドを紹介します。設定例は v1beta1 の API を使用していますが、将来的な v1 移行時にも同様の構造になる点をご留意ください。
PeerAuthentication でグローバル mTLS を有効化
以下のマニフェストを istio-system Namespace に適用すると、クラスタ内すべてのサービスがデフォルトで mTLS(STRICT)を使用します。
|
1 2 3 4 5 6 7 8 9 |
apiVersion: security.istio.io/v1beta1 # 将来的に v1 へ変更予定 kind: PeerAuthentication metadata: name: default-mtls namespace: istio-system # グローバル適用はこの Namespace に配置 spec: mtls: mode: STRICT # mTLS を必須化 |
- ポイント:
STRICTモードでは TLS が確立できない接続は即座に 404(または 503)で切断されます。 - ベストプラクティス:本番環境導入前にステージングクラスタで
PERMISSIVE→STRICTの段階的移行を検証すると安全です。
DestinationRule による外部サービス向け TLS 設定
非 Istio 環境や外部 API と通信する場合は、クライアント側の DestinationRule で TLS 動作を上書きします。以下は SIMPLE モード(サーバ証明書のみ検証)と CA 証明書パスの例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
apiVersion: networking.istio.io/v1beta1 # 将来的に v1 に変更予定 kind: DestinationRule metadata: name: external-svc-mtls namespace: default spec: host: external.example.com # FQDN を指定 trafficPolicy: tls: mode: SIMPLE # サーバ証明書のみ検証 caCertificates: /etc/certs/ca.crt # 必要に応じて ConfigMap 等で提供 |
- ポイント:外部サービスが mTLS に対応していない場合でも、
SIMPLEで TLS 終端を行えるため、通信は暗号化されたままです。
証明書自動ローテーションの可視化
istiod が発行する証明書はデフォルト 90 日 の有効期限です。ローテーションは内部的に自動で行われますが、以下コマンドで現在のステータスと残存期間を確認できます。
|
1 2 3 |
# <namespace>/<service> に対して mTLS が有効かつ証明書期限を表示 istioctl authn tls-check -n prod orders-service |
出力例(抜粋):
|
1 2 3 |
SERVICE PORT TLS STATUS EXPIRY orders-service 80 ISTIO_MUTUAL OK 2026-09-15T12:34Z |
Tip:
istioctl analyze -n <ns>と併用すると、ポリシーの不整合や証明書関連の警告も同時に取得できます。
RequestAuthentication と JWKS キャッシュ設定の注意点
JWT 検証は RequestAuthentication で行い、公開鍵情報(JWKS)を外部 IdP から取得します。Istio は取得した JWKS を内部キャッシュに保持し、頻繁なネットワーク呼び出しを防止していますが、キャッシュ TTL の設定方法はバージョン間で差異があることがあります。以下では一般的な手順と、公式ドキュメントでの確認ポイントを示します。
基本的な RequestAuthentication マニフェスト
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
apiVersion: security.istio.io/v1beta1 # 将来的に v1 へ変更予定 kind: RequestAuthentication metadata: name: jwt-auth namespace: prod spec: selector: matchLabels: app: payment-service jwtRules: - issuer: "https://auth.example.com/" jwksUri: "https://auth.example.com/.well-known/jwks.json" forwardOriginalToken: true # バックエンドにトークンを転送したい場合のみ設定 |
- ポイント:
jwksUriに IdP の JWKS エンドポイントを指定すると、Istio が自動で取得・キャッシュします。 - ベストプラクティス:外部ネットワークポリシーで
auth.example.comへのアウトバウンドが許可されているか事前に確認してください。
JWKS キャッシュ TTL のチューニング例
Istio 1.20 では MeshConfig の jwtPolicy.jwksCacheDuration フィールドでキャッシュ期間を上書きできます(デフォルトは 10 分)。以下は ConfigMap に追加する例です。
|
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: v1 kind: ConfigMap metadata: name: istio-controlplane-config namespace: istio-system data: mesh: | # ... 省略された既存設定 ... jwtPolicy: jwksCacheDuration: "30m" # 30 分に延長(公式ドキュメントでキー名を必ず確認) |
📌 重要:
jwtPolicy.jwksCacheDurationのキー名は Istio バージョンによってjwksCacheDuration、jwksCacheTTL、あるいはjwksCachePeriodと変わることがあります。実際に適用する前に公式リファレンス(https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/)で正しいキー名を確認してください。
キャッシュ設定のトレードオフ
| 設定 | メリット | デメリット |
|---|---|---|
| 短め(10 〜 15 分) | 鍵ローテーションに即座に追従できる | IdP へのリクエスト頻度が上がり、レートリミットに引っかかりやすい |
| 長め(30 〜 60 分) | 外部呼び出し回数を削減し、ネットワーク負荷低減 | 鍵ローテーション後の反映遅延が発生する可能性 |
AuthorizationPolicy の階層的設計とベストプラクティス
AuthorizationPolicy は Namespace → Service → Workload の順に評価されます。正しい階層構造を意識しないと、期待しないアクセス許可やデフォルト deny が機能しなくなるリスクがあります。本節では各レベル別の実装例と、設計時に留意すべきポイントを解説します。
Namespace スコープでのデフォルト deny
Namespace 全体に対して デフォルトでアクセスを拒否 するポリシーです。下位レベルで ALLOW を明示的に設定しない限り、全トラフィックは遮断されます。
|
1 2 3 4 5 6 7 8 9 10 |
apiVersion: security.istio.io/v1beta1 # 将来的に v1 に移行予定 kind: AuthorizationPolicy metadata: name: ns-default-deny namespace: prod spec: action: DENY rules: - {} # 空ルールは「すべてのリクエスト」を対象にする |
- ポイント:
DENYが上位にあると、下位のALLOWは無効になる点を必ず意識してください。 - ベストプラクティス:新規サービスが追加された際に自動で保護されるよう、必ず Namespace にこのポリシーを配置します。
Service スコープでメソッド単位の許可
特定の Service(例: orders-service)だけ GET メソッドを許可し、それ以外はデフォルト deny が適用されます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: security.istio.io/v1beta1 # 将来的に v1 に変更予定 kind: AuthorizationPolicy metadata: name: svc-allow-get namespace: prod spec: selector: matchLabels: app: orders-service action: ALLOW rules: - to: - operation: methods: ["GET"] |
- ポイント:
to.operation.methodsに対象メソッドを列挙するだけで、他の HTTP メソッドは自動的に拒否されます。
Workload スコープで属性ベース制御(RBAC)
JWT の role クレームが admin または finance の場合のみアクセス許可します。Workload ラベルで絞り込むことで、バージョンごとの細かい権限設定が可能です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apiVersion: security.istio.io/v1beta1 # 将来的に v1 に変更予定 kind: AuthorizationPolicy metadata: name: workload-role-based namespace: prod spec: selector: matchLabels: app: payment-service version: v2 action: ALLOW rules: - when: - key: request.auth.claims[role] values: ["admin", "finance"] |
- ポイント:
request.auth.claims[...]はRequestAuthenticationが正しく設定されていることが前提です。 - ベストプラクティス:クレーム名のスペルミスや大小文字の違いでポリシーがマッチしないケースが多いため、IdP 側のクレーム定義と合わせてテストを行うこと。
ポリシー評価順序のまとめ表
| 階層 | 適用対象 | 評価順序 | 典型的な action |
|---|---|---|---|
| Namespace | 全 Service / Workload | 1 | DENY(デフォルト) |
| Service | 同名 Service の全 Pod | 2 | ALLOW(メソッド単位) |
| Workload | ラベルで絞り込んだ Pod | 3 | ALLOW(属性ベース) |
- ポイント:同一リクエストが複数のポリシーにヒットした場合、
ALLOWが優先されます。ただし、上位層でDENYが設定されていると最終的に拒否になります。
ポリシー検証・可視化とトラブルシューティング手順
ポリシーが期待通りに適用されたかは CLI と UI(Kiali) の両方で確認できます。本節では代表的なコマンド、ダッシュボードの見方、そしてよくあるエラーとその対処法を具体例付きで紹介します。
istioctl 系コマンドによる基本チェック
| コマンド | 目的 | 主な出力例 |
|---|---|---|
istioctl authn tls-check -n <ns> <svc> |
サービスの mTLS 状態と証明書有効期限を確認 | ISTIO_MUTUAL OK EXPIRY=2026-09-15T12:34Z |
istioctl analyze -n <ns> |
CRD の構文エラーやポリシー競合を検出 | warning: AuthorizationPolicy ... may be shadowed by a higher‑level DENY |
kubectl get meshconfig -o yaml(Istiod が ConfigMap で提供) |
MeshConfig 全体設定(JWKS キャッシュ含む)の確認 | jwtPolicy:\n jwksCacheDuration: "30m" |
- ベストプラクティス:CI パイプラインに
istioctl analyzeを組み込み、マージ前にポリシーの整合性を自動検証します。
Kiali ダッシュボードでの可視化
- ポートフォワーディング
bash
kubectl -n istio-system port-forward svc/kiali 20001:20001 - ブラウザで
http://localhost:20001にアクセスし、対象 Namespace を選択。 -
グラフ表示画面左上の 「Security」アイコン(鍵マーク)が出ているノードはポリシーが適用中です。
-
ポイント:Kiali の「Policies」タブで
AuthorizationPolicyやPeerAuthenticationが一覧化され、どの Service がどのポリシーにバインドされているか一目で把握できます。
代表的なエラーと対処フロー
| エラーコード | 発生シナリオ | 推奨調査手順 |
|---|---|---|
CERTIFICATE_VERIFY_FAILED |
Envoy が期待する証明書と不一致(例:古い証明書が残存) | 1. istioctl authn tls-checkで有効期限確認 2. DestinationRule の caCertificates を最新に更新 |
JWT_VERIFICATION_FAILURE |
JWKS が取得できない、またはトークン署名が不正 | 1. IdP の .well-known/jwks.json に直接アクセスして JSON が返るか確認 2. ネットワークポリシーでアウトバウンド許可を再チェック |
403 Forbidden (AuthorizationPolicy) |
ポリシーにマッチしないリクエストが来た | 1. kubectl logs -l app=istiod -n istio-system で Envoy デバッグログ取得 2. when.key のスペル・ケースと values が正しいか再確認 |
デバッグプロキシの活用例
|
1 2 3 4 5 6 7 |
# 対象 Pod の名前を取得 POD=$(kubectl get pod -n prod -l app=orders-service -o jsonpath='{.items[0].metadata.name}') # サイドカー Envoy に対して直接 curl(TLS 無効化)し、ポリシー適用状況を確認 kubectl exec -n prod $POD -c istio-proxy -- \ curl -s -k http://127.0.0.1:15020/metrics | grep envoy_http_conn_manager |
- ポイント:管理ポート(デフォルト 15020)から取得できるメトリクスに
envoy_http_conn_managerの統計情報が含まれ、許可/拒否のカウントをリアルタイムで確認できます。
CI/CD パイプラインへの自動適用と 2026 年版ベストプラクティス
運用フェーズでは コードとしてポリシーを管理 し、手作業による設定ミスを防止することが必須です。ここでは Helm と ArgoCD を組み合わせた GitOps パターンの実装例と、2026 年に向けて推奨される設定項目をまとめます。
Helm チャート構造とテンプレート化
|
1 2 3 4 5 6 7 8 |
istio-policies/ ├── Chart.yaml ├── values.yaml # 環境別パラメータ(mtlsMode, jwtIssuer, jwksUri 等) └── templates/ ├── peer-authentication.yaml ├── authorizationpolicy-namespace.yaml └── requestauthentication.yaml |
values.yaml の抜粋例:
|
1 2 3 4 5 6 |
# values.yaml crdVersion: "v1beta1" # 将来的に v1 へ切り替える変数 mtlsMode: STRICT jwtIssuer: "https://auth.example.com/" jwksUri: "https://auth.example.com/.well-known/jwks.json" |
templates/peer-authentication.yaml
|
1 2 3 4 5 6 7 8 9 |
apiVersion: security.istio.io/{{ .Values.crdVersion }} kind: PeerAuthentication metadata: name: default-mtls namespace: istio-system spec: mtls: mode: {{ .Values.mtlsMode }} |
- ポイント:
{{ .Values.crdVersion }}を変数化しておくと、Istio のバージョンアップ時にv1へ一括置換可能です。
ArgoCD アプリケーション定義(YAML)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: istio-policies-prod spec: project: default source: repoURL: https://github.com/your-org/istio-policies.git targetRevision: HEAD path: charts/istio-policies helm: values: | crdVersion: v1beta1 mtlsMode: STRICT jwtIssuer: "https://auth.example.com/" jwksUri: "https://auth.example.com/.well-known/jwks.json" destination: server: https://kubernetes.default.svc namespace: prod syncPolicy: automated: prune: true selfHeal: true # 手動変更があれば自動で復元 |
- ベストプラクティス:
selfHealを有効にすると、運用中に誰かがkubectl editした場合でも Git の定義と乖離しないよう自動で修正されます。
2026 年版推奨設定チェックリスト
| 項目 | 推奨設定(Istio 1.20) | 将来の移行ポイント |
|---|---|---|
| mTLS モード | STRICT(デフォルトで有効化) |
PERMISSIVE は非推奨、削除予定 |
| JWT キャッシュ TTL | jwksCacheDuration: "30m" 以上 |
キー名が変わる可能性あり → ドキュメント確認必須 |
AuthorizationPolicy の action |
明示的に ALLOW / DENY を記述 |
空のポリシーは暗黙的許可になる危険性 |
| CRD バージョン | v1beta1(現行) |
v1 へ段階的移行、apiVersion の変数化が有効 |
| 証明書有効期限 | デフォルト 90 日 | caCertificateValidityDuration によりカスタマイズ可能(公式ドキュメント参照) |
実装ヒント:CI パイプラインのステージで
istioctl analyze -n <ns>とhelm lintを組み合わせ、ポリシー定義が正しいか自動検証すると、リリース前にミスを捕捉できます。
まとめ
| 項目 | 要点 |
|---|---|
| 全体像 | データプレーンとコントロールプレーンの分離で、認証・認可・暗号化を宣言的に管理できる。 |
| mTLS 設定 | PeerAuthentication(STRICT)でグローバル有効化し、外部向けは DestinationRule で調整。自動ローテーションはデフォルトで機能するが、istioctl authn tls-check で可視化推奨。 |
| 認証・JWKS | RequestAuthentication に JWKS URI を設定し、Cache TTL は MeshConfig の jwtPolicy.jwksCacheDuration(公式ドキュメントでキー名を必ず確認)で調整可能。 |
| 認可設計 | Namespace → Service → Workload の階層でデフォルト deny を配置し、最小権限の原則に沿った ALLOW ポリシーを明示的に追加。 |
| 検証・トラブルシューティング | istioctl 系コマンドと Kiali ダッシュボードでポリシー状態を確認し、代表エラーは証明書不一致・JWT 検証失敗・AuthorizationPolicy のミスマッチが中心。 |
| CI/CD と将来の移行 | Helm + ArgoCD による GitOps が標準的な運用手法。crdVersion 変数化で v1beta1 → v1 移行をスムーズにし、2026 年版ベストプラクティス(STRICT mTLS、長めの JWKS キャッシュ等)に合わせて設定を調整する。 |
以上の手順と注意点を踏まえて、Istio 1.20 環境で 安全・自動化されたセキュリティポリシー運用 を実現してください。公式ドキュメントは常に最新情報の唯一の信頼ソースですので、設定変更前に必ず該当バージョンのリファレンスを確認することを忘れないでください。