Skip to content
Published on

Kubernetes Network Policy와 Service Mesh 완벽 가이드 (Istio, Cilium, Calico 비교)

Authors
  • Name
    Twitter
Kubernetes Network Policy와 Service Mesh 아키텍처

들어가며

Kubernetes 클러스터에서 Pod 간 통신은 기본적으로 모두 허용(allow-all) 상태입니다. 같은 클러스터 내라면 어떤 Pod든 다른 Pod에 자유롭게 접근할 수 있다는 뜻입니다. 작은 규모의 개발 환경에서는 크게 문제되지 않지만, 프로덕션 환경에서 수십, 수백 개의 마이크로서비스가 동작하는 상황이라면 이는 심각한 보안 위협이 됩니다.

공격자가 하나의 Pod를 탈취하면 클러스터 내 모든 서비스에 횡방향 이동(lateral movement)이 가능해지기 때문입니다. 이를 방지하려면 Network Policy를 통한 네트워크 세그멘테이션과, Service Mesh를 통한 mTLS 암호화 및 제로 트러스트 아키텍처가 필수적입니다.

이 글에서는 Kubernetes Network Policy의 기초부터 심화까지 다루고, Istio, Cilium, Calico 세 가지 솔루션의 Service Mesh 아키텍처를 비교 분석합니다. 실제 운영에서 만날 수 있는 트러블슈팅 사례와 성능 벤치마크까지 포함하여, 여러분의 환경에 가장 적합한 선택을 할 수 있도록 안내합니다.

Kubernetes Network Policy 기초

Network Policy란?

Network Policy는 Kubernetes 네이티브 리소스로, Pod 레벨에서 인바운드(Ingress)와 아웃바운드(Egress) 트래픽을 제어하는 방화벽 규칙입니다. 레이블 셀렉터를 기반으로 동작하며, Pod가 재시작되거나 노드 간 이동하더라도 일관된 정책이 적용됩니다.

중요한 전제 조건: Network Policy 리소스를 생성하더라도 이를 구현하는 CNI 플러그인(Calico, Cilium, Antrea 등)이 없으면 정책이 전혀 적용되지 않습니다. 기본 kubenet이나 Flannel은 Network Policy를 지원하지 않습니다.

Default Deny 정책

모든 네트워크 보안의 시작은 Default Deny 정책입니다. 먼저 모든 트래픽을 차단한 후, 필요한 통신만 명시적으로 허용하는 화이트리스트 방식을 적용합니다.

# default-deny-all.yaml
# 네임스페이스 내 모든 Pod의 Ingress/Egress 트래픽을 차단
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {} # 빈 셀렉터 = 네임스페이스 내 모든 Pod
  policyTypes:
    - Ingress
    - Egress

이 정책이 적용되면 production 네임스페이스의 모든 Pod는 인바운드/아웃바운드 트래픽이 완전히 차단됩니다. DNS 조회조차 불가능해지므로 반드시 DNS 허용 정책을 함께 적용해야 합니다.

# allow-dns.yaml
# kube-dns(CoreDNS) 접근을 허용하는 정책
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53

Pod 간 특정 통신 허용

Default Deny 상태에서 프론트엔드가 백엔드 API에 접근하도록 허용하는 예시입니다.

# allow-frontend-to-backend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend-api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

이 정책은 app: frontend 레이블을 가진 Pod에서 app: backend-api Pod의 TCP 8080 포트로의 인바운드 트래픽만 허용합니다.

Network Policy 심화: Egress, CIDR, 포트 제어

Egress 정책으로 외부 접근 제어

마이크로서비스가 외부 API나 데이터베이스에 접근하는 경우, Egress 정책으로 허용 대상을 세밀하게 제한할 수 있습니다.

# egress-external-api-and-db.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-egress-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend-api
  policyTypes:
    - Egress
  egress:
    # 1. 같은 네임스페이스의 Redis 접근 허용
    - to:
        - podSelector:
            matchLabels:
              app: redis
      ports:
        - protocol: TCP
          port: 6379
    # 2. 외부 PostgreSQL RDS 접근 (CIDR 기반)
    - to:
        - ipBlock:
            cidr: 10.100.0.0/16
      ports:
        - protocol: TCP
          port: 5432
    # 3. 외부 HTTPS API 접근 허용
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8
              - 172.16.0.0/12
              - 192.168.0.0/16
      ports:
        - protocol: TCP
          port: 443
    # 4. DNS 허용
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53

