1 HPA (Horizontal Pod Autoscaler): 트래픽이 몰릴 때 Pod 개수를 자동으로 늘리기 Metrics Server 설치 (사전 준비) kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml #설치 후 (2분 걸림) kubectl top nodes 명령어를 입력했을 때 노드의 리소스 상태가 보이면 성공입니다. 2 HPA 작동을 위한 Deployment 설정 HPA가 제대로 작동하려면, Pod가 사용할 리소스의 최솟값(requests)이 명시되어야 합니다. 그래야 "사용률(%)"을 계산할 수 있기 때문입니다. # 터미널 1 watch -d kubectl get hpa,no,svc,deploy,rs,pod # 터미널 2 k ns kube-system # 불필요한 부분 삭제 k delete deployment.apps/my-web-app 3 mkdir 6 cd 6 vi my-app-hpa.yaml # my-app-hpa.yaml (Deployment 수정본) apiVersion: apps/v1 kind: Deployment metadata: name: my-web-app spec: replicas: 2 # 1. 어떤 Pod를 관리할지 선택하는 셀렉터 추가 selector: matchLabels: app: my-web-app template: metadata: # 2. Pod에 부여할 라벨 추가 (위의 selector와 일치해야 함) labels: app: my-web-app spec: containers: - name: nginx image: nginx resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "256Mi" kubectl apply -f my-app-hpa.yaml 4 HPA 리소스 생성 이제 CPU 사용량이 50%를 넘어가면 Pod를 최대 10개까지 늘리도록 설정해 보겠습니다. vi hpa-config.yaml # hpa-config.yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: my-web-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: my-web-app # 대상 Deployment 이름 minReplicas: 2 # 최소 유지 Pod 개수 maxReplicas: 10 # 최대 확장 Pod 개수 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 10 # CPU 사용률이 10%를 초과하면 확장 kubectl apply -f hpa-config.yaml # 상태 확인 kubectl get hpa -w 5 이제 부하 테스트 도구(예: Locust, Hey)를 사용하여 실제로 Pod가 늘어나는 것을 확인 부하 테스트 실행: # -z: 2분 동안, -c: 50개의 커넥션으로 유지하며 공격 hey -z 2m -c 50 http://<내-ALB-도메인-주소>/ # Linux (Ubuntu 기준) sudo apt update && sudo apt install -y hey 6 amazon 리눅스 설치법 1. 바이너리 직접 다운로드 (가장 추천) 컴파일 과정 없이 실행 파일만 내려받아 바로 사용하는 방법입니다. # 1. 아키텍처 확인 (x86_64 인지 arm64 인지 확인) arch # 2. 최신 바이너리 다운로드 (대부분의 EC2는 Linux 64bit) curl -O https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64 # 3. 실행 권한 부여 chmod +x hey_linux_amd64 # 4. 경로 이동 (어디서든 실행할 수 있게 bin 폴더로 이동) sudo mv hey_linux_amd64 /usr/local/bin/hey # 5. 설치 확인 hey -n 10 -c 2 http://localhost:3000 hey -z 2m -c 50 http://afd1af64e5f6944db9863b9ec5b296f8-2025976873.ap-northeast-2.elb.amazonaws.com/ more service1.yaml apiVersion: v1 kind: Service metadata: name: my-web-service spec: selector: app: my-web-app ports: - protocol: TCP port: 80 # 서비스가 노출할 포트 targetPort: 80 # 파드 내부의 포트 type: LoadBalancer # ALB 연동을 위해 NodePort 혹은 IP 모드로 설정 # Go를 통해 설치하기 만약 서버에 이미 Go가 설치되어 있거나, 최신 소스 코드로 설치하고 싶을 때 사용합니다. # Go 설치 (Amazon Linux 2023 기준) sudo dnf install -y golang # hey 설치 go install github.com/rakyll/hey@latest # 실행 파일 위치 확인 및 이동 (go install은 ~/go/bin에 저장됨) sudo cp ~/go/bin/hey /usr/local/bin/ 7 HPA 부하 테스트 자동화 스크립트 (test-hpa.sh) afd1af64e5f6944db9863b9ec5b296f8-2025976873.ap-northeast-2.elb.amazonaws.com vi test-hpa.sh #!/bin/bash # 1. 설정 변수 (본인의 환경에 맞게 수정) URL="http://<내-ALB-도메인-주소>" # 테스트할 서비스 주소 DURATION="300s" # 테스트 지속 시간 (5분) CONCURRENCY=50 # 동시 접속자 수 echo "🚀 HPA 부하 테스트를 시작합니다..." echo "대상 URL: $URL" echo "설정: $DURATION 동안 $CONCURRENCY 명의 동시 접속 시뮬레이션" # 2. 터미널 창 분할 안내 (또는 새 창에서 아래 명령어를 미리 실행해두세요) # watch -n 1 "kubectl get hpa,pods" # 3. 부하 발생 (백그라운드 실행) hey -z $DURATION -c $CONCURRENCY $URL & # 4. 실시간 모니터링 (부하가 끝날 때까지 2초마다 상태 출력) echo "📈 실시간 상태 모니터링 중... (Ctrl+C로 중단 가능)" while pgrep -x "hey" > /dev/null; do clear echo "--- [ 현재 HPA 및 Pod 상태 ] ---" kubectl get hpa,pods -l app=my-web-app # Deployment 레이블에 맞게 수정 sleep 2 done echo "✅ 부하 테스트가 완료되었습니다." 8 테스트 실행 가이드 터미널을 두 개 띄워서 실행하는 것을 추천합니다. 터미널 1: 실시간 모니터링 아래 명령어를 입력해두면 상태 변화를 계속 관찰할 수 있습니다. # 1초마다 HPA와 Pod 상태를 갱신해서 보여줍니다. watch -n 1 "kubectl get hpa,pods" # 5분 동안 50명의 사용자가 동시에 접속하는 수준의 부하 hey -z 5m -c 50 http://<내-ALB-도메인-주소>/ 9 카펜터 # EC2NodeClass (AWS 환경 설정) # 어떤 서브넷과 보안 그룹을 사용할지 지정합니다 vi ec2node.yaml apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: default spec: # 1. AMI 선택 조건 추가 (EKS 최적화 AMI를 찾음) amiSelectorTerms: - alias: al2023@latest # Amazon Linux 2023 최신 버전 사용 # 또는 아래와 같이 태그로 지정 가능 # - tags: # karpenter.sh/discovery: "my-eks-cluster" # 2. 역할 이름 확인 (본인의 역할 이름으로 수정 필요) role: "KarpenterNodeRole-my-eks-cluster" # 3. 서브넷 및 보안그룹 선택 (태그가 일치해야 함) subnetSelectorTerms: - tags: karpenter.sh/discovery: "my-eks-cluster" securityGroupSelectorTerms: - tags: karpenter.sh/discovery: "my-eks-cluster" # (선택) EBS 볼륨 크기 설정 blockDeviceMappings: - deviceName: /dev/xvda ebs: volumeSize: 20Gi volumeType: gp3 encrypted: true 10 # NodePool (노드 사양 결정) -어떤 인스턴스 타입을 쓸지, 얼마나 늘릴지 결정합니다. vi nodepool.yaml apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: default spec: template: spec: nodeClassRef: group: karpenter.k8s.aws # [필수] 추가됨 kind: EC2NodeClass # [필수] 추가됨 name: default # 아까 생성한 EC2NodeClass 이름 requirements: - key: karpenter.sh/capacity-type operator: In values: ["on-demand"] - key: kubernetes.io/arch operator: In values: ["amd64"] - key: karpenter.k8s.aws/instance-category operator: In values: ["c", "m", "r"] disruption: # 1. 정책 이름 변경: WhenUnderutilized -> WhenEmptyOrUnderutilized consolidationPolicy: WhenEmptyOrUnderutilized # 2. 필수 값 추가 (얼마나 비어있어야 삭제할지 결정, 예: 30초) consolidateAfter: 30s kubectl apply -f ec2node.yaml kubectl apply -f nodepool.yaml 만약 API 버전 문제가 아니라면, 카펜터 필수 구성 요소가 설치되지 않은 것입니다. 아래 명령어로 EC2NodeClass 관련 CRD가 있는지 확인하세요. kubectl get crds | grep karpenter 11 Helm을 이용한 CRD 직접 설치 (권장) 카펜터는 별도의 CRD 파일을 제공합니다. 아래 명령어로 최신 버전(또는 사용 중인 버전)의 CRD를 강제로 적용할 수 있습니다. 첫번째 방법 # 카펜터 버전 변수 설정 (예: v1.0.1) export KARPENTER_VERSION=v1.0.1 # CRD 설치/업데이트 kubectl create -f https://raw.githubusercontent.com/aws/karpenter-provider-aws/${KARPENTER_VERSION}/pkg/apis/crds/karpenter.sh_nodepools.yaml kubectl create -f https://raw.githubusercontent.com/aws/karpenter-provider-aws/${KARPENTER_VERSION}/pkg/apis/crds/karpenter.sh_nodeclaims.yaml kubectl create -f https://raw.githubusercontent.com/aws/karpenter-provider-aws/${KARPENTER_VERSION}/pkg/apis/crds/karpenter.k8s.aws_ec2nodeclasses.yaml 이미 존재한다는 에러가 뜨면 create 대신 replace --force를 사용하세요. (선택) 두번쨰 방법 Helm 차트로 전체 재설치/업데이트 CRD를 포함하여 카펜터 전체 설정을 Helm으로 관리하는 것이 정석입니다. # 1. OCI 레지스트리 로그인 (AWS Public ECR 사용) aws ecr-public get-login-password --region us-east-1 | helm registry login --username AWS --password-stdin public.ecr.aws # 2. Helm 업그레이드 (CRD 설치 옵션 포함) helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \ --version ${KARPENTER_VERSION} \ --namespace karpenter --create-namespace \ --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=${KARPENTER_IAM_ROLE_ARN} \ --set settings.clusterName=${CLUSTER_NAME} \ --set settings.interruptionQueue=${CLUSTER_NAME} \ --wait 12 설치 확인 CRD가 정상적으로 등록되었는지 확인합니다. kubectl get crds | grep karpenter.sh 아래와 같이 3개 이상의 목록이 나오면 성공입니다: ec2nodeclasses.karpenter.k8s.aws nodeclaims.karpenter.sh nodepools.karpenter.sh 13 kubectl logs -f -n karpenter -l app.kubernetes.io/name=carpenter 로그에 "Found 1 pending pod(s)... launching node" 라는 메시지가 뜨면서 kubectl get nodes에 새로운 노드가 즉시 추가되는 것을 볼 수 있습니다. 14 # Helm을 이용한 Prometheus 스택 설치 # 1. Helm 레포지토리 추가 helm repo add prometheus-community https://github.com/prometheus-community/helm-charts helm repo update # 2. 모니터링 전용 네임스페이스 생성 kubectl create namespace monitoring # 3. 스택 설치 # 1. 레포지토리 등록 helm repo add prometheus-community https://prometheus-community.github.io/helm-charts # 2. 로컬 레포지토리 정보 갱신 helm repo update helm install monitoring prometheus-community/kube-prometheus-stack --namespace monitoring (arn:aws:eks:ap-northeast-2:588752323301:cluster/my-eks-cluster:default) [root@myeks2-bastion-EC2 ~]# helm install monitoring prometheus-community/kube-prometheus-stack --names pace monitoring NAME: monitoring LAST DEPLOYED: Wed Feb 11 10:21:57 2026 NAMESPACE: monitoring STATUS: deployed REVISION: 1 NOTES: kube-prometheus-stack has been installed. Check its status by running: kubectl --namespace monitoring get pods -l "release=monitoring" Get Grafana 'admin' user password by running: kubectl --namespace monitoring get secrets monitoring-grafana -o jsonpath="{.data.admin-password}" | base64 -d ; echo Access Grafana local instance: export POD_NAME=$(kubectl --namespace monitoring get pod -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=monitoring" -oname) kubectl --namespace monitoring port-forward $POD_NAME 3000 Get your grafana admin user password by running: kubectl get secret --namespace monitoring -l app.kubernetes.io/component=admin-secret -o jsonpath="{.items[0].data.admin-password}" | base64 --decode ; echo Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator. (arn:aws:eks:ap-northeast-2:588752323301:cluster/my-eks-cluster:default) [root@myeks2-bastion-EC2 ~]# 15 k ns monitoring 16 kubectl port-forward --address 0.0.0.0 svc/monitoring-grafana 3000:80 -n monitoring http://43.203.179.86:3000/ 접속하고, 아이디 `admin`과 위에서 얻은 비밀번호로 로그인 17 암호 확인 kubectl get secret --namespace monitoring monitoring-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo 43krG5tId6TRf1Q0DXaOIy2Bek2LWlTxeuxpZMEc # 암호 초기화 helm upgrade monitoring prometheus-community/kube-prometheus-stack \ --namespace monitoring \ --reuse-values \ --set grafana.adminPassword=admin echo "PASSWORD IS: [$(kubectl get secret --namespace monitoring monitoring-grafana -o jsonpath="{.data.admin-password}" | base64 --decode)]" admin admin