Container Orchestration/Kubernetes

Cilium CNI 환경에서의 Kubernetes 네트워크 문제 해결

Somaz 2026. 5. 28. 00:00
728x90
반응형

Overview

Cilium은 eBPF 기반의 차세대 CNI 플러그인으로, 기존 kube-proxy와 함께 사용하거나 완전히 대체할 수 있다. 이 문서는 Cilium + kube-proxy 혼합 환경에서 발생하는 특수한 상황과 문제 해결 방법을 다룬다.

 

 

해당 실습은 Kubernetes 내부 네트워크 완벽 분석: IPVS 모드 환경에서의 패킷 플로우 추적 글의 실습환경과 동일하다.

2025.11.12 - [Container Orchestration/Kubernetes] - Kubernetes 내부 네트워크 완벽 분석: IPVS 모드 환경에서의 패킷 플로우 추적

 

 

 

 

 

 


 

환경 특성 파악

./network-test-info.sh 
======================================
  Kubernetes Network Test Environment
======================================

Service ClusterIP: 10.233.9.232

Client Pod:
  IP: 10.233.66.94
  Node: k8s-compute-02

Backend Pods:
  nginx-54c98b4f84-ftvlg
    IP: 10.233.66.111
    Node: k8s-compute-02
  nginx-54c98b4f84-tgmgh
    IP: 10.233.65.212
    Node: k8s-compute-01
  nginx-54c98b4f84-vzgjc
    IP: 10.233.67.86
    Node: k8s-compute-03

Endpoints:
  10.233.65.212 10.233.66.111 10.233.67.86

======================================
  Useful Commands
======================================

# Export variables:
export SERVICE_IP=10.233.9.232
export CLIENT_IP=10.233.66.94
export BACKEND_IP=10.233.65.212

# IPVS rules on k8s-compute-02:
ssh k8s-compute-02 'sudo ipvsadm -Ln | grep -A 5 10.233.9.232'

# tcpdump on client pod:
kubectl exec -it client-pod -n network-test -- tcpdump -i any -nn "host 10.233.9.232 or host 10.233.65.212" -w /tmp/client.pcap

# tcpdump on node:
ssh k8s-compute-02 'sudo tcpdump -i any -nn "host 10.233.9.232 or host 10.233.65.212" -w /tmp/node.pcap'

 

Step 1: 현재 환경 확인

# 1. kube-proxy 실행 여부
kubectl get pods -n kube-system | grep kube-proxy

# 2. kube-proxy 모드
kubectl get cm kube-proxy -n kube-system -o yaml | grep mode

# 3. Cilium KubeProxyReplacement 설정
kubectl -n kube-system exec -it ds/cilium -- cilium status | grep KubeProxyReplacement


# 예상 출력
kube-proxy-6lw4l         1/1     Running   1 (70d ago)   103d
mode: ipvs
KubeProxyReplacement:    False

 

 

 

Step 2: 환경 유형 판별

kube-proxy Mode KubeProxyReplacement 환경 유형
✅ Running ipvs False Cilium + IPVS 혼합
✅ Running iptables False Cilium + iptables 혼합
❌ Not Running - True Cilium 완전 대체
✅ Running ipvs - 순수 IPVS

 

 

 

 

 

주요 증상: IPVS 통계가 0

 

증상 확인

sudo ipvsadm -Ln --stats | grep -A 5 "10.233.9.232"


# 출력
TCP  10.233.9.232:80 rr
  -> 10.233.65.212:80             Masq    0      0          0
  -> 10.233.66.111:80             Masq    0      0          0
  -> 10.233.67.86:80              Masq    0      0          0
  • 모든 통계가 0! 하지만 `curl http://nginx-service` 는 정상 작동한다

 

 


원인

Cilium eBPF가 Socket-level에서 먼저 처리하기 때문이다.

┌─────────────────────┐
│ 애플리케이션 (curl)  │
└──────────┬──────────┘
           │ syscall
           ▼
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
│    Cilium eBPF Hook            │ ← 여기서 가로챔!
│    (Socket-level)              │
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
           │
           ▼
┌────────────────────┐
│   Socket Layer     │
└──────────┬─────────┘
           │
           ▼