네임스페이스 간 통신 제어

멀티 테넌트 환경에서 네임스페이스 간 격리는 필수입니다. 특정 네임스페이스에서만 접근을 허용하는 패턴입니다.

# cross-namespace-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-monitoring-access
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend-api
  policyTypes:
    - Ingress
  ingress:
    # monitoring 네임스페이스의 Prometheus만 메트릭 스크래핑 허용
    - from:
        - namespaceSelector:
            matchLabels:
              team: monitoring
          podSelector:
            matchLabels:
              app: prometheus
      ports:
        - protocol: TCP
          port: 9090

Network Policy의 한계

Kubernetes 기본 Network Policy는 L3/L4 수준(IP, 포트, 프로토콜)의 제어만 가능합니다. 다음과 같은 요구사항은 기본 Network Policy로는 대응할 수 없습니다:

  • L7(HTTP 경로, 메서드, 헤더) 기반 필터링
  • mTLS 암호화 및 서비스 인증
  • 트래픽 관측성(Observability) 및 분산 트레이싱
  • 고급 트래픽 관리(카나리 배포, 서킷 브레이커, 리트라이)
  • FQDN(도메인) 기반 Egress 제어

이러한 고급 기능이 필요할 때 Service Mesh가 등장합니다.

Service Mesh 아키텍처 비교 (Istio vs Cilium vs Calico)

세 가지 주요 솔루션의 아키텍처와 기능을 비교합니다.

항목Istio (Ambient Mode)Cilium Service MeshCalico (Enterprise)
데이터 플레인ztunnel(L4) + Waypoint Proxy(L7)eBPF(L3/L4) + 노드별 Envoy(L7)iptables/eBPF + Envoy(L7)
사이드카불필요 (Ambient Mode)불필요선택적
mTLS자동 (HBONE 프로토콜)WireGuard/IPsecWireGuard 수동 설정
L7 정책AuthorizationPolicyCiliumNetworkPolicyGlobalNetworkPolicy
관측성Kiali, Jaeger, PrometheusHubble (내장)Calico Enterprise UI
성능 오버헤드중간 (ztunnel 경유)낮음 (커널 레벨)중간
CPU 사용량보통30% 적음 (L4 기준)보통
QPS 성능높음 (저연결 시 우수)높음 (고연결 시 우수)보통
멀티 클러스터지원 (East-West Gateway)Cluster Mesh 지원Federation 지원
학습 곡선높음중간중간
커뮤니티매우 큼 (CNCF Graduated)큼 (CNCF Graduated)큼 (Tigera 주도)
Windows 노드미지원미지원지원
최적 사용 사례대규모 멀티 클러스터, L7 정밀 제어고성능 L4, eBPF 기반 관측하이브리드 환경, 엔터프라이즈 규정 준수

아키텍처 선택 기준

  • 순수 L3/L4 네트워크 보안만 필요: Kubernetes 기본 Network Policy + Calico/Cilium CNI
  • L7 트래픽 관리 + mTLS가 핵심: Istio Ambient Mode
  • 고성능 + 커널 레벨 관측성: Cilium Service Mesh
  • 엔터프라이즈 규정 준수 + 하이브리드: Calico Enterprise

Istio 기반 Service Mesh 구축

Istio Ambient Mode 설치

Istio 1.24부터 Ambient Mode가 정식 GA 되었습니다. 기존 사이드카 방식 대비 CPU/메모리 오버헤드를 90% 이상 줄이면서도 mTLS와 L7 트래픽 관리를 제공합니다.

# istioctl 설치
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.24.2 sh -
export PATH="$HOME/istio-1.24.2/bin:$PATH"

# Ambient 프로파일로 설치
istioctl install --set profile=ambient --skip-confirmation

# 설치 확인
kubectl get pods -n istio-system
# NAME                                   READY   STATUS    RESTARTS   AGE
# istiod-7b69f4b6c-xxxxx                 1/1     Running   0          60s
# ztunnel-xxxxx                          1/1     Running   0          60s
# istio-cni-node-xxxxx                   1/1     Running   0          60s

# 네임스페이스에 Ambient 모드 활성화
kubectl label namespace production istio.io/dataplane-mode=ambient

Waypoint Proxy 배포 (L7 정책용)

