Multi-Cluster Services (MCS) — Service Discovery Xuyên Cluster
Tại Sao Quan Trọng Trong Production
Khi workload trên cluster-A cần call service trên cluster-B, bạn có các lựa chọn:
- External LoadBalancer: Expose cluster-B service bằng LoadBalancer type, hardcode external IP vào cluster-A config
- VPC peering + shared VPC: Routes định tuyến traffic xuyên clusters, dùng internal IPs
- Service mesh: Istio/Linkerd maintain endpoint registry xuyên clusters
- Multi-Cluster Services: Native Kubernetes abstraction để discover và call services xuyên clusters
MCS là giải pháp "most Kubernetes-native" — không cần external LB, không cần peering cấu hình phức tạp, không cần service mesh overhead. Chỉ cần ServiceExport trên cluster B và ServiceImport consume xuyên clusters. Nó leverage Cloud DNS và GKE native networking để achieve cross-cluster connectivity.
ServiceExport — "I Export This Service"
Để service có thể được accessed từ clusters khác, tạo ServiceExport resource cùng namespace và name với service:
# Cluster B (service provider)
apiVersion: net.gke.io/v1
kind: ServiceExport
metadata:
name: payment-api
namespace: payments
---
# Cũng phải tồn tại underlying Service
apiVersion: v1
kind: Service
metadata:
name: payment-api
namespace: payments
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: payment-api
type: ClusterIP # Luôn ClusterIP, không LoadBalancerKhi ServiceExport được tạo:
- Fleet controller (chạy ở GCP control plane) phát hiện ServiceExport
- Retrieve Service object — endpoint list, port definitions
- Tạo Cloud DNS public zone record trong fleet project
- Record name:
{service}.{namespace}.svc.clusterset.local - Record type: A record (cho headless service) hoặc CNAME (cho ClusterIP service)
Ví dụ: payment-api.payments.svc.clusterset.local trỏ đến virtual IP của service.
Cluster B không cần public IP — MCS handle mọi thứ internal với Cloud DNS. Service vẫn là ClusterIP, chỉ được exported, không expose ra internet.
ServiceImport — "I Want to Use This Service"
Khi service được exported từ provider cluster, consumer clusters tự động có ServiceImport object được tạo:
# Cluster A (service consumer) — tự động generated
apiVersion: net.gke.io/v1
kind: ServiceImport
metadata:
name: payment-api
namespace: payments
status:
type: ClusterSetIP # Có thể là ClusterSetIP hoặc Headless
clusterSetIPs:
- 10.100.0.10 # Virtual IP, routable từ bất kỳ cluster nào trong fleet
clusters:
- name: cluster-b
lbBalancePolicy: Random # Hoặc Round Robin
conditions:
- type: Clusterset
status: "True"ServiceImport object này cấp phép workloads trong cluster A để discover service từ cluster B.
Cơ Chế DNS Resolution Xuyên Cluster
Cloud DNS Integration
MCS tương tác với Cloud DNS ở fleet level:
- RootSync/Policy Controller distribute Config Sync tạo Private Cloud DNS Zone cho fleet trong fleet host project
- Khi ServiceExport tạo: Fleet controller tạo DNS record trong zone này
- DNS queries từ pods: Pod trong bất kỳ cluster nào query
payment-api.payments.svc.clusterset.local - Routing: CloudDNS resolve tới virtual IP, traffic routed dựa trên locality
DNS Name Format
Kubernetes định nghĩa MCS DNS naming:
- ClusterIP service:
{service}.{namespace}.svc.clusterset.local - Headless service:
{service}.{namespace}.svc.clusterset.local(A records cho mỗi pod)
clusterset.local là TLD dành riêng cho MCS, không phải cluster.local của single-cluster DNS.
Query Resolution Path
Pod → CoreDNS trong cluster
→ Query `payment-api.payments.svc.clusterset.local`
→ CoreDNS không biết, forward tới upstream (Cloud DNS)
→ Cloud DNS lookup record trong MCS zone
→ Return virtual IP
→ kube-proxy trong cluster route VIP đến endpoints
→ Traffic flow đến backing pods ở cluster BLatency được thêm vào là một DNS lookup + potential cross-cluster latency. Mặc định MCS không dùng local caching ở CoreDNS level (để đảm bảo endpoint freshness), nhưng NodeLocal DNSCache có thể cache MCS records để reduce latency.
Endpoint Discovery Và Consistency Model
Endpoint Controller
Fleet maintain một endpoint controller (không visible trực tiếp) monitor Endpoints objects xuyên clusters:
- Khi pod được created/deleted ở cluster B đã export service, local kube-proxy update Endpoints object
- Fleet controller watch cluster B's Endpoints object
- Update internal endpoint registry trong fleet control plane
- Propagate changes đến consumer clusters' Endpoints objects
- kube-proxy ở consumer clusters update local iptables/routes để route traffic đến new/removed endpoints
Delay giữa pod creation/deletion và endpoint availability xuyên clusters phụ thuộc vào:
- Kube-proxy sync period (mặc định 30s, có thể tune xuống nhưng không nên quá thấp)
- Fleet controller update latency (thường < 5s)
- DNS cache TTL (mặc định 30s)
Tổng latency thường là 30–60 giây cho endpoint propagation xuyên clusters.
Consistency Model
MCS eventually consistent, không strong consistent. Nếu pod ở cluster B bị terminate:
- Local kube-proxy remove endpoint ngay
- Cluster A kube-proxy vẫn có endpoint trong cache
- Requests từ cluster A tới endpoint cũ sẽ fail
- Kube-proxy retry logic hoặc connection reset (TCP) trigger fallback
Ứng dụng phải handle transient failures — đó là lý do tại sao circuit breakers và retry logic là critical cho cross-cluster calls.
Locality-Aware Load Balancing
MCS có thể choose endpoints dựa trên locality (prefer endpoints trong cùng region/zone):
apiVersion: v1
kind: Service
metadata:
name: payment-api
namespace: payments
spec:
topologyKeys:
- topology.kubernetes.io/zone
- topology.kubernetes.io/region
- "*" # Fallback tới any endpointVới topology keys, kube-proxy prefer endpoints có topology label giống với requesting pod. Ví dụ: pod trong us-east1 zone sẽ prefer payment-api endpoints ở us-east1 trước, fallback đến other regions nếu cần.
Constraints Và Failure Modes
Constraint 1: Namespace Sameness Required ServiceExport cần exact namespace name match trên provider cluster. Nếu service ở namespace payment-api-prod ở cluster B, consumer cluster A phải có cùng namespace với cùng name payment-api — không thể rename hoặc namespace-map.
Constraint 2: All Fleet Members Are Consumers Khi ServiceExport tạo, mọi cluster trong fleet tự động có ServiceImport được created. Không thể "selective export" (export đến 3 clusters nhưng không đến 4 clusters khác). Nếu cần selective, phải dùng NetworkPolicy để block traffic từ non-authorized clusters.
Constraint 3: No Cross-Service Dependencies ServiceImport là consumer view. Nếu Consumer A dùng ServiceImport của Provider B, và Provider B lại dùng ServiceImport của Provider C (cross-cluster dependency chain), behavior có thể trở nên unpredictable. Tốt nhất flat service topology — consumers don't depend trên MCS-imported services của nhau.
Failure Mode: Endpoint Propagation Delay Khi pod scale up/down ở provider cluster, endpoint change không propagate instantly. Requests tới old endpoints sẽ fail. Để mitigate: dùng connection-level retries, circuit breakers, và monitor MCS endpoint propagation latency.
Failure Mode: CloudDNS Zone Outage Nếu Cloud DNS zone cho fleet không accessible (rare, but possible), DNS queries sẽ fail. Fallback mechanisms không automatic — applications mất connection. Luôn có fallback path (không exclusively rely trên MCS).
Failure Mode: Port Mismatch Service export tới port 8080, nhưng ứng dụng expect port 8081. MCS không do mapping port — chỉ reexport same ports. Port mismatch là application-level issue, không MCS issue.
Khi Nào Dùng MCS vs Alternatives
Dùng MCS:
- Workloads cùng namespace xuyên clusters
- Service discovery là primary need (không cần complex traffic management)
- Locality-aware routing là useful
- Simple, native Kubernetes model là priority
Dùng Service Mesh (Istio/ASM):
- Cần advanced traffic management (weighted routing, circuit breaking, retry logic)
- Cross-namespace service dependencies
- mTLS giữa services
- Detailed observability (latencies, error rates per service pair)
Dùng External LoadBalancer:
- Legacy applications không biết sao cluster boundaries
- Cần deterministic routing (không accept eventually consistent)
- Cluster hybrid (GKE + non-GKE)
Dùng VPC Peering/NCC:
- Cần communicate tới resources ngoài Kubernetes (databases, VMs)
- Fleet topology very complex (hub-and-spoke across regions)
Example: Payment Service Topology
cluster-prod-us-east1:
├── ServiceExport payment-api (ports 8080)
└── Pod payment-api-xyz
cluster-prod-eu-west1:
├── Deployment order-processor
│ ├── Calls payment-api.payments.svc.clusterset.local:8080
│ └── MCS resolve → cluster-prod-us-east1 payment-api endpoints
└── Pod order-processor-abc
Architecture:
order-processor (eu-west1) → MCS DNS → cloud-dns.payments.svc.clusterset.local →
kube-proxy route → VIP → payment-api endpoints (us-east1)Latency: Intra-region DNS lookup + cross-region network latency (50–100ms).
Circuit breaker pattern critical: order-processor timeout quá thấp sẽ cause cascading failures khi EU cluster call US service.