service-mesh について
Kubernetes 運用担当者向けのサービスメッシュスキルです。Istio または Linkerd によるサービス間通信の管理を案内し、セキュリティ、トラフィック制御、可観測性、ポリシー適用を扱います。
主な機能
- 01サービス間 mTLS の設定
- 02トラフィック分割とルーティング
- 03サーキットブレーカー、再試行、タイムアウトの追加
- 04サービスレベルの可観測性の確認
- 05サービス認可ポリシーの定義
活用シーン
- 01マイクロサービス通信の自動 mTLS 化
- 02カナリアリリースや A/B テストの設定
- 03アプリケーションコードを変えずに再試行を追加
- 04サービス間アクセスの制限
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill service-meshインストール後、Claude Code で/service-meshを入力して読み込まれたか確認します。
詳細
サービスメッシュ
Istio または Linkerd を使用して、mTLS、トラフィックシェーピング、可観測性、ポリシー適用によるサービス間通信管理を実装します。
使用する場面
- 自動 mTLS によってマイクロサービス間の通信を保護するとき。
- カナリアデプロイ、トラフィック分割、A/B テストを実装するとき。
- アプリケーションコードを変更せずに、サーキットブレーカー、再試行、タイムアウトを追加するとき。
- サービスレベルの可観測性(レイテンシ、エラー率、リクエスト数)を得るとき。
- サービス間の認可ポリシーを適用するとき。
前提条件
- kubectl を設定済みの Kubernetes クラスター(1.26 以降)。
- Helm 3 がインストール済み(一部のインストール方法で必要)。
- 十分なクラスターリソース(Istio コントロールプレーンには約 2 GB の RAM が必要)。
- Istio の場合:
istioctlCLI がインストール済み。 - Linkerd の場合:
linkerdCLI がインストール済み。
Istio のインストール
istioctl でインストール
# Download istioctl
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
# Install with the production profile
istioctl install --set profile=default -y
# Or use the demo profile (includes all addons, good for learning)
istioctl install --set profile=demo -y
# Verify installation
istioctl verify-install
# Check running components
kubectl get pods -n istio-system
サイドカーインジェクションを有効化
# Enable automatic sidecar injection for a namespace
kubectl label namespace default istio-injection=enabled
# Verify label
kubectl get namespace default --show-labels
# Restart existing pods to inject sidecars
kubectl rollout restart deployment -n default
# Check sidecar status
kubectl get pods -n default -o jsonpath='{range .items[*]}{.metadata.name}{" containers: "}{range .spec.containers[*]}{.name}{" "}{end}{"\n"}{end}'
可観測性アドオンをインストール
# Install Kiali, Prometheus, Grafana, Jaeger
kubectl apply -f samples/addons/prometheus.yaml
kubectl apply -f samples/addons/grafana.yaml
kubectl apply -f samples/addons/jaeger.yaml
kubectl apply -f samples/addons/kiali.yaml
# Wait for rollout
kubectl rollout status deployment/kiali -n istio-system
# Access dashboards
istioctl dashboard kiali
istioctl dashboard grafana
istioctl dashboard jaeger
トラフィック管理
VirtualService(ルーティングルール)
# virtualservice.yaml — canary deployment with traffic split
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my-app
namespace: default
spec:
hosts:
- my-app
http:
# Header-based routing (canary testers)
- match:
- headers:
x-canary:
exact: "true"
route:
- destination:
host: my-app
subset: canary
# Percentage-based traffic split
- route:
- destination:
host: my-app
subset: stable
weight: 90
- destination:
host: my-app
subset: canary
weight: 10
timeout: 30s
retries:
attempts: 3
perTryTimeout: 10s
retryOn: gateway-error,connect-failure,refused-stream
DestinationRule(サブセットと接続ポリシー)
# destinationrule.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-app
namespace: default
spec:
host: my-app
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
h2UpgradePolicy: DEFAULT
http1MaxPendingRequests: 100
http2MaxRequests: 1000
maxRequestsPerConnection: 10
outlierDetection:
consecutive5xxErrors: 5
interval: 10s
baseEjectionTime: 30s
maxEjectionPercent: 50
subsets:
- name: stable
labels:
version: v1
- name: canary
labels:
version: v2
Gateway(イングレストラフィック)
# gateway.yaml — expose service to external traffic
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: app-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: app-tls-cert # Kubernetes secret
hosts:
- app.example.com
- port:
number: 80
name: http
protocol: HTTP
hosts:
- app.example.com
tls:
httpsRedirect: true
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: app-external
namespace: default
spec:
hosts:
- app.example.com
gateways:
- app-gateway
http:
- route:
- destination:
host: my-app
port:
number: 8080
mTLS の設定
厳格な mTLS(クラスター全体)
# peer-authentication.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system # Applies to entire mesh
spec:
mtls:
mode: STRICT
許容モードの mTLS(名前空間ごと)
# Allow both plaintext and mTLS during migration
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: legacy-apps
spec:
mtls:
mode: PERMISSIVE
mTLS の状態を確認
# Check mTLS status for a namespace
istioctl x describe pod <pod-name> -n default
# View TLS configuration
istioctl proxy-config cluster <pod-name>.default --fqdn my-app.default.svc.cluster.local -o json | grep -A5 "tlsContext"
# Verify with istioctl authn
istioctl authn tls-check <pod-name>.default my-app.default.svc.cluster.local
認可ポリシー
# authz-policy.yaml — only allow frontend to call API
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: api-access
namespace: default
spec:
selector:
matchLabels:
app: my-api
action: ALLOW
rules:
- from:
- source:
principals:
- "cluster.local/ns/default/sa/frontend"
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*"]
---
# Deny all other traffic to api
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: default
spec:
selector:
matchLabels:
app: my-api
action: DENY
rules:
- from:
- source:
notPrincipals:
- "cluster.local/ns/default/sa/frontend"
サーキットブレーキング
# circuit-breaker.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-api-circuit-breaker
spec:
host: my-api
trafficPolicy:
connectionPool:
tcp:
maxConnections: 50
http:
http1MaxPendingRequests: 50
http2MaxRequests: 100
maxRetries: 3
outlierDetection:
consecutive5xxErrors: 3
interval: 15s
baseEjectionTime: 60s
maxEjectionPercent: 100
Linkerd のインストール
# Install Linkerd CLI
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh
export PATH=$HOME/.linkerd2/bin:$PATH
# Validate cluster prerequisites
linkerd check --pre
# Install Linkerd CRDs
linkerd install --crds | kubectl apply -f -
# Install Linkerd control plane
linkerd install | kubectl apply -f -
# Verify installation
linkerd check
# Inject sidecar into a namespace
kubectl get deploy -n my-app -o yaml | linkerd inject - | kubectl apply -f -
# Or annotate namespace for auto-injection
kubectl annotate namespace my-app linkerd.io/inject=enabled
# View live traffic dashboard
linkerd viz install | kubectl apply -f -
linkerd viz dashboard
Linkerd トラフィック分割(SMI)
# traffic-split.yaml
apiVersion: split.smi-spec.io/v1alpha4
kind: TrafficSplit
metadata:
name: my-app-split
namespace: default
spec:
service: my-app
backends:
- service: my-app-stable
weight: 900
- service: my-app-canary
weight: 100
デバッグ
# Istio: check proxy configuration
istioctl proxy-config routes <pod-name>.default
istioctl proxy-config clusters <pod-name>.default
istioctl proxy-config listeners <pod-name>.default
# Istio: analyze configuration for issues
istioctl analyze -n default
# Istio: proxy debug logs
istioctl proxy-config log <pod-name>.default --level debug
# Linkerd: check proxy stats
linkerd viz stat deploy -n default
linkerd viz top deploy/my-app -n default
linkerd viz edges deploy -n default
トラブルシューティング
| 症状 | 原因 | 対処方法 |
|---|---|---|
| サイドカーがインジェクションされない | 名前空間のラベルがない | istio-injection=enabled ラベルを追加し、ポッドを再起動します |
| サービス間で 503 エラーが発生する | mTLS の不一致(一方が平文) | 移行中は PeerAuthentication を PERMISSIVE に設定します |
| メッシュのインストール後にレイテンシが高い | サイドカーのリソース制限が低すぎる | メッシュ設定でサイドカーの CPU/メモリ制限を増やします |
| VirtualService がルーティングしない | DestinationRule のサブセットがない | サブセットラベルが一致する DestinationRule を作成します |
upstream connect error | サーキットブレーカーが作動した | 外れ値検出の設定を確認し、しきい値を上げます |
| 認可ポリシーがすべてをブロックする | 一致する許可ルールのないデフォルト拒否 | 全拒否の前に明示的な ALLOW ルールを追加します |
| Kiali のトラフィック表示が「Unknown」になる | 呼び出し元のサービスにサイドカーがない | 通信するすべてのサービスにサイドカーをインジェクションします |
関連スキル
- 負荷分散 - Kubernetes 外部でのレイヤー 4/7 負荷分散
- リバースプロキシ - イングレスレベルのプロキシ処理
- AI 推論サービスメッシュ - ML ワークロード向けのメッシュパターン
- DNS 管理 - メッシュのイングレスゲートウェイ向け DNS
コメント
Markdown 対応