쿠버네티스 NetworkPolicy로 기본 거부 정책을 구현하고, Calico/Cilium 네트워크 정책과 Istio mTLS로 컨테이너 간 통신을 안전하게 제어합니다.
쿠버네티스의 기본 네트워크 모델은 **Flat Network(플랫 네트워크)**입니다. 이는 클러스터 내 모든 파드가 NAT 없이 서로 직접 통신할 수 있다는 뜻입니다.
개발 편의성 측면에서는 장점이지만, 보안 측면에서는 심각한 문제입니다.
공격자가 Frontend 파드 하나를 장악하면, Database 파드는 물론 다른 네임스페이스의 파드까지 접근할 수 있습니다. 이것이 Lateral Movement(횡방향 이동) 공격의 기본 패턴입니다.
NetworkPolicy가 없는 쿠버네티스 클러스터는 방화벽이 없는 내부 네트워크와 같습니다. 프로덕션 환경에서는 반드시 네트워크 정책을 적용해야 합니다.
쿠버네티스 NetworkPolicy는 파드 간 트래픽을 제어하는 리소스입니다. Label Selector를 사용하여 어떤 파드가 어떤 파드와 통신할 수 있는지를 선언적으로 정의합니다.
가장 먼저 적용해야 할 정책은 **Default Deny(기본 거부)**입니다. 모든 트래픽을 차단한 후, 필요한 통신만 명시적으로 허용하는 방식입니다.
# 인그레스(들어오는 트래픽) 기본 거부
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:
- EgresspodSelector: {}는 해당 네임스페이스의 모든 파드를 대상으로 합니다. 인그레스/이그레스 규칙이 비어있으므로 모든 트래픽이 차단됩니다.
기본 거부 정책을 적용한 후, 필요한 통신만 허용합니다.
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: 8080apiVersion: 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(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
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53NetworkPolicy를 적용할 때는 DNS 이그레스를 가장 먼저 허용하세요. DNS가 차단되면 서비스 이름 기반의 모든 통신이 실패하여 디버깅이 매우 어려워집니다.
멀티테넌트 환경에서는 네임스페이스 간 통신을 기본적으로 차단해야 합니다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: team-a
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {} # 같은 네임스페이스 내 파드만 허용특정 네임스페이스(예: 모니터링)에서의 접근만 허용하려면 다음과 같이 설정합니다.
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: 9090Calico는 쿠버네티스 표준 NetworkPolicy를 넘어서는 확장 기능을 제공합니다.
클러스터 전체에 적용되는 정책을 GlobalNetworkPolicy로 정의할 수 있습니다.
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: DenyCalico는 파드뿐만 아니라 노드 자체의 네트워크도 보호할 수 있습니다.
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.10Cilium은 **eBPF(extended Berkeley Packet Filter)**를 활용하여 커널 수준에서 네트워크 정책을 적용합니다. iptables 기반 솔루션보다 성능이 뛰어나고, L7(애플리케이션 계층) 정책까지 지원합니다.
Cilium은 HTTP, gRPC, Kafka 등 애플리케이션 프로토콜 수준의 정책을 적용할 수 있습니다.
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로의 통신 중 특정 경로만 허용하는 것이 가능합니다.
# 실시간 네트워크 흐름 모니터링
hubble observe --namespace production
# 차단된 트래픽만 필터링
hubble observe --namespace production --verdict DROPPED
# 특정 파드의 통신 추적
hubble observe --to-pod production/backend-api-xxxHubble은 Cilium의 관측성(Observability) 도구로, 클러스터 내 모든 네트워크 흐름을 실시간으로 시각화합니다.
Cilium은 eBPF 기반이므로 iptables 규칙 수에 영향받지 않습니다. 대규모 클러스터에서 수천 개의 NetworkPolicy를 적용해도 성능 저하가 거의 없습니다.
**Service Mesh(서비스 메시)**는 애플리케이션 코드를 수정하지 않고 서비스 간 통신에 보안, 관측성, 트래픽 관리 기능을 추가하는 인프라 계층입니다.
**mTLS(mutual TLS, 상호 TLS)**는 클라이언트와 서버 양쪽 모두 인증서를 제시하여 서로의 신원을 검증하는 방식입니다. 일반 TLS에서는 클라이언트만 서버를 검증하지만, mTLS에서는 양방향으로 검증합니다.
# 네임스페이스 전체에 strict mTLS 적용
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICTSTRICT 모드는 mTLS가 아닌 통신을 모두 차단합니다. 마이그레이션 중에는 PERMISSIVE 모드로 mTLS와 평문 통신을 모두 허용할 수 있습니다.
mTLS와 함께 AuthorizationPolicy를 사용하면 서비스 ID 기반의 접근 제어가 가능합니다.
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는 Istio보다 가벼운 서비스 메시로, 설치와 운영이 간단합니다.
# Linkerd 설치
linkerd install | kubectl apply -f -
# 네임스페이스에 메시 주입
kubectl annotate namespace production linkerd.io/inject=enabled
# mTLS 상태 확인
linkerd viz stat deploy -n productionLinkerd는 기본적으로 모든 메시 내 통신에 mTLS를 적용하며, 별도 설정이 필요하지 않습니다.
네트워크 정책이 의도대로 동작하는지 반드시 테스트해야 합니다.
# 테스트용 파드 생성
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:5432kubectl-np-viewer와 같은 도구를 사용하면 현재 적용된 네트워크 정책을 시각적으로 확인할 수 있습니다. 복잡한 정책 환경에서 예상치 못한 차단이 발생했을 때 디버깅에 유용합니다.
이번 장에서는 컨테이너 네트워크 보안의 핵심을 다루었습니다.
다음 장에서는 컨테이너 환경에서 민감한 정보를 안전하게 관리하는 시크릿 관리를 다룹니다. 쿠버네티스 Secrets의 한계와 HashiCorp Vault, External Secrets Operator 등의 대안을 실습합니다.
이 글이 도움이 되셨나요?
쿠버네티스 Secrets의 한계를 이해하고, HashiCorp Vault, External Secrets Operator, Sealed Secrets로 안전한 시크릿 관리 체계를 구축합니다.
Falco의 eBPF 기반 시스콜 모니터링으로 컨테이너 런타임 위협을 실시간 감지하고, 규칙 작성부터 알림 통합까지 런타임 보안 체계를 구축합니다.
의존성 혼동, 타이포스쿼팅, CI 침투 등 공급망 공격 유형을 분석하고, SLSA 프레임워크와 어드미션 컨트롤러 기반의 제로 트러스트 방어 전략을 구축합니다.