┌────────────────────┐
│ Transport (TCP)    │
└──────────┬─────────┘
           │
           ▼
┌────────────────────┐
│  Network (IP)      │
└──────────┬─────────┘
           │
           ▼
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
│   IPVS/Netfilter              │ ← 패킷 못 받음!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
           │
           ▼
┌────────────────────┐
│  Data Link Layer   │
└────────────────────┘

 

 

 

결과

  • IPVS 규칙은 생성됨 (kube-proxy가 작동 중)
  • 실제 패킷은 eBPF가 처리
  • IPVS 통계는 항상 0
  • Linux conntrack도 우회됨 (Socket-level 처리)

 

 

 

 

Cilium 환경 모니터링 방법

 

도구별 작동 여부 (실제 테스트 결과)

방법 작동 여부 추천도 비고
cilium bpf lb list 완벽 작동 ⭐⭐⭐⭐⭐ 가장 확실!
tcpdump 완벽 작동 ⭐⭐⭐⭐⭐ 패킷 레벨 분석
cilium monitor 부분 작동 ⭐⭐ L7은 안 보임
conntrack -L 작동 안 함 eBPF가 우회
cilium service list 비어있음 혼합 환경 비활성화
ipvsadm --stats 항상 0 참고용으로만

 

 

방법 1: eBPF 로드밸런싱 맵 확인 (★★★★)

kubectl -n kube-system exec -it ds/cilium -- cilium bpf lb list | grep 10.233.9.232

# 출력
10.233.9.232:80/TCP (1)      10.233.67.86:80/TCP (79) (1)                    
10.233.9.232:80/TCP (3)      10.233.65.212:80/TCP (79) (3)                   
10.233.9.232:80/TCP (2)      10.233.66.111:80/TCP (79) (2)                   
10.233.9.232:80/TCP (0)      0.0.0.0:0 (79) (0) [ClusterIP, non-routable]

해석:

  • `(0)`: Master entry (가상 서버)
  • `(1), (2), (3)`: 백엔드 슬롯 번호
  • `10.233.67.86:80, 10.233.65.212:80, 10.233.66.111:80`: 실제 백엔드 Pod IP
  • `(79)`: RevNAT ID (응답 패킷 처리용)

 

 

 

방법 2: Cilium Service 목록 (★)

혼합 환경에서는 작동하지 않는다.

kubectl -n kube-system exec -it ds/cilium -- cilium service list | grep nginx

 

 

 

출력

# 아무것도 출력되지 않음

 

 

이유

  • `KubeProxyReplacement: False` 환경에서는 Cilium이 Service를 직접 관리하지 않음
  • kube-proxy가 Service 관리를 담당
  • Cilium의 Service 목록은 비어있음

 

 

대신 `cilium bpf lb list` 를 사용하세요! ← 실제 eBPF 데이터플레인 조회

 

 

 

 

 

 

방법 3: conntrack 실시간 모니터링(★) 

Cilium eBPF 환경에서는 작동하지 않는다.

# 시도 1
sudo conntrack -L -p tcp --dport 80 | grep 10.233.9.232

 

 

출력

conntrack v1.4.8 (conntrack-tools): 6 flow entries have been shown.
# Service IP 관련 연결 없음!

 

# 시도 2 (포트 필터 제거)
sudo conntrack -L | grep 10.233.9.232

 

 

 

출력

conntrack v1.4.8 (conntrack-tools): 888 flow entries have been shown.
# 여전히 Service IP 관련 연결 없음!

 

 

원인

  • Cilium eBPF가 Socket-level에서 처리
  • Linux 커널 네트워크 스택을 거치지 않음
  • Netfilter conntrack을 완전히 우회
  • Service IP(10.233.9.232)는 conntrack에 기록되지 않음

 

 

방법 4: tcpdump(★★★★)

언제나 작동하는 최고의 도구!

 

# Service IP 관련 모든 트래픽
sudo tcpdump -i any -nn host 10.233.9.232

 

 

터미널 1

ssh k8s-compute-02
sudo tcpdump -i any -nn "host 10.233.9.232 or port 80"

 

 

 

터미널 2

