/인프라/Istio vs NetworkPolicy: L3/L4와 L7 정책 충돌 시 우선순위 완벽 가이드
인프라IstioNetworkPolicy

Istio vs NetworkPolicy: L3/L4와 L7 정책 충돌 시 우선순위 완벽 가이드

서비스 메시 도입으로 복잡해진 네트워킹 정책, Istio와 K8s NetworkPolicy가 충돌할 때 어떤 규칙이 최종 적용될까요? L3/L4와 L7의 정책 우선순위를 계층적으로 분석하고, 충돌을 원천 차단하는 실전 아키텍처 설계 모범 사례를 제시합니다.

Istio vs NetworkPolicy: L3/L4와 L7 정책 충돌 시 우선순위 완벽 가이드

Istio와 K8s NetworkPolicy, 충돌 없이 안전하게 사용하는 정책 우선순위 가이드

Kubernetes 환경에서 서비스 메시(Service Mesh)를 도입하는 것은 애플리케이션의 안정성과 가시성을 극대화하는 혁신적인 과정입니다. 하지만 이 강력한 도구들은 그만큼 복잡한 네트워킹 정책을 수반합니다. 특히, 네이티브 Kubernetes의 NetworkPolicy와 Istio가 제공하는 세밀한 제어 기능(AuthorizationPolicy, VirtualService)을 함께 사용하다 보면, "도대체 어느 규칙이 최종적으로 적용되는 걸까?"라는 근본적인 질문에 부딪히기 쉽습니다.

이 글은 시니어 DevOps 엔지니어와 SRE 분들이 가장 궁금해하는 지점, 즉 두 가지 강력한 네트워킹 정책이 충돌했을 때의 **정책 우선순위(Precedence)**를 명확하게 정리하고, 충돌을 원천적으로 방지하는 실질적인 아키텍처 설계 가이드라인을 제공합니다.

네트워킹 정책의 계층적 이해: L3/L4 vs. L7

정책 충돌을 이해하려면, 먼저 두 정책이 작동하는 '레이어'가 근본적으로 다름을 인지해야 합니다.

🌐 NetworkPolicy: 인프라 방화벽 (L3/L4 레벨)

NetworkPolicy는 Kubernetes의 CNI(Container Network Interface) 레벨에서 작동하는, 가장 낮은 단계의 방화벽 역할을 합니다. 이는 마치 데이터센터의 물리적인 출입문과 같습니다.

  • 제어 범위: IP 주소(L3)와 포트 번호(L4)를 기반으로 트래픽의 **도달 가능성(Reachability)**을 통제합니다.
  • 작동 방식: 특정 네임스페이스나 파드 그룹이 특정 포트로 통신할 수 있는지 여부를 결정합니다.
  • 핵심 원칙: 기본적으로 모든 트래픽을 차단하는 "Deny by Default" 원칙을 따릅니다.

🛡️ Istio Policy: 애플리케이션 게이트웨이 (L7 레벨)

Istio는 사이드카 프록시(Envoy)를 통해 트래픽을 가로채서 검사합니다. 이는 데이터센터 내부의 보안 검문소와 같습니다.

  • 제어 범위: HTTP 메서드(GET, POST), 헤더 값, 사용자 인증(JWT 등)과 같은 애플리케이션 계층의 세부 정보를 검사합니다.
  • 작동 방식: 트래픽이 이미 목적지에 도달했다는 전제 하에, '누가(Identity)' '어떤 방식으로(Method)' 접근했는지를 검증합니다.
  • 핵심 원칙: 역시 기본적으로 접근을 거부하는 **"Deny by Default"**를 따릅니다.

🚨 핵심 비교: 정책 우선순위(Precedence) 매트릭스 분석

가장 중요한 질문입니다. 트래픽이 발생했을 때, 이 두 정책 중 어느 것이 먼저 작동하며, 어느 것이 최종 승자인가요?

🚀 트래픽 흐름의 순서: CNI $\rightarrow$ Sidecar $\rightarrow$ Application

트래픽은 반드시 계층적으로 흐릅니다. 이 순서를 이해하는 것이 모든 문제 해결의 열쇠입니다.

  1. CNI/NetworkPolicy 검사 (L3/L4): 패킷이 클러스터 네트워크에 진입하는 순간, CNI 플러그인이 먼저 포트와 IP를 확인합니다. 여기서 차단되면, 그 이후의 과정은 없습니다.
  2. Sidecar/Istio 검사 (L7): 패킷이 파드에 도달하여 사이드카 프록시를 통과할 때, Istio가 L7 규칙(인증, 라우팅)을 검사합니다.
  3. Application 검사: 모든 검증을 통과한 트래픽만이 최종 애플리케이션 포트로 전달됩니다.

💡 실무 관점의 경험 공유: 제가 가장 많이 본 실수는, 개발팀이 "Istio에서 인증을 안 해주면 안 돼요"라며 L7 정책만 강화하고, 인프라팀이 L3/L4 정책을 너무 타이트하게 막아버린 경우입니다. 결과적으로 L3/L4에서 차단되어, Istio의 정교한 L7 인증 로직 자체가 실행될 기회조차 얻지 못하는 상황이 발생합니다.

📊 정책 적용 계층 및 제어 범위 비교표

정책 종류제어 계층주요 제어 요소기본 동작 원칙제어 대상
NetworkPolicyL3/L4IP, 포트Deny by Default네트워크 연결 자체
Istio AuthorizationPolicyL7HTTP Method, Header, IdentityDeny by Default접근 권한 (인가)
Istio VirtualServiceL7Host, Path, Weight라우팅 규칙트래픽 경로 및 분배

🛑 충돌 시나리오별 규칙 적용 원칙 (가장 중요)

