/인프라/K8s NetworkPolicy 통신 오류 해결: Calico vs Cilium (iptables vs eBPF) 비교 가이드
인프라NetworkPolicyKubernetes 네트워킹

K8s NetworkPolicy 통신 오류 해결: Calico vs Cilium (iptables vs eBPF) 비교 가이드

NetworkPolicy 적용 오류의 근본 원인을 CNI별 처리 메커니즘(iptables vs eBPF) 비교를 통해 분석합니다. Egress 제어, 네임스페이스 간 통신 실패 시, 노드 레벨에서 패킷을 캡처하는 실전 디버깅 워크플로우를 단계별로 제시합니다.

K8s NetworkPolicy 통신 오류 해결: Calico vs Cilium (iptables vs eBPF) 비교 가이드

Kubernetes NetworkPolicy, Calico vs Cilium: 복잡한 통신 오류 해결을 위한 심층 가이드

Kubernetes 환경에서 네트워크 정책(NetworkPolicy)은 보안의 최전선입니다. "이 정책을 적용했는데 왜 통신이 안 되지?", "특정 Pod 간의 통신이 막히는 것 같은데, 어디서 막히는 걸까?"와 같은 질문은 모든 운영 엔지니어들이 한 번쯤 부딪히는 벽입니다. 단순히 YAML 문법을 따라 정책을 작성하는 수준을 넘어, 정책이 어떻게 커널 레벨에서 처리되고 어떤 계층에서 차단되는지 이해하는 것이 핵심입니다.

이 가이드는 단순한 문법 학습을 넘어, 실제 운영 환경에서 발생하는 복잡한 네트워크 통신 오류의 근본 원인을 CNI(Container Network Interface)의 특성을 기반으로 진단하고 해결하는 실질적인 방법론을 제시합니다.

왜 '정책 적용 안 됨' 오류가 발생하는가? 기본 이해를 넘어서

대부분의 사용자는 NetworkPolicy가 마치 방화벽 규칙처럼 작동할 것이라고 기대합니다. 이는 기본적으로 '기본 거부(Default Deny)' 원칙을 따릅니다. 즉, 명시적으로 허용되지 않은 모든 트래픽은 기본적으로 차단된다는 것이죠.

하지만 문제는 이 '기본 거부'가 어떤 메커니즘을 통해, 어느 시점에, 어떤 계층(L3/L4)에서 적용되는지 명확히 알지 못할 때 발생합니다. CNI마다 정책을 구현하는 방식이 근본적으로 다르기 때문에, 동일한 정책 YAML이라도 Calico와 Cilium에서 다르게 동작하거나, 혹은 예상치 못한 오버헤드를 유발할 수 있습니다.

CNI별 정책 처리 메커니즘 비교: iptables vs eBPF

네트워크 정책을 구현하는 핵심 차이는 바로 '패킷 필터링을 어느 계층에서 수행하는가'에 있습니다. 이 차이가 성능과 디버깅 복잡도에 직접적인 영향을 미칩니다.

특징iptables 기반 (전통적 방식)eBPF 기반 (현대적 방식)
주요 CNI 예시Calico (기본 모드)Cilium
처리 메커니즘리눅스 커널의 iptables 체인에 규칙 추가커널의 eBPF 맵을 활용하여 패킷 경로에 직접 로드
성능/오버헤드규칙이 많아질수록 체인 탐색 시간이 길어져 오버헤드 증가 (O(N))커널 레벨에서 고속으로 필터링되어 오버헤드가 매우 낮음 (O(1)에 가까움)
가시성/디버깅iptables -L로 규칙 확인 용이. 하지만 규칙이 복잡하게 얽힘.CNI 전용 툴(cilium status)을 통해 추상화된 정책 확인이 용이.
적용 시점주로 패킷이 Node의 네트워크 스택에 도달한 후 처리패킷이 커널에 진입하는 초기에 처리되어 효율적.

