Contents
前提条件と環境整備
Linkerd のマルチクラスタ機能を有効化するには、Kubernetes クラスタのバージョンと CLI ツールが一定以上であること、そして各クラスタ間で IP アドレス空間が衝突しない 設計が不可欠です。この節ではそれらを確認・整備する手順を示します。
Kubernetes バージョンと CLI の要件
Linkerd 2.13(執筆時点の最新安定版)は Kubernetes API 1.27 以上 を前提に動作します。kubectl はクラスタの API サーバーと互換性があるバージョンであれば問題ありませんが、最低でも v1.27.x が推奨されます。
|
1 2 3 4 5 6 |
# kubectl のバージョン確認(クライアント側) kubectl version --client --short # 例: v1.27.3 # クラスタの API バージョン確認 kubectl version -o jsonpath='{.serverVersion.gitVersion}' |
ポイント
*kubectlが古すぎるとlinkerd checkの一部チェックが失敗します。必要に応じて公式サイトからアップデートしてください。
CIDR 設計のベストプラクティス
マルチクラスタ間で Service CIDR と Pod CIDR が重複すると、ServiceMirror が生成した Service が名前解決できなくなります。以下は 2 クラスタ構成を想定した典型的な設計例です(/16 のサブネットを使用)。
| 項目 | クラスタ A | クラスタ B |
|---|---|---|
| Pod CIDR | 10.0.0.0/16 | 10.1.0.0/16 |
| Service CIDR | 10.96.0.0/16 | 10.112.0.0/16 |
| 必要ポート | 4143 (gateway), 4191 (identity) の TCP 開放 |
備考
* 多くのマネージドサービスでは Service CIDR に/16がデフォルトです。独自に拡張する場合は必ず重複チェックを行いましょう。
コントロールプレーンのインストール
本章では CLI と Helm の両方で Linkerd コントロールプレーンをデプロイする手順を示します。どちらの方法でも、マルチクラスタ向けに必要な拡張機能(ServiceMirror・gateway)を有効化しています。
CLI (linkerd install) によるインストール
linkerd install は Helm と同等の設定が可能ですが、シンプルさと即時検証が利点です。以下はマルチクラスタ環境で推奨するオプションです。
--set extensions.serviceMirroring.enabled=true… ServiceMirror 拡張を有効化--set identity.issuer.scheme=kubernetes… Kubernetes の ServiceAccount を利用した証明書発行(デフォルト)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# クラスタ A にインストール kubectl config use-context cluster-a linkerd install \ --set extensions.serviceMirroring.enabled=true \ --set identity.issuer.scheme=kubernetes \ | kubectl apply -f - # クラスタ B でも同様に実行 kubectl config use-context cluster-b linkerd install \ --set extensions.serviceMirroring.enabled=true \ --set identity.issuer.scheme=kubernetes \ | kubectl apply -f - |
注意
--disable-heartbeatやgateway.tls.enabledといったフラグは Linkerd 2.x には存在しません。代わりに拡張機能の有効化はextensions.*系の設定で行います。
Helm Chart を用いたインストール
CI/CD パイプラインへの組み込みやバージョン管理が必要な場合は Helm が便利です。公式チャートは linkerd/linkerd2 にあります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# リポジトリ登録(2024年現在の URL) helm repo add linkerd https://helm.linkerd.io/stable helm repo update # クラスタ A へデプロイ kubectl config use-context cluster-a helm upgrade --install linkerd-control-plane linkerd/linkerd2 \ --namespace linkerd \ --create-namespace \ --set extensions.serviceMirroring.enabled=true \ --version 2.13.4 # 執筆時点の最新安定版 # クラスタ B でも同様に実行 kubectl config use-context cluster-b helm upgrade --install linkerd-control-plane linkerd/linkerd2 \ --namespace linkerd \ --create-namespace \ --set extensions.serviceMirroring.enabled=true \ --version 2.13.4 |
ポイント
Helm の--setオプションは CLI と同様のキー構造を持ちます。バージョン指定 (--version) を忘れないようにしてください。
インストール後の検証
インストールが完了したら、必ず Linkerd のヘルスチェック を実行します。マルチクラスタではそれぞれのクラスタで個別に確認し、すべて PASS が出ることを目指します。
|
1 2 3 4 5 6 7 8 9 10 |
# クラスタ A kubectl config use-context cluster-a linkerd check --pre # 前提条件チェック(CRD の有無等) linkerd check # 実稼働チェック # クラスタ B でも同様に実施 kubectl config use-context cluster-b linkerd check --pre linkerd check |
ServiceMirror と linkerd‑gateway の設定
ServiceMirror により、あるクラスタの Service が別クラスタから参照できるようになります。ここでは CRD 有効化 → マニフェスト適用 → 外部アクセス可能な gateway デプロイ までを順に示します。
ServiceMirror 拡張機能の有効化
既に linkerd install の際に extensions.serviceMirroring.enabled=true を指定していますが、追加で gateway 用拡張 を有効にすると外部からのトラフィック受信が可能になります。
|
1 2 3 4 5 6 7 |
# 例: クラスタ B(gateway 配置先)に gateway 拡張を適用 kubectl config use-context cluster-b linkerd install \ --set extensions.serviceMirroring.enabled=true \ --set extensions.gateway.enabled=true \ | kubectl apply -f - |
結果
servicemirror.linkerd.io/v1beta2とgateway.linkerd.io/v1alpha1の CRD が作成されます。
ServiceMirror と MirrorTarget のマニフェスト例
以下は orders サービスをクラスタ A からクラスタ B にミラーする最小構成です。targetCluster は cluster-b の名前(kubeconfig 上のコンテキスト名)で指定します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# orders ServiceMirror (クラスタAに適用) apiVersion: linkerd.io/v1beta2 kind: ServiceMirror metadata: name: orders namespace: prod spec: targetCluster: cluster-b # ミラー先クラスタのコンテキスト名 --- # gateway 側で受信する MirrorTarget (クラスタBに適用) apiVersion: linkerd.io/v1beta2 kind: MirrorTarget metadata: name: orders-gateway namespace: linkerd spec: gateway: selector: app.kubernetes.io/name: linkerd-gateway port: 4143 # ServiceMirror が参照するポート |
|
1 2 3 4 5 6 7 8 |
# クラスタ A に適用 kubectl config use-context cluster-a kubectl apply -f orders-servicemirror.yaml # クラスタ B に適用(MirrorTarget) kubectl config use-context cluster-b kubectl apply -f orders-servicemirror.yaml # 同一ファイルに両方の定義が入っている想定 |
効果
適用後、orders.prod.svc.cluster.localがクラスタ A に自動生成され、gateway 経由でクラスタ B の実体 Service へリクエストが転送されます。
TLS 終端付き linkerd‑gateway のデプロイ
外部からのトラフィックは TLS で暗号化し、gateway が終端します。Linkerd の gateway は linkerd-gateway デプロイメントと Service(LoadBalancer または NodePort)で構成します。
|
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 |
# クラスタ B に gateway をインストール kubectl config use-context cluster-b linkerd install \ --set extensions.gateway.enabled=true \ --set extensions.gateway.tls.enable=true \ --set extensions.gateway.tls.identity=cluster-b-gateway \ | kubectl apply -f - # LoadBalancer Service の例(クラウド環境向け) cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: name: linkerd-gateway namespace: linkerd spec: selector: app.kubernetes.io/name: linkerd-gateway ports: - protocol: TCP port: 4143 # 外部に公開するポート targetPort: 4143 type: LoadBalancer EOF |
ポイント
extensions.gateway.tls.enableは Linkerd 2.13 の正しいキーです。
クラウドベンダーが自動で外部 IP を付与しない場合は、type: NodePortに切り替えて Ingress コントローラ等と組み合わせてください。
トラフィックフローと証明書自動ローテーション
マルチクラスタ構成では、トラフィックの流れ と 証明書管理 が特に重要です。ここではデータパスを簡潔に示し、Linkerd の mTLS 証明書自動ローテーション設定方法を解説します。
データフロー概要(テキスト版)
- クライアント Pod → サイドカー
linkerd-proxy(送信側) - Proxy が mTLS で暗号化し、ServiceMirror の ClusterIP に転送
- gateway (
linkerd-gateway) が TLS を終端し、内部の ServiceMirror に渡す - 受信側クラスタの
linkerd-proxyが復号して 対象 Pod に配送
この流れにより、全ての往来が Linkerd のポリシーと可観測性(Viz)で管理されます。
証明書自動ローテーション設定
Linkerd 2.13 では identity.autoRotate.enabled が標準で提供されています。以下は 24 時間ごと に証明書を更新する例です(Helm と CLI の両方で同様に適用可能)。
Helm での設定
|
1 2 3 4 5 6 |
helm upgrade linkerd-control-plane linkerd/linkerd2 \ --namespace linkerd \ --set identity.autoRotate.enabled=true \ --set identity.autoRotate.period=24h \ --version 2.13.4 |
CLI(既存インストールへのパッチ)
|
1 2 3 4 5 6 |
kubectl config use-context cluster-a linkerd install \ --set identity.autoRotate.enabled=true \ --set identity.autoRotate.period=24h \ | kubectl apply -f - |
効果
証明書が自動的に更新され、手作業でのローテーションや期限切れエラーを防げます。
認証・ポリシーの統一管理
マルチクラスタ環境では 信頼できる根本 CA と 共通 ServiceAccount を用意することで、各クラスタ間の認証が一本化できます。また、RBAC のスコープを最小限に抑えつつ全クラスターで同一ポリシーを適用する方法を示します。
Trust Anchor(根本 CA)の共有
Linkerd が生成した Identity Trust Root をエクスポートし、他クラスタへインポートします。これにより、どちらのクラスタでも同一 CA に署名された証明書が有効になります。
|
1 2 3 4 5 6 7 8 |
# クラスタ A から CA を取得 kubectl -n linkerd get secret linkerd-identity-trust-roots \ -o jsonpath='{.data.ca.crt}' | base64 --decode > ca-a.crt # クラスタ B にインポート(Secret として保存) kubectl -n linkerd create secret generic linkerd-trust-anchor \ --from-file=ca.crt=ca-a.crt |
共通 ServiceAccount の作成
|
1 2 3 4 5 6 7 |
apiVersion: v1 kind: ServiceAccount metadata: name: shared-sa namespace: prod automountServiceAccountToken: true |
|
1 2 |
kubectl -n prod apply -f shared-sa.yaml # 両クラスタで同一マニフェストを適用 |
結果
shared-saが使用するトークンは、どちらのクラスタでも同一 CA で検証できるため、相互認証がシームレスになります。
RBAC の統一例(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 |
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: linkerd-proxy-global rules: - apiGroups: [""] resources: ["pods", "services"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["pods/portforward"] verbs: ["create"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: linkerd-proxy-global-binding subjects: - kind: ServiceAccount name: shared-sa # 共通 SA を指定 namespace: prod roleRef: kind: ClusterRole name: linkerd-proxy-global apiGroup: rbac.authorization.k8s.io |
ポイント
ClusterRoleは全名前空間に対して権限を付与しますが、対象は linkerd‑proxy が必要とする最小権限* に留めてください。
トラブルシューティングとデバッグ
マルチクラスタ構成でよく発生する問題と、Linkerd が提供する診断ツールを組み合わせた対処フローをまとめます。
linkerd diagnostics の活用方法
|
1 2 3 4 5 6 7 |
# クラスタ A 全体の診断 kubectl config use-context cluster-a linkerd diagnostics # 特定リソース(gateway)だけを対象にしたい場合 linkerd diagnostics -n linkerd gateway |
出力に PASS がすべて揃っていれば、コンポーネント間の依存関係は正常です。エラーが出た箇所だけを切り分けて次のステップへ進みます。
リアルタイムモニタリング:linkerd tap と linkerd stat
| コマンド | 用途 |
|---|---|
linkerd tap deploy/orders -n prod --duration 60s |
1 分間だけリクエストの詳細をリアルタイムで取得 |
linkerd stat svc/orders -n prod --window 5m |
過去 5 分間の成功率・レイテンシを集計 |
これらは ServiceMirror 経由 のトラフィックも可視化できるため、問題発生時に即座にパターンを把握できます。
代表的なエラーと対処法
| エラーメッセージ | 主な原因 | 推奨対策 |
|---|---|---|
gateway not ready |
LoadBalancer が外部 IP を取得できない(クラウドプロバイダー設定) | Service のアノテーションを確認し、必要なら service.beta.kubernetes.io/aws-load-balancer-type: external 等を追加 |
failed to resolve ServiceMirror |
targetCluster 名が誤っている、または対象クラスタで CRD が未作成 |
kubectl get servicemirror -A で名前を検証し、CRD の有無 (kubectl api-resources | grep ServiceMirror) を確認 |
mTLS handshake failed |
Identity 証明書のローテーション失敗、もしくは Trust Anchor が不一致 | linkerd check --pre の identity 項目を再チェックし、全クラスタで同一 CA が設定されているか確認 |
デバッグ手順
1.linkerd diagnostics→ エラー箇所特定
2. 該当リソースの YAML (kubectl get <kind> -n <ns> <name> -o yaml) を取得し設定ミスを修正
3. 再度linkerd checkで検証、必要ならlinkerd install --forceで再適用
まとめ
- 前提条件 – Kubernetes 1.27+、kubectl は同等かそれ以上、CIDR は /16 で重複を回避
- インストール – CLI/Helm 両方の手順を示し、
extensions.serviceMirroring.enabled=trueを必ず設定 - ServiceMirror と gateway – CRD 有効化 → マニフェスト適用 → TLS 終端 gateway のデプロイで構成完了
- トラフィックと証明書管理 – データフローを把握し、
identity.autoRotate.enabled=trueで自動ローテーションを有効化 - 認証・RBAC の統一 – Trust Anchor と共通 ServiceAccount を共有し、ClusterRole/Binding で最小権限付与
- トラブルシューティング –
linkerd diagnostics、tap、statを組み合わせて迅速に原因特定
以上の手順とベストプラクティスを踏むことで、Linkerd のマルチクラスタ機能を 安全・安定・可観測 に運用できるようになります。ぜひ本ガイドを参考に、実際の環境へ適用してみてください。