본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 7장: 네트워크 정책과 서비스 메시
2026년 3월 19일·인프라·

7장: 네트워크 정책과 서비스 메시

쿠버네티스 NetworkPolicy로 기본 거부 정책을 구현하고, Calico/Cilium 네트워크 정책과 Istio mTLS로 컨테이너 간 통신을 안전하게 제어합니다.

14분617자9개 섹션
securitykubernetesdevopsinfrastructure
공유
container-security7 / 10
12345678910
이전6장: 런타임 보안 — Falco와 위협 감지다음8장: 시크릿 관리

학습 목표

  • 쿠버네티스의 기본 네트워크 모델과 보안 위험을 이해합니다.
  • NetworkPolicy로 기본 거부(Default Deny) 정책을 구현합니다.
  • Calico와 Cilium의 확장 네트워크 정책 기능을 비교합니다.
  • **mTLS(mutual TLS)**와 서비스 메시의 보안 기능을 파악합니다.

쿠버네티스 기본 네트워크 모델

쿠버네티스의 기본 네트워크 모델은 **Flat Network(플랫 네트워크)**입니다. 이는 클러스터 내 모든 파드가 NAT 없이 서로 직접 통신할 수 있다는 뜻입니다.

개발 편의성 측면에서는 장점이지만, 보안 측면에서는 심각한 문제입니다.

공격자가 Frontend 파드 하나를 장악하면, Database 파드는 물론 다른 네임스페이스의 파드까지 접근할 수 있습니다. 이것이 Lateral Movement(횡방향 이동) 공격의 기본 패턴입니다.

Warning

NetworkPolicy가 없는 쿠버네티스 클러스터는 방화벽이 없는 내부 네트워크와 같습니다. 프로덕션 환경에서는 반드시 네트워크 정책을 적용해야 합니다.


NetworkPolicy 기초

쿠버네티스 NetworkPolicy는 파드 간 트래픽을 제어하는 리소스입니다. Label Selector를 사용하여 어떤 파드가 어떤 파드와 통신할 수 있는지를 선언적으로 정의합니다.

기본 거부 정책

가장 먼저 적용해야 할 정책은 **Default Deny(기본 거부)**입니다. 모든 트래픽을 차단한 후, 필요한 통신만 명시적으로 허용하는 방식입니다.

default-deny-all.yaml
yaml
# 인그레스(들어오는 트래픽) 기본 거부
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}  # 네임스페이스의 모든 파드에 적용
  policyTypes:
    - Ingress
 
---
# 이그레스(나가는 트래픽) 기본 거부
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Egress

podSelector: {}는 해당 네임스페이스의 모든 파드를 대상으로 합니다. 인그레스/이그레스 규칙이 비어있으므로 모든 트래픽이 차단됩니다.

허용 규칙 추가

기본 거부 정책을 적용한 후, 필요한 통신만 허용합니다.

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

이제 네트워크 흐름이 다음과 같이 제한됩니다.

DNS 이그레스 허용

기본 거부를 적용하면 DNS 조회도 차단됩니다. 클러스터 내 DNS(CoreDNS)로의 이그레스를 허용해야 합니다.

allow-dns-egress.yaml
yaml
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
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
Tip

NetworkPolicy를 적용할 때는 DNS 이그레스를 가장 먼저 허용하세요. DNS가 차단되면 서비스 이름 기반의 모든 통신이 실패하여 디버깅이 매우 어려워집니다.


네임스페이스 격리

멀티테넌트 환경에서는 네임스페이스 간 통신을 기본적으로 차단해야 합니다.

namespace-isolation.yaml
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-from-other-namespaces
  namespace: team-a
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector: {}  # 같은 네임스페이스 내 파드만 허용

특정 네임스페이스(예: 모니터링)에서의 접근만 허용하려면 다음과 같이 설정합니다.

allow-monitoring.yaml
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-monitoring-scrape
  namespace: team-a
spec:
  podSelector:
    matchLabels:
      monitoring: enabled
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              purpose: monitoring
      ports:
        - protocol: TCP
          port: 9090

Calico 네트워크 정책

Calico는 쿠버네티스 표준 NetworkPolicy를 넘어서는 확장 기능을 제공합니다.

