Multi-Cluster Services API

Multi-Cluster Services API (MCS-API)

이 튜토리얼은 Cilium에서 Multi-Cluster Services API (MCS-API)를 지원하는 방법을 안내해요. ServiceExport로 서비스를 내보내면 같은 이름·네임스페이스의 서비스들이 ServiceImport로 병합되어 전역에서 사용 가능하게 됩니다.

출처: Multi-Cluster Services API

본문

이 튜튜얼은 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 구현만 지원합니다.

더 알아보기 (Learn more)