
CNI 갈아탈까 말까 하는 고민은 누구나 한 번쯤 한다. 우리 팀도 작년 말부터 "Cilium 한번 가보자" 분위기가 있었고, 결국 6개월 가까이 PoC와 운영 시뮬레이션을 돌렸다. 결론부터 말하면, 메인 워크로드는 Calico에 남겼고 새로 구축한 ML 추론 클러스터만 Cilium으로 갔다. 같은 회사 안에서 CNI를 두 개 쓰게 된 셈인데, 이 글은 왜 그런 결정을 했는지에 대한 정리다.
왜 갈아타고 싶었나
우리 메인 EKS 클러스터는 노드 80대 규모. Calico를 3년 넘게 써왔고 큰 문제는 없었다. 그런데 최근 1년 사이 두 가지 가려운 부분이 생겼다.
하나는 kube-proxy iptables 룰이 너무 길어진 거다. Service 수가 1,200개를 넘기면서 노드당 iptables 룰이 4만 줄을 넘었다. 새 Pod 뜰 때 룰 동기화하는 동안 잠깐 connection refused가 나는 케이스가 종종 보였다. ipvs 모드로 바꾸는 것도 검토했는데, 그러느니 eBPF로 가는 게 낫지 않나 하는 얘기가 나왔다.
다른 하나는 관측성. 어느 Pod가 어느 외부 엔드포인트로 얼마나 트래픽을 보내는지 알고 싶을 때마다 sidecar 띄우거나 VPC Flow Logs 파싱하느라 고생했다. Hubble의 데모를 보고 팀 내부에서 "이거 너무 좋은데?"라는 분위기가 형성됐다. 사실 이게 가장 큰 동기였다.
Cilium의 강점, 실제로 써보니
Cilium 1.16을 PoC 환경에 깔고 한 달 굴렸다. 좋은 점은 확실했다.
kubeProxyReplacement=true로 켜고 나서 측정해보니 Service heavy 워크로드에서 P99 레이턴시가 15~20% 정도 줄었다. 우리 환경은 east-west 트래픽이 많은 편이라 socket-level load balancing의 효과를 체감하기 쉬웠다. 노드의 iptables 룰도 3~4천 줄로 줄었다. 이거 하나만으로도 매력적이다.
Hubble UI는 기대 이상이었다. L7 가시성을 별도 sidecar 없이 얻을 수 있다는 게 큰 장점이고, 특정 네임스페이스에서 어떤 외부 도메인으로 요청이 나가는지 한눈에 보여서 보안팀이 반겼다. Network Policy를 작성할 때도 Calico의 GlobalNetworkPolicy보다 표현력이 좋았다. 특히 FQDN 기반 정책은 진작에 썼어야 했다 싶었다.
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-external-api
spec:
endpointSelector:
matchLabels:
app: payment-worker
egress:
- toFQDNs:
- matchPattern: "*.payments.example.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
이런 정책을 Calico에서 흉내내려면 별도 DNS 정책이 필요한데, Cilium은 기본 기능이다.
그런데 왜 메인은 안 옮겼나
이게 글의 핵심이다. 좋은 거 많이 보고도 메인을 안 옮긴 이유.
첫째, 마이그레이션 리스크. 메인 클러스터는 결제, 주문, 검색 등 핵심 워크로드를 다 들고 있다. CNI를 갈아끼우려면 어느 시점에 노드를 cordon/drain하면서 새 CNI로 다시 띄우는 절차가 필요하다. AWS CNI에서 Cilium chaining으로 갈지, 완전히 Cilium native로 갈지 결정도 해야 한다. 이론적으로는 노드 단위로 점진적 마이그레이션이 가능하지만, 우리 케이스에서는 Pod CIDR 정책과 Security Group이 얽혀 있어서 깔끔하지 않았다. PoC 중에 두 번 정도 IP 할당 충돌로 Pod가 NotReady가 됐다. 운영 클러스터에서 이런 일이 나면 PostMortem 한 트럭이다.
둘째, 디버깅 난이도. Calico에서는 문제가 생기면 iptables -L, ip route, tcpdump로 대충 따라갈 수 있다. Cilium은 eBPF map을 들여다봐야 할 때가 있는데, cilium-dbg나 bpftool 사용에 익숙한 사람이 팀에 적었다. 새벽 3시에 장애 났을 때 누가 디버깅할 거냐는 질문에 자신 있게 손드는 사람이 없었다. 솔직히 이건 학습으로 해결할 수 있는 문제지만, 당장의 운영 안정성을 무시할 수는 없었다.
셋째, 리소스 사용량. Cilium agent의 메모리 사용량이 Calico Felix보다 2~3배 컸다. 노드당 평균 250MB vs 800MB 정도. 80대 클러스터로 환산하면 결코 무시할 수 없는 차이다. 1.17부터 개선됐다는 얘기는 있는데 우리가 검증하지는 못했다.
넷째, AWS 생태계 호환성. Network Load Balancer target type IP, Pod Security Group, VPC Lattice 같은 AWS 고유 기능들이 AWS VPC CNI 위에서 동작한다. Cilium native로 가면 이걸 다시 검증해야 한다. ML 추론 클러스터처럼 외부 LB 안 거치고 내부 서비스만 쓰는 환경에서는 큰 문제가 아니지만, 외부 트래픽 받는 메인은 얘기가 다르다.
우리가 내린 결정
메인 EKS: Calico 유지. 대신 kube-proxy를 ipvs 모드로 바꾸고, FQDN 기반 egress 제어가 필요한 경우는 별도 NetworkPolicy enforcer를 검토하기로.
ML 추론 클러스터: Cilium native + Hubble. 어차피 새로 만드는 환경이라 마이그레이션 리스크가 없고, GPU 노드 적은 수에서 운영하므로 디버깅 부담도 작다. 내부 서비스 위주라 AWS 통합 이슈도 적었다.
이 결정이 정답이라고 생각하진 않는다. 1년 뒤에 Cilium이 더 성숙해지고 우리 팀의 eBPF 역량이 올라오면 메인도 옮길 가능성이 있다. 사실 같은 회사에서 CNI 두 개 쓰는 게 좋은 그림은 아니다. 그래도 "당장 갈아탈 만한 이유가 충분한가"라는 질문에 솔직하게 답하면, 우리는 아직 아니었다.
비슷한 고민 하는 팀이 있다면, 다음 질문을 먼저 던져보면 좋겠다. 정말로 Hubble이 없으면 안 되는가? eBPF 디버깅을 새벽에 할 수 있는 사람이 팀에 있는가? AWS 고유 기능에 얼마나 묶여 있는가? 이 세 가지에 명확하게 답이 나오면, 그게 곧 결정이다.
혹시 이미 메인 클러스터를 Cilium으로 옮긴 팀이 있다면 후기 들려주세요. 특히 마이그레이션 전략 부분 궁금합니다.
'IT > Kubernets' 카테고리의 다른 글
| HPA behavior 필드 잘못 만지다가 P99 튀어버린 이야기 (0) | 2026.05.16 |
|---|---|
| CronJob 실패 로그가 증발한 사건 (0) | 2026.05.15 |
| Kubernetes graceful node shutdown, 안에서 도는 것들 (1) | 2026.05.15 |
| Karpenter 스케줄러는 어떻게 노드를 결정하는가 — 내부 동작 분석 (0) | 2026.05.14 |
| startupProbe 모르고 슬로우 스타트 앱 운영하지 마세요 (0) | 2026.05.13 |