L4 수준의 mTLS만 필요하다면 ztunnel만으로 충분합니다. L7 수준의 정밀한 트래픽 제어가 필요하면 Waypoint Proxy를 추가 배포합니다.

# Waypoint Proxy 생성
istioctl waypoint apply --namespace production --name backend-waypoint

# 특정 서비스에 Waypoint 연결
kubectl label service backend-api \
  istio.io/use-waypoint=backend-waypoint \
  -n production

Istio AuthorizationPolicy 설정

Istio의 L7 정책은 AuthorizationPolicy를 통해 HTTP 메서드, 경로, 헤더 수준까지 제어합니다.

# istio-auth-policy.yaml
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: backend-api-policy
  namespace: production
spec:
  targetRefs:
    - kind: Service
      group: ''
      name: backend-api
  action: ALLOW
  rules:
    - from:
        - source:
            principals:
              - 'cluster.local/ns/production/sa/frontend'
      to:
        - operation:
            methods: ['GET', 'POST']
            paths: ['/api/v1/*']
    - from:
        - source:
            principals:
              - 'cluster.local/ns/monitoring/sa/prometheus'
      to:
        - operation:
            methods: ['GET']
            paths: ['/metrics']

이 정책은 frontend 서비스 어카운트에서 /api/v1/ 경로로의 GET, POST만 허용하고, Prometheus에서 /metrics 경로로의 GET만 허용합니다. 그 외 모든 요청은 403 Forbidden으로 거부됩니다.

Cilium 기반 eBPF Service Mesh

Cilium 설치 및 Service Mesh 활성화

Cilium은 eBPF를 활용하여 커널 레벨에서 네트워킹을 처리합니다. 사이드카 프록시 없이 L4 트래픽을 처리하고, L7 처리가 필요한 경우에만 노드별 공유 Envoy 프록시를 사용합니다.

# Cilium CLI 설치
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
GOOS=$(go env GOOS)
GOARCH=$(go env GOARCH)
curl -L --fail --remote-name-all \
  "https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-${GOOS}-${GOARCH}.tar.gz"
sudo tar xzvfC "cilium-${GOOS}-${GOARCH}.tar.gz" /usr/local/bin

# Helm으로 Cilium 설치 (Service Mesh + Hubble 활성화)
helm repo add cilium https://helm.cilium.io/
helm repo update

helm install cilium cilium/cilium --version 1.17.0 \
  --namespace kube-system \
  --set kubeProxyReplacement=true \
  --set hubble.enabled=true \
  --set hubble.relay.enabled=true \
  --set hubble.ui.enabled=true \
  --set envoy.enabled=true \
  --set encryption.enabled=true \
  --set encryption.type=wireguard

# 설치 확인
cilium status --wait
cilium connectivity test

CiliumNetworkPolicy로 L7 정책 적용

Cilium은 자체 CRD인 CiliumNetworkPolicy를 통해 HTTP, gRPC, Kafka 등 L7 프로토콜 수준의 정밀한 정책을 지원합니다.

# cilium-l7-policy.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: backend-l7-policy
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: backend-api
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      toPorts:
        - ports:
            - port: '8080'
              protocol: TCP
          rules:
            http:
              - method: 'GET'
                path: '/api/v1/products'
              - method: 'POST'
                path: '/api/v1/orders'
              - method: 'GET'
                path: '/healthz'
    - fromEndpoints:
        - matchLabels:
            app: prometheus
      toPorts:
        - ports:
            - port: '9090'
              protocol: TCP
          rules:
            http:
              - method: 'GET'
                path: '/metrics'

Hubble을 활용한 네트워크 관측

Cilium의 Hubble은 eBPF 기반으로 모든 네트워크 플로우를 실시간 모니터링합니다.

# Hubble CLI 설치 후 관측
hubble observe --namespace production --follow

# 특정 Pod의 트래픽만 필터링
hubble observe --namespace production \
  --to-label app=backend-api \
  --verdict DROPPED

# HTTP 요청 관측 (L7)
hubble observe --namespace production \
  --protocol http \
  --http-status 5xx

# 네트워크 플로우 시각화 (Hubble UI)
cilium hubble port-forward &
# 브라우저에서 http://localhost:12000 접속

Hubble의 출력 예시:

