EKS 네트워크 보안: NetworkPolicy와 SGP로 구현하는 파드 트래픽 격리

1. 들어가며

“클러스터 안에서는 NetworkPolicy, 클러스터 밖 AWS 리소스에는 SecurityGroupPolicy”

EKS 환경에서 애플리케이션을 운영하다 보면 자연스럽게 네트워크 통신 제어와 보안에 대한 고민이 생깁니다.

“Frontend 파드에서 Backend 파드로의 접근만 허용하고, 미승인 파드는 차단하려면 어떻게 해야 할까?”
“특정 백엔드 파드만 AWS RDS에 접근할 수 있게 노드 전체가 아닌 파드 단위로 AWS 보안 그룹을 걸 수는 없을까?”

쿠버네티스 내부 파드 간의 트래픽은 IP와 포트 기반(L3/L4 계층)의 NetworkPolicy로 통제하고, EKS 파드와 외부 AWS 리소스(RDS 등) 간의 통신은 SecurityGroupPolicy를 통해 파드에 직접 AWS 보안 그룹(SG)을 연결하여 제어할 수 있습니다.

두 기능의 핵심 개념을 가볍게 비교해 보고, 실제 매니페스트로 트래픽 격리가 정상적으로 동작하는지 확인해 보겠습니다.


2. 핵심 개념

NetworkPolicy (클러스터 내부에서 L3/L4 레벨 제어)
쿠버네티스 클러스터 내부에서 파드(Pod) 간의 IP 대역 및 TCP/UDP 포트(L3/L4) 트래픽을 라벨 기준으로 제어하는 인클러스터 네트워크 방화벽 규칙입니다.

SecurityGroupPolicy (AWS 리소스 연동 제어)
노드(EC2) 단위가 아니라 개별 파드(Pod)에 전용 Branch ENI를 붙여 AWS 보안 그룹(SG)을 직접 매핑해 주는 EKS 전용 CRD(Custom Resource Definition)입니다.

구분NetworkPolicySecurityGroupPolicy
적용 영역클러스터 내부 (Pod ↔ Pod)클러스터 내-외부 (Pod ↔ AWS RDS, EC2 등)
제어 기준K8s Pod 라벨(label), 네임스페이스, IP/Port (L3/L4)AWS Security Group ID (SG간 서로 참조 가능)
핵심 특징동적 (Pod 재생성 시 IP가 바뀌어도 라벨을 기준으로 유지)AWS 관리형 리소스(RDS 등)와 파드 간 최소 권한 제어 (보안 그룹 ID 기준)
동작 방식파드 레벨 eBPF/iptables 소프트웨어 방화벽노드에 파드 전용 ENI 부착 및 AWS 보안 그룹 적용
필수 컴포넌트
(EKS Add-on & 옵션)
Amazon VPC CNI (네트워크 정책 활성화:
–enable-network-policy=true)
• 또는 서드파티 CNI/엔진 (Cilium, Calico 등)
Amazon VPC CNI (파드 ENI 활성화: ENABLE_POD_ENI=true)
• 워커 노드 인스턴스 (AWS Nitro 기반 인스턴스, t 계열 제외) 


3. 실습 1: NetworkPolicy로 파드 간 통신 제어하

(1) 네임스페이스 및 pod 정의 (frontend, backend, 미승인 client)

(2) 기본 차단 정책 (Default Deny)

가장 먼저 네임스페이스 내 모든 인바운드 트래픽을 기본 차단(default-deny)하여 인가되지 않은 통신을 막습니다.

(3) 허용 정책 정의 (Frontend → Backend 허용)

app: backend 라벨이 붙은 파드는 오직 app: frontend 라벨을 가진 파드의 80 포트 인바운드만 수신하도록 허용합니다.

(4) 검증

검증결과                               

   • frontend (동일 ns 승인 파드): 200 OK 정상 응답 수신
   • unauthorized-client (동일 ns 미승인 파드): 연결 시간 초과 (Timeout / Exit Code 28) 
   • other-ns-client (타 ns 파드): 연결 시간 초과 (Timeout / Exit Code 28)

결론

   • 인가되지 않은 Pod는 기본 차단하고, 지정된 라벨의 파드만 통신을 허용


4. 실습 2: SecurityGroupPolicy로 AWS RDS 접근 제어하기