kubectl exec -it client-pod -n network-test -- bash -c "for i in {1..5}; do echo Request $i; curl -s http://nginx-service; sleep 1; done"

 

 

 

터미널 1 출력 예시

12:15:36.180603 In  10.233.66.94.34376 > 10.233.9.232.80: Flags [S], seq 1234567890
12:15:36.180621 Out 10.233.66.94.34376 > 10.233.65.212.80: Flags [S], seq 1234567890
12:15:36.180869 P   10.233.65.212.80 > 10.233.66.94.34376: Flags [S.], seq 9876543210
12:15:36.180901 Out 10.233.9.232.80 > 10.233.66.94.34376: Flags [S.], seq 9876543210
  • DNAT/SNAT 전후 패킷을 모두 볼 수 있다!

 

 

 

방법 5: Cilium Monitor 

제한적으로 작동한다.

kubectl -n kube-system exec -it ds/cilium -- cilium monitor

 

 

결과

  • 일반 트래픽은 보임
  • nginx Service 트래픽은 안 보임 (L7 visibility 비활성화)
 
# L7 트래픽 시도 (작동 안 할 수 있음)
kubectl -n kube-system exec -it ds/cilium -- cilium monitor --type l7

 

 

 

출력

Press Ctrl-C to quit
# nginx 관련 트래픽 없음
# 다른 애플리케이션 트래픽만 보임

 

 

원인

  • `KubeProxyReplacement: False` 환경에서는 L7 visibility 비활성화
  • eBPF가 Socket-level에서 너무 빨리 처리

 

 

 

 


 

 

 

실전 트러블슈팅

 

시나리오 1: Service 응답은 정상인데 IPVS 통계가 0

 

 

증상

# curl은 정상
kubectl exec -it client-pod -n network-test -- curl http://nginx-service
Backend POD-1: nginx-54c98b4f84-ftvlg

# IPVS 통계는 0
sudo ipvsadm -Ln --stats | grep 10.233.9.232
TCP  10.233.9.232:80 rr
  -> 10.233.65.212:80             Masq    0      0          0

 

 

 

진단

# 1. Cilium eBPF 맵 확인 (가장 중요!)
kubectl -n kube-system exec -it ds/cilium -- cilium bpf lb list | grep 10.233.9.232

# 2. tcpdump로 실제 패킷 확인
sudo tcpdump -i any -nn host 10.233.9.232 -c 10

 

 

결론: Cilium 혼합 환경에서는 정상 동작이다. IPVS 통계는 무시하면 된다.

 

 

 

 

시나리오 2: conntrack에 연결이 안 보임

 

 

 

증상

sudo conntrack -L | grep 10.233.9.232
conntrack v1.4.8 (conntrack-tools): 888 flow entries have been shown.
# 아무것도 없음

 

 

 

원인

  • Cilium eBPF가 Socket-level에서 처리
  • Linux conntrack을 완전히 우회

 

 

해결

# conntrack 대신 tcpdump 사용
sudo tcpdump -i any -nn "host 10.233.9.232 or port 80"

# 또는 Cilium eBPF 맵 확인
kubectl -n kube-system exec -it ds/cilium -- cilium bpf lb list | grep 10.233.9.232

 

 

결론: conntrack이 안 나와도 정상이다. tcpdump를 사용하면 된다.

 

 

 

시나리오 3: Cilium monitor에 트래픽이 안 보임

 

 

증상

kubectl -n kube-system exec -it ds/cilium -- cilium monitor --type l7
# nginx 트래픽 없음

 

 

 

해결

# 일반 monitor 확인
kubectl -n kube-system exec -it ds/cilium -- cilium monitor

# 또는 tcpdump 사용
sudo tcpdump -i any -nn port 80

 

 

결론: L7 monitor에 안 나와도 정상이다.

 

 

 

시나리오 4: Service 연결 실패

 

 

증상

kubectl exec -it client-pod -n network-test -- curl http://nginx-service
curl: (7) Failed to connect to nginx-service port 80: Connection timeout

 

 

 

진단 순서

# 1. Service 존재 확인
kubectl get svc nginx-service -n network-test

# 2. Endpoint 확인
kubectl get endpointslices -n network-test