TIMESTAMP             SOURCE                  DESTINATION             TYPE      VERDICT   SUMMARY
Mar 14 10:23:01.123   production/frontend     production/backend-api  L7/HTTP   FORWARDED GET /api/v1/products => 200
Mar 14 10:23:01.456   production/attacker     production/backend-api  L7/HTTP   DROPPED   POST /api/v1/admin => Policy denied
Mar 14 10:23:02.789   production/backend-api  production/redis        L4/TCP    FORWARDED TCP 6379

mTLS와 제로 트러스트 네트워크

제로 트러스트란?

제로 트러스트(Zero Trust)는 "아무것도 신뢰하지 않고 모든 것을 검증한다"는 보안 모델입니다. 클러스터 내부 통신도 암호화하고, 모든 서비스 간 호출에서 신원을 검증합니다. Network Policy만으로는 트래픽 암호화가 불가능하기 때문에, mTLS(mutual TLS)를 제공하는 Service Mesh가 필요합니다.

Istio Ambient Mode의 mTLS

Istio Ambient Mode는 HBONE(HTTP-Based Overlay Network Environment) 프로토콜을 사용하여 모든 트래픽을 자동으로 mTLS 암호화합니다. ztunnel이 노드 레벨에서 인증서를 관리하며, 각 Pod마다 고유한 SPIFFE 기반 워크로드 ID를 발급합니다.

# istio-peer-auth.yaml
# STRICT 모드: mTLS가 아닌 평문 트래픽 거부
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: strict-mtls
  namespace: production
spec:
  mtls:
    mode: STRICT

STRICT 모드를 설정하면 해당 네임스페이스의 모든 서비스는 mTLS 연결만 수락합니다. 메시에 포함되지 않은 서비스로부터의 평문 요청은 모두 거부됩니다.

Cilium의 WireGuard 기반 암호화

Cilium은 커널 내장 WireGuard를 사용하여 노드 간 트래픽을 자동 암호화합니다. Istio의 mTLS와 달리 애플리케이션 레벨이 아닌 커널 레벨에서 작동하므로 성능 오버헤드가 적습니다.

# WireGuard 암호화 상태 확인
cilium encrypt status

# 출력 예시:
# Encryption:  Wireguard
# Keys in use: 2
# Errors:      0
# Interfaces:  cilium_wg0

# 암호화 키 목록 확인
cilium encrypt get

WireGuard와 mTLS의 차이점:

  • WireGuard: 노드 간 L3 수준 암호화, 커널 레벨 처리, Pod 개별 ID 미부여
  • mTLS (Istio): 서비스 간 L7 수준 암호화, SPIFFE 기반 워크로드 ID, 세밀한 인가 정책

프로덕션 환경에서는 Cilium WireGuard로 노드 간 암호화를 적용하고, 추가로 Istio mTLS를 통해 워크로드 레벨 인증까지 구현하는 이중 보안 전략을 사용하기도 합니다.

운영 시 주의사항과 트러블슈팅

1. Network Policy 적용 순서 주의

Network Policy는 합집합(additive) 방식으로 동작합니다. 여러 정책이 동일 Pod에 적용되면 허용 규칙이 합산됩니다. 충돌하는 정책이 있을 때 거부 규칙이 우선하는 것이 아니라, 어느 하나라도 허용하면 트래픽이 통과합니다.

# 특정 Pod에 적용된 모든 Network Policy 확인
kubectl get networkpolicy -n production -o wide

# Pod 레이블 확인 (정책 셀렉터 매칭 검증)
kubectl get pods -n production --show-labels

# Calico를 사용하는 경우 정책 매칭 확인
calicoctl get networkpolicy -n production -o yaml

2. CNI 플러그인 미설치 상태에서 Network Policy 무시

가장 흔한 실수입니다. Network Policy 리소스를 생성해도 이를 구현하는 CNI 플러그인이 없으면 정책이 전혀 적용되지 않습니다.

# CNI 플러그인 확인
kubectl get pods -n kube-system | grep -E 'calico|cilium|antrea'

# Network Policy가 실제로 적용되는지 검증하는 테스트
# 1. Default Deny 적용
kubectl apply -f default-deny-all.yaml

# 2. 통신 테스트 (차단되어야 정상)
kubectl exec -n production deploy/frontend -- \
  curl -s --connect-timeout 3 http://backend-api:8080/healthz
