지원 버전: Amazon EKS 1.31, 1.32, 1.33
마지막 업데이트: 2026년 2월 19일
Amazon EKS(Elastic Kubernetes Service)에서 워크로드를 안전하게 실행하기 위해서는 다양한 보안 계층과 모범 사례를 이해하고 구현해야 합니다. 이 문서에서는 EKS 클러스터의 보안을 강화하기 위한 주요 개념, 구성 요소 및 모범 사례를 다룹니다.
JWKS(JSON Web Key Set)는 토큰 서명을 검증하는 데 사용되는 공개 키 집합입니다:
JWKS 응답 예시:
IAM 역할 신뢰 정책 설정
OIDC를 사용하는 IAM 역할의 신뢰 정책:
EKS Pod Identity
EKS Pod Identity는 2023년에 도입된 새로운 방식으로, IRSA의 복잡성을 줄이고 더 간단하게 파드에 AWS IAM 권한을 부여합니다.
IRSA 대비 장점
특성
IRSA
EKS Pod Identity
설정 복잡도
OIDC Provider, IAM 역할 신뢰 정책 필요
Pod Identity Association만 필요
IAM 역할 재사용
클러스터별 역할 필요
여러 클러스터에서 역할 재사용 가능
세션 태그
미지원
지원 (리소스 태깅 자동화)
자격 증명 위치
Projected Volume
EKS Auth API
토큰 갱신
파드 내 SDK 담당
Pod Identity Agent 담당
Pod Identity Agent 동작 원리
Pod Identity Agent는 각 노드에서 DaemonSet으로 실행되며:
파드의 자격 증명 요청을 가로챕니다
Pod Identity Association을 확인합니다
연결된 IAM 역할의 임시 자격 증명을 획득합니다
파드에 자격 증명을 전달합니다
Pod Identity Association 설정
eksctl 사용
AWS CLI 사용
IRSA에서 Pod Identity로 마이그레이션
기존 IRSA 설정을 Pod Identity로 마이그레이션하는 절차:
Pod Identity 사용 예제
Cluster Endpoint 접근 제어
EKS 클러스터의 Kubernetes API 서버 엔드포인트에 대한 접근을 제어하는 것은 보안의 기본입니다.
엔드포인트 구성 옵션
EKS는 세 가지 엔드포인트 구성을 지원합니다:
구성
Public
Private
사용 사례
Public Only
✅
❌
개발/테스트 환경, 빠른 시작
Private Only
❌
✅
프로덕션, 금융/의료 워크로드
Public + Private
✅
✅
하이브리드 접근, CI/CD 통합
Public/Private/Public+Private 엔드포인트 구성
CIDR 제한 설정
퍼블릭 엔드포인트에 접근 가능한 IP 범위를 제한합니다:
권장사항: 프로덕션 환경에서는 CIDR 제한과 함께 Public + Private 구성을 사용하거나, 보안이 중요한 환경에서는 Private Only 구성을 사용하세요.
Private 클러스터 운영 패턴
Private 엔드포인트만 활성화된 클러스터에 접근하는 방법:
VPN 연결
Transit Gateway
Bastion Host / Session Manager
엔드포인트 접근 제어 설정 예제
eksctl을 사용한 완전한 클러스터 구성:
네트워크 보안
보안 그룹
EKS 클러스터의 노드와 파드에 대한 네트워크 트래픽을 제어하기 위해 AWS 보안 그룹을 사용할 수 있습니다.
클러스터 보안 그룹
EKS 클러스터 보안 그룹은 컨트롤 플레인과 워커 노드 간의 통신을 허용합니다:
포트 443(HTTPS): 클러스터 API 서버 통신
포트 10250: kubelet API
포트 범위 1025-65535: 노드 간 통신
노드 보안 그룹
워커 노드에 대한 보안 그룹 권장 구성:
인바운드: 클러스터 보안 그룹으로부터의 트래픽 허용
아웃바운드: 모든 트래픽 허용(필요에 따라 제한 가능)
네트워크 정책
Kubernetes 네트워크 정책을 사용하여 파드 간 통신을 제어할 수 있습니다. EKS에서는 Amazon VPC CNI, Calico, Cilium 등의 네트워크 플러그인을 통해 네트워크 정책을 구현할 수 있습니다.
기본 거부 정책 예시
특정 애플리케이션 간 통신 허용 정책 예시
VPC 엔드포인트
AWS 서비스에 대한 프라이빗 액세스를 위해 VPC 엔드포인트를 사용하여 인터넷 게이트웨이를 통하지 않고 AWS 서비스에 안전하게 액세스할 수 있습니다.
EKS 클러스터에 권장되는 VPC 엔드포인트:
com.amazonaws.region.ecr.api
com.amazonaws.region.ecr.dkr
com.amazonaws.region.s3
com.amazonaws.region.logs
com.amazonaws.region.sts
포드 보안
포드 보안 표준(PSS)
Kubernetes 1.23부터 도입된 포드 보안 표준은 파드의 보안 컨텍스트를 제한하는 내장 메커니즘을 제공합니다. EKS에서는 다음과 같은 수준의 PSS를 적용할 수 있습니다:
Privileged: 제한 없음
Baseline: 알려진 권한 에스컬레이션 방지
Restricted: 강력한 보안 제한 적용
네임스페이스에 PSS 적용 예시:
보안 컨텍스트
파드 및 컨테이너 수준에서 보안 컨텍스트를 구성하여 권한을 제한할 수 있습니다:
OPA Gatekeeper 및 Kyverno
OPA Gatekeeper 또는 Kyverno와 같은 정책 엔진을 사용하여 클러스터 전체에 보안 정책을 적용할 수 있습니다.
Kyverno 정책 예시 - 권한 있는 컨테이너 방지
Bottlerocket 및 읽기 전용 OS
Bottlerocket은 AWS에서 개발한 컨테이너 워크로드 전용 Linux 운영 체제입니다. 보안을 최우선으로 설계되어 불변 인프라 전략에 적합합니다.
Bottlerocket 특성
API 기반 구성
Bottlerocket은 SSH 대신 API 서버를 통해 구성됩니다:
자동 업데이트
SELinux 적용
Bottlerocket은 SELinux가 기본 활성화되어 있어 컨테이너 간 격리를 강화합니다:
dm-verity (루트 파일시스템 무결성)
dm-verity는 블록 레벨에서 루트 파일시스템의 무결성을 검증합니다:
부팅 시 루트 파일시스템의 무결성 검증
런타임에 수정 시도 감지 및 차단
악성 코드 주입 방지
불변 인프라 전략
Bottlerocket을 사용한 불변 인프라 구현:
EKS 관리형 노드 그룹에서 Bottlerocket 사용
IAM 권한 경계
IAM 권한 경계(Permission Boundary)는 IAM 역할이나 사용자에게 부여할 수 있는 최대 권한을 정의합니다. EKS 환경에서 권한 경계를 적절히 활용하면 보안을 강화할 수 있습니다.
Permission Boundary 개념
권한 경계는 "유효 권한 = 정책 ∩ 경계"의 원칙을 따릅니다:
SCP (Service Control Policy) 활용
AWS Organizations의 SCP와 IAM 권한 경계를 함께 사용하여 다층 방어:
최소 권한 IAM 정책 패턴
EKS 워크로드에 대한 최소 권한 정책 예시:
EKS 노드 역할 권한 경계 예제
권한 경계 적용
파드 IAM 역할에 권한 경계 적용
IRSA 또는 Pod Identity에서 사용하는 IAM 역할에도 권한 경계를 적용할 수 있습니다:
암호화 및 비밀 관리
EKS 암호화 옵션
etcd 암호화
EKS는 기본적으로 etcd에 저장된 Kubernetes 비밀을 암호화합니다. 추가적인 암호화 계층을 위해 AWS KMS를 사용할 수 있습니다:
AWS Secrets Manager 및 Parameter Store 통합
AWS Secrets Manager 또는 Parameter Store에 저장된 비밀을 Kubernetes 파드에 마운트하기 위해 External Secrets Operator 또는 AWS Secrets and Configuration Provider(ASCP)를 사용할 수 있습니다.
External Secrets Operator 설치
SecretStore 및 ExternalSecret 정의
SOPS(Secrets OPerationS)
Mozilla SOPS를 사용하여 Git 저장소에 암호화된 비밀을 안전하게 저장하고 관리할 수 있습니다.
SOPS 설치 및 사용
컴플라이언스 및 감사
EKS 감사 로깅
EKS 컨트롤 플레인 감사 로그를 활성화하여 클러스터에서 수행된 모든 API 호출을 기록할 수 있습니다:
AWS Config 규칙
AWS Config를 사용하여 EKS 클러스터의 규정 준수 상태를 모니터링할 수 있습니다:
eks-cluster-logging-enabled
eks-cluster-oldest-supported-version
eks-endpoint-no-public-access
eks-secrets-encrypted
AWS Security Hub 통합
AWS Security Hub를 사용하여 EKS 클러스터의 보안 상태를 중앙에서 관리하고 모니터링할 수 있습니다. Security Hub는 CIS Kubernetes Benchmark와 같은 업계 표준에 대한 규정 준수를 확인합니다.
보안 모니터링 및 탐지
GuardDuty EKS Protection
Amazon GuardDuty EKS Protection을 활성화하여 EKS 클러스터에서 잠재적인 보안 위협을 탐지할 수 있습니다:
AWS Security Hub
AWS Security Hub를 사용하여 EKS 클러스터의 보안 상태를 중앙에서 관리하고 모니터링할 수 있습니다:
Falco
Falco를 사용하여 런타임 보안 모니터링 및 이상 탐지를 수행할 수 있습니다:
Falco 규칙 예시:
EKS 보안 모범 사례
클러스터 보안 강화
최신 Kubernetes 버전 유지: 정기적으로 EKS 클러스터를 최신 버전으로 업그레이드하여 보안 패치 적용
프라이빗 API 엔드포인트 사용: 퍼블릭 인터넷에서 API 서버에 대한 액세스 제한
최소 권한 원칙 적용: IAM 역할 및 RBAC에 최소 권한 원칙 적용
보안 그룹 제한: 필요한 포트만 허용하도록 보안 그룹 구성
네트워크 정책 구현: 파드 간 통신을 제한하는 네트워크 정책 적용
노드 및 컨테이너 보안
최신 AMI 사용: 최신 보안 패치가 적용된 EKS 최적화 AMI 사용
컨테이너 이미지 스캔: ECR 이미지 스캔 또는 Trivy와 같은 도구를 사용하여 취약점 스캔
불변 인프라 사용: 노드 업데이트 시 새 노드 그룹 생성 및 이전 노드 그룹 삭제
비 루트 사용자로 컨테이너 실행: 컨테이너를 비 루트 사용자로 실행하여 권한 제한
읽기 전용 파일 시스템 사용: 가능한 경우 컨테이너의 루트 파일 시스템을 읽기 전용으로 마운트
지속적인 보안 모니터링
감사 로깅 활성화: EKS 컨트롤 플레인 감사 로그 활성화
GuardDuty EKS Protection 활성화: 런타임 보안 모니터링을 위한 GuardDuty EKS Protection 활성화
Security Hub 통합: AWS Security Hub를 사용하여 보안 상태 중앙 관리
정기적인 보안 평가: CIS Kubernetes Benchmark를 기준으로 정기적인 보안 평가 수행
인시던트 대응 계획 수립: EKS 클러스터에 대한 보안 인시던트 대응 계획 수립 및 테스트
금융 서비스를 위한 EKS 보안 고려사항
금융 서비스 산업에서 EKS를 사용할 때 고려해야 할 추가 보안 요구사항:
규제 준수
PCI DSS: 카드 결제 데이터를 처리하는 워크로드에 대한 PCI DSS 요구사항 준수
GDPR/CCPA: 개인 식별 정보(PII)에 대한 데이터 보호 규정 준수
금융 규제: 국내 금융 규제 기관의 요구사항 준수(예: 금융감독원 지침)
데이터 보안
전송 중 암호화: TLS 1.2 이상을 사용하여 모든 네트워크 통신 암호화
저장 데이터 암호화: AWS KMS를 사용하여 저장 데이터 암호화
데이터 분류: 민감도에 따른 데이터 분류 및 적절한 보안 제어 적용
데이터 액세스 로깅: 모든 민감한 데이터 액세스에 대한 상세 로깅 및 모니터링
고가용성 및 재해 복구
다중 가용 영역 배포: 여러 가용 영역에 걸쳐 EKS 클러스터 배포
재해 복구 계획: 정기적인 백업 및 복구 테스트를 포함한 재해 복구 계획 수립
비즈니스 연속성: 금융 서비스에 적합한 RTO(Recovery Time Objective) 및 RPO(Recovery Point Objective) 정의
금융 서비스를 위한 EKS 보안 아키텍처 예시
결론
Amazon EKS의 보안은 여러 계층에 걸친 방어 전략을 통해 구현됩니다. IAM 및 RBAC를 통한 강력한 인증 및 권한 부여, 네트워크 정책 및 보안 그룹을 통한 네트워크 보안, 포드 보안 표준 및 보안 컨텍스트를 통한 워크로드 보안, 그리고 AWS의 다양한 보안 서비스와의 통합을 통해 EKS 클러스터를 안전하게 운영할 수 있습니다.
특히 금융 서비스와 같은 규제가 엄격한 산업에서는 추가적인 보안 제어 및 규정 준수 요구사항을 고려해야 합니다. 정기적인 보안 평가, 취약점 스캔, 그리고 지속적인 모니터링을 통해 EKS 환경의 보안 상태를 유지하는 것이 중요합니다.
# Pod Identity Association 생성
eksctl create podidentityassociation \
--cluster my-cluster \
--namespace default \
--service-account-name s3-reader \
--role-arn arn:aws:iam::123456789012:role/S3ReaderRole
# 연결 확인
eksctl get podidentityassociation --cluster my-cluster
# Pod Identity Association 생성
aws eks create-pod-identity-association \
--cluster-name my-cluster \
--namespace default \
--service-account s3-reader \
--role-arn arn:aws:iam::123456789012:role/S3ReaderRole
# 연결 목록 조회
aws eks list-pod-identity-associations --cluster-name my-cluster
# 특정 연결 상세 정보
aws eks describe-pod-identity-association \
--cluster-name my-cluster \
--association-id a-xxxxxxxxxxxxx
# 1. Pod Identity Agent 애드온 설치 확인
aws eks describe-addon \
--cluster-name my-cluster \
--addon-name eks-pod-identity-agent
# 애드온 미설치 시 설치
aws eks create-addon \
--cluster-name my-cluster \
--addon-name eks-pod-identity-agent
# 2. 기존 IRSA IAM 역할의 신뢰 정책 업데이트
# Pod Identity도 허용하도록 Principal 추가
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
EOF
aws iam update-assume-role-policy \
--role-name S3ReaderRole \
--policy-document file://trust-policy.json
# 3. Pod Identity Association 생성
aws eks create-pod-identity-association \
--cluster-name my-cluster \
--namespace default \
--service-account s3-reader \
--role-arn arn:aws:iam::123456789012:role/S3ReaderRole
# 4. 서비스 계정에서 IRSA 어노테이션 제거 (선택적)
kubectl annotate serviceaccount s3-reader \
eks.amazonaws.com/role-arn- \
-n default
# 5. 파드 재시작하여 Pod Identity 사용 확인
kubectl rollout restart deployment my-app -n default
# 1. 서비스 계정 생성 (IRSA 어노테이션 불필요)
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-reader
namespace: default
---
# 2. 파드에서 서비스 계정 사용
apiVersion: v1
kind: Pod
metadata:
name: s3-reader-pod
spec:
serviceAccountName: s3-reader
containers:
- name: app
image: amazonlinux:2
command:
- /bin/sh
- -c
- |
# AWS SDK가 자동으로 Pod Identity Agent에서 자격 증명 획득
aws s3 ls
aws sts get-caller-identity
# 현재 엔드포인트 설정 확인
aws eks describe-cluster \
--name my-cluster \
--query "cluster.resourcesVpcConfig.{PublicAccess:endpointPublicAccess, PrivateAccess:endpointPrivateAccess, PublicCIDRs:publicAccessCidrs}"
# Public + Private 설정 (권장)
aws eks update-cluster-config \
--name my-cluster \
--resources-vpc-config endpointPublicAccess=true,endpointPrivateAccess=true
# Private Only 설정 (최고 보안)
aws eks update-cluster-config \
--name my-cluster \
--resources-vpc-config endpointPublicAccess=false,endpointPrivateAccess=true
# 특정 CIDR 범위만 허용
aws eks update-cluster-config \
--name my-cluster \
--resources-vpc-config publicAccessCidrs="203.0.113.0/24","198.51.100.0/24"
# 회사 VPN IP 대역만 허용
aws eks update-cluster-config \
--name my-cluster \
--resources-vpc-config publicAccessCidrs="10.0.0.0/8"
# Site-to-Site VPN 설정 후 kubectl 사용
kubectl --kubeconfig ~/.kube/config get nodes
# Systems Manager Session Manager를 통한 접근
aws ssm start-session \
--target i-xxxxxxxxxxxxx \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["443"],"localPortNumber":["6443"]}'
# 로컬에서 kubectl 사용
kubectl --server=https://localhost:6443 get nodes
# Bottlerocket 설정 확인 (컨트롤 컨테이너에서)
apiclient get settings
# 설정 변경
apiclient set kubernetes.node-labels.environment=production
# 커밋 및 적용
apiclient commit
# 자동 업데이트 설정 (eksctl)
managedNodeGroups:
- name: bottlerocket-ng
amiFamily: Bottlerocket
bottlerocket:
settings:
# 업데이트 설정
motd: "EKS Production Node"
kubernetes:
node-labels:
environment: production
# SELinux 상태 확인 (파드 내에서)
apiVersion: v1
kind: Pod
metadata:
name: selinux-check
spec:
containers:
- name: check
image: amazonlinux:2
command:
- /bin/sh
- -c
- |
getenforce
cat /proc/self/attr/current
# 1. 새 버전의 노드 그룹 생성
managedNodeGroups:
- name: bottlerocket-v2
amiFamily: Bottlerocket
instanceType: m5.xlarge
desiredCapacity: 3
labels:
version: v2
# 2. 기존 노드 드레인 및 삭제
# kubectl cordon/drain 사용
# 노드 교체 전략
# 1. 새 노드 그룹 생성
eksctl create nodegroup -f new-nodegroup.yaml
# 2. 기존 노드 cordon
kubectl cordon -l eks.amazonaws.com/nodegroup=bottlerocket-v1
# 3. 기존 노드 drain
kubectl drain -l eks.amazonaws.com/nodegroup=bottlerocket-v1 \
--ignore-daemonsets \
--delete-emptydir-data
# 4. 기존 노드 그룹 삭제
eksctl delete nodegroup \
--cluster my-cluster \
--name bottlerocket-v1
# 권한 경계 생성
aws iam create-policy \
--policy-name EKSNodePermissionBoundary \
--policy-document file://permission-boundary.json
# IAM 역할에 권한 경계 적용
aws iam put-role-permissions-boundary \
--role-name EKSNodeRole \
--permissions-boundary arn:aws:iam::123456789012:policy/EKSNodePermissionBoundary
# 권한 경계 확인
aws iam get-role --role-name EKSNodeRole --query "Role.PermissionsBoundary"
# 파드용 IAM 역할 생성 시 권한 경계 포함
aws iam create-role \
--role-name PodS3ReaderRole \
--assume-role-policy-document file://trust-policy.json \
--permissions-boundary arn:aws:iam::123456789012:policy/PodPermissionBoundary
# 기존 역할에 권한 경계 추가
aws iam put-role-permissions-boundary \
--role-name PodS3ReaderRole \
--permissions-boundary arn:aws:iam::123456789012:policy/PodPermissionBoundary
- rule: Terminal shell in container
desc: A shell was spawned by a pod in the container
condition: container and shell_procs and not container_entrypoint
output: Shell spawned in a container (user=%user.name pod=%k8s.pod.name container=%container.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)
priority: WARNING