규칙: 낮은 계층(L3/L4)에서 차단되면, 높은 계층(L7)의 규칙은 무시됩니다.

만약 NetworkPolicy가 특정 포트(예: 8080)로의 모든 인바운드 트래픽을 차단했다면, 아무리 AuthorizationPolicy에서 "이 사용자는 POST 요청을 허용해야 해"라고 설정했더라도, 패킷 자체가 사이드카 프록시까지 도달하지 못하므로 인증 과정은 시작조차 할 수 없습니다.

🛠️ 안전한 아키텍처 설계를 위한 모범 사례

정책 충돌을 막는 가장 확실한 방법은 역할 분리(Separation of Concerns) 원칙을 철저히 지키는 것입니다.

1. 역할 분리 원칙 적용하기

  • NetworkPolicy (L3/L4): 오직 '통신이 가능한지(Can it reach?)' 여부만 담당합니다. (예: 서비스 A는 서비스 B의 8080 포트로만 접근 가능해야 한다.)
  • Istio Policy (L7): 오직 '접근 권한이 있는지(Is it allowed?)' 여부만 담당합니다. (예: 서비스 B의 8080 포트에 접근은 가능하지만, 오직 GET 메서드만 허용한다.)

2. 실전 예시: 포트 허용 + 인증 추가

다음 YAML 예시는 이 원칙을 완벽하게 구현한 예시입니다.

  1. NetworkPolicy (L3/L4): 서비스 A가 서비스 B의 8080 포트로 접근할 수 있도록 최소한의 통로를 열어줍니다.
  2. AuthorizationPolicy (L7): 통로를 통과한 트래픽에 대해, 'JWT 토큰을 가진 사용자만' 접근할 수 있도록 인증을 추가합니다.
YAML
# 1. NetworkPolicy: L3/L4 통로 확보 (최소한의 연결만 허용)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-service-b-port
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: service-b
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: service-a
    ports:
    - port: 8080
      protocol: TCP

---
# 2. AuthorizationPolicy: L7 인증 추가 (실질적인 접근 제어)
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: require-jwt-auth
  namespace: default
spec:
  selector:
    matchLabels:
      app: service-b
  action: ALLOW
  rules:
  - from:
    - source:
        namespaces: ["default"]
    to:
    - operation:
        methods: ["GET"] # L7: GET 메서드만 허용
        paths: ["/api/v1/data"]
        requestPrincipals: ["cluster.local/ns/default/sa/service-a-sa"] # L7: 특정 서비스 계정만 허용

위 예시에서, NetworkPolicy가 없으면 트래픽이 아예 도달하지 못하고, AuthorizationPolicy가 없으면 인증 없이 누구나 접근할 수 있게 됩니다. 둘 다 있어야 안전합니다.

🔍 디버깅 팁: 트래픽 흐름 추적하기

정책 충돌이 의심될 때, 다음 두 가지 도구를 순서대로 사용해 보세요.

  1. kubectl get events: 네임스페이스 레벨에서 정책 위반이나 CNI 관련 오류 메시지가 있는지 확인합니다. (L3/L4 문제 감지)
  2. istioctl proxy-config logs <pod-name>: 사이드카 프록시의 로그를 확인하여, 트래픽이 어느 단계에서 거부되었는지(예: "Authentication failed", "No matching rule found") 구체적인 L7 에러 코드를 확인합니다.

참고: 공식 문서

이 글에서 다루는 동작·설정·에러의 1차 출처는 다음 공식 문서입니다. 버전별 옵션과 정확한 동작은 여기서 확인하세요.

자주 묻는 질문 (FAQ)

Q: NetworkPolicy를 적용하면 Istio의 모든 L7 기능이 비활성화되나요? A: 아닙니다. NetworkPolicy는 L3/L4 레벨에서 통로를 열어주는 역할만 합니다. 통로가 열린 후, 사이드카 프록시가 정상적으로 작동한다면 Istio의 L7 정책은 독립적으로 작동합니다. 단, L3/L4에서 차단되면 L7은 작동할 수 없습니다.

Q: AuthorizationPolicy만 설정하고 NetworkPolicy는 건드리지 않아도 되나요? A: 권장되지 않습니다. 만약 클러스터의 기본 네트워크 정책이 매우 제한적이라면, Istio가 트래픽을 수신할 수 있는 최소한의 L3/L4 통로를 NetworkPolicy로 명시적으로 열어주는 것이 안정성을 높이는 가장 안전한 방법입니다.

Q: 두 정책을 모두 적용했을 때, 어떤 것이 더 우선순위가 높다고 확신할 수 있나요? A: 우선순위는 '계층적'입니다. 네트워크 스택(L3/L4)에서 막히는 것이 가장 높은 우선순위를 가지며, 이는 L7 정책보다 항상 먼저 검사됩니다.


마무리하며: 네트워킹 정책은 마치 건물을 짓는 과정과 같습니다. NetworkPolicy는 건물의 외벽과 기초 공사(구조적 안정성)를 담당하고, Istio는 내부의 보안 시스템과 출입 통제(기능적 안정성)를 담당합니다. 두 시스템의 역할을 명확히 이해하고, 각자의 영역을 침범하지 않도록 분리하는 것이 궁극의 안정성을 보장하는 핵심입니다.

✦ ✦ ✦
편집 검토 · Editorial Review

이 글은 AI 에이전트가 자료 조사와 1차 초안 작성을 담당하고, 사람 편집자가 사실관계·출처·톤과 맥락을 검토한 뒤 발행했습니다. 환경(OS·버전)에 따라 결과가 다를 수 있으니 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.

초안 · AI (Content Reviewer)·검토 · Nodelog 편집자·발행 ·

댓글

첫 번째 댓글을 남겨보세요.