# 타임아웃이 발생하면 정책이 제대로 적용된 것

3. DNS 해결 실패

Default Deny 정책 적용 후 DNS 허용을 누락하면 모든 서비스 디스커버리가 중단됩니다.

# DNS 문제 진단
kubectl exec -n production deploy/frontend -- nslookup backend-api
# ;; connection timed out; no servers could be reached

# CoreDNS Pod 확인
kubectl get pods -n kube-system -l k8s-app=kube-dns

# DNS 정책 적용 후 재테스트
kubectl apply -f allow-dns.yaml
kubectl exec -n production deploy/frontend -- nslookup backend-api
# Server:    10.96.0.10
# Name:      backend-api.production.svc.cluster.local

4. Istio ztunnel 장애 대응

ztunnel은 노드별 DaemonSet으로 실행되며, 장애 시 해당 노드의 모든 Ambient Mesh 트래픽이 중단됩니다.

# ztunnel 상태 확인
kubectl get pods -n istio-system -l app=ztunnel

# ztunnel 로그 확인 (인증서 문제 진단)
kubectl logs -n istio-system -l app=ztunnel --tail=50

# ztunnel 재시작
kubectl rollout restart daemonset/ztunnel -n istio-system

# Istiod와의 xDS 연결 상태 확인
istioctl proxy-status

5. Cilium eBPF 맵 용량 초과

대규모 클러스터에서 Cilium eBPF 맵의 기본 크기가 부족할 수 있습니다.

# eBPF 맵 사용량 확인
cilium bpf ct list global | wc -l
cilium bpf policy get --all

# 맵 크기 증가 (Helm values 수정)
# bpf.ctGlobalTCPMax: 524288  (기본값보다 증가)
# bpf.ctGlobalAnyMax: 262144
# bpf.policyMapMax: 65536

# 변경 적용
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --reuse-values \
  --set bpf.ctGlobalTCPMax=524288

실패 사례와 복구 절차

사례 1: 잘못된 Egress 정책으로 전체 서비스 장애

상황: 운영팀이 보안 강화를 위해 Default Deny Egress를 적용했으나, DNS 허용 정책을 누락하여 모든 서비스 간 통신이 중단됨.

증상: 모든 Pod에서 서비스 이름으로의 접근이 실패. IP 직접 지정 시에는 통신 가능.

복구 절차:

# 1. 즉시 문제 확인
kubectl get networkpolicy -n production

# 2. DNS 허용 정책 긴급 적용
kubectl apply -f - <<'POLICY'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: emergency-allow-dns
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
POLICY

# 3. 서비스 복구 확인
kubectl exec -n production deploy/frontend -- nslookup backend-api

교훈: Default Deny 정책은 반드시 DNS 허용 정책과 함께 적용해야 합니다. 정책 변경 전에 반드시 스테이징 환경에서 테스트하고, 롤백 계획을 준비하세요.

사례 2: Istio 업그레이드 중 mTLS 불일치

상황: Istio 버전 업그레이드 과정에서 구버전 사이드카와 신버전 ztunnel 간 mTLS 핸드셰이크 실패.

증상: 일부 서비스 간 503 에러 및 "upstream connect error" 메시지 발생.

복구 절차:

# 1. mTLS 모드를 임시로 PERMISSIVE로 변경 (평문+mTLS 모두 허용)
kubectl apply -f - <<'POLICY'
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: permissive-during-upgrade
  namespace: production
spec:
  mtls:
    mode: PERMISSIVE
POLICY

# 2. 모든 워크로드 재시작하여 최신 프록시 적용
kubectl rollout restart deployment -n production

# 3. 모든 Pod가 새 버전으로 교체된 후 STRICT 복원
kubectl rollout status deployment -n production --timeout=300s
kubectl apply -f - <<'POLICY'
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: strict-mtls
  namespace: production
spec:
  mtls:
    mode: STRICT
POLICY

사례 3: Cilium Agent 재시작으로 인한 순간 트래픽 드롭

상황: Cilium DaemonSet 업데이트 중 노드의 eBPF 프로그램이 잠시 언로드되어 해당 노드의 Pod 간 통신이 수 초간 중단.

복구 및 예방:

# Rolling Update 전략으로 한 노드씩 업데이트
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --reuse-values \
  --set upgradeCompatibility=1.16 \
  --set rollOutCiliumPods=true

