EKS 프로덕션 아키텍처 개요
EKS(Elastic Kubernetes Service)는 AWS 관리형 컨트롤 플레인 위에서 Kubernetes를 운영합니다. 프로덕션에서는 Multi-AZ 노드 그룹 + Karpenter 오토스케일링 + ALB Ingress 조합이 표준입니다.
사전 준비 — 도구 설치
# eksctl
curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
# kubectl
curl -LO "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && sudo mv kubectl /usr/local/bin
# helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 버전 확인
eksctl version && kubectl version --client && helm version클러스터 생성 — eksctl 선언형 설정
# cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: prod-cluster
region: ap-northeast-2
version: "1.29"
iam:
withOIDC: true # IRSA(IAM Roles for Service Accounts) 활성화
managedNodeGroups:
- name: system
instanceType: m6i.large
minSize: 2
maxSize: 4
desiredCapacity: 2
availabilityZones: [ap-northeast-2a, ap-northeast-2b, ap-northeast-2c]
labels:
role: system
taints:
- key: CriticalAddonsOnly
value: "true"
effect: NoSchedule
iam:
attachPolicyARNs:
- arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
- arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
addons:
- name: vpc-cni
version: latest
- name: coredns
version: latest
- name: kube-proxy
version: latest
- name: aws-ebs-csi-driver
version: latest
wellKnownPolicies:
ebsCSIController: trueeksctl create cluster -f cluster.yaml
# kubeconfig 자동 업데이트됨
kubectl get nodesKarpenter — 지능형 노드 오토스케일링
Cluster Autoscaler 대신 Karpenter를 사용하면 미사용 노드를 빠르게 정리하고 비용을 절감합니다.
Karpenter 설치
export CLUSTER_NAME=prod-cluster
export AWS_REGION=ap-northeast-2
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
# IRSA 생성
eksctl create iamserviceaccount \
--name karpenter \
--namespace karpenter \
--cluster $CLUSTER_NAME \
--attach-policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/KarpenterControllerPolicy \
--approve
# Helm으로 설치
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \
--version v0.37.0 \
--namespace karpenter --create-namespace \
--set settings.clusterName=$CLUSTER_NAME \
--set settings.interruptionQueue=$CLUSTER_NAME \
--waitNodePool · NodeClass 정의
# karpenter-nodepool.yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
nodeClassRef:
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand", "spot"]
- key: node.kubernetes.io/instance-type
operator: In
values: ["m6i.large", "m6i.xlarge", "m6a.large", "m6a.xlarge"]
- key: topology.kubernetes.io/zone
operator: In
values: ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c"]
limits:
cpu: 200
memory: 400Gi
disruption:
consolidationPolicy: WhenUnderutilized
consolidateAfter: 30s
---
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
role: KarpenterNodeRole-prod-cluster
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: prod-cluster
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: prod-cluster
blockDeviceMappings:
- deviceName: /dev/xvda
ebs:
volumeSize: 50Gi
volumeType: gp3
encrypted: truekubectl apply -f karpenter-nodepool.yamlALB Ingress Controller + HTTPS 설정
# AWS Load Balancer Controller 설치
helm repo add eks https://aws.github.io/eks-charts && helm repo update
helm upgrade --install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=$CLUSTER_NAME \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:ACCOUNT:certificate/CERT-ID
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80HPA — CPU/메모리 기반 Pod 오토스케일링
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 5분간 관망 후 스케일 다운
policies:
- type: Pods
value: 2
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 30운영 — 핵심 명령어 모음
# 클러스터 전체 리소스 사용량
kubectl top nodes
kubectl top pods -A
# Karpenter 노드 현황
kubectl get nodeclaims
kubectl get nodepools
# HPA 상태 모니터링
kubectl get hpa -w
# 롤링 업데이트 (무중단)
kubectl set image deployment/api app=my-image:v2
kubectl rollout status deployment/api
# 롤백
kubectl rollout undo deployment/api
kubectl rollout history deployment/api --revision=3
# 강제 종료 없이 파드 재스케줄
kubectl drain node-id --ignore-daemonsets --delete-emptydir-data
# 비용 최적화: Spot 중단 시뮬레이션
kubectl taint nodes NODE_NAME karpenter.sh/disruption:NoSchedule-보안 강화 — IRSA와 NetworkPolicy
# IRSA: Pod에 최소 권한 IAM 역할 부여
eksctl create iamserviceaccount \
--name s3-reader \
--namespace production \
--cluster $CLUSTER_NAME \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve# networkpolicy.yaml — 기본 차단 후 필요한 것만 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-ingress
namespace: production
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- port: 8080이 가이드는 AI 도구를 활용해 초안을 구성하고 사람이 명령어·문맥을 검토해 발행했습니다. 운영체제와 도구 버전에 따라 결과가 달라질 수 있으므로 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요.
질문 & 답변 (Q&A)
이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.