Linkerdマルチクラスター
最終更新: September 11, 2026 · Linkerd edge-26.9.1 / charts 2026.9.1 · Gateway API 1.5.1
Linkerdは選択サービス情報をクラスター間で複製します。動作するcontrol-plane検出経路と適切なdata-plane経路の両方が必要です。cluster統合、アプリデータ複製、シャドーテスト用の全要求複製はしません。
通信モード
| モード | 検出/Service選択 | データ経路とID |
|---|---|---|
| 階層型 | 既定mirror.linkerd.io/exported=true | Source client proxy → target Gateway → server。元caller IDはGatewayで失われる |
| フラット / remote discovery | mirror.linkerd.io/exported=remote-discovery | cluster間Pod直接接続。元workload IDを保持 |
| Federated Service | mirror.linkerd.io/federated=member | フラット網で同名/同namespace Serviceの和集合。メッシュclient必須 |
sourceのmirror controllerは他mirrorでなくtarget Kubernetes APIを監視します。mirror Serviceは検出オブジェクトでTLS処理プロセスではありません。通常名は対応namespaceの<service>-<Link cluster name>です。
階層型はsource clientからtarget Gatewayへの到達性が必要です。flat/federatedにはさらにcluster間の直接で曖昧さのないPod IP routingと同じcontrol-plane namespaceが必要です。内部LBやVPC endpoint単体ではflat networkは成立しません。
前提条件と共有信頼
明示context west/eastの準備済み2 clusterを使います。local別名でAWS account/Regionの証明ではありません。導入ガイドの互換Kubernetes/Gateway API、Linux worker/CNI、固定CLIを使い、最新Kubernetesを互換性と同一視しません。
両Linkerdは関連issuer chainを信頼する必要があります。共通公開rootが最も単純で、複数適切rootを含む共有bundleも対応します。issuer秘密鍵やworkload証明書は共有不要です。
新規の隔離演習専用として共通rootと別ECDSA P-256 issuerを作ります。root 10年は例でCLI defaultや普遍的推奨ではありません。
set -euo pipefail
umask 077
# New lab PKI only. The chosen root lifetime is an example, not a default.
step certificate create root.linkerd.cluster.local ca.crt ca.key \
--profile root-ca --kty EC --curve P-256 \
--not-after 87600h --no-password --insecure
step certificate create identity.linkerd.cluster.local issuer-west.crt issuer-west.key \
--profile intermediate-ca --kty EC --curve P-256 \
--ca ca.crt --ca-key ca.key --not-after 8760h --no-password --insecure
step certificate create identity.linkerd.cluster.local issuer-east.crt issuer-east.key \
--profile intermediate-ca --kty EC --curve P-256 \
--ca ca.crt --ca-key ca.key --not-after 8760h --no-password --insecure
cp ca.crt shared-roots.pem--no-password --insecureは暗号化なし秘密鍵ファイルを作ります。保護した作業場所に置き、公開trust bundleと各clusterに必要issuerだけ配布します。既存meshは段階的trust rotationを使い、新規例のためだけにrootを置換しません。
明示contextでcoreを導入
両clusterで導入ガイドのGateway API/CNI前提を完了した後のCLI所有core経路です。Helm所有はその所有者を維持し、reviewしたvaluesでcluster別認証情報を渡します。
互換Linux workerの既定proxy-init経路を示します。Linkerd CNIでは選択導入設定にcniEnabled:trueも渡します。
set -euo pipefail
# New CLI-owned installations only; complete Gateway API/CNI prerequisites first.
linkerd --context west install --crds | kubectl --context west apply -f -
linkerd --context west install \
--identity-trust-anchors-file shared-roots.pem \
--identity-issuer-certificate-file issuer-west.crt \
--identity-issuer-key-file issuer-west.key | kubectl --context west apply -f -
linkerd --context east install --crds | kubectl --context east apply -f -
linkerd --context east install \
--identity-trust-anchors-file shared-roots.pem \
--identity-issuer-certificate-file issuer-east.crt \
--identity-issuer-key-file issuer-east.key | kubectl --context east apply -f -
linkerd --context west check
linkerd --context east check通信統計が必要ならVizを別導入します。multicluster自身の確認はアプリ/業務検証ではありません。
拡張と方向付きリンク
演習はHelmでmulticluster拡張とpeer controllerを所有します。旧multicluster linkは非推奨です。link-genでLink/認証Secretを生成し、チャートのcontrollersリストと併用します。
基本導入
AWS Load Balancer Controller導入済みEKS用にmc-base-values.yamlへ保存します。内部TCP NLBを要求し、peer経路、DNS、SG、必要portは設計済みにします。他platformには対応LB設定が必要です。
gateway:
enabled: true
serviceType: LoadBalancer
loadBalancerClass: service.k8s.aws/nlb
serviceAnnotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internal
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=truehelm repo add linkerd-edge https://helm.linkerd.io/edge
helm repo update linkerd-edge
# Initially install gateway/remote-access prerequisites, without peer controllers.
helm --kube-context west upgrade --install linkerd-multicluster \
linkerd-edge/linkerd-multicluster --version 2026.9.1 \
-n linkerd-multicluster --create-namespace -f mc-base-values.yaml \
--wait --timeout 10m
helm --kube-context east upgrade --install linkerd-multicluster \
linkerd-edge/linkerd-multicluster --version 2026.9.1 \
-n linkerd-multicluster --create-namespace -f mc-base-values.yaml \
--wait --timeout 10m
kubectl --context west -n linkerd-multicluster get svc linkerd-gateway -o yaml
kubectl --context east -n linkerd-multicluster get svc linkerd-gateway -o yamlgateway型Link生成にはtarget Serviceのingress IPまたはhost名が必要です。AWS NLBは通常host名で、link-genは受け入れます。データは既定4143、準備probeは4191です。どちらへの到達性もremote APIや全アプリの健全性を証明しません。
EastからWestを利用
希望controller一覧をmc-east-links.yamlとして保存します。
controllers:
- link:
ref:
name: westset -euo pipefail
umask 077
# Read West's configuration; install the generated credentials/Link into East.
linkerd --context west multicluster link-gen --cluster-name west > west-link.yaml
# Review public metadata and target endpoint without printing credential values.
kubectl --context east apply -f west-link.yaml
helm --kube-context east upgrade linkerd-multicluster \
linkerd-edge/linkerd-multicluster --version 2026.9.1 \
-n linkerd-multicluster -f mc-base-values.yaml -f mc-east-links.yaml \
--wait --timeout 10m
kubectl --context east -n linkerd-multicluster get links.multicluster.linkerd.io
linkerd --context east multicluster check
linkerd --context east multicluster gatewayslink-genはWest API位置/CAと選択remote-access ServiceAccount tokenを読み、Linkと、linkerd-multiclusterおよびcontrol-planeのlinkerd向け2 Secretを出します。ネットワーク経路やsource mirror controllerは導入しません。
生成ファイルは認証情報として制限し、commitやログへの内容出力をしません。kubeconfigは自己完結したAPI CAと、到達可能で証明書有効なserver addressを含み、controllerから使える必要があります。workstation endpointが不適なら、実controller到達APIへ対応--api-server-addressを使います。
Linkは方向付きです。Westで生成しEastへ適用するとEastがWestを検出できます。既存導入更新では希望Helm一覧の全peerを保持します。配列を1件例で置換すると他controllerを削除し得ます。
任意の逆方向
mc-west-links.yamlを保存します。
controllers:
- link:
ref:
name: eastset -euo pipefail
umask 077
linkerd --context east multicluster link-gen --cluster-name east > east-link.yaml
kubectl --context west apply -f east-link.yaml
helm --kube-context west upgrade linkerd-multicluster \
linkerd-edge/linkerd-multicluster --version 2026.9.1 \
-n linkerd-multicluster -f mc-base-values.yaml -f mc-west-links.yaml \
--wait --timeout 10m
linkerd --context west multicluster checkpeer別remote-access ServiceAccountは選択的失効に役立ちます。RBACと認証情報更新を調整します。これはKubernetes API認証情報で、mesh workload証明書とは別です。
Serviceの公開と利用
両clusterにアプリ名前空間を準備します。チャートは既定で欠けたmirror namespaceを作りません。
mc-namespace.yamlとして保存します。
apiVersion: v1
kind: Namespace
metadata:
name: mc-demo
annotations:
linkerd.io/inject: enabled8080で待つapp:webのテスト済みメッシュwebと、要求確認用の既存メッシュclientを使います。このページは版不明client:latestを導入せず、部分Deploymentが有効とも主張しません。
このWest Serviceをwest-web-service.yamlへ保存します。
apiVersion: v1
kind: Service
metadata:
name: web
namespace: mc-demo
labels:
mirror.linkerd.io/exported: 'true'
spec:
selector:
app: web
ports:
- name: http
port: 80
targetPort: 8080
appProtocol: http# Apply the Namespace manifest to both contexts before creating workloads/mirrors.
kubectl --context west apply -f mc-namespace.yaml
kubectl --context east apply -f mc-namespace.yaml
kubectl --context west apply -f west-web-service.yaml
# Alternative for an existing West Service:
kubectl --context west -n mc-demo label service/web mirror.linkerd.io/exported=true --overwrite
kubectl --context east -n mc-demo get service web-west
# Hierarchical mode: current service-mirror still manages legacy Endpoints.
kubectl --context east -n mc-demo get endpoints web-west -o yaml
kubectl --context east -n mc-demo get endpointslices.discovery.k8s.io \
-l kubernetes.io/service-name=web-west -o yaml
# Existing meshed client with curl installed and the expected app endpoint.
kubectl --context east -n mc-demo exec deployment/client -c client -- \
curl --fail --show-error --retry 0 --max-time 10 http://web-west.mc-demo.svc.cluster.local/新Serviceはnamespace/workload準備後にマニフェスト適用します。ラベルコマンドは既存Service向け代替です。export labelは検出を選び、アクセス制御境界ではありません。Link selector/RBACが一致するpeerだけに作用します。
選択service-mirrorは階層mirrorに旧Endpointsを維持します。存在するEndpointSliceも見ますが、診断コマンド変更でcontrollerが移行すると装わないでください。remote-discoveryではdestinationがremote endpointを照会するため、local Endpointsが意図的にない場合があります。
明示的なローカル/リモートルーティング
Eastのlocal web用apex/local backendをeast-web-services.yamlへ保存します。
apiVersion: v1
kind: Service
metadata:
name: web
namespace: mc-demo
spec:
selector:
app: web
ports:
- name: http
port: 80
targetPort: 8080
appProtocol: http
---
apiVersion: v1
kind: Service
metadata:
name: web-local
namespace: mc-demo
spec:
selector:
app: web
ports:
- name: http
port: 80
targetPort: 8080
appProtocol: httpeast-web-route.yamlで適格mesh clientをlocal backendとimport Serviceへ分割します。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-cluster-route
namespace: mc-demo
spec:
parentRefs:
- group: ''
kind: Service
name: web
port: 80
rules:
- backendRefs:
- name: web-local
port: 80
weight: 80
- name: web-west
port: 80
weight: 20kubectl --context east apply -f east-web-services.yaml
kubectl --context east apply -f east-web-route.yaml
kubectl --context east -n mc-demo get httproute web-cluster-route -o yaml
linkerd --context east diagnostics policy -n mc-demo service/web 80 -o jsoncore Service group ""とService port 80を使います。local/remote準備、route受理、実効client policyを確認します。競合ServiceProfileは現送信policyより優先し得ます。トラフィック管理を参照します。
手動移行と自動フェイルオーバー
100/0設定は0重みbackendを自動的にactive standbyへ変えません。手動所有routeの明示review済みremote-only状態は次です。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-cluster-route
namespace: mc-demo
spec:
parentRefs:
- group: ''
kind: Service
name: web
port: 80
rules:
- backendRefs:
- name: web-local
port: 80
weight: 0
- name: web-west
port: 80
weight: 100状態を意図的に適用し、アプリ結果、remote容量、データ整合性を確認してから復旧と扱います。既存要求/書込結果が不明な場合もあり、routing変更はDB複製やcommit済み操作取消をしません。
旧Flagger rollback webhookは未導入/未検証/failoverを参照し、別名TrafficSplitへpatchしていました。信頼できる地域切り替えは成立していません。Flaggerはtrafficガイドで別に扱います。
SMI TrafficSplitとLinkerd Failover拡張は非推奨です。公式移行先はflat網がある場合のfederated serviceで、全階層網や厳格local-primary要件の自動代替ではありません。
フラットネットワークとFederated Service
別のflat専用設定ではGatewayを省き、flat-base-values.yamlへ保存します。
gateway:
enabled: falseEast peer valuesのflat-east-links.yamlもGateway probeを省きます。
controllers:
- link:
ref:
name: west
gateway:
enabled: false同じ基本導入 → Link/Secret → Helm controller順で、これらとLink生成の--gateway=falseを使います。先に両clusterのPod経路、namespace、信頼を用意します。既存移行では最後の階層consumer移動までGatewayを保持します。
set -euo pipefail
umask 077
# Separate flat-network setup: both base installs omit the gateway.
# Use flat-base-values.yaml plus the corresponding flat controller values.
linkerd --context west multicluster link-gen --cluster-name west \
--gateway=false > west-flat-link.yaml
kubectl --context east apply -f west-flat-link.yaml
helm --kube-context east upgrade linkerd-multicluster \
linkerd-edge/linkerd-multicluster --version 2026.9.1 \
-n linkerd-multicluster -f flat-base-values.yaml -f flat-east-links.yaml \
--wait --timeout 10m
kubectl --context west -n mc-demo label service/web \
mirror.linkerd.io/exported=remote-discovery --overwrite
linkerd --context east diagnostics endpoints web-west.mc-demo.svc.cluster.local:80remote-discoveryはendpoint検索場所を変え、Pod経路、SG、remote APIアクセスは作りません。対応control-plane認証情報はdestination componentからも動く必要があります。
Federated Serviceのメンバー
同名/同namespace Serviceはfederated Serviceに参加でき、例では通常web-federatedです。
# Flat connectivity, matching namespaces and the required directional Links first.
kubectl --context west -n mc-demo label service/web mirror.linkerd.io/federated=member --overwrite
kubectl --context east -n mc-demo label service/web mirror.linkerd.io/federated=member --overwrite
kubectl --context east -n mc-demo get service web-federated
kubectl --context east -n linkerd-multicluster get link west -o yaml
linkerd --context east diagnostics endpoints web-federated.mc-demo.svc.cluster.local:80関連方向Link/controllerがある場所にfederated Serviceが存在します。mesh clientはGatewayなしで検出member endpointへ直接分散します。耐障害性の基盤ですが即時復旧、厳格local-first、アプリ/データ可用性は保証しません。
endpoint準備、failure-accrual、ネットワーク分断、検出鮮度、client再試行意味を確認します。member Serviceが異なるとmetadata/port選択も重要です。競合アノテーションが全部意図通りマージされると想定しないでください。
headless mirroringは別の任意controller機能(設定のenableHeadlessServices)です。適切な名前付きhostが必要でendpoint動作が異なり、headlessはfederatedに参加できません。
クラスター間認可
階層Gatewayは受信mesh接続を認証し、別の送信接続を作ります。最終serverは元remote client IDでGateway経由callerを区別できません。
flat/federated通信ではWestの次policyが保持されたclient.mc-demo.serviceaccount.identity.linkerd.cluster.localを許可します。
apiVersion: policy.linkerd.io/v1beta3
kind: Server
metadata:
name: web-http
namespace: mc-demo
spec:
podSelector:
matchLabels:
app: web
port: 8080
proxyProtocol: HTTP/1
accessPolicy: deny
---
apiVersion: policy.linkerd.io/v1alpha1
kind: AuthorizationPolicy
metadata:
name: web-from-client
namespace: mc-demo
spec:
targetRef:
group: policy.linkerd.io
kind: Server
name: web-http
requiredAuthenticationRefs:
- kind: ServiceAccount
name: client
namespace: mc-demoAPIはServer v1beta3とLinkerd AuthorizationPolicyで、存在しないServerAuthorization v1beta2ではありません。標準Kubernetes IDはDNS形式で、旧Istio型SPIFFE URIではありません。
同ServiceAccount/namespace/trust-domainの組は複数clusterで同じIDになれます。別issuer鍵でも暗黙の暗号学的cluster IDは加わりません。このpolicyはworkload IDを許し、「Eastのみ」の証明ではありません。必要な別ID/信頼境界を設計し、各強制点で実際に見えるIDを評価します。
Gateway型では最終serverから見えるGateway IDと、Gateway/network境界制御を考慮します。export labelや内部LBは認可を代替しません。
EKS接続と所有権
基本valuesはAWS Load Balancer Controller、service.k8s.aws/nlb、IP target、内部NLBを前提とします。非推奨cross-zoneでなく現load-balancer attributesアノテーションを使います。Auto Modeは別owner/classのeks.amazonaws.com/nlbで、対応アノテーションを別確認します。
Linkerd TCP/mTLS経路を維持します。ALB HTTP routing/TLS終端は交換可能なGateway転送ではありません。source→Gateway data 4143、mirror controller→Gateway probe 4191、source control plane→target APIを別に考慮し、実routing/SNAT/SG設計でsourceを制限します。
| 接続 | 提供するもの |
|---|---|
| VPC peering / 適切なTGW routing | 経路、アドレス、DNS、security設定時の私設接続 |
| AWS PrivateLink | endpoint経由の選択サービス/リソースアクセス。peeringや任意Pod間自動routingではない |
| EKS private Kubernetes API endpoint | VPC/適切な接続網からそのclusterのKubernetes APIへアクセス |
| EKS interface VPC endpoint | AWS EKS管理APIへのprivateアクセス。Kubernetes API endpointではない |
flatでは非競合で直接到達可能なPodアドレスが必要です。Gatewayだけでは不足します。階層では任意remote Pod routingがなくてもGatewayとremote API到達性を設計します。
review済みインフラ手順でcluster/networkを用意し、対象AWS account/profileと互換版を選びます。2つのeksctl create clusterに違う名前を付けても別accountにはなりません。監査ではcluster作成、Gateway作成、実地域間通信はしていません。
AWS管理を行う運用者/controllerにIAMが必要です。生成mirror認証情報はKubernetes ServiceAccount token/RBACで認証し、全runtime Linkに一律cross-account IAMが必須ではありません。信頼関係を分離します。
可観測性とFederation
multicluster gatewaysはtarget Gateway probeで、全exportアプリのend-to-end healthではありません。probe metricsはsource mirror controllerに属し、target_cluster_name付きgateway_alive、gateway_probe_latency_msなどです。local Gateway proxyの通常metricsではありません。
中央Prometheus向けの以下は、Basic認証付きの導入済みprivate HTTPS endpoint用client設定例です。実DNS、CA/passwordファイル、server認証、到達性、scrape認可を用意します。既定Vizは自動公開しません。
scrape_configs:
- job_name: federate-west
scheme: https
honor_labels: true
metrics_path: /federate
params:
match[]:
- '{job=~"linkerd-proxy|linkerd-controller"}'
static_configs:
- targets:
- prometheus-west.internal.example.com:443
tls_config:
ca_file: /etc/prometheus/federation/ca.crt
basic_auth:
username: federation-reader
password_file: /etc/prometheus/federation/west/password
metric_relabel_configs:
- target_label: origin_cluster
replacement: west
- job_name: federate-east
scheme: https
honor_labels: true
metrics_path: /federate
params:
match[]:
- '{job=~"linkerd-proxy|linkerd-controller"}'
static_configs:
- targets:
- prometheus-east.internal.example.com:443
tls_config:
ca_file: /etc/prometheus/federation/ca.crt
basic_auth:
username: federation-reader
password_file: /etc/prometheus/federation/east/password
metric_relabel_configs:
- target_label: origin_cluster
replacement: easthonor_labels:trueはsource labelを保持します。target relabelだけでは競合exported labelを確実に上書きできません。ここではscrape後にmetric relabelでcollector管理のorigin_clusterを設定します。集約で保持し重複収集を避けます。
メトリクス起点ごとのbackend成功率:
(sum by (origin_cluster) (rate(response_total{namespace="mc-demo",deployment="web",direction="inbound",classification="success"}[5m]))
or on(origin_cluster) (0 * sum by (origin_cluster) (rate(response_total{namespace="mc-demo",deployment="web",direction="inbound"}[5m])))) / sum by (origin_cluster) (rate(response_total{namespace="mc-demo",deployment="web",direction="inbound"}[5m]))
and on(origin_cluster) (sum by (origin_cluster) (rate(response_total{namespace="mc-demo",deployment="web",direction="inbound"}[5m])) > 0)メトリクス起点ごとのclient観測TTFB:
histogram_quantile(0.99,
sum by (le, origin_cluster) (rate(response_latency_ms_bucket{namespace="mc-demo",deployment="client",direction="outbound"}[5m]))
)2つ目がその経路を表すにはデモclientが意図remote通信を送る必要があります。アプリ/proxy/network時間を含み、純粋な地域間RTTではありません。src_cluster/dst_clusterはこの設定で追加される保証がありません。詳細なcluster間次元を作る前に実系列を確認します。
欠けたsuccess系列はclusterごとのtotalに合わせ、idle/欠損totalは100%成功と報告しません。分類、単位、scrape health、dashboard前提は可観測性ガイドを参照します。
トラブルシューティング
linkerd --context east multicluster check
linkerd --context east multicluster gateways
kubectl --context east -n linkerd-multicluster get link west -o yaml
kubectl --context east -n linkerd-multicluster logs deployment/controller-west -c controller --tail=100
kubectl --context west -n linkerd-multicluster logs deployment/linkerd-gateway -c linkerd-proxy --tail=100
linkerd --context east viz stat deployment/client -n mc-demo --to service/web-west
linkerd --context west check --proxy
linkerd --context east check --proxyLink statusとcontrollerログでremote API/RBAC/namespace問題を確認します。Gateway問題はtarget Service ingress、probe経路/port、networkを調べます。正常probeはdata portや業務ロジックを検証しません。flatではGateway統計を期待せずdestination診断と直接Pod接続を使います。
実公開trust bundleを読みます。
set -euo pipefail
# Public bundle data, not private keys or the generated Link kubeconfig.
kubectl --context west -n linkerd get configmap linkerd-identity-trust-roots -o json \
| jq -er '.data["ca-bundle.crt"] | select(length > 0)' > west-trust.pem
kubectl --context east -n linkerd get configmap linkerd-identity-trust-roots -o json \
| jq -er '.data["ca-bundle.crt"] | select(length > 0)' > east-trust.pem
openssl crl2pkcs7 -nocrl -certfile west-trust.pem | openssl pkcs7 -print_certs -text -noout
openssl crl2pkcs7 -nocrl -certfile east-trust.pem | openssl pkcs7 -print_certs -text -noout全証明書と期限/issuer chainを調べます。PEM順/形式だけでは同等信頼テストではなく、旧configの短いgrepも完全検証ではありません。変更はsecurityガイドの段階rotationを使います。