GlobalNetworkPolicy

클러스터 전체에 적용되는 정책을 GlobalNetworkPolicy로 정의할 수 있습니다.

calico-global-deny.yaml
yaml
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: deny-external-egress
spec:
  selector: all()
  types:
    - Egress
  egress:
    # 클러스터 내부 통신만 허용
    - action: Allow
      destination:
        nets:
          - 10.0.0.0/8
          - 172.16.0.0/12
          - 192.168.0.0/16
    # DNS 허용
    - action: Allow
      protocol: UDP
      destination:
        ports:
          - 53
    # 그 외 외부 통신 차단
    - action: Deny

호스트 엔드포인트 보호

Calico는 파드뿐만 아니라 노드 자체의 네트워크도 보호할 수 있습니다.

calico-host-endpoint.yaml
yaml
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: worker-node-01-eth0
  labels:
    role: worker
spec:
  interfaceName: eth0
  node: worker-node-01
  expectedIPs:
    - 10.0.1.10

Cilium과 eBPF 기반 네트워크 보안

Cilium은 **eBPF(extended Berkeley Packet Filter)**를 활용하여 커널 수준에서 네트워크 정책을 적용합니다. iptables 기반 솔루션보다 성능이 뛰어나고, L7(애플리케이션 계층) 정책까지 지원합니다.

L7 정책

Cilium은 HTTP, gRPC, Kafka 등 애플리케이션 프로토콜 수준의 정책을 적용할 수 있습니다.

cilium-l7-policy.yaml
yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: api-access-control
  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/public/.*"
              - method: "POST"
                path: "/api/v1/orders"
                headers:
                  - 'Content-Type: application/json'

이 정책은 단순히 포트 수준의 접근 제어를 넘어서, HTTP 메서드와 경로까지 세밀하게 제어합니다. Frontend에서 Backend API로의 통신 중 특정 경로만 허용하는 것이 가능합니다.

Cilium의 네트워크 가시성

Hubble CLI로 네트워크 흐름 확인
bash
# 실시간 네트워크 흐름 모니터링
hubble observe --namespace production
 
# 차단된 트래픽만 필터링
hubble observe --namespace production --verdict DROPPED
 
# 특정 파드의 통신 추적
hubble observe --to-pod production/backend-api-xxx

Hubble은 Cilium의 관측성(Observability) 도구로, 클러스터 내 모든 네트워크 흐름을 실시간으로 시각화합니다.

Info

Cilium은 eBPF 기반이므로 iptables 규칙 수에 영향받지 않습니다. 대규모 클러스터에서 수천 개의 NetworkPolicy를 적용해도 성능 저하가 거의 없습니다.


서비스 메시와 mTLS

**Service Mesh(서비스 메시)**는 애플리케이션 코드를 수정하지 않고 서비스 간 통신에 보안, 관측성, 트래픽 관리 기능을 추가하는 인프라 계층입니다.

mTLS란

**mTLS(mutual TLS, 상호 TLS)**는 클라이언트와 서버 양쪽 모두 인증서를 제시하여 서로의 신원을 검증하는 방식입니다. 일반 TLS에서는 클라이언트만 서버를 검증하지만, mTLS에서는 양방향으로 검증합니다.

Istio에서 mTLS 적용

istio-mtls-strict.yaml
yaml
# 네임스페이스 전체에 strict mTLS 적용
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT

STRICT 모드는 mTLS가 아닌 통신을 모두 차단합니다. 마이그레이션 중에는 PERMISSIVE 모드로 mTLS와 평문 통신을 모두 허용할 수 있습니다.

Istio AuthorizationPolicy

mTLS와 함께 AuthorizationPolicy를 사용하면 서비스 ID 기반의 접근 제어가 가능합니다.

istio-authz-policy.yaml
yaml
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: backend-access
  namespace: production
