Multi-Cluster Services API
Multi-Cluster Services API (MCS-API)
이 튜토리얼은 Cilium에서 Multi-Cluster Services API (MCS-API)를 지원하는 방법을 안내해요. ServiceExport로 서비스를 내보내면 같은 이름·네임스페이스의 서비스들이 ServiceImport로 병합되어 전역에서 사용 가능하게 됩니다.
본문
이 튜튜얼은 Cilium에서 Multi-Cluster Services API (MCS-API)의 지원을 안내합니다.
사전 준비
정상 작동하는 Cluster Mesh 설정이 필요해요. 설정하려면 Cluster Mesh 설정하기 가이드를 따라주세요.
CoreDNS 1.12.2 이상을 실행 중인지 확인하세요 (Kubernetes 1.35부터 기본 설치됩니다).
MCS-API 지원으로 Cilium을 설치하려면 다음을 실행하세요:
Helm RepositoryOCI Registry
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set clustermesh.mcsapi.enabled=true
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set clustermesh.mcsapi.enabled=true
기존 Cilium 설치에서 MCS-API 지원을 활성화하려면 다음을 실행하세요:
Helm RepositoryOCI Registry
helm upgrade cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--reuse-values \
--set clustermesh.mcsapi.enabled=true
helm upgrade cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--reuse-values \
--set clustermesh.mcsapi.enabled=true
Headless Services 지원이 필요하다면 EndpointSlice 동기화 기능도 확인해 보세요.
clustermesh.mcsapi.corednsAutoConfigure.enabled 를 true 로 설정하면 Cilium이 MCS-API 지원을 위해 CoreDNS를 자동으로 구성하고 rollout합니다. 그렇지 않고 CoreDNS를 수동으로 구성하려면 다음 단계를 실행해야 합니다:
# (optional) Install MCS-API CRDs if Cilium has not yet started or automatic CRDs installation is disabled
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/vendor/sigs.k8s.io/mcs-api/config/crd/multicluster.x-k8s.io_serviceexports.yaml
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/vendor/sigs.k8s.io/mcs-api/config/crd/multicluster.x-k8s.io_serviceimports.yaml
# Adding RBAC to read ServiceImports
kubectl create clusterrole coredns-mcsapi \
--verb=list,watch --resource=serviceimports.multicluster.x-k8s.io
kubectl create clusterrolebinding coredns-mcsapi \
--clusterrole=coredns-mcsapi --serviceaccount=kube-system:coredns
# Configure CoreDNS to support MCS-API
kubectl get configmap -n kube-system coredns -o yaml | \
sed -e 's/cluster.local/cluster.local clusterset.local/g' | \
sed -E 's/^(.*)kubernetes(.*){/1kubernetes2{n1 multicluster clusterset.local/' | \
kubectl replace -f-
# Rollout CoreDNS to apply the change
kubectl rollout deployment -n kube-system coredns
Service 내보내기
서비스를 내보내려면 ServiceExport 리소스를 만들어야 합니다. 결과적으로 Service는 해당 Service 네임스페이스가 그 클러스터에 존재하기만 하면 모든 클러스터로 내보내집니다.
apiVersion: multicluster.x-k8s.io/v1beta1
kind: ServiceExport
metadata:
name: rebel-base
모든 클러스터에서, 같은 이름과 네임스페이스를 가진 각 내보낸 Service 집합에 대해 ServiceImport 리소스가 자동으로 생성됩니다. 같은 이름과 네임스페이스를 가진 내보낸 Service들의 모든 Endpoints가 병합되어 전역에서 사용 가능하게 됩니다.
Cilium에서 ServiceImport는 derived-$hash 라는 이름의 파생 Service를 만들어 구현됩니다. 이 파생 Service들은 Cilium Global Services를 구동하는 것과 동일한 Global Services 메커니즘을 사용해요.
MCS-API를 통해 내보낸 Service는 기본적으로 ..svc.clusterset.local 도메인에서 사용할 수 있습니다. Pod에 호스트 이름을 정의했다면(예: Statefulset을 통해) 각 Pod도 ....svc.clusterset.local 도메인을 통해 사용 가능해요.
Note
특정 클러스터에서 Service의 모든 엔드포인트를 가져오도록 허용하는 ...svc.clusterset.local 도메인은 허용되지 않습니다!
이런 동작을 원한다면 클러스터 및/또는 지역별로 서비스를 하나씩 만들어 각각 내보내기를 권장합니다. 예를 들어 하나의 mysvc 대신 mysvc-eu 와 mysvc-us 서비스를 만들고 내보내는 거죠. 자세한 내용은 MCS-API KEP에서 이 동작을 설명하는 전용 섹션을 확인하세요.
같은 이름과 네임스페이스를 가진 내보낸 Service 집합 각각에 대해, MCS-API는 전역적으로 일관된 멀티 클러스터 Service 정의를 하나 제공합니다. Cilium은 다음 속성을 ServiceImport에 전역적으로 조정합니다:
- SessionAffinity
- Ports (다른 ServiceExport들의 합집합)
- Type (ClusterSetIP/Headless)
- InternalTrafficPolicy
- TrafficDistribution
- Annotations & Labels (ServiceExport
exportedLabels및exportedAnnotations필드를 통해)
이 속성 중 하나라도 충돌이 발생하면 Cilium은 해당 ServiceExport 상태에 충돌 조건을 설정하고, ServiceExport 생성 시간 기준으로 가장 오래된 것부터 최신 순으로 충돌을 해결합니다. 충돌이 의도하지 않은 속성으로 해결될 수 있으므로, 내보낸 Service 사이의 충돌은 결국 해결해야 해요.
라벨과 애노테이션 내보내기
생성된 ServiceImport와 파생 Service에 라벨이나 애노테이션을 구성하려면 ServiceExport exportedLabels 및 exportedAnnotations 필드로 지정하세요.
예를 들어 Service affinity나 EndpointSlice 동기화 같은 지원되는 Cilium 서비스 애노테이션을 추가하는 데 유용해요.
apiVersion: multicluster.x-k8s.io/v1beta1
kind: ServiceExport
metadata:
name: rebel-base
spec:
exportedLabels:
app.kubernetes.io/name: rebel-base
exportedAnnotations:
service.cilium.io/affinity: local
MCS-API로 간단한 예시 Service 배포
클러스터 1에서 배포합니다:
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/clustermesh/cluster1.yaml
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/clustermesh/mcsapi-example.yaml
클러스터 2에서 배포합니다:
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/clustermesh/cluster2.yaml
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/clustermesh/mcsapi-example.yaml
어느 클러스터에서든 내보낸 서비스에 접근합니다:
kubectl exec -ti deployment/x-wing -- curl rebel-base-mcsapi.default.svc.clusterset.local
두 클러스터의 Pod에서 응답을 볼 수 있을 거예요.
Gateway-API
Gateway-API는 GEP1748를 통해 MCS-API를 선택적으로 지원하며, ServiceImport 백엔드를 지정하면 됩니다. 예를 들면:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: rebel-base-mcsapi
namespace: default
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: my-gateway
namespace: default
rules:
- backendRefs:
- group: multicluster.x-k8s.io
kind: ServiceImport
name: rebel-base-mcsapi
port: 80
matches:
- method: GET
path:
type: PathPrefix
value: /
Cilium의 Gateway API 구현은 자체 MCS-API 구현을 완전히 지원해요.
다른 Gateway API 구현을 Cilium MCS-API 구현과 함께 사용하려면, 사용하는 Gateway API 구현이 MCS-API / GEP1748을 공식적으로 지원해야 합니다. 대안 Gateway-API 구현이 동작하기 위해 EndpointSlice에 의존한다면, Cilium이 EndpointSlice 동기화를 활성화하도록 구성하세요.
반면, Cilium Gateway API 구현은 ServiceImport와 연결된 기본 Service를 사용하고, ServiceImport 리소스에 multicluster.kubernetes.io/derived-service 애노테이션이 있는 MCS-API 구현만 지원합니다.