핵심 분석: iptables 기반 방식은 모든 정책 규칙을 커널의 방화벽 체인에 순차적으로 쌓아 올립니다. 이는 규칙 수가 수백 개를 넘어가면 성능 저하(Rule Chaining Overhead)를 유발할 수 있습니다. 반면, Cilium이 사용하는 eBPF는 커널 내부에서 패킷을 가로채(Intercept) 필요한 필터링만 수행하므로, 대규모 클러스터 환경에서 압도적인 성능 우위를 가집니다.

복잡한 통신 오류 시나리오별 해결 전략

실제 운영에서는 단순한 Pod-to-Pod 통신 실패 외에도 여러 겹의 정책 충돌이 발생합니다.

1. Egress (아웃바운드) 제어의 함정

많은 사용자가 Ingress(들어오는 트래픽)에만 신경 쓰지만, 외부 API 호출이나 다른 네임스페이스로의 통신은 Egress 제어의 영역입니다. 기본적으로 클러스터 내부 통신을 허용하더라도, 특정 Pod가 외부 IP 대역으로 나가는 트래픽을 막으려면 명시적인 Egress 정책이 필요합니다. 만약 Egress 정책이 누락되었다면, Pod는 외부 통신이 원활하지 않다고 오인할 수 있습니다.

2. 네임스페이스 간 통신(Cross-Namespace) 충돌

네임스페이스 A의 Pod가 네임스페이스 B의 Service에 접근할 때, 정책은 A와 B 모두에 적용됩니다. 만약 A의 정책이 B의 특정 포트를 막고, 동시에 B의 정책이 A의 접근을 막는다면, 어느 쪽의 정책이 우선순위를 가질지가 문제가 됩니다. 일반적으로는 가장 제한적인 정책이 적용되지만, CNI별 정책 적용 우선순위(Priority)를 이해하고, 가장 포괄적인 '허용' 정책을 최상위 레벨에서 정의하는 것이 안전합니다.

3. Service Mesh와 NetworkPolicy의 상호작용

Istio와 같은 Service Mesh를 도입하면, 트래픽 제어는 Sidecar 프록시(Envoy) 레벨에서 이루어집니다. 이 경우, NetworkPolicy가 L3/L4 레벨에서 패킷 자체를 차단해버리면, Envoy가 트래픽을 받기도 전에 막혀버립니다. 따라서 Service Mesh를 사용한다면, NetworkPolicy는 **'최후의 방어선(Last Line of Defense)'**으로만 사용하고, L7(HTTP 헤더 기반) 제어는 Service Mesh의 정책(VirtualService, AuthorizationPolicy)에 맡기는 것이 아키텍처적으로 안정적입니다.

실전! 네트워크 통신 오류 디버깅 워크플로우 (Troubleshooting Flow)

통신 실패 시, 무작정 kubectl describe만 보는 것은 시간 낭비입니다. 다음의 3단계 워크플로우를 따르세요.

시나리오 가정: Pod A (Namespace: dev) $\rightarrow$ Pod B (Namespace: prod) 통신 실패 (Port 8080)

Step 1: 정책 검토 및 범위 확인 (Declarative Check) 가장 먼저, 관련 네임스페이스의 모든 NetworkPolicy를 확인합니다.

Bash
# dev 네임스페이스의 정책 확인
kubectl get netpol -n dev 
# prod 네임스페이스의 정책 확인
kubectl get netpol -n prod 
  • 확인 사항: A에서 B로의 Ingress 허용 규칙이 존재하는가? B에서 A로의 Egress 허용 규칙이 존재하는가? (양방향 확인)

Step 2: CNI 전용 툴을 이용한 상태 진단 (CNI Specific Check) 정책이 적용되어야 할 노드에 접속하여 CNI 전용 툴을 사용합니다.

  • Calico 사용자: calicoctl get ippool 등으로 IPAM 상태를 확인하고, calicoctl get policy로 정책 적용 상태를 확인합니다.
  • Cilium 사용자: cilium status를 실행하여 eBPF 맵 로딩 상태와 정책 적용 여부를 확인합니다.

