Skip to content
Published on

Cilium과 eBPF로 구현하는 Kubernetes 네트워크 보안: L3/L4/L7 정책부터 암호화까지

Authors
  • Name
    Twitter

들어가며

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 비교

항목iptableseBPF (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

정리

기능기존 NetworkPolicyCiliumNetworkPolicy
L3/L4 필터링OO
L7 HTTP 필터링XO
L7 gRPC 필터링XO
DNS 기반 정책XO
암호화XWireGuard/IPsec
관측성XHubble 내장
클러스터 전역 정책XCCNP
성능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 규칙 체인이 제거되어 서비스 라우팅 성능이 향상되고, 대규모 클러스터에서 규칙 수 증가에 따른 성능 저하가 없습니다.