- Published on
Cilium과 eBPF로 구현하는 Kubernetes 네트워크 보안: L3/L4/L7 정책부터 암호화까지
- Authors
- Name
- 들어가며
- eBPF란 무엇인가?
- Cilium 설치
- L3/L4 네트워크 정책
- L7 HTTP 정책 — Cilium의 핵심 차별점
- DNS 기반 정책
- WireGuard 투명 암호화
- Hubble 네트워크 관측성
- 실전 시나리오: 마이크로서비스 보안
- CiliumClusterwideNetworkPolicy
- 트러블슈팅
- 성능 벤치마크
- 정리
들어가며
Kubernetes 네트워크 보안의 판도가 바뀌고 있습니다. 기존 iptables 기반의 NetworkPolicy는 L3/L4 수준의 단순한 IP/포트 필터링만 가능했지만, Cilium은 eBPF를 활용하여 커널 수준에서 L7까지의 정밀한 네트워크 정책을 구현합니다. 2026년 2월 릴리스된 Cilium 1.19에서는 보안 강화, 암호화 개선, 대규모 클러스터 확장성이 크게 향상되었습니다.
이 글에서는 Cilium을 설치하고 실전 네트워크 정책을 단계별로 구성해봅니다.
eBPF란 무엇인가?
eBPF(extended Berkeley Packet Filter)는 리눅스 커널 내부에서 샌드박스된 프로그램을 실행할 수 있는 기술입니다. 커널을 수정하지 않고도 네트워킹, 보안, 관측성 기능을 주입할 수 있습니다.
# eBPF 지원 확인
uname -r # 5.10+ 권장
cat /boot/config-$(uname -r) | grep CONFIG_BPF
# CONFIG_BPF=y
# CONFIG_BPF_SYSCALL=y
# CONFIG_BPF_JIT=y
eBPF vs iptables 비교
| 항목 | iptables | eBPF (Cilium) |
|---|---|---|
| 처리 위치 | 유저스페이스 규칙 체인 | 커널 내 직접 실행 |
| L7 지원 | 불가 | HTTP, gRPC, Kafka 등 |
| 성능 | 규칙 수에 비례하여 저하 | O(1) 해시맵 조회 |
| 관측성 | 별도 도구 필요 | Hubble 내장 |
| 암호화 | 미지원 | WireGuard/IPsec |
Cilium 설치
Helm으로 설치
# Helm repo 추가
helm repo add cilium https://helm.cilium.io/
helm repo update
# Cilium 설치 (kube-proxy 대체 모드)
helm install cilium cilium/cilium --version 1.19.0 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set k8sServiceHost=<API_SERVER_IP> \
--set k8sServicePort=6443 \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set encryption.enabled=true \
--set encryption.type=wireguard
설치 확인
# Cilium 상태 확인
cilium status --wait
# 연결 테스트
cilium connectivity test
출력 예시:
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: OK
\__/¯¯\__/ Hubble Relay: OK
\__/ ClusterMesh: disabled
Deployment cilium-operator Desired: 1, Ready: 1/1
DaemonSet cilium Desired: 3, Ready: 3/3
L3/L4 네트워크 정책
기본 CiliumNetworkPolicy
표준 Kubernetes NetworkPolicy와 달리 CiliumNetworkPolicy는 더 세밀한 제어가 가능합니다.
# deny-all.yaml - 모든 트래픽 차단 (기본 거부 정책)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
endpointSelector: {} # 모든 Pod에 적용
ingress:
- {} # 빈 규칙 = 아무 것도 허용 안 함
kubectl apply -f deny-all.yaml
# 테스트: 다른 네임스페이스에서 접근 시도
kubectl run test --rm -it --image=curlimages/curl -- \
curl -s --connect-timeout 3 http://app.production.svc.cluster.local
# curl: (28) Connection timed out
라벨 기반 허용 정책
# allow-frontend-to-backend.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: '8080'
protocol: TCP
L7 HTTP 정책 — Cilium의 핵심 차별점
여기서부터 Cilium의 진가가 드러납니다. HTTP 경로, 메서드, 헤더까지 필터링할 수 있습니다.
# l7-http-policy.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: api-l7-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: api-server
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: '8080'
protocol: TCP
rules:
http:
# GET /api/products 만 허용
- method: GET
path: '/api/products'
# POST /api/orders 만 허용
- method: POST
path: '/api/orders'
# GET /api/users/* 패턴 허용
- method: GET
path: '/api/users/[0-9]+'
L7 gRPC 정책
# l7-grpc-policy.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: grpc-l7-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: grpc-server
ingress:
- fromEndpoints:
- matchLabels:
app: grpc-client
toPorts:
- ports:
- port: '50051'
protocol: TCP
rules:
http:
- method: POST
path: '/mypackage.MyService/GetItems'
- method: POST
path: '/mypackage.MyService/CreateItem'
DNS 기반 정책
외부 서비스 접근을 FQDN으로 제어할 수 있습니다.
# dns-policy.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-external-apis
namespace: production
spec:
endpointSelector:
matchLabels:
app: backend
egress:
# 특정 외부 API만 허용
- toFQDNs:
- matchName: 'api.stripe.com'
- matchName: 'api.github.com'
- matchPattern: '*.amazonaws.com'
toPorts:
- ports:
- port: '443'
protocol: TCP
# DNS 조회 허용 (필수!)
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: '53'
protocol: UDP
rules:
dns:
- matchPattern: '*'
# DNS 정책 테스트
kubectl exec -n production deploy/backend -- \
curl -s https://api.stripe.com/v1/charges # 성공
kubectl exec -n production deploy/backend -- \
curl -s https://evil-site.com # 차단됨
WireGuard 투명 암호화
Cilium 1.19에서는 WireGuard 기반의 노드 간 암호화가 더욱 안정화되었습니다.
# 암호화 상태 확인
cilium encrypt status
# helm values로 WireGuard 활성화
# values-encryption.yaml
encryption:
enabled: true
type: wireguard
wireguard:
userspaceFallback: false
nodeEncryption: true # 노드 간 모든 트래픽 암호화
# 암호화 확인 - tcpdump로 패킷 검사
kubectl exec -n kube-system ds/cilium -- \
tcpdump -i cilium_wg0 -c 5 2>&1 | head -10
# WireGuard 인터페이스에서 암호화된 트래픽 확인
kubectl exec -n kube-system ds/cilium -- \
cilium-dbg encrypt status
Hubble 네트워크 관측성
Hubble은 Cilium의 내장 관측성 도구로, 모든 네트워크 흐름을 실시간으로 모니터링합니다.
# Hubble CLI 설치
HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -L --remote-name-all \
https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz
tar xzvf hubble-linux-amd64.tar.gz
sudo mv hubble /usr/local/bin/
# Hubble 포트포워딩
cilium hubble port-forward &
# 실시간 흐름 관찰
hubble observe --namespace production
# 차단된 트래픽만 필터
hubble observe --namespace production --verdict DROPPED
# HTTP 요청만 필터
hubble observe --namespace production --protocol http
# 특정 Pod의 트래픽
hubble observe --to-pod production/backend-xxx --type l7
Hubble 메트릭을 Prometheus로 수집
# values-hubble-metrics.yaml
hubble:
metrics:
enabled:
- dns
- drop
- tcp
- flow
- icmp
- http
serviceMonitor:
enabled: true
# 메트릭 확인
curl -s http://localhost:9965/metrics | grep hubble
실전 시나리오: 마이크로서비스 보안
전체 아키텍처에 Cilium 정책을 적용하는 예제입니다.
# microservice-policies.yaml
---
# 1. Frontend -> API Gateway만 허용
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: frontend-egress
namespace: production
spec:
endpointSelector:
matchLabels:
tier: frontend
egress:
- toEndpoints:
- matchLabels:
tier: api-gateway
toPorts:
- ports:
- port: '8080'
---
# 2. API Gateway -> Backend 서비스들 (L7 제어)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: api-gateway-egress
namespace: production
spec:
endpointSelector:
matchLabels:
tier: api-gateway
egress:
- toEndpoints:
- matchLabels:
tier: backend
service: user-service
toPorts:
- ports:
- port: '8081'
rules:
http:
- method: GET
path: '/users/.*'
- method: POST
path: '/users'
- toEndpoints:
- matchLabels:
tier: backend
service: order-service
toPorts:
- ports:
- port: '8082'
rules:
http:
- method: GET
path: '/orders/.*'
- method: POST
path: '/orders'
---
# 3. Backend -> Database (포트 제한)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: backend-to-db
namespace: production
spec:
endpointSelector:
matchLabels:
tier: backend
egress:
- toEndpoints:
- matchLabels:
tier: database
toPorts:
- ports:
- port: '5432'
protocol: TCP
CiliumClusterwideNetworkPolicy
클러스터 전역에 적용되는 정책입니다.
# cluster-wide-deny-external.yaml
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: deny-external-by-default
spec:
endpointSelector:
matchExpressions:
- key: io.kubernetes.pod.namespace
operator: NotIn
values:
- kube-system
- ingress-nginx
egress:
# 클러스터 내부만 허용
- toEntities:
- cluster
# DNS는 허용
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
toPorts:
- ports:
- port: '53'
protocol: UDP
트러블슈팅
# 정책 적용 상태 확인
kubectl get cnp -A
kubectl get ccnp
# 특정 Pod의 정책 상태
kubectl exec -n kube-system ds/cilium -- \
cilium-dbg endpoint list
# 정책 디버깅
kubectl exec -n kube-system ds/cilium -- \
cilium-dbg policy get -n production
# BPF 맵 상태 확인
kubectl exec -n kube-system ds/cilium -- \
cilium-dbg bpf policy get --all
# Identity 확인
kubectl exec -n kube-system ds/cilium -- \
cilium-dbg identity list
성능 벤치마크
# iperf3로 네트워크 성능 측정
# 서버 Pod
kubectl run iperf-server --image=networkstatic/iperf3 -- -s
# 클라이언트에서 테스트
kubectl run iperf-client --rm -it --image=networkstatic/iperf3 -- \
-c iperf-server -t 30 -P 4
# 일반적인 결과:
# iptables CNI: ~9.2 Gbps
# Cilium eBPF: ~9.8 Gbps (약 6-7% 향상)
# Cilium + WireGuard: ~8.5 Gbps
정리
| 기능 | 기존 NetworkPolicy | CiliumNetworkPolicy |
|---|---|---|
| L3/L4 필터링 | O | O |
| L7 HTTP 필터링 | X | O |
| L7 gRPC 필터링 | X | O |
| DNS 기반 정책 | X | O |
| 암호화 | X | WireGuard/IPsec |
| 관측성 | X | Hubble 내장 |
| 클러스터 전역 정책 | X | CCNP |
| 성능 | iptables 의존 | eBPF 최적화 |
Cilium은 단순한 CNI를 넘어 Kubernetes 네트워크 보안 플랫폼으로 자리잡았습니다. 특히 L7 정책과 Hubble 관측성은 마이크로서비스 환경에서 필수적인 기능입니다.
✅ 퀴즈: Cilium과 eBPF 이해도 점검 (7문제)
Q1. eBPF가 iptables 대비 성능이 좋은 주된 이유는?
커널 내에서 직접 실행되며, 해시맵 기반 O(1) 조회로 규칙 수에 관계없이 일정한 성능을 유지합니다.
Q2. CiliumNetworkPolicy에서 L7 HTTP 정책을 적용하려면 어떤 필드를 사용하나요?
toPorts.rules.http 필드에서 method, path 등을 지정합니다.
Q3. DNS 기반 egress 정책을 설정할 때 반드시 함께 허용해야 하는 것은?
kube-dns로의 UDP 53 포트 트래픽을 허용해야 합니다. DNS 조회가 안 되면 FQDN 정책이 작동하지 않습니다.
Q4. Cilium에서 지원하는 투명 암호화 방식 두 가지는?
WireGuard와 IPsec입니다. Cilium 1.19에서는 WireGuard가 권장됩니다.
Q5. Hubble에서 차단된 트래픽만 보려면 어떤 옵션을 사용하나요?
hubble observe --verdict DROPPED
Q6. CiliumClusterwideNetworkPolicy(CCNP)와 CiliumNetworkPolicy(CNP)의 차이는?
CCNP는 클러스터 전체에 적용되며 namespace가 없고, CNP는 특정 네임스페이스에만 적용됩니다.
Q7. Cilium을 kube-proxy 대체 모드로 설치하면 어떤 이점이 있나요?
iptables 규칙 체인이 제거되어 서비스 라우팅 성능이 향상되고, 대규모 클러스터에서 규칙 수 증가에 따른 성능 저하가 없습니다.