Skip to content
Published on

Cilium ClusterMesh: 멀티클러스터 네트워킹 내부 구현

Authors

Cilium ClusterMesh: 멀티클러스터 네트워킹 내부 구현

개요

Cilium ClusterMesh는 여러 쿠버네티스 클러스터를 하나의 통합 네트워크로 연결하는 멀티클러스터 솔루션입니다. 각 클러스터의 독립성을 유지하면서도 클러스터 간 서비스 디스커버리, 로드 밸런싱, 네트워크 정책을 제공합니다.

1. ClusterMesh 아키텍처

1.1 핵심 컴포넌트

클러스터 A                              클러스터 B
+---------------------------+          +---------------------------+
| Cilium Agent (노드별)      |          | Cilium Agent (노드별)      |
|   - 로컬 엔드포인트 관리    |          |   - 로컬 엔드포인트 관리    |
|   - 원격 클러스터 상태 감시  |          |   - 원격 클러스터 상태 감시  |
+---------------------------+          +---------------------------+
         |                                       |
         v                                       v
+---------------------------+          +---------------------------+
| clustermesh-apiserver     |          | clustermesh-apiserver     |
|   - etcd 인스턴스 내장     |   <--->  |   - etcd 인스턴스 내장     |
|   - 외부 접근 가능한 API   |          |   - 외부 접근 가능한 API   |
+---------------------------+          +---------------------------+
         |                                       |
         v                                       v
+---------------------------+          +---------------------------+
| 내부 etcd (k8s 상태)      |          | 내부 etcd (k8s 상태)      |
+---------------------------+          +---------------------------+

1.2 clustermesh-apiserver

clustermesh-apiserver는 각 클러스터에서 실행되는 컴포넌트로, 다른 클러스터에 대해 해당 클러스터의 상태를 노출합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: clustermesh-apiserver
  namespace: kube-system
spec:
  replicas: 2
  template:
    spec:
      containers:
        - name: apiserver
          image: quay.io/cilium/clustermesh-apiserver:v1.16.0
          ports:
            - containerPort: 2379
              name: etcd
        - name: etcd
          image: quay.io/coreos/etcd:v3.5.11
          args:
            - --data-dir=/var/run/etcd
            - --listen-client-urls=https://0.0.0.0:2379

1.3 데이터 동기화 흐름

클러스터 A의 상태 변경 (:Pod 생성)
    |
    v
Cilium Agent (클러스터 A) -> CiliumEndpoint CRD 업데이트
    |
    v
clustermesh-apiserver (클러스터 A) -> 내장 etcd에 상태 저장
    |
    v
Cilium Agent (클러스터 B) -> 클러스터 A의 etcd 감시
    |
    v
클러스터 B의 ipcache, 서비스 맵 업데이트

2. 교차 클러스터 서비스 디스커버리

2.1 글로벌 서비스

글로벌 서비스는 여러 클러스터에서 동일한 이름과 네임스페이스를 가진 서비스입니다.

apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: production
  annotations:
    io.cilium/global-service: 'true'
spec:
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 8080

2.2 글로벌 서비스 동작 원리

글로벌 서비스 "api-service" (production 네임스페이스)

클러스터 A 백엔드: Pod-A1 (10.244.1.5), Pod-A2 (10.244.1.6)
클러스터 B 백엔드: Pod-B1 (10.245.1.5), Pod-B2 (10.245.1.6)

클러스터 ABPF 서비스 맵:
  api-service:80 -> [Pod-A1, Pod-A2, Pod-B1, Pod-B2]

클러스터 BBPF 서비스 맵:
  api-service:80 -> [Pod-A1, Pod-A2, Pod-B1, Pod-B2]

모든 클러스터에서 동일한 백엔드 풀로 로드 밸런싱

2.3 서비스 어피니티

apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: production
  annotations:
    io.cilium/global-service: 'true'
    io.cilium/service-affinity: 'local'
spec:
  selector:
    app: api
  ports:
    - port: 80

서비스 어피니티 옵션:

동작
default모든 클러스터의 백엔드로 균등 분배
local로컬 클러스터 우선, 로컬 없으면 원격
remote원격 클러스터 우선, 원격 없으면 로컬
none어피니티 없음 (default와 동일)

2.4 공유 서비스 vs 글로벌 서비스

# 글로벌 서비스: 모든 클러스터에서 동일한 서비스
annotations:
  io.cilium/global-service: "true"

# 공유 서비스: 특정 클러스터의 서비스를 다른 클러스터에 노출
annotations:
  io.cilium/global-service: "true"
  io.cilium/shared-service: "true"

3. 교차 클러스터 네트워크 정책

3.1 Identity 동기화

ClusterMesh에서는 각 클러스터의 Identity가 동기화됩니다.

Identity 동기화 흐름:

클러스터 A: Pod 생성 (app=frontend)
  -> Identity 할당: 48291 (클러스터 A 범위)
  -> CiliumIdentity CRD 생성
  -> clustermesh-apiserver를 통해 공유