# 3. Cilium eBPF 맵 확인 (가장 중요!)
kubectl -n kube-system exec -it ds/cilium -- cilium bpf lb list | grep 10.233.9.232

# 4. IPVS 규칙 확인 (참고용)
sudo ipvsadm -Ln | grep 10.233.9.232

# 5. Pod 직접 접근 테스트
BACKEND_IP=$(kubectl get pods -n network-test -l app=nginx -o jsonpath='{.items[0].status.podIP}')
kubectl exec -it client-pod -n network-test -- curl http://$BACKEND_IP

# 6. tcpdump로 패킷 확인
sudo tcpdump -i any -nn host 10.233.9.232

 

 

 

가능한 원인과 해결

증상 원인 해결책
Service 없음 미생성 kubectl expose 재실행
Endpoint 없음 Pod 미실행 Pod 상태 확인
eBPF 맵 없음 Cilium agent 문제 Cilium 재시작
직접 접근 실패 네트워크 정책 정책 확인
패킷 안 보임 CNI 문제 CNI 로그 확인

 

 

 

 

Cilium agent 재시작

kubectl rollout restart ds/cilium -n kube-system
kubectl rollout status ds/cilium -n kube-system

 

 

 

 

 


 

 

 

 

패킷 플로우 비교

 

 

순수 IPVS 환경

┌──────────────┐
│  Client Pod  │ 10.233.66.94
└──────┬───────┘
       │ 10.233.66.94 → 10.233.9.232:80
       ▼
┌──────────────────┐
│  Network Stack   │
└──────┬───────────┘
       │
       ▼
┌──────────────────┐
│ Netfilter        │
│ PREROUTING       │
└──────┬───────────┘
       │
       ▼
┌──────────────────┐
│  IPVS            │ ← DNAT 수행
│  목적지 변환     │
└──────┬───────────┘
       │ 10.233.66.94 → 10.233.65.212:80
       ▼
┌──────────────────┐
│  Pod Network     │
└──────┬───────────┘
       │
       ▼
┌──────────────┐
│ Backend Pod  │ 10.233.65.212
└──────────────┘

 

 

 

Cilium 혼합 환경 (본 환경)

┌──────────────┐
│  Client Pod  │ 10.233.66.94
└──────┬───────┘
       │ curl syscall
       ▼
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
│  Cilium eBPF Hook        │ ← DNAT 수행 (Socket-level)
│  목적지 변환              │
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
       │ 10.233.66.94 → 10.233.65.212:80
       ▼
┌──────────────────┐
│  Socket Layer    │
└──────┬───────────┘
       │
       ▼
┌──────────────────┐
│  Network Stack   │
└──────┬───────────┘
       │
       ▼
┌──────────────────┐
│ Netfilter/IPVS   │ ← 규칙만 존재, 패킷 안 옴
│ (규칙만 존재)    │
└──────┬───────────┘
       │
       ▼
┌──────────────────┐
│  Pod Network     │
└──────┬───────────┘
       │
       ▼
┌──────────────┐
│ Backend Pod  │ 10.233.65.212
└──────────────┘

 

 

핵심 차이점

항목 IPVS 환경 Cilium 혼합 환경
처리 위치 Netfilter (PREROUTING) Socket-level (syscall)
처리 시점 네트워크 스택 중간 애플리케이션 syscall 직후
conntrack 기록됨 우회됨
IPVS 관여 실제 처리 규칙만 존재
성능 매우 빠름 더 빠름 (syscall 우회)
모니터링 ipvsadm, conntrack tcpdump, cilium bpf

 

 

 

유용한 명령어 모음

 

 

Cilium eBPF 맵 (가장 중요!)

# eBPF 로드밸런싱 맵 전체
kubectl -n kube-system exec -it ds/cilium -- cilium bpf lb list

# 특정 Service IP 필터링
kubectl -n kube-system exec -it ds/cilium -- cilium bpf lb list | grep 10.233.9.232

# 모든 Service 확인
kubectl get svc --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.clusterIP}{"\n"}{end}' | while read ns name ip; do
  echo "=== $ns/$name ($ip) ==="
  kubectl -n kube-system exec ds/cilium -- cilium bpf lb list 2>/dev/null | grep $ip | head -n 4
