EKS 설계 및 설정 명세 - 100-hours-a-week/20-real-wiki GitHub Wiki
2.1. 개요
본 문서는 AWS EKS를 Terraform을 이용하여 Kubernetes 멀티 노드 클러스터를 자동으로 구축한 구조에 대한 설정 명세서이다. 이 문서는 클러스터의 목적, 적용 대상, 구조 및 주요 구성 요소를 정의하며, 향후 운영 자동화 및 고도화를 위한 기준 자료로 활용될 수 있다.
- 목적: Dev/Prod 환경을 분리한 Kubernetes 클러스터 구성으로 인프라 안정성과 확장성 확보
- 구축 방식: Terraform으로 AWS EKS 클러스터 및 Managed Node Group을 구성하며, Helm Chart 및 ArgoCD 기반의 GitOps 방식으로 서비스 배포 및 운영
2.2. 클러스터 구조 개요
2.2.1 아키텍처 다이어그램

2.2.2 클러스터 다이어그램

2.2.3 아키텍처 개요
항목 |
구성 |
마스터 노드 |
AWS에서 관리하는 Control Plane (EKS) |
워커 노드 수 |
2대 이상 (Managed Node Group 구성) |
네트워크 구성 |
동일 VPC, 퍼블릭/프라이빗 서브넷 분리 |
CNI 플러그인 |
AWS VPC CNI 자동 설치 |
2.2.4 노드 구성 및 역할
노드 그룹 |
구성 요소 및 역할 |
Node Group 1 (dev) |
next.js, spring, grafana, prom 등 개발용 서비스 실행 |
Node Group 2 (prod) |
운영 환경용 spring, ingress, scouter 등 실행 |
**모니터링 노드 그룹 ** |
Fluent Bit, Prometheus, Loki 실행, ALB Ingress Controller 배포 대상 |
2.2.5 주요 구성 요소
구성 요소 |
역할 |
Ingress |
AWS ALB Ingress Controller를 통한 서비스 라우팅 |
CI/CD |
ArgoCD 기반 GitOps 배포 |
모니터링 |
Prometheus + Grafana + Loki + Fluent Bit (메트릭 및 로그 수집) |
Helm |
Helm Chart 기반 서비스 배포 및 설정 관리 |
보안 |
IAM OIDC Provider, IRSA를 통한 서비스 계정 권한 부여, RBAC 및 네임스페이스 분리 관리 |
2.2.6 Namespace 설계
네임스페이스 |
용도 |
포함 서비스 |
dev |
개발용 환경 |
next.js, spring, grafana, prom |
prod |
운영 환경 |
next.js, spring, scouter, ingress |
monitoring |
공통 모니터링 |
prometheus, fluentbit, loki |
argocd |
GitOps 관리 |
argo-cd |
kube-system |
시스템 관리 |
ingress controller, CoreDNS 등 |
2.2.7 Kubernetes 리소스 명세서 (서비스별)
서비스(Pod) |
Replica |
CPU 요청 / 제한 |
메모리 요청 / 제한 |
이미지 |
HPA 설정 |
ConfigMap / Secret |
next.js |
2 |
100m / 200m |
128Mi / 256Mi |
nextjs:latest |
X |
env-config |
spring |
2 |
250m / 500m |
512Mi / 1Gi |
spring-backend:1.0 |
70% CPU |
db-config / db-secret |
prometheus |
1 |
300m / 500m |
512Mi / 1Gi |
prom/prometheus |
X |
prom-config |
grafana |
1 |
100m / 300m |
256Mi / 512Mi |
grafana/grafana |
X |
grafana-config |
fluentbit |
1~2 |
100m / 200m |
256Mi / 512Mi |
fluent/fluent-bit |
X |
fluent-config |
loki |
1 |
200m / 400m |
512Mi / 1Gi |
grafana/loki |
X |
loki-config |
ingress controller |
1 |
200m / 300m |
256Mi / 512Mi |
amazon/aws-alb-ingress-controller |
X |
- |
argocd |
1 |
200m / 400m |
512Mi / 1Gi |
argoproj/argocd |
X |
- |
scouter agent |
1 per spring |
50m / 100m |
128Mi / 256Mi |
scouter-agent |
X |
- |
2.3. EC2 인스턴스 및 초기 설정
2.3.1 인스턴스 구성
- 인스턴스 타입: t3.medium (이상)
- AMI: Ubuntu 22.04 LTS (HVM)
- VPC/서브넷 구성: 프라이빗 Nat 서브넷 (Master, Worker)
2.3.2 보안 그룹 오픈 포트 구성
노드 유형 |
포트 |
목적 |
Master |
6443 |
Kubernetes API Server |
Master |
2379-2380 |
etcd 통신 |
Worker |
30000-32767 |
NodePort용 서비스 통신 |
모두 |
22 |
SSH 접속 |
모두 |
80, 443 |
HTTP/HTTPS (Ingress용 ALB 등) |
모두 |
10250 |
kubelet 통신 |
2.4. EKS 클러스터 및 노드 그룹 구성
EKS 클러스터 및 노드 그룹은 Terraform을 통해 자동으로 구성됩니다. 클러스터 생성 시 다음과 같은 설정을 포함합니다:
- eks_cluster 모듈을 통해 EKS Control Plane 생성
- 퍼블릭/프라이빗 서브넷을 활용한 분산 구성
- dev / prod 용도로 분리된 Managed Node Group 구성
- IAM OIDC Provider 생성 및 IRSA (IAM Roles for Service Account) 연동
aws-auth
ConfigMap을 통해 Node Role을 워커노드로 승인
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "ktb-eks-cluster"
cluster_version = "1.28"
subnet_ids = ["subnet-xxxxx", "subnet-yyyyy"]
vpc_id = "vpc-xxxxx"
node_groups = {
dev = {
desired_capacity = 2
instance_types = ["t3.medium"]
},
prod = {
desired_capacity = 2
instance_types = ["t3.large"]
}
}
}
2.5. CNI 및 IAM 설정 요약
- CNI: AWS VPC CNI가 기본 설치되며, Pod는 VPC 내 ENI를 통해 IP를 직접 할당받음
- OIDC Provider: Terraform으로 생성 후 IRSA 구성을 통해 서비스 계정 단위로 IAM 권한 연동 가능
- ALB Ingress Controller: Helm Chart로 설치하며, IAM 정책은 IRSA로 관리
- aws-auth ConfigMap: NodeGroup의 IAM Role을 worker로 등록하여 kubelet 승인 처리
2.6. 서비스 구성 명세
2.6.1 서비스별 설정
서비스 |
컨테이너 이미지 |
환경변수 |
포트 |
Next.js |
ghcr.io/yourorg/fe-app:main-xxxx |
API_URL, NODE_ENV |
3000 |
Spring |
ghcr.io/yourorg/be-app:main-xxxx |
DB_URL, REDIS_HOST |
8080 |
FastAPI |
ghcr.io/yourorg/ai-app:main-xxxx |
MODEL_PATH, LOG_LEVEL |
8000 |
ArgoCD |
argoproj/argocd:v2.7.0 |
없음 |
8080 |
Prometheus |
prom/prometheus:v2.44.0 |
config-mount |
9090 |
Loki |
grafana/loki:2.8.0 |
config-mount, S3 설정 |
3100 |
Fluent Bit |
fluent/fluent-bit:2.1 |
output 설정, tag |
2020 (TCP) |
Grafana |
grafana/grafana:10.0.0 |
GF_SECURITY_ADMIN_PASSWORD, GF_AUTH_ANONYMOUS_ENABLED |
3000 |
2.7. Helm Chart 관리
2.7.1 Helm Provider 구성 (Terraform)
- Terraform의 Helm provider를 사용해 클러스터 외부에서 Helm Chart를 설치
- kubeadm 환경에서는
helm install
명령을 직접 수행하거나, provider로 관리
- EKS와 달리 kubeconfig를 수동 구성해야 하며, OIDC 기반 인증이 아닌 토큰 기반 혹은 static config 필요
2.7.2 Helm Chart 목록 및 버전
컴포넌트 |
Chart 이름 |
버전 |
설치 위치 |
설치 방식 |
ArgoCD |
argo-cd |
5.x |
argocd |
Helm (Terraform) |
Prometheus |
kube-prometheus-stack |
45.x |
monitoring |
Helm |
Grafana |
grafana |
10.x |
monitoring |
Helm |
Loki |
loki |
2.x |
monitoring |
Helm |
Fluent Bit |
fluent-bit |
2.x |
monitoring |
Helm |
2.7.3 ArgoCD로 배포되는 서비스 목록
서비스 |
Git 경로 |
Git Revision |
설치 위치 (Namespace) |
설치 방식 |
Next.js |
charts/fe-app |
main |
dev / prod |
ArgoCD + Helm |
Spring Boot |
charts/be-app |
main |
dev / prod |
ArgoCD + Helm |
2.8. 모니터링/로깅 구성
2.8.1 모니터링 구성 다이어그램