클러스터 B: 원격 Identity 수신
  -> 원격 Identity를 로컬 ipcache에 추가
  -> 정책 맵에서 원격 Identity 참조 가능

3.2 교차 클러스터 정책 예시

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-cross-cluster
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
            io.cilium.k8s.policy.cluster: cluster-a

3.3 클러스터 식별

클러스터 식별 레이블:
  io.cilium.k8s.policy.cluster: <cluster-name>

각 클러스터의 Identity에 클러스터 이름이 포함됨:
  k8s:app=frontend
  k8s:io.kubernetes.pod.namespace=production
  k8s:io.cilium.k8s.policy.cluster=cluster-a

이를 통해 정책에서 특정 클러스터의 워크로드를 선택 가능

4. ClusterMesh 연결 설정

4.1 필수 요구 사항

1. 고유한 클러스터 ID (1-255)
   - 각 클러스터에 서로 다른 cluster-id 설정
   - cilium config --set cluster-id=1

2. 고유한 클러스터 이름
   - cilium config --set cluster-name=cluster-a

3. Pod CIDR 비중복
   - 클러스터 간 Pod CIDR이 겹치면 안 됨
   - 클러스터 A: 10.244.0.0/16
   - 클러스터 B: 10.245.0.0/16

4. 네트워크 연결
   - 클러스터 간 Pod 네트워크가 상호 도달 가능
   - 터널 또는 직접 라우팅 필요

4.2 설정 단계

# 1단계: 각 클러스터에 ClusterMesh 활성화
cilium clustermesh enable --service-type LoadBalancer

# 2단계: 클러스터 간 연결
cilium clustermesh connect --destination-context ctx-cluster-b

# 3단계: 상태 확인
cilium clustermesh status

# 출력 예시:
# Cluster Connections:
#   cluster-b:
#     connected: true
#     endpoints: 24
#     identities: 42
#     services: 8

4.3 클러스터 간 통신 경로

Pod A (클러스터 A, 10.244.1.5)
  -> Pod B (클러스터 B, 10.245.1.5)

경로 옵션:

1. 터널 모드 (VXLAN/Geneve):
   Pod A -> [from-container BPF]
     -> [VXLAN 캡슐화: 대상 노드 = 클러스터 B 노드]
     -> 클러스터 B 노드
     -> [VXLAN 디캡슐화]
     -> [to-container BPF]
     -> Pod B

2. 다이렉트 라우팅:
   Pod A -> [from-container BPF]
     -> [라우팅: Pod B IP 대상]
     -> 네트워크 인프라 (BGP, VPN)
     -> 클러스터 B 노드
     -> [to-container BPF]
     -> Pod B

5. KVStoreMesh: 확장성 개선

5.1 KVStoreMesh 아키텍처

대규모 ClusterMesh 환경에서 각 Agent가 원격 클러스터의 etcd에 직접 연결하면 부하가 증가합니다. KVStoreMesh는 이를 해결합니다.

KVStoreMesh 없이:
  클러스터 A의 모든 Agent -> 클러스터 Betcd (직접 연결)
  N개 노드 x M개 클러스터 = N*M 연결

KVStoreMesh 있을 때:
  클러스터 AKVStoreMesh -> 클러스터 Betcd (단일 연결)
  클러스터 A의 모든 Agent -> 로컬 KVStoreMesh 캐시
  연결 수 대폭 감소

5.2 KVStoreMesh 동작

원격 클러스터 B의 데이터 흐름:

클러스터 B: clustermesh-apiserver (etcd)
    |
    v (단일 연결)
클러스터 A: KVStoreMesh
    |
    v (로컬 캐시에 데이터 복제)
클러스터 A: 로컬 etcd 또는 CRD
    |
    v
클러스터 A: Cilium Agent (각 노드)
    - 로컬 데이터소스에서 읽기
    - 원격 etcd 직접 연결 불필요

5.3 KVStoreMesh 설정

# Helm으로 KVStoreMesh 활성화
# helm install cilium cilium/cilium \
#   --set clustermesh.useAPIServer=true \
#   --set clustermesh.apiserver.kvstoremesh.enabled=true

6. 외부 워크로드 (External Workloads)

6.1 개요

외부 워크로드 기능을 통해 VM이나 베어메탈 서버에 Cilium Agent를 설치하고 쿠버네티스 클러스터에 참여시킬 수 있습니다.

쿠버네티스 클러스터
+---------------------------+
| Pod A (10.244.1.5)        |
| Pod B (10.244.1.6)        |
| Cilium Agent (각 노드)    |
+---------------------------+
         |
         v (ClusterMesh 연결)
+---------------------------+
| 외부 VM (192.168.1.100)  |
| Cilium Agent 설치          |
| - 동일한 정책 적용          |
| - 동일한 Identity 할당     |
| - 서비스 접근 가능          |
+---------------------------+

6.2 외부 워크로드 설정

# 1단계: 클러스터에서 외부 워크로드 지원 활성화
cilium clustermesh vm create my-vm --ipv4-alloc-cidr 10.192.1.0/24

# 2단계: VM에 설치 스크립트 생성
cilium clustermesh vm install install-external-workload.sh

# 3단계: VM에서 스크립트 실행
# 이 스크립트는:
# - Cilium Agent 설치
# - 클러스터 연결 설정
# - 인증서 설정
# - Agent 시작

6.3 외부 워크로드의 Identity

외부 VM에도 쿠버네티스 Pod와 동일한 Identity 메커니즘 적용:

VM 레이블:
  app: legacy-app
  env: production

Identity 할당: 59102

정책 적용:
  - 클러스터 내 Pod에서 VM으로의 통신 제어
  - VM에서 클러스터 내 Pod으로의 통신 제어
  - Identity 기반으로 동일한 정책 모델

7. 장애 처리 및 고가용성

7.1 클러스터 장애 시 동작

시나리오: 클러스터 B가 완전히 다운

클러스터 A의 동작:
1. clustermesh-apiserver 연결 끊김 감지
2. 클러스터 B의 백엔드를 서비스 맵에서 제거
3. 새로운 연결은 클러스터 A 백엔드로만 라우팅
4. 기존 연결은 타임아웃 후 자동 정리

서비스 어피니티가 "local"인 경우:
  - 클러스터 B 장애가 클러스터 A에 영향 없음
  - 클러스터 A 백엔드만 사용 중이었으므로

7.2 clustermesh-apiserver 고가용성

# 복수 인스턴스 배포로 HA 구성
spec:
  replicas: 2
  # 리더 선출을 통해 하나의 인스턴스만 활성
  # 장애 시 자동 페일오버

7.3 네트워크 분할 대응

네트워크 분할 시:
1. 원격 클러스터 연결 시간 초과
2. 원격 백엔드 상태를 "unreachable"로 표시
3. 로컬 백엔드 우선 사용
4. 네트워크 복구 시 자동 재연결 및 상태 동기화

8. 모니터링 및 트러블슈팅

8.1 ClusterMesh 상태 확인

# ClusterMesh 연결 상태
cilium clustermesh status

# 원격 클러스터에서 동기화된 엔드포인트 수
cilium endpoint list --selector "reserved:remote-node"

# 글로벌 서비스 확인
cilium service list

# 원격 Identity 확인
cilium identity list | grep "cluster-b"

8.2 디버깅 명령

# ClusterMesh 관련 로그
cilium-agent --debug

# 원격 클러스터 연결 상태
cilium status --verbose | grep -A 10 "ClusterMesh"

# 교차 클러스터 서비스 백엔드 확인
cilium bpf lb list | grep "global"

# 원격 ipcache 항목
cilium bpf ipcache list | grep "cluster-b"

8.3 일반적인 문제와 해결

문제: 클러스터 간 연결이 되지 않음
확인 사항:
1. cluster-id가 고유한지 확인
2. Pod CIDR이 겹치지 않는지 확인
3. clustermesh-apiserver가 외부에서 접근 가능한지 확인
4. TLS 인증서가 올바른지 확인

문제: 글로벌 서비스가 원격 백엔드를 포함하지 않음
확인 사항:
1. 양쪽 클러스터에 동일한 서비스 이름/네임스페이스
2. io.cilium/global-service 어노테이션 확인
3. cilium service list로 백엔드 목록 확인

문제: 교차 클러스터 정책이 적용되지 않음
확인 사항:
1. Identity가 올바르게 동기화되는지 확인
2. 클러스터 이름 레이블이 정책에 올바르게 사용되는지 확인
3. cilium identity list로 원격 Identity 확인

9. 성능 고려사항

9.1 확장성

ClusterMesh 확장성 지표:
  - 최대 255개 클러스터 연결
  - 클러스터당 수천 개 노드 지원
  - KVStoreMesh로 대규모 환경 최적화

데이터 동기화 오버헤드:
  - 엔드포인트 변경: 증분 업데이트
  - 서비스 변경: 증분 업데이트
  - Identity 변경: 증분 업데이트
  - 초기 동기화: 전체 상태 전송

9.2 지연 시간

교차 클러스터 통신 지연:
  - 같은 리전 내: 네트워크 지연 + 캡슐화 오버헤드
  - 다른 리전: WAN 지연 추가
  - DSR 모드: 응답 지연 감소
  - 서비스 어피니티 "local": 로컬 우선으로 지연 최소화

정리

Cilium ClusterMesh는 다음과 같은 핵심 원칙으로 멀티클러스터 네트워킹을 제공합니다.

  • 분산 아키텍처: 중앙 컨트롤 플레인 없이 각 클러스터가 독립적으로 동작
  • Identity 동기화: 클러스터 간 보안 Identity를 공유하여 일관된 정책 적용
  • 글로벌 서비스: 여러 클러스터에 걸친 서비스 디스커버리와 로드 밸런싱
  • KVStoreMesh: 대규모 환경에서의 확장성 최적화
  • 외부 워크로드: VM/베어메탈 서버도 쿠버네티스 네트워크에 통합
  • 장애 격리: 클러스터 간 장애가 격리되어 전체 시스템 안정성 유지