done

 

 

tcpdump

# Service IP 관련 모든 트래픽
sudo tcpdump -i any -nn host 10.233.9.232

# Client와 Service 간
sudo tcpdump -i any -nn "host 10.233.66.94 and host 10.233.9.232"

# HTTP 트래픽만
sudo tcpdump -i any -nn port 80

# 파일로 저장 후 분석
sudo tcpdump -i any -nn host 10.233.9.232 -w /tmp/capture.pcap
tcpdump -r /tmp/capture.pcap -nn -v

 

 

Cilium 상태 확인

# 전체 상태
kubectl -n kube-system exec -it ds/cilium -- cilium status

# KubeProxyReplacement 확인
kubectl -n kube-system exec -it ds/cilium -- cilium status | grep KubeProxyReplacement

# Cilium 버전
kubectl -n kube-system exec -it ds/cilium -- cilium version

Cilium Endpoint

 
 
bash
# Endpoint 목록
kubectl -n kube-system exec -it ds/cilium -- cilium endpoint list

# 특정 IP로 검색
kubectl -n kube-system exec -it ds/cilium -- cilium endpoint list | grep 10.233.66.111

 

 

Cilium Monitor

# 모든 이벤트
kubectl -n kube-system exec -it ds/cilium -- cilium monitor

# Drop 이벤트
kubectl -n kube-system exec -it ds/cilium -- cilium monitor --type drop

 

 

IPVS (참고용)

# 규칙 확인
sudo ipvsadm -Ln | grep -A 5 "10.233.9.232"

# 통계 (항상 0)
sudo ipvsadm -Ln --stats

 

 

conntrack (작동 안 함)

# 시도는 해볼 수 있지만 Service IP는 안 보임
sudo conntrack -L | grep 10.233.9.232

 

 

 

 

 

 


 

 

 

 

 

환경별 권장 모니터링 전략

 

Cilium + IPVS 혼합 환경 (KubeProxyReplacement: False)

이 환경에서는 Cilium eBPF가 Socket-level에서 먼저 패킷을 처리하므로, 기존 IPVS/conntrack 기반 모니터링 도구가 제대로 작동하지 않는다.

 

 

 

1순위: tcpdump

# 가장 확실한 방법 - 항상 작동
sudo tcpdump -i any -nn "host $SERVICE_IP or port 80"

 

 

 

 

2순위: Cilium eBPF 맵

# Service 로드밸런싱 상태 확인
kubectl -n kube-system exec -it ds/cilium -- cilium bpf lb list | grep $SERVICE_IP

 

 

 

 

3순위: Kubernetes 리소스

# EndpointSlice로 백엔드 상태 확인
kubectl get endpointslices -n $NAMESPACE -o wide

 

 

 

 

사용하지 말 것

  • `ipvsadm --stats`: 항상 0 (참고용으로만)
  • `conntrack -L`: Service IP 안 보임
  • `cilium service list`: 혼합 환경에서 비어있음

 

 

 

 

 

Cilium 완전 대체 환경 (KubeProxyReplacement: True)

kube-proxy가 없고 Cilium이 모든 Service 처리를 담당하는 환경이다.

 

 

 

1순위: Cilium Service 목록

# 완전 대체 환경에서만 작동
kubectl -n kube-system exec -it ds/cilium -- cilium service list

 

 

 

 

2순위: Cilium eBPF 맵

kubectl -n kube-system exec -it ds/cilium -- cilium bpf lb list

 

 

 

 

3순위: Cilium Monitor

# L7 visibility 활성화 시 상세 정보 확인 가능
kubectl -n kube-system exec -it ds/cilium -- cilium monitor --type l7

 

 

 

 

 

 

 

 

혼합 환경 vs 완전 대체 환경

항목 혼합 환경 완전 대체 환경
kube-proxy 실행 중 없음
KubeProxyReplacement False True
Service 관리 주체 kube-proxy Cilium
실제 패킷 처리 Cilium eBPF Cilium eBPF
IPVS 규칙 존재하지만 미사용 없음
cilium service list 비어있음 작동
cilium bpf lb list 작동 작동
리소스 사용량 높음 (중복) 낮음
복잡도 높음 낮음

 

 

 