# PodDisruptionBudget 확인
kubectl get pdb -n kube-system

# 업데이트 진행 상황 모니터링
kubectl rollout status daemonset/cilium -n kube-system --timeout=600s

성능 벤치마크와 선택 가이드

실측 벤치마크 결과 (2025년 기준)

최근 대규모 엔터프라이즈 환경에서의 비교 테스트 결과를 요약합니다.

메트릭Network Policy OnlyIstio AmbientCilium Service Mesh
P99 Latency (ms)1.23.82.1
QPS (요청/초)45,00038,00042,000
QPS per Core-2,1781,815
CPU 오버헤드기준+15%+8%
메모리 오버헤드기준+120MB/노드+80MB/노드
저연결 성능-우수보통
고연결 성능-보통우수

참고: Istio의 QPS per Core가 높은 것은 L7 처리 능력이 포함된 수치이며, Cilium의 CPU 측정에는 커널 내 WireGuard 암호화 비용이 제외된 점을 고려해야 합니다.

선택 가이드 플로우차트

  1. L3/L4 네트워크 격리만 필요한가?

    • 예: Kubernetes Network Policy + Calico 또는 Cilium CNI로 충분
    • 아니오: 2번으로
  2. L7 트래픽 관리(카나리, 리트라이, 서킷 브레이커)가 필요한가?

    • 예: Istio Ambient Mode 또는 Cilium + Envoy
    • 아니오: 3번으로
  3. mTLS 기반 제로 트러스트가 요구사항인가?

    • 예: Istio Ambient Mode (SPIFFE 기반 워크로드 ID)
    • 아니오: Cilium WireGuard 암호화로 노드 간 암호화
  4. 고성능 + 커널 레벨 관측성이 우선인가?

    • 예: Cilium Service Mesh + Hubble
    • 아니오: Istio (더 풍부한 L7 기능)
  5. Windows 노드 혼용 또는 하이브리드 환경인가?

    • 예: Calico Enterprise
    • 아니오: Istio 또는 Cilium

운영 규모별 권장사항

  • 소규모 클러스터 (노드 10개 이하): Cilium CNI + 기본 Network Policy. Service Mesh 도입은 오버헤드 대비 이점이 적음.
  • 중규모 클러스터 (노드 10~100개): Cilium Service Mesh 또는 Istio Ambient. L7 요구사항에 따라 선택.
  • 대규모 클러스터 (노드 100개 이상): Istio Ambient Mode. 성숙한 멀티 클러스터 지원, 풍부한 에코시스템, 안정성.
  • 하이브리드/멀티 클라우드: Calico Enterprise 또는 Cilium Cluster Mesh.

마치며

Kubernetes 네트워크 보안은 단순히 Network Policy를 적용하는 것을 넘어, 애플리케이션의 특성과 보안 요구사항에 맞는 전체적인 전략이 필요합니다.

핵심 요약:

  • Network Policy는 기본 중의 기본: Default Deny로 시작하여 필요한 통신만 허용하는 화이트리스트 방식을 반드시 적용하세요. DNS 허용 정책을 잊지 마세요.
  • Service Mesh는 필요할 때 도입: mTLS, L7 정책, 고급 트래픽 관리가 실제로 필요한 시점에 도입하세요. 불필요한 복잡성은 오히려 운영 부담을 증가시킵니다.
  • Istio vs Cilium은 트레이드오프: Istio는 L7 기능과 생태계가 풍부하고, Cilium은 커널 레벨 성능과 관측성이 강점입니다. 요구사항에 맞게 선택하세요.
  • 점진적 도입이 핵심: Default Deny 정책부터 시작하여, Network Policy를 충분히 검증한 후, 필요에 따라 Service Mesh를 추가하는 단계적 접근이 가장 안전합니다.
  • 자동화와 테스트: 정책 변경은 반드시 CI/CD 파이프라인을 통해 스테이징에서 먼저 검증하고, 롤백 계획을 항상 준비하세요.

네트워크 보안은 한 번 설정하고 끝나는 것이 아닙니다. 서비스가 변화함에 따라 정책도 지속적으로 리뷰하고 업데이트해야 합니다. 분기별 정책 감사를 권장하며, Hubble이나 Kiali 같은 관측 도구를 활용하여 실제 트래픽 패턴을 기반으로 정책을 최적화하시기 바랍니다.

참고자료