노드 전체에 RDS 3306 포트를 개방하지 않고, 인가된 파드 보안 그룹만 RDS에 접근하도록 구성합니다.

(1) RDS 보안 그룹 및 파드 전용 보안 그룹 생성 (Terraform)

RDS의 인바운드 규칙에 노드 보안 그룹이 아닌 app_pod_sg의 ID를 등록합니다.

(2) 파드에 보안 그룹 매핑 (SecurityGroupPolicy)

파드 생성 시 자동으로 파드 전용 보안 그룹(app_pod_sg)이 연결될 수 있도록, role: db-client 라벨을 대상으로 하는 SecurityGroupPolicy를 사전 배포합니다.

SGP가 적용된 파드가 생성될 때, 노드에 파드 전용 네트워크 인터페이스(Branch ENI)가 할당되어 지정한 보안 그룹이 연결됩니다.

(3) 네임스페이스 및 테스트용 파드 생성 

SGP 정책이 활성화된 상태에서 승인 파드와 미승인 파드를 생성합니다.
backend는 라벨 매칭을 통해 파드 전용 보안 그룹을 부여받습니다. 

(4) 검증

검증 결과

   •backend (SGP 적용 승인 Pod): 파드 전용 Branch ENI와 보안 그룹(app_pod_sg)이 정상 할당되어 RDS MySQL 3306 포트 접속 및 DB 쿼리 성공
   • unauthorized-client (SGP 미적용 일반 Pod): 노드 기본 보안 그룹을 사용하여 RDS 보안 그룹의 

인바운드 차단에 의해 3306 포트 연결 시간 초과 (Connection timed out / Exit Code 1)                                                                                                          

결론

   • 동일한 EC2 워커 노드에 배포된 파드라 할지라도, AWS 인프라(보안 그룹) 수준에서 파드 단위 최소 권한(Least Privilege) 통제가 완벽히 동작함을 확인


5. 마무리

   • 클러스터 내부 파드 간 통신 제어: K8s 표준 NetworkPolicy (L3/L4 라벨 셀렉터 기반)
   • 파드 ↔ AWS 클라우드 리소스 통신 제어: EKS SecurityGroupPolicy (파드 레벨 AWS SG 적용)

두 방식을 목적에 맞게 조합하면 노드 단위의 과도한 권한 부여를 막고 안전한 EKS 네트워크 환경을 구축할 수 있습니다.

지금까지는 각각 따로 실습해봤지만, 사실 두 정책은 같은 파드에 동시에 걸어도 문제없이 동작합니다. 예를 들어 “backend 파드는 frontend 파드에서 오는 트래픽만 받고(NetworkPolicy), RDS로 나가는 트래픽은 app_pod_sg를 통해서만 허용한다(SGP)”는 식으로 두 계층을 함께 적용할 수 있습니다. 클러스터 내부 통제와 AWS 리소스 접근 통제를 하나의 정책으로 억지로 묶기보다, 역할을 나눠 병행 적용하는 편이 관리 관점에서 더 깔끔합니다. 

다만 두 정책을 같이 쓸 때 한 가지 짚을 부분이 있습니다. SGP 적용 시 기본값은 strict 모드인데, 이 모드에서는 kubelet이 보내는 liveness/readiness probe 트래픽까지 파드 전용 보안 그룹(app_pod_sg)의 규칙을 통과해야 합니다. 즉 실제로 리스닝 포트가 있는 백엔드 파드에 SGP를 걸 경우, app_pod_sg에 클러스터 보안그룹발 인바운드를 별도로 열어주지 않으면 헬스체크가 실패할 수 있습니다. 이런 문제를 피하려면 ENABLE_POD_ENI 관련 설정 중 POD_SECURITY_GROUP_ENFORCING_MODE=standard로 바꿔 노드 로컬 트래픽은 SG 검사를 건너뛰게 하거나, app_pod_sg에 필요한 인바운드 규칙을 명시적으로 추가해야 합니다. 


참고문헌

https://kubernetes.io/docs/concepts/services-networking/network-policies/
https://docs.aws.amazon.com/eks/latest/userguide/sg-pods-example-deployment.html
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/misc/eni-max-pods.txt
https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/pkg/aws/vpc/limits.go
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance