- Authors

- Name
- Youngju Kim
- @fjvbn20031
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)
클러스터 A의 BPF 서비스 맵:
api-service:80 -> [Pod-A1, Pod-A2, Pod-B1, Pod-B2]
클러스터 B의 BPF 서비스 맵:
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 -> 클러스터 B의 etcd (직접 연결)
N개 노드 x M개 클러스터 = N*M 연결
KVStoreMesh 있을 때:
클러스터 A의 KVStoreMesh -> 클러스터 B의 etcd (단일 연결)
클러스터 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/베어메탈 서버도 쿠버네티스 네트워크에 통합
- 장애 격리: 클러스터 간 장애가 격리되어 전체 시스템 안정성 유지