spec:
  selector:
    matchLabels:
      app: backend
  rules:
    - from:
        - source:
            principals:
              - "cluster.local/ns/production/sa/frontend"
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/v1/*"]

이 정책은 frontend 서비스 계정을 가진 파드만 backend의 /api/v1/* 경로에 GET, POST 요청을 보낼 수 있도록 제한합니다.

Linkerd 대안

Linkerd는 Istio보다 가벼운 서비스 메시로, 설치와 운영이 간단합니다.

Linkerd mTLS 확인
bash
# Linkerd 설치
linkerd install | kubectl apply -f -
 
# 네임스페이스에 메시 주입
kubectl annotate namespace production linkerd.io/inject=enabled
 
# mTLS 상태 확인
linkerd viz stat deploy -n production

Linkerd는 기본적으로 모든 메시 내 통신에 mTLS를 적용하며, 별도 설정이 필요하지 않습니다.


네트워크 정책 테스트

네트워크 정책이 의도대로 동작하는지 반드시 테스트해야 합니다.

네트워크 정책 테스트
bash
# 테스트용 파드 생성
kubectl run test-pod --image=busybox --rm -it --restart=Never -- sh
 
# 허용된 통신 테스트
wget -qO- --timeout=3 http://backend-svc.production:8080/health
 
# 차단된 통신 테스트 (타임아웃 예상)
wget -qO- --timeout=3 http://database-svc.production:5432
Tip

kubectl-np-viewer와 같은 도구를 사용하면 현재 적용된 네트워크 정책을 시각적으로 확인할 수 있습니다. 복잡한 정책 환경에서 예상치 못한 차단이 발생했을 때 디버깅에 유용합니다.


정리

이번 장에서는 컨테이너 네트워크 보안의 핵심을 다루었습니다.

  • 쿠버네티스 기본 네트워크는 모든 파드 간 통신을 허용하므로, NetworkPolicy로 기본 거부 정책을 반드시 적용해야 합니다.
  • Calico는 GlobalNetworkPolicy와 호스트 엔드포인트 보호를, Cilium은 eBPF 기반 L7 정책과 Hubble 관측성을 제공합니다.
  • mTLS는 서비스 간 통신의 기밀성과 상호 인증을 보장하며, Istio나 Linkerd로 구현할 수 있습니다.
  • 네트워크 정책은 적용 후 반드시 테스트하여 의도한 대로 동작하는지 검증해야 합니다.

다음 장에서는 컨테이너 환경에서 민감한 정보를 안전하게 관리하는 시크릿 관리를 다룹니다. 쿠버네티스 Secrets의 한계와 HashiCorp Vault, External Secrets Operator 등의 대안을 실습합니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#security#kubernetes#devops#infrastructure

관련 글

인프라

8장: 시크릿 관리

쿠버네티스 Secrets의 한계를 이해하고, HashiCorp Vault, External Secrets Operator, Sealed Secrets로 안전한 시크릿 관리 체계를 구축합니다.

2026년 3월 21일·14분
인프라

6장: 런타임 보안 — Falco와 위협 감지

Falco의 eBPF 기반 시스콜 모니터링으로 컨테이너 런타임 위협을 실시간 감지하고, 규칙 작성부터 알림 통합까지 런타임 보안 체계를 구축합니다.

2026년 3월 17일·14분
인프라

9장: 공급망 공격 방어와 제로 트러스트

의존성 혼동, 타이포스쿼팅, CI 침투 등 공급망 공격 유형을 분석하고, SLSA 프레임워크와 어드미션 컨트롤러 기반의 제로 트러스트 방어 전략을 구축합니다.

2026년 3월 23일·16분
이전 글6장: 런타임 보안 — Falco와 위협 감지
다음 글8장: 시크릿 관리

댓글

목차

약 14분 남음
  • 학습 목표
  • 쿠버네티스 기본 네트워크 모델
  • NetworkPolicy 기초
    • 기본 거부 정책
    • 허용 규칙 추가
    • DNS 이그레스 허용
  • 네임스페이스 격리
  • Calico 네트워크 정책
    • GlobalNetworkPolicy
    • 호스트 엔드포인트 보호
  • Cilium과 eBPF 기반 네트워크 보안
    • L7 정책
    • Cilium의 네트워크 가시성
  • 서비스 메시와 mTLS
    • mTLS란
    • Istio에서 mTLS 적용
    • Istio AuthorizationPolicy
    • Linkerd 대안
  • 네트워크 정책 테스트
  • 정리