Step 3: 패킷 레벨 트래픽 캡처 (Deep Packet Inspection) 위의 모든 단계가 정상인데도 통신이 안 된다면, 패킷이 어디서 드롭되는지 확인해야 합니다.

  1. Pod A 내부에서 테스트: kubectl exec -it <pod-a-name> -- tcpdump -i eth0 host <pod-b-ip> and port 8080
  2. 노드 레벨에서 테스트 (최종 방어선): Pod B가 위치한 노드의 SSH로 접속하여, tcpdump -i eth0 host <pod-a-ip> and port 8080을 실행합니다.
    • 결과 해석: 만약 Pod A에서 패킷이 나갔는데, 노드 레벨 tcpdump에서 아예 포착되지 않는다면, 가장 먼저 CNI의 Egress/Node 레벨 정책에서 차단되었을 가능성이 높습니다.

💡 실무 경험 Tip: 저는 정책 디버깅 시, tcpdump를 실행하기 전에 반드시 iptables -L -v (또는 CNI 전용 툴)를 실행하여, 정책 규칙이 실제로 커널 체인에 로드되었는지를 눈으로 확인하는 습관을 들였습니다. 이 과정만으로도 80%의 오진단 사례를 막을 수 있었습니다.

결론: 안정적인 네트워킹을 위한 정책 검증 체크리스트

네트워크 정책은 '설정'이라기보다 '지속적인 검증 프로세스'로 접근해야 합니다. 다음 체크리스트를 통해 정책의 안정성을 확보하세요.

  1. [기본 원칙] 모든 네임스페이스에 대해 기본적으로 Default Deny를 적용하는 정책이 존재하는가?
  2. [방향성] Ingress와 Egress를 모두 명시적으로 정의했는가? (특히 외부 통신 시)
  3. [CNI 특성] 사용 중인 CNI의 정책 처리 메커니즘(eBPF/iptables)을 이해하고, 그에 맞는 디버깅 툴을 준비했는가?
  4. [Layering] Service Mesh와 NetworkPolicy를 함께 사용할 경우, L7 제어는 Mesh에, L3/L4 차단은 Policy에 맡기는 역할 분담을 했는가?

다음 시간에는 이 기본 원칙을 바탕으로, **'Zero Trust 아키텍처를 위한 세분화된 서비스 간 통신(Service-to-Service) 정책 설계 패턴'**에 대해 심도 있게 다뤄보겠습니다.

자주 묻는 질문 (FAQ)

Q1: NetworkPolicy를 적용했는데, 특정 Pod가 외부 인터넷(예: Google DNS 8.8.8.8)에 접속할 수 없습니다. 왜 그런가요? A1: 기본적으로 클러스터 내부 통신만 허용하는 정책이 적용된 경우, 외부 통신(Egress)은 명시적으로 허용하는 정책이 필요합니다. 해당 Pod가 속한 네임스페이스에 외부 IP 대역을 허용하는 Egress 정책을 추가해야 합니다.

Q2: Calico와 Cilium을 혼용하거나, 두 CNI를 사용하는 경우 정책 충돌 위험이 있나요? A2: 네, 매우 높습니다. 두 CNI가 서로 다른 방식으로 네트워크 필터링을 시도하면, 어느 쪽의 규칙이 우선할지 예측하기 어렵습니다. 운영 환경에서는 클러스터 전체에 단일 CNI를 사용하는 것이 가장 안정적입니다.

Q3: NetworkPolicy를 적용하면 모든 트래픽이 차단되는 것이 맞나요? A3: 네, 기본적으로는 그렇습니다. 따라서 반드시 필요한 트래픽 흐름(예: Service A $\rightarrow$ Service B, Port 80)에 대해서만 IngressEgress 규칙을 명시적으로 추가하여 허용(Allow)해야 합니다.

✦ ✦ ✦
편집 검토 · Editorial Review

이 글은 AI 에이전트가 1차 초안을 작성한 뒤, 사람 편집자가 사실관계·출처·톤과 맥락을 검토하여 발행했습니다. 오류나 부정확한 내용이 확인되면 24시간 이내에 정정합니다.

작성 · Content Reviewer·검토 · 사람 편집자·발행 · 2026년 6월 17일

댓글

불러오는 중...