이 글에서는 쿠버네티스 네트워킹의 핵심 개념인 CNI(Container Network Interface)에 대해 알아보고, 다양한 CNI 플러그인들의 특징과 차이점, 그리고, 최근 주목받고 있는 eBPF 기반 CNI인 Cilium의 장점에 대해 살펴보겠습니다. 쿠버네티스를 처음 접하는 분들도 이해할 수 있도록 기본 개념부터 차근차근 설명하겠습니다.
📌 CNI(Container Network Interface)란?
CNI는 쿠버네티스와 같은 컨테이너 오케스트레이션 시스템에서 네트워크 리소스를 설정하고 관리하기 위한 표준 인터페이스입니다. 컨테이너 간 통신, 외부와의 통신 등 컨테이너 네트워킹의 모든 측면을 처리합니다.
✅ CNI의 기본 정의 CNI는 Linux 컨테이너를 위한 네트워킹 표준으로, Cloud Native Computing Foundation(CNCF)에서 관리합니다. 이 표준은 네트워크 플러그인이 컨테이너 런타임과 상호작용하는 방식을 정의합니다.
▶️ CNI 작동 방식
- 컨테이너 생성 시, 컨테이너 런타임(Docker, containerd 등)은 CNI 플러그인을 호출
- CNI 플러그인은 컨테이너의 네트워크 네임스페이스 설정
- IP 주소 할당, 라우팅 규칙 설정, DNS 구성 등의 작업 수행
- 컨테이너 삭제 시, 네트워크 리소스 정리
# CNI 플러그인 작동 예시 명령 (참고용)
# 새 네트워크 네임스페이스 추가
$ sudo CNI_COMMAND=ADD CNI_CONTAINERID=example CNI_NETNS=/var/run/netns/ns1 CNI_IFNAME=eth0 CNI_PATH=/opt/cni/bin /opt/cni/bin/bridge < /etc/cni/net.d/10-mynet.conf
# 위 명령에 대한 상세 설명:
# CNI_COMMAND=ADD: CNI 플러그인에 '네트워크 추가' 작업을 지시
# CNI_CONTAINERID=example: 컨테이너 식별자 지정 (실제로는 고유한 ID가 사용됨)
# CNI_NETNS=/var/run/netns/ns1: 컨테이너의 네트워크 네임스페이스 경로
# CNI_IFNAME=eth0: 컨테이너 내 생성될 인터페이스 이름
# CNI_PATH=/opt/cni/bin: CNI 바이너리 위치
# /opt/cni/bin/bridge: 사용할 CNI 플러그인 (여기서는 bridge 플러그인)
# < /etc/cni/net.d/10-mynet.conf: 네트워크 구성 파일을 표준 입력으로 전달
✅ CNI의 주요 역할
- Pod 네트워킹: 각 Pod에 고유 IP 할당
- Pod-to-Pod 통신: 노드 내부 및 노드 간 Pod 통신 처리
- Pod-to-Service 통신: 클러스터 내 서비스 접근 관리
- 외부 통신: 클러스터 외부와의 통신 처리
- 네트워크 격리: 네트워크 정책을 통한 트래픽 제어
▶️ CNI 플러그인의 요구사항
- 컨테이너 추가/삭제 시 네트워크 설정
- JSON 형식 구성 파일 지원
- 바이너리 실행 파일로 구현 (컨테이너 런타임이 직접 호출)
📌 주요 CNI 플러그인 비교
쿠버네티스 환경에서 사용할 수 있는 여러 CNI 플러그인들이 있으며, 각각 다른 특징과 장단점을 가지고 있습니다. 여기서는 가장 많이 사용되는 Flannel, Calico, Cilium을 비교해 보겠습니다.
✅ Flannel
가장 단순하고 가벼운 CNI 플러그인으로, 쿠버네티스 입문자들이 처음 접하기 좋습니다.
주요 특징:
- 간단한 설정: 최소한의 구성으로 빠르게 설정 가능
- 가벼운 오버헤드: 복잡한 기능 없이 기본적인 네트워킹 제공
- VXLAN 기반: 기본적으로 VXLAN 캡슐화 사용
한계점:
- 네트워크 정책 지원 없음 (기본 상태)
- 고급 네트워킹 기능 부족
- 대규모 클러스터에서 성능 제한
# Flannel 설치 예시 (참고용)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-system
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
app: flannel
spec:
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.14.0
# 이 컨테이너는 모든 노드에서 실행되는 Flannel 데몬
command:
- /opt/bin/flanneld
args:
- --ip-masq # IP 마스커레이딩 활성화 (노드 외부로 나가는 패킷에 SNAT 적용)
- --kube-subnet-mgr # 쿠버네티스 API를 통해 서브넷 정보 관리
- --iface=$(POD_NETWORK_IFACE) # 사용할 네트워크 인터페이스 지정
env:
- name: POD_NETWORK_IFACE # 환경 변수를 통해 인터페이스 지정
valueFrom:
fieldRef:
fieldPath: status.hostIP
# 호스트 네트워크 모드로 실행 (노드의 네트워크 스택 직접 사용)
securityContext:
privileged: true # 컨테이너에 특권 부여 (네트워크 설정 변경 위해 필요)
volumeMounts:
- name: run
mountPath: /run/flannel # Flannel 런타임 파일 저장 위치
- name: flannel-cfg
mountPath: /etc/kube-flannel/ # Flannel 구성 파일 마운트 위치
volumes:
- name: run
hostPath:
path: /run/flannel
- name: flannel-cfg
configMap:
name: kube-flannel-cfg # Flannel 구성이 저장된 ConfigMap
✅ Calico
네트워크 정책 및 보안 기능이 강화된 CNI 플러그인으로, 엔터프라이즈 환경에서 많이 사용됩니다.
주요 특징:
- 네트워크 정책: 세밀한 트래픽 제어 기능 제공
- BGP 라우팅: IP-in-IP 또는 직접 라우팅 지원
- 높은 성능: 캡슐화 옵션 선택 가능 (성능 최적화)
- 보안 중심: 마이크로서비스 격리에 적합
단점:
- Flannel보다 복잡한 설정
- 일부 환경(특히 클라우드)에서는 BGP 구성이 어려울 수 있음
# Calico 네트워크 정책 예시 (참고용)
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default
spec:
selector: app == 'backend' # 백엔드 앱 선택 (정책이 적용될 대상)
ingress: # 인그레스 규칙 (들어오는 트래픽)
- action: Allow # 일치하는 트래픽 허용 (Deny로 변경하면 차단)
source:
selector: app == 'frontend' # 프론트엔드 레이블을 가진 소스에서만 접근 허용
# 다른 모든 소스로부터의 트래픽은 차단됨
protocol: TCP # TCP 프로토콜만 허용 (UDP 등은 차단)
destination:
ports:
- 8080 # 8080 포트로의 트래픽만 허용
# 다른 모든 포트로의 트래픽은 차단됨
# 명시적인 정책이 없는 경우의 기본 동작:
# 1. 이그레스(나가는 트래픽)는 모두 허용 (별도로 지정하지 않은 경우)
# 2. 다른 출처에서 오는 인그레스는 모두 차단 (위에서 frontend만 허용했으므로)
✅ Cilium
eBPF 기술을 기반으로 한 최신 CNI 플러그인으로, 성능과 보안에 중점을 둔 차세대 네트워킹 솔루션입니다.
주요 특징:
- eBPF 기반: 커널 수준에서 효율적인 네트워킹
- L3-L7 정책: 애플리케이션 계층까지 세밀한 제어
- 강력한 가시성: Hubble을 통한 네트워크 흐름 모니터링
- 높은 성능: iptables 우회를 통한 성능 향상
- 클러스터 메시: 멀티 클러스터 연결 지원
고려사항:
- 다른 CNI에 비해 학습 곡선이 있음
- eBPF를 지원하는 최신 커널 필요 (4.9+)
# Cilium 네트워크 정책 예시 (참고용)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: http-policy
namespace: default
spec:
endpointSelector:
matchLabels:
app: shopping-backend # 백엔드 앱 선택 (정책이 적용될 대상)
ingress: # 인그레스 규칙 (들어오는 트래픽)
- fromEndpoints:
- matchLabels:
app: shopping-frontend # 프론트엔드에서만 접근 허용
# 이 레이블을 가진 Pod에서만 트래픽 허용
toPorts: # 포트 및 HTTP 메소드 제한 (L7 정책 - Cilium의 강점!)
- ports:
- port: "8080" # 8080 포트로의 트래픽만 허용
protocol: TCP # TCP 프로토콜만 허용
rules:
http: # HTTP 계층(L7) 정책 - Cilium만의 고유 기능
- method: "GET" # GET 메소드만 허용 (POST, PUT 등은 차단)
path: "/api/v1/products" # 특정 API 경로만 허용
# 다른 모든 경로는 차단됨
# Cilium의 고급 기능:
# 1. HTTP 헤더, 메소드, 경로 기반 필터링 가능
# 2. Kafka, gRPC, DNS 등 다양한 프로토콜 지원
# 3. 위의 정책은 frontend -> backend로의 GET /api/v1/products 요청만 허용
# 다른 모든 종류의 요청은 차단됨
📌 CNI 플러그인 작동 방식
CNI 플러그인이 어떻게 작동하는지 좀 더 자세히 살펴보겠습니다. 이는 모든 CNI 플러그인의 기본적인 작동 원리를 이해하는 데 도움이 됩니다.
✅ CNI 규격 개요
CNI 규격은 다음 주요 명령을 정의합니다:
- ADD: 컨테이너를 네트워크에 연결
- DEL: 컨테이너를 네트워크에서 제거
- CHECK: 컨테이너의 네트워크 상태 검사
- VERSION: CNI 플러그인의 버전 정보 반환
✅ Pod 생성 시 네트워크 설정 과정
- kubelet이 Pod 생성 요청을 받음
- Pod의 네트워크 네임스페이스 생성
- CNI 플러그인 호출 (ADD 명령)
- CNI 플러그인이 다음 작업 수행:
- IP 주소 할당 (IPAM 플러그인 사용)
- veth 쌍 생성 (컨테이너와 호스트 연결)
- 라우팅 및 NAT 규칙 설정
- DNS 구성 (필요시)
- kubelet에게 결과 반환
✅ Pod 간 통신 매커니즘
같은 노드 내 Pod 간 통신
- 직접 통신 또는 호스트 브리지를 통한 통신
다른 노드 간 Pod 통신
플러그인별로 다른 구현 방식:
- Flannel: VXLAN 캡슐화
- [Pod1] → [호스트 veth] → [VXLAN 캡슐화] → [네트워크] → [VXLAN 디캡슐화] → [호스트 veth] → [Pod2]
- Calico: BGP 라우팅 또는 IP-in-IP
- [Pod1] → [호스트 veth] → [IP 라우팅(BGP)] → [네트워크] → [호스트 veth] → [Pod2]
- Cilium: eBPF 기반 라우팅
- [Pod1] → [호스트 veth] → [eBPF 프로그램] → [네트워크] → [eBPF 프로그램] → [호스트 veth] → [Pod2]
📌 왜 eBPF 기반 CNI가 주목받는가?
최근 eBPF 기반 CNI, 특히 Cilium이 많은 관심을 받고 있는 이유를 알아보겠습니다.
✅ 기존 CNI의 한계
기존 CNI 플러그인들은 대부분 다음과 같은 한계가 있습니다:
- iptables 의존성:
- 수천 개의 규칙 생성으로 성능 저하
- 규칙 갱신 시 전체 규칙 재로드 필요
- 규모 확장 시 성능 문제 발생
- 제한된 가시성:
- 네트워크 흐름에 대한 제한된 정보
- 문제 추적 및 디버깅 어려움
- L3/L4 중심 정책:
- 애플리케이션 계층(L7) 제어의 한계
- 마이크로서비스 환경에서 세밀한 제어 불가
✅ eBPF의 혁신
eBPF(extended Berkeley Packet Filter)는 리눅스 커널에서 실행되는 샌드박스 프로그램으로, 다음과 같은 혁신을 제공합니다:
- 커널 수준 처리:
- 패킷 경로의 다양한 지점에 훅 제공
- 불필요한 컨텍스트 전환 감소
- 프로그래밍 가능:
- 사용자 정의 패킷 처리 로직 구현 가능
- JIT(Just-In-Time) 컴파일로 네이티브 성능 확보
- 안전한 실행:
- 커널 크래시 방지 메커니즘
- 검증기를 통한 안전성 보장
✅ Cilium이 제공하는 장점
Cilium은 eBPF를 활용하여 다음과 같은 이점을 제공합니다:
- 성능 향상:
- iptables 체인 우회를 통한 지연 시간 감소
- 오버헤드 최소화로 높은 처리량 달성
- 대규모 클러스터에서도 일관된 성능
# 전통적인 방식 vs Cilium 패킷 처리 흐름 전통적인 방식: [패킷 수신] → [netfilter] → [iptables 규칙 체인] → [라우팅] → [전달] Cilium: [패킷 수신] → [eBPF 프로그램 직접 처리] → [전달]
- 향상된 보안:
- ID 기반 보안 모델
- L3-L7 네트워크 정책 지원
- API 인식 네트워크 제어
# HTTP 메소드 및 경로 기반 정책 예시 apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: api-protection spec: endpointSelector: matchLabels: app: payment-api # 이 정책이 payment-api 앱에 적용됨 ingress: - fromEndpoints: - matchLabels: app: shopping-cart # shopping-cart 앱만 접근 가능 # 다른 모든 소스에서의 접근은 차단됨 toPorts: - ports: - port: "8080" # 8080 포트만 허용 protocol: TCP # TCP 프로토콜만 허용 rules: http: # HTTP 계층(L7) 검사 수행 - method: "POST" # POST 메소드만 허용 # GET, PUT 등은 차단됨 path: "/api/v1/payments" # /api/v1/payments 경로만 허용 # 다른 경로는 모두 차단됨 # 위 정책의 효과: # 1. payment-api 앱에는 shopping-cart 앱에서 오는 HTTP POST 요청만 허용됨 # 2. 해당 요청도 /api/v1/payments 경로로만 가능함 # 3. 다른 모든 앱/경로/메소드 조합은 차단됨 # 4. 이런 세밀한 제어는 기존 CNI에서는 불가능하고 Cilium의 eBPF 기능 덕분에 가능함
- 뛰어난 가시성:
- Hubble을 통한 네트워크 흐름 모니터링
- L7 계층까지 관찰 가능
- 실시간 메트릭 및 분석
- 쿠버네티스 최적화:
- 쿠버네티스 서비스 구현 최적화
- 고급 로드 밸런싱 전략
- 쿠버네티스 리소스와의 원활한 통합
📌 Docker Desktop에서 CNI 테스트 환경 구성
Docker Desktop 기반으로 간단한 CNI 테스트 환경을 구성하는 방법을 알아보겠습니다.
✅ 테스트 환경 준비
- Docker Desktop 설치 및 쿠버네티스 활성화:
# Docker Desktop 설치 후 쿠버네티스 기능 활성화
# Settings > Kubernetes > Enable Kubernetes 체크 > Apply & Restart
# 참고: Docker Desktop에서 쿠버네티스 활성화하면 다음과 같은 작업이 자동으로 수행됩니다
# 1. 단일 노드 쿠버네티스 클러스터 생성
# 2. kubectl 명령줄 도구 설치 및 구성
# 3. 쿠버네티스 대시보드 설치
# 4. 기본 CNI(Docker 네트워크) 구성
- 클러스터 상태 확인:
# 클러스터 정보 확인
$ kubectl cluster-info
# 결과 예시:
# Kubernetes control plane is running at https://kubernetes.docker.internal:6443
# CoreDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
# 노드 상태 확인
$ kubectl get nodes
# 결과 예시:
# NAME STATUS ROLES AGE VERSION
# docker-desktop Ready control-plane 1d v1.25.0
# 실행 중인 Pod 확인
$ kubectl get pods --all-namespaces
# 결과에는 쿠버네티스 시스템 Pod들이 표시됨 (예: coredns, kube-proxy 등)
# 이 Pod들은 Docker Desktop이 쿠버네티스를 활성화할 때 자동으로 생성됨
✅ CNI 플러그인 비교 테스트 준비
Docker Desktop은 기본적으로 자체 CNI를 사용하지만, 테스트를 위해 다른 CNI로 전환할 수 있습니다.
- 테스트용 애플리케이션 배포:
# 테스트용 YAML (network-test.yaml)
apiVersion: v1
kind: Namespace
metadata:
name: network-test # 테스트용 전용 네임스페이스 생성
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: network-test # 앞서 생성한 네임스페이스에 배포
spec:
replicas: 2 # 2개의 Pod를 실행하여 Pod 간 통신 테스트 가능
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx # Pod에 레이블 지정 (네트워크 정책에서 활용 가능)
spec:
containers:
- name: nginx
image: nginx:latest # 웹 서버로 nginx 사용
ports:
- containerPort: 80 # 컨테이너 포트 80 노출
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox-client
namespace: network-test
spec:
replicas: 1 # 테스트용 클라이언트 Pod 1개 실행
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox # 클라이언트 Pod 레이블
spec:
containers:
- name: busybox
image: busybox:latest # 가벼운 테스트 클라이언트로 busybox 사용
command: ["/bin/sh", "-c", "while true; do sleep 3600; done"]
# busybox가 계속 실행되도록 sleep 명령 사용
# 이렇게 하면 exec 명령으로 접속하여 테스트 가능
- 배포 및 확인:
# 테스트 리소스 배포
$ kubectl apply -f network-test.yaml
# 결과 예시:
# namespace/network-test created
# deployment.apps/nginx-deployment created
# deployment.apps/busybox-client created
# Pod 상태 확인
$ kubectl get pods -n network-test
# 결과 예시:
# NAME READY STATUS RESTARTS AGE
# nginx-deployment-6b6489f76-abcd1 1/1 Running 0 1m
# nginx-deployment-6b6489f76-efgh2 1/1 Running 0 1m
# busybox-client-5bb8d56f8b-ijkl3 1/1 Running 0 1m
# Pod IP 확인 (네트워크 테스트에 필요)
$ kubectl get pods -n network-test -o wide
# 결과에는 각 Pod의 IP 주소가 표시됨
# 이 IP를 사용하여 Pod 간 통신 테스트 가능
- 간단한 네트워크 테스트:
# busybox에서 nginx로 요청 테스트
$ kubectl exec -it -n network-test busybox-client-5bb8d56f8b-ijkl3 -- wget -O- http://nginx-deployment.network-test.svc.cluster.local
# 결과: nginx 웹 페이지 HTML이 출력됨
# 참고:
# - nginx-deployment.network-test.svc.cluster.local: 쿠버네티스 DNS로 서비스 접근
# - -O-: 다운로드 내용을 표준 출력으로 보냄
# - 성공 시: nginx 웹 페이지 내용이 표시됨 (CNI가 정상 작동한다는 의미)
# - 실패 시: 타임아웃 또는 연결 오류 (CNI 구성 문제 가능성)
✅ CNI 전환 참고 (실제 적용은 다음 글에서)
계속해서 CNI 플러그인에 관한 내용을 작성하겠습니다.
# 참고: Docker Desktop에서는 CNI 변경이 복잡할 수 있음
# 이 부분은 다음 글에서 Cilium 설치 시 자세히 다룰 예정
# Docker Desktop에서 기본 CNI를 변경하는 일반적인 방법:
# 1. 쿠버네티스 재설정 (Settings > Kubernetes > Reset Kubernetes Cluster)
# 2. CNI 플러그인 설치 (helm 또는 직접 YAML 배포)
# 3. CNI 구성 파일 생성 (/etc/cni/net.d/ 디렉토리)
# 4. 클러스터 재시작 및 확인
# 주의사항:
# - Docker Desktop은 재시작 시 일부 설정이 초기화될 수 있음
# - CNI 플러그인 설치 전 공식 문서 확인 필요
# - 다음 편에서 Cilium 설치 방법 상세히 안내 예정
📌 CNI 설치 및 구성 시 고려사항
실무에서 CNI를 선택할 때 고려해야 할 사항들을 살펴보겠습니다.
✅ 환경에 따른 CNI 선택
- 소규모/개발 환경:
- Flannel: 간단하고 빠른 설정
- 리소스 요구사항이 적음
- 중간 규모/프로덕션:
- Calico: 안정성과 네트워크 정책 지원
- 성능과 기능의 균형
- 대규모/현대적인 마이크로서비스:
- Cilium: 고급 기능과 최적화된 성능
- 보안 및 가시성 강화
✅ 기술 요구사항 비교
CNI | 최소 커널 버전 | 메모리 사용량 | CPU 사용량 | 지원 기능 |
Flannel | 3.10+ | 낮음 | 낮음 | 기본 네트워킹 |
Calico | 3.10+ | 중간 | 중간 | 네트워크 정책, BGP |
Cilium | 4.9+ (최적 5.10+) | 중간~높음 | 중간 | L3-L7 정책, 가시성 |
✅ 운영 환경 고려사항
- 업그레이드 및 유지보수:
- CNI 업그레이드 전략
- 다운타임 최소화 방안
- 모니터링 및 로깅:
- 네트워크 성능 모니터링
- 문제 발생 시 디버깅 방법
- 통합 및 호환성:
- 클라우드 제공업체와의 호환성
- 서비스 메시, 인그레스 컨트롤러와의 통합
📌 실무 적용 사례
CNI가 실제 환경에서 어떻게 활용되는지 몇 가지 사례를 살펴보겠습니다.
✅ 대규모 클라우드 환경
사례: 수백 노드 규모의 쿠버네티스 클러스터
- 도전: 노드 간 효율적인 통신, 네트워크 오버헤드 최소화
- 선택 CNI: Cilium
- 결과: eBPF 기반 최적화로 30% 이상 네트워크 성능 향상
✅ 금융 서비스 환경
사례: 엄격한 보안 요구사항을 가진 금융 애플리케이션
- 도전: 마이크로서비스 간 세밀한 트래픽 제어 필요
- 선택 CNI: Calico + Istio (서비스 메시)
- 결과: 세분화된 네트워크 정책으로 PCI-DSS 준수 달성
✅ 에지 컴퓨팅 환경
사례: 소규모 에지 장치에 배포된 쿠버네티스
- 도전: 제한된 리소스, 단순한 구성 필요
- 선택 CNI: Flannel
- 결과: 가벼운 오버헤드로 에지 장치에 효율적 배포
📌 Summary
이번 글에서는 쿠버네티스 네트워킹의 기본이 되는 CNI에 대해 알아보았습니다. 주요 내용을 정리하면:
- CNI는 컨테이너 네트워킹 표준 인터페이스로, 쿠버네티스와 같은 환경에서 네트워크 구성을 관리
- 주요 CNI 플러그인:
- Flannel: 단순하고 가벼운 솔루션
- Calico: 네트워크 정책 및 보안에 강점
- Cilium: eBPF 기반의 고성능, 고급 기능 제공
- eBPF 기반 CNI의 장점:
- 커널 수준 프로그래밍으로 성능 향상
- iptables 우회를 통한 확장성 개선
- L3-L7 수준의 세밀한 네트워크 정책
- 향상된 가시성 및 모니터링
'Kubernetes Tools > Cilium' 카테고리의 다른 글
EP06. 기본 L3/L4 정책 설정 | CiliumNetworkPolicy 기초 실습 (0) | 2025.03.22 |
---|---|
EP05. Hubble 설치 및 구성 | 쿠버네티스 네트워크 가시성 확보 (0) | 2025.03.22 |
EP04. Cilium 설치하기 | Docker Desktop 기반 실습 환경 구성 (0) | 2025.03.22 |
EP03. Cilium 아키텍처 이해하기 | Agent, Hubble, Operator (0) | 2025.03.22 |
EP02. eBPF란 무엇인가? | Cilium의 핵심 엔진 이해하기 (0) | 2025.03.21 |