혼합 환경의 장단점

 

 

장점

  • 기존 환경에서 점진적 마이그레이션 가능
  • Cilium 문제 시 kube-proxy로 폴백 가능 (이론적)
  • 기존 모니터링 인프라 일부 유지

 

 

단점

  • 리소스 중복 사용 (kube-proxy + Cilium 둘 다 실행)
  • 모니터링 혼란 (IPVS 통계 0, conntrack 우회)
  • 디버깅 복잡도 증가
  • 실제로는 Cilium만 패킷 처리 (kube-proxy 무의미)

 

 

 

 

 

완전 대체 환경 권장 시나리오

다음 조건을 만족하면 Cilium 완전 대체를 고려할 만하다.

  • Cilium 버전 1.12 이상
  • Kubernetes 버전 1.24 이상
  • 충분한 테스트 환경 확보
  • Cilium 운영 경험 축적
  • Network Policy를 Cilium으로 관리

 

 

 

 

 

 

 

마이그레이션 고려사항

 

 

혼합 환경에서 완전 대체로 전환

 

 

 

사전 점검

# Cilium 버전 확인
kubectl -n kube-system exec -it ds/cilium -- cilium version

# 현재 설정 확인
helm get values cilium -n kube-system

# 클러스터 상태 확인
kubectl -n kube-system exec -it ds/cilium -- cilium status --verbose

 

 

 

 

전환 시 주의사항

  • 반드시 테스트 환경에서 먼저 검증
  • 롤백 계획 수립
  • 모니터링 대시보드 업데이트 (IPVS 메트릭 제거)
  • Network Policy 호환성 확인
  • NodePort, LoadBalancer 타입 Service 동작 검증

 

 

 

 

전환 후 확인

# kube-proxy 제거 확인
kubectl get pods -n kube-system | grep kube-proxy

# Cilium 완전 대체 확인
kubectl -n kube-system exec -it ds/cilium -- cilium status | grep KubeProxyReplacement

# Service 목록 확인 (이제 작동해야 함)
kubectl -n kube-system exec -it ds/cilium -- cilium service list

 

 

 

 

 

실습 환경 정리

 

실습이 완료되면 생성한 리소스를 정리한다.

# 테스트 네임스페이스 삭제
kubectl delete namespace network-test

# 로컬 파일 정리
rm -f client.pcap node.pcap backend.pcap network-test-info.sh

# 노드에서 캡처 파일 정리
ssh k8s-compute-02 'sudo rm -f /tmp/*.pcap'

 

 

 

삭제 확인

kubectl get all -n network-test
# 출력: No resources found in network-test namespace.

 

 

 

 

 

 


 

 

 

 

정리

 

 

핵심 내용 요약

 

 

 

Cilium + IPVS 혼합 환경의 특성

  • Cilium eBPF가 Socket-level에서 패킷을 먼저 가로챔
  • IPVS 규칙은 존재하지만 실제 패킷 처리에 관여하지 않음
  • conntrack도 우회되어 연결 추적 불가
  • 기존 모니터링 도구(ipvsadm, conntrack)가 무용지물

 

 

 

모니터링 전략

  • tcpdump가 가장 확실한 도구
  • cilium bpf lb list로 eBPF 로드밸런싱 맵 확인
  • IPVS 통계가 0이어도 정상 동작
  • conntrack에 Service IP가 없어도 정상

 

 

 

트러블슈팅 접근법

  • 먼저 환경 유형 파악 (KubeProxyReplacement 값 확인)
  • Cilium eBPF 맵에서 Service 등록 여부 확인
  • tcpdump로 실제 패킷 플로우 추적
  • Pod 직접 접근 테스트로 네트워크 문제 분리

 

 

 

권장사항

  • 혼합 환경은 과도기적 상태로, 장기적으로 완전 대체 고려
  • 모니터링 인프라를 Cilium 기반으로 전환
  • IPVS 메트릭 기반 알림은 비활성화 또는 수정 필요

 

 

 

 

 

 

 

 


Reference

 

 

 

Somaz | DevOps Engineer | Kubernetes & Cloud Infrastructure Specialist

728x90
반응형