2.8.2 Fluent Bit → Loki → Grafana
- Fluent Bit은 데몬셋(각 노드에 설치)으로,
/var/log/containers/*.log
를 수집
- 로그를 Loki로 전송하며, Loki는 이를 시계열로 저장
- Grafana는 Loki와 연결해 쿼리 기반 대시보드 및 시각화를 지원
- Loki는 S3 연동을 통해 장기 저장도 가능함 (
boltdb-shipper
+ S3 백엔드)
2.8.3 Prometheus 메트릭 수집
- Node Exporter와 Kubelet 메트릭을 통해 노드/Pod 리소스 수집
- Spring 서비스는 Micrometer + Actuator를 통해
/actuator/prometheus
엔드포인트 노출
- Prometheus가 이를 scrape 하여 수집 → Grafana에서 대시보드 구성
- 개발환경(dev)은 Micrometer 기반 단순 수집, 운영(prod)은 시스템 전체 메트릭 포함
2.9. CI/CD 전략
2.9.1 CI/CD 다이어그램

2.9.2 ArgoCD 구조 및 배포 방식
- GitOps 방식으로 모든 리소스 배포는 GitHub 저장소 기준
- ArgoCD는 Helm 기반 애플리케이션을 추적하며, HelmRelease CRD 기반 배포
- dev/prod 네임스페이스에 따라 분리된 애플리케이션 정의 적용
방식 |
설명 |
예시 |
Application CRD |
ArgoCD가 기본으로 사용하는 방식. Helm Chart도 이 안에서 values 설정 포함해서 직접 관리함. |
argocd-app.yaml 안에 helm: 설정이 포함됨 |
HelmRelease (CRD) |
Helm Controller (예: Flux, Helm Operator)가 설치된 경우 사용하는 CRD. ArgoCD는 HelmRelease라는 Kubernetes 리소스를 추적함. |
HelmRelease 리소스를 Git에 선언해두고 ArgoCD가 이를 배포함 |
2.9.3 HPA 설정
- 각 서비스는 CPU/메모리 기준 HPA 설정 포함
- 예시: Spring 서비스 기준
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: backend-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: backend
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
2.8.3 PVC 구성
- Prometheus는 메트릭 장기 저장을 위해 PVC 연결 (
/prometheus
)
- PVC는
standard
스토리지 클래스 기준 5Gi ~ 20Gi로 설정 (EBS 사용)
2.10. 보안 및 운영 설정
2.10.1 네임스페이스 전략
- dev / prod 환경 분리:
- Kubernetes 네임스페이스를
dev
, prod
로 구분하여 리소스 간 격리
- ArgoCD Application 리소스에서 각 네임스페이스로 배포 목적지 설정
- Helm values 파일도 dev/prod 별도로 관리 (
values-dev.yaml
, values-prod.yaml
)
- RBAC 및 리소스 쿼리 시 혼선을 줄이고, 운영자/개발자의 권한을 구분할 수 있음
2.10.2 서비스 디스커버리
- CoreDNS는 클러스터 내 서비스 이름 기반의 DNS 해석을 담당
- 예:
http://backend.dev.svc.cluster.local
형식으로 접근 가능
- 모든 Pod와 서비스는 DNS 등록을 통해 통신 가능
- 별도 설정 없이 kubeadm 설치 시 CoreDNS 자동 구성됨
2.10.3 접근 제어 및 RBAC
- RBAC(Role-Based Access Control)을 통해 사용자/서비스 계정별 권한 분리
admin-role
: 클러스터 관리자용, 모든 네임스페이스에서 리소스 제어 가능
readonly-role
: 개발자/QA용, 읽기 전용 권한만 부여
dev-role
: dev 네임스페이스 한정 권한
- 필요 시 OIDC 연동으로 사용자 인증도 연계 가능 (예: GitHub SSO)
2.11. 기타 운영 전략
2.11.1 Bastion 접근 구성
- 클러스터 외부 접근은 Bastion EC2를 통해 제한
- 마스터/워커노드는 Private Subnet에 배치하여 직접 SSH 차단
- Bastion만 Public Subnet에 위치하며, 특정 IP에만 포트 22 개방
2.11.2 백업 전략
- Grafana: 대시보드는 JSON 내보내기 및 Git 관리
- Loki: S3 연동을 통해 로그 장기 저장
- Prometheus: 장기 보존이 필요한 경우 EBS-backed PVC 설정 (최소 20Gi)
- Kubernetes 리소스: Helm Chart 및 Kustomize 기반 Git 저장소에 원천 상태 보존 (GitOps)
2.11.3 클러스터 운영 정책
- 클러스터는 비용 절감을 위해 시간대별 운영
- 오전 9시 ~ 오후 6시까지만 인스턴스 유지, 이후 자동 종료
- Terraform 또는 AWS Lambda Scheduler를 통해 제어
- ArgoCD와 Git 상태 동기화를 통해 재기동 시에도 상태 복원 가능