Calico와 Flannel, 어떤 CNI를 선택해야 할까? eBPF와 BGP가 뭐길래 성능이 3배나 빨라진다는 걸까? 실전 사용 사례를 통해 완벽하게 이해해보자.
CNI (Container Network Interface)는 Kubernetes에서 Pod 간 네트워킹을 담당하는 플러그인입니다.
쉽게 말하면:
Pod A (10.244.1.5) Pod B (10.244.2.10)
↓ ↓
Node 1 Node 2
↓ ↓
└────── CNI가 연결 ──────┘
특징: 고성능 + 강력한 보안
# Calico 주요 특징
네트워킹: BGP, VXLAN, IPIP
네트워크 정책: ✅ 강력함 (L3/L4/L7)
성능: ⚡ 매우 높음 (eBPF 모드)
복잡도: 🔧 높음
리소스 사용: 📊 중간~높음
적합한 환경: 🏢 엔터프라이즈, 대규모 프로덕션
특징: 단순함 + 안정성
# Flannel 주요 특징
네트워킹: VXLAN, host-gw, UDP
네트워크 정책: ❌ 지원 안함
성능: 💨 좋음
복잡도: 🎯 매우 낮음
리소스 사용: 📊 낮음
적합한 환경: 🛠️ 개발/테스트, 중소규모
| 기능 | Calico | Flannel |
|---|---|---|
| 네트워크 정책 | ✅ 고급 (L3/L4/L7) | ❌ 없음 |
| 암호화 | ✅ WireGuard | ❌ 없음 |
| 성능 (eBPF) | 🚀🚀🚀 | 🚀🚀 |
| 설정 복잡도 | 높음 | 낮음 |
| 학습 곡선 | 가파름 | 완만함 |
| 리소스 사용 | 350MB | 200MB |
| 멀티 클라우드 | ✅ 뛰어남 | ⚠️ 제한적 |
| 설치 시간 | 1시간+ | 30분 |
eBPF (extended Berkeley Packet Filter)는 리눅스 커널을 재컴파일 없이 확장할 수 있는 혁명적 기술입니다.
손님(패킷) → 홀(사용자 공간) → 주문서 작성
→ 주방(커널)으로 전달 📝
→ 주방에서 요리
→ 홀로 다시 전달 📝
→ 손님에게 서빙
❌ 문제: 홀 ↔ 주방 왕복이 너무 많음!
손님(패킷) → 주방(커널)에서 바로 처리
→ 즉시 서빙
✅ 장점: 중간 단계 생략!
컴퓨터는 크게 두 공간으로 나뉩니다:
┌─────────────────────────────────┐
│ 👤 사용자 공간 (User Space) │
│ │
│ • 일반 프로그램들 │
│ • Docker 컨테이너 │
│ • 느리지만 안전 │
└────────────┬────────────────────┘
│ 시스템 콜 (느림!)
┌────────────▼────────────────────┐
│ ⚙️ 커널 공간 (Kernel Space) │
│ │
│ • 하드웨어 직접 제어 │
│ • 네트워크 카드 제어 │
│ • 빠르지만 위험 │
└─────────────────────────────────┘
패킷 도착
↓
커널이 받음
↓
사용자 공간으로 복사 ⚠️ (느림)
↓
애플리케이션 처리
↓
다시 커널로 전달 ⚠️ (느림)
↓
패킷 전송
총 소요 시간: ~10 마이크로초
패킷 도착
↓
커널에서 즉시 처리 ⚡
↓
패킷 전송
총 소요 시간: ~3 마이크로초
# 초당 100만 패킷 처리 시
전통적 방식: 10초 소요
eBPF 방식: 3초 소요
절약 시간: 7초 (70% 빨라짐!)
개발자 코드 작성
↓
컴파일 → eBPF 바이트코드
↓
┌─────────────────────────────┐
│ eBPF Verifier (검증기) │
│ │
│ ✓ 무한 루프 없나? │
│ ✓ 메모리 침범 없나? │
│ ✓ 커널 크래시 가능성? │
└──────┬──────────────────────┘
│
├─ ❌ 위험 → 거부
└─ ✅ 안전
↓
JIT 컴파일
↓
커널에서 실행!
# eBPF 모드 활성화
kubectl patch configmap/calico-config -n kube-system --type merge \
-p '{"data":{"bpf-enabled":"true"}}'
# 상태 확인
calicoctl get felixconfiguration default -o yaml
BGP (Border Gateway Protocol)는 인터넷의 우체국입니다. 각 네트워크가 "나는 이 주소들을 관리해!"라고 알려주는 프로토콜이죠.
당신이 편지를 보낼 때:
"서울시 강남구 XX동" → 우체국이 경로 찾음
"10.244.1.0/24 네트워크" → BGP가 경로 찾음
┌──────────────────────────────────┐
│ Kubernetes 클러스터 │
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Node 1 │ │ Node 2 │ │
│ │ │ │ │ │
│ │ BGP │◄──►│ BGP │ │
│ │Speaker │ │Speaker │ │
│ │ │ │ │ │
│ │10.1.0/24│ │10.2.0/24│ │
│ └────┬────┘ └────┬────┘ │
└───────┼──────────────┼──────────┘
│ │
└──────┬───────┘
│
┌────────▼────────┐
│ 물리 라우터 │
│ │
│ "10.1.0/24는 │
│ Node1로" │
└─────────────────┘
오버레이 불필요
기존 인프라 통합
멀티 클라우드
# BGP 피어 설정
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rack-tor-switch
spec:
peerIP: 192.168.1.1
asNumber: 64512
# BGP 상태 확인
calicoctl node status
상황
선택 이유
✅ 즉시 사용: 1시간 내 설정 완료
✅ 낮은 복잡도: 팀원 모두 1일 내 숙지
✅ 안정성: 5년 이상 검증됨
✅ 리소스 효율: 노드당 200MB만 사용
결과
상황
선택 이유
✅ 네트워크 정책: L7까지 세밀한 제어
✅ 암호화: WireGuard로 Pod 간 통신 암호화
✅ 고성능: eBPF로 레이턴시 최소화
✅ 가시성: Hubble로 모든 트래픽 모니터링
핵심 정책 예시
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: payment-service-policy
spec:
selector: app == 'payment'
ingress:
- action: Allow
protocol: TCP
source:
selector: app == 'api-gateway'
destination:
ports: [8080]
# 결제 서비스는 API Gateway만 접근 가능
결과
요구사항
솔루션
# Terraform으로 15분 내 클러스터 생성
terraform apply -var="env=dev-team-42"
# Flannel 자동 설치
kubectl apply -f flannel.yaml
효과
요구사항
아키텍처
┌─────────────────────────────────────┐
│ Global Load Balancer │
└────────────┬───────────┬────────────┘
│ │
┌────────▼───┐ ┌────▼────────┐
│ Seoul │ │ Singapore │
│ 500 nodes │ │ 500 nodes │
│ │ │ │
│ Calico BGP │◄─┤ Calico BGP │
│ + eBPF │ │ + eBPF │
└────────────┘ └─────────────┘
핵심 설정
# eBPF + BGP 조합
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
name: default
spec:
bpfEnabled: true
bpfLogLevel: Info
---
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
nodeToNodeMeshEnabled: false
asNumber: 64512
결과
멀티 테넌트 환경
핵심 정책
# 테넌트 격리 정책
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: tenant-isolation
spec:
selector: tenant != ''
ingress:
- action: Allow
source:
selector: tenant == $TENANT_ID
egress:
- action: Allow
destination:
selector: tenant == $TENANT_ID
# 같은 테넌트끼리만 통신 가능
WireGuard 암호화
# 테넌트 간 트래픽 암호화
calicoctl patch felixconfiguration default \
--patch='{"spec":{"wireguardEnabled":true}}'
결과
💡 왜 Flannel은 불가능했나?
시기: 시드 투자 직후
팀: 10명
클러스터: 단일 리전, 10 노드
선택: Flannel
이유: 빠른 출시, 운영 단순화
시기: 시리즈 A
팀: 50명, MAU 10만
클러스터: 30 노드
결정: Flannel 계속 사용
이유: 여전히 충분한 성능
시기: 시리즈 B
팀: 200명, MAU 100만
클러스터: 멀티 리전, 100+ 노드/리전
트리거:
✓ 엔터프라이즈 고객 요구
✓ SOC2 인증 필요
✓ 글로벌 확장
✓ 마이크로서비스 200개로 증가
시기: 시리즈 C+
팀: 500명, MAU 500만+
클러스터: 글로벌 10개 리전
효과:
✓ 네트워크 정책 1,000+ 적용
✓ eBPF로 성능 30% 개선
✓ 멀티 클라우드 하이브리드
✓ 보안 인증 다수 획득
시작
│
▼
네트워크 정책 필요?
├─ YES → Calico ✅
└─ NO → 계속
│
▼
클러스터 100+ 노드?
├─ YES → Calico 권장
└─ NO → 계속
│
▼
멀티 클라우드?
├─ YES → Calico 권장
└─ NO → 계속
│
▼
컴플라이언스 필요?
├─ YES → Calico 필수
└─ NO → 계속
│
▼
초저 레이턴시 중요?
├─ YES → Calico 권장
└─ NO → 계속
│
▼
빠른 구축/단순함 우선?
├─ YES → Flannel ✅
└─ NO → Calico 권장
| 시나리오 | 추천 | 핵심 이유 |
|---|---|---|
| 스타트업 MVP | Flannel | 빠른 구축, 낮은 복잡도 |
| 개발/테스트 | Flannel | 간단한 관리, 낮은 리소스 |
| 금융 서비스 | Calico | 네트워크 정책, 암호화, 컴플라이언스 |
| 대규모 커머스 | Calico | eBPF 성능, BGP 멀티 리전 |
| 멀티 테넌트 SaaS | Calico | 네트워크 격리, 동적 정책 |
| AAA 게임 | Calico | 초저 레이턴시, DDoS 방어 |
| 인디 게임 | Flannel | 작은 팀, 충분한 성능 |
| 엔터프라이즈 온프레미스 | Calico | BGP 라우터 통합, 보안 정책 |
| 교육/학습 | Flannel | 낮은 학습 곡선 |
Calico (eBPF): 9.5 Gbps ███████████████████
Flannel (VXLAN): 8.5 Gbps █████████████████
Calico (eBPF): 0.5ms █████
Flannel (VXLAN): 0.7ms ███████
Calico: 6% ████████████
Flannel: 4% ████████
Calico: 350MB ██████████████
Flannel: 200MB ████████
# 1. 백업
kubectl get all --all-namespaces -o yaml > backup.yaml
# 2. 현재 네트워크 정보 저장
kubectl get nodes -o wide > nodes.txt
kubectl get pods -o wide --all-namespaces > pods.txt
# 1. Flannel 제거 (신중하게!)
kubectl delete -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 2. CNI 관련 파일 정리 (각 노드에서)
sudo rm -rf /etc/cni/net.d/*
sudo rm -rf /var/lib/cni/*
# 3. Calico 설치
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
# 4. eBPF 활성화 (선택)
calicoctl patch felixconfiguration default --patch='{"spec":{"bpfEnabled":true}}'
# 5. 검증
calicoctl node status
kubectl get pods -n kube-system
⚠️ 다운타임 발생: Blue-Green 배포 권장
⚠️ Pod 재시작 필요: 모든 Pod가 재시작됨
⚠️ 테스트 환경 먼저: 프로덕션 전 반드시 테스트
# 고성능 설정
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
name: default
spec:
# eBPF 데이터플레인
bpfEnabled: true
# 로그 레벨 낮추기 (성능 향상)
logSeverityScreen: Warning
# 라우팅 최적화
routeRefreshInterval: 90s
# 연결 추적 최적화
bpfConntrackCleanupInterval: 90s
# ConfigMap 수정
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-flannel-cfg
namespace: kube-system
data:
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan",
# MTU 최적화 (AWS는 9001)
"VNI": 1,
"Port": 8472,
"MTU": 1450
}
}
# Calico 메트릭
kubectl top pods -n kube-system | grep calico
# Flannel 로그 확인
kubectl logs -n kube-system -l app=flannel
# 네트워크 연결성 테스트
kubectl run test-pod --image=nicolaka/netshoot --rm -it -- /bin/bash
A: 네, Linux Kernel 4.9 이상이 필요하며, 최상의 성능을 위해서는 5.3 이상을 권장합니다.
# 커널 버전 확인
uname -r
# eBPF 지원 확인
kubectl exec -it -n kube-system <calico-node-pod> -- bpftool prog show
A: 필요하다면 Calico와 함께 사용할 수 있습니다!
# Flannel + Calico 정책 엔진 조합
kubectl apply -f https://docs.projectcalico.org/manifests/canal.yaml
100 노드 클러스터 기준
Flannel:
- 메모리: 200MB × 100 = 20GB
- 월 비용: 약 $30
Calico:
- 메모리: 350MB × 100 = 35GB
- 월 비용: 약 $52
차이: $22/월 (75% 증가)
하지만 Calico의 성능 개선으로 노드 수를 줄일 수 있다면 오히려 절약!
Single Cluster: 10-30분
Blue-Green 방식: 0분 (무중단)
| 클라우드 | Calico | Flannel |
|---|---|---|
| AWS | ✅✅✅ | ✅✅ |
| GCP | ✅✅✅ | ✅✅ |
| Azure | ✅✅✅ | ✅✅ |
| 온프레미스 | ✅✅✅ | ✅ |
| 멀티 클라우드 | ✅✅✅ | ⚠️ |
Phase 1 (스타트업): Flannel
→ 빠른 출시, 시장 검증
Phase 2 (성장기): Flannel 유지
→ 안정적 운영, 기능 개발 집중
Phase 3 (스케일업): Calico로 마이그레이션
→ 엔터프라이즈 요구사항 대응
Phase 4 (엔터프라이즈): Calico 고도화
→ eBPF, BGP, 멀티 클라우드
"완벽한 CNI는 없습니다. 여러분의 현재 상황과 미래 계획에 맞는 CNI를 선택하세요."
이 글이 CNI 선택에 도움이 되었기를 바랍니다!
궁금한 점이나 실전 경험을 공유하고 싶으시다면 댓글로 남겨주세요. 함께 배우고 성장합시다!
Happy Networking!