Contents
Linkerd のセキュリティ基礎と自動 mTLS
Kubernetes 上でマイクロサービス間の通信を安全に保つ第一歩は、Linkerd が提供する 自動 mTLS と証明書管理です。この章では、仕組みの概要とデフォルトで有効化できる最小構成を示し、実際に導入したときに期待できる効果をまとめます。
自動 mTLS の仕組み
Linkerd は各 Pod にサイドカー proxy(linkerd-proxy)を注入し、プロキシがすべての inbound/outbound 通信に対して TLS ハンドシェイクと証明書更新を自動で行います。
- 自動暗号化: サービス間のトラフィックは手動設定なしで TLS に保護されます。
- 証明書管理: 証明書は Linkerd の Identity コンポーネントが 24 時間ごとにローテーションし、失効や期限切れを防ぎます。
デフォルトインストール手順(CLI)
以下のコマンドだけで、Linkerd コントロールプレーンとデータプレーンをインストールできます。--identity-trust-anchors-file は Helm ではなく linkerd install の出力に含める形です。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# 1. Linkerd CLI と helm がインストールされていることを確認 linkerd version # 2. デフォルト設定でコントロールプレーンをデプロイ linkerd install | kubectl apply -f - # 3. 自動サイドカー注入用のネームスペースにラベル付与 kubectl label namespace default linkerd.io/inject=enabled # 4. 動作確認 linkerd check |
ポイント:
linkerd installの出力にはidentityTrustAnchorsPEMが組み込まれているため、別途フラグを指定する必要はありません。
設定検証とローテーションテスト
インストール後に以下のコマンドで Identity が正しく稼働していることを確認します。
|
1 2 3 4 5 6 |
# Identity の状態を取得 linkerd identity check # プロキシ側のバージョン情報と TLS 状態を表示 linkerd -n default stat deploy --proxy-version |
出力に Identity is ready と表示され、プロキシが最新証明書を使用していることが確認できれば完了です。
コントロールプレーン保護と Kubernetes ベストプラクティス
Linkerd のコントロールプレーンはクラスタ全体の認証基盤となるため、RBAC・Pod Security Standards(PSS)・CIS Benchmarks に沿った最小権限設定が不可欠です。この章では具体的なマニフェスト例と運用上の留意点を示します。
RBAC の最小権限設計
Linkerd コンポーネントは ServiceAccount 経由で API Server と通信しますが、必要な操作は 読み取り と Pod/Service の監視 に限定できます。以下は推奨する ClusterRole と ClusterRoleBinding の例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: linkerd-controller-minimal rules: - apiGroups: [""] resources: ["pods", "services"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: linkerd-controller-minimal-binding subjects: - kind: ServiceAccount name: linkerd-controller namespace: linkerd roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: linkerd-controller-minimal |
ポイント:
admin権限や*ワイルドカードは避け、必要最小のリソースと verb のみを列挙します。
Pod Security Standards(PSS)での制御プレーン固化
Linkerd のポッドには特権モードやホストネットワークを許可しない restricted プロファイルを適用します。
|
1 2 3 4 5 |
kubectl label namespace linkerd \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/warn=restricted |
このラベルにより、以下のポリシーが自動的に有効化されます。
allowPrivilegeEscalation: falserunAsNonRoot: truereadOnlyRootFilesystem: true
CIS Benchmark に基づく定期評価
CIS Kubernetes Benchmark の 5.2(API Server の認証設定)・6.1/6.2(ネットワークポリシーと RBAC)の項目は、Linkerd デプロイ時に必ずチェックすべきポイントです。kube-bench を CI に組み込む例を示します。
|
1 2 3 4 5 6 7 |
# GitHub Actions のジョブ例 - name: Run kube‑bench CIS checks run: | curl -L https://github.com/aquasecurity/kube-bench/releases/download/v0.7.1/kube-bench_0.7.1_linux_amd64.tar.gz | tar xz ./kube-bench --benchmark cis-1.23 > kube-bench-report.txt # CI に結果をアップロード |
ポイント: レポートは毎週実行し、スコアが 90 %以上であることを目標に保守します。
Linkerd 2‑edge と Gateway API の統合
エッジプロキシとしての Linkerd 2‑edge は、Kubernetes 標準の Gateway API と組み合わせることで、外部トラフィックの TLS 終端と内部 mTLS を一貫して管理できます。ここでは実装フローと主要リソースを解説します。
Gateway API リソースでエッジプロキシを構成
まずは GatewayClass(Linkerd が提供)と Gateway、HTTPRoute の三つのオブジェクトを作成します。以下は最小構成です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
apiVersion: gateway.networking.k8s.io/v1beta1 kind: GatewayClass metadata: name: linkerd spec: controllerName: io.linkerd.gateway --- apiVersion: gateway.networking.k8s.io/v1beta1 kind: Gateway metadata: name: edge-gateway namespace: edge spec: gatewayClassName: linkerd listeners: - protocol: HTTPS port: 443 tls: mode: Terminate # TLS をエッジで終端 certificateRef: group: core kind: Secret name: edge-tls-secret # 事前に作成した TLS secret |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: demo-httproute namespace: edge spec: parentRefs: - name: edge-gateway namespace: edge rules: - matches: - path: type: Prefix value: / forwardTo: - serviceName: demo-service port: 80 |
ポイント:
Gatewayが TLS を終端すると、Linkerd のデータプレーンが自動的に内部トラフィックへ mTLS を適用します。
エッジ側認可ポリシーの設定例
Linkerd は policy.linkerd.io/v1beta1 系の CRD として AuthorizationPolicy を提供しています。以下は特定 ServiceAccount のみアクセスを許可する例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
apiVersion: policy.linkerd.io/v1beta1 kind: AuthorizationPolicy metadata: name: edge-authz-demo namespace: edge spec: targetRef: kind: Service name: demo-service rules: - from: - requestPrincipals: ["cluster.local/ns/edge/sa/allowed-client"] |
このポリシーは、Edge Proxy が JWT 等で認証されたクライアントの requestPrincipal を検査し、一致しないリクエストを 403 で拒否します。
Trust Anchor と証明書チェーン管理のベストプラクティス
Linkerd の信頼基盤は Trust Anchor(CA) です。安全に保管・ローテーションできなければ、全サービスの TLS が無効化されるリスクがあります。この章では外部シークレットストアと連携した実装手順を詳述します。
外部 CA(HashiCorp Vault)との統合フロー
- Vault に PKI シークレットエンジンを有効化
bash
vault secrets enable pki
vault write pki/root/generate/internal common_name="linkerd-ca" ttl=8760h
- CSR 発行用ロールを作成(Linkerd が CSR を送信できるように)
bash
vault write pki/roles/linkerd \
allowed_domains="svc.cluster.local" \
allow_subdomains=true \
max_ttl="72h"
- Kubernetes 側で Vault トークンを保持する Secret
bash
kubectl create secret generic vault-token \
--from-literal=token=$(vault token create -policy=linkerd -period=72h -format=json | jq -r .auth.client_token) \
-n linkerd
- Linkerd の values.yaml に外部 CA 設定を記述
yaml
identity:
externalCA:
enabled: true
address: vault.example.com:8200 # Vault アドレス
tokenSecretName: vault-token # 上で作成した Secret 名
caBundleConfigMapName: linkerd-ca-bundle
- Helm でデプロイ(または upgrade)
bash
helm repo add linkerd https://helm.linkerd.io/stable
helm upgrade --install linkerd linkerd/linkerd2 \
-n linkerd \
-f values.yaml
ポイント:
identity.externalCA.enabledが true の場合、Linkerd は起動時に Vault へ CSR を送信し、取得した証明書とチェーンを自動で更新します。
Trust Anchor のローテーション自動化
Vault の pki/rotate-root API と Kubernetes CronJob を組み合わせることで、年間単位のルート証明書ローテーションを自動化できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
apiVersion: batch/v1 kind: CronJob metadata: name: linkerd-ca-rotate namespace: linkerd spec: schedule: "0 2 * * 1" # 毎週月曜 02:00 に実行 jobTemplate: spec: template: spec: serviceAccountName: linkerd-controller containers: - name: vault-rotate image: hashicorp/vault:latest env: - name: VAULT_ADDR value: "https://vault.example.com:8200" command: ["sh", "-c"] args: - | vault write -format=json pki/rotate-root > /tmp/rotate.json && \ cat /tmp/rotate.json | jq -r .data.certificate > /certs/new-ca.crt && \ kubectl create secret generic linkerd-trust-anchor \ --from-file=crt=/certs/new-ca.crt \ -n linkerd --dry-run=client -o yaml | kubectl apply -f - restartPolicy: OnFailure |
証明書チェーンの検証方法
Linkerd の診断コマンドでチェーン整合性を確認できます。
|
1 2 3 4 |
linkerd diagnostics cert verify \ --namespace default \ --pod demo-pod-abcde |
期待される出力: Certificate chain is valid が表示されたら正常です。異常があれば、以下のようにプロキシログで詳細を取得します。
|
1 2 3 |
kubectl logs -n linkerd -l linkerd.io/control-plane-component=proxy -c linkerd-proxy \ | grep "certificate verification failed" |
監視・ロギング、トラブルシューティングと実装事例
Linkerd の観測機能は Tap と Metrics API に集約されており、Prometheus + Grafana と組み合わせることで TLS エラーや認可違反をリアルタイムに把握できます。この章では主要メトリクスと障害時の復旧フローを示します。
Tap と Metrics API を用いたセキュリティ指標取得
Tap は HTTP/gRPC リクエストをミラーし、Metrics API は集計済みデータを公開します。TLS 関連で注目すべきメトリクスは次のとおりです。
| メトリクス名 | 意味 | 推奨する PromQL |
|---|---|---|
linkerd_proxy_server_connection_failure_total |
プロキシ側の接続失敗(TLS ハンドシェイク含む) | sum(rate(linkerd_proxy_server_connection_failure_total[5m])) |
linkerd_policy_error_total{type="authorization"} |
認可ポリシー違反件数 | sum(rate(linkerd_policy_error_total{type="authorization"}[5m])) |
linkerd_identity_issuer_cert_expiry_seconds |
発行証明書の有効期限(秒) | avg(linkerd_identity_issuer_cert_expiry_seconds) |
これらを Grafana のパネルに組み込むだけで、異常が検知された瞬間にアラートを発砲できます。
Prometheus + Grafana ダッシュボード例
公式リポジトリの grafana-dashboards/linkerd.json をインポートし、以下のカスタムウィジェットを追加します。
- TLS エラー率(5 分間平均)
promql
sum(rate(linkerd_proxy_server_connection_failure_total[5m])) / sum(rate(linkerd_proxy_server_connections_total[5m])) - 認可エラー上位 5 Service
promql
topk(5, sum by (destination_service) (rate(linkerd_policy_error_total{type="authorization"}[5m])))
ダッシュボード作成後は、Alertmanager と連携させて Slack や Microsoft Teams に通知を送る設定も忘れずに行いましょう。
証明書エラー・mTLS 無効時のフェイルオーバー手順
- エラーログの確認
bash
linkerd diagnostics proxy-metrics -n <namespace> | grep failure
- プロキシ再起動(最優先)
bash
kubectl rollout restart deployment/linkerd-proxy-injector -n linkerd
- 証明書ローテーションを手動でトリガー
bash
linkerd identity secret create \
--namespace linkerd \
--name trust-anchor \
--cert ca.crt --key ca.key
- 緊急時は非暗号化モードへ切替(監査ログ必須)
bash
helm upgrade linkerd/linkerd2 -n linkerd \
--set proxy.insecure=true
# 変更は即座に反映され、全プロキシが平文通信になるので注意
ポイント: 非暗号化モードへの切替は最終手段とし、必ず監査ログ(
kubectl logs -n linkerd linkerd-proxy-<id>)に記録しておきます。
エッジコンピューティング環境での追加セキュリティ対策
Rancher / RKE2 などのマルチクラスタ管理プラットフォームでも、Linkerd 2‑edge を安全に運用するためのベストプラクティスをまとめます。
Rancher UI から Service Mesh の有効化
- Cluster → Edit → Add‑On → Service Mesh をオンにし、バージョンと「Edge mode(Gateway API)」を選択。
- Rancher が自動的に
linkerd名前空間・RBAC・PSS ラベルを作成しますが、必要なら カスタム RBAC を追加してください。
ポイント: UI で有効化した場合でも、外部 CA(Vault)や独自の AuthorizationPolicy は別途マニフェストで適用する必要があります。
エッジノード間の証明書同期
エッジノードはすべて同一の Trust Anchor に対して CSR を送信し、取得した証明書をローカルにキャッシュします。以下は 12 時間ごとに再取得する CronJob の例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
apiVersion: batch/v1 kind: CronJob metadata: name: linkerd-edge-cert-sync namespace: linkerd spec: schedule: "0 */12 * * *" jobTemplate: spec: template: spec: serviceAccountName: linkerd-controller containers: - name: cert-sync image: ghcr.io/linkerd/cert-sync:stable args: ["--anchor-secret=linkerd-trust-anchor"] restartPolicy: OnFailure |
このジョブは Vault から新しい証明書を取得し、linkerd-trust-anchor Secret を上書きすることで、全エッジノードが同一チェーンを共有できるようにします。
分散環境でのポリシー統一
Gateway API の HTTPRoute に共通の filters(例: JWT 検証)や AuthorizationPolicy を適用すれば、エッジごとに個別設定を行う必要がなくなります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apiVersion: policy.linkerd.io/v1beta1 kind: AuthorizationPolicy metadata: name: edge-jwt-authz namespace: edge spec: targetRef: kind: Service name: demo-service rules: - from: - requestAuthenticated: jwt: issuer: "https://issuer.example.com" audiences: ["demo"] |
まとめ
- 自動 mTLS と証明書ローテーション はデフォルトで有効化し、外部 CA(Vault 等)と連携すれば鍵管理が一元化できる。
- コントロールプレーンは RBAC・PSS・CIS Benchmark に沿って最小権限で運用 し、
kube-benchで定期的にスコアを測定する。 - Linkerd 2‑edge と Gateway API の統合 により、エッジで TLS 終端と認可ポリシーがコードベースだけで完結できる。
- Trust Anchor は外部シークレットストアに保管し、Vault の CSR/CSR ロールと CronJob でローテーション自動化 することで証明書チェーンの整合性を担保する。
- Tap と Metrics API を活用した可視化 によって TLS エラーや認可違反をリアルタイムに検知し、Prometheus/Grafana のアラートで即時対応できる。
- 障害時はプロキシ再起動→証明書ローテーション強制→最終手段として非暗号化モード へ切り替える手順を標準化しておく。
- Rancher / RKE2 環境でも UI 有効化と外部 CA 設定を組み合わせ、CronJob で証明書同期 させることでエッジコンピューティングでも一貫したセキュリティ基盤が構築できる。
上記チェックリストを順に実装すれば、Kubernetes クラスタ全体で 安全かつ可観測性の高い Linkerd サービスメッシュ を運用できます。