<1> 테스트 준비와 메트릭 서버 배포 0 서울리전 ec2 명령서버 eks 설치 access-key, secret-key 준비 aws configure ap-northeast-2 aws s3 ls # EKS 생성 # 아래는 리눅스 용 cat < eks-freetier-setup.yaml apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: free-vpc-cluster region: ap-northeast-2 version: "1.34" vpc: clusterEndpoints: publicAccess: true privateAccess: true nat: gateway: Single # 비용 절감을 위해 NAT 게이트웨이를 1개만 생성 (중요!) managedNodeGroups: - name: standard-nodes # --- 인스턴스 타입 선택 가이드 --- # 1. t3.micro : 프리티어 대상 (단, K8s 시스템 Pod 실행 시 리소스가 매우 부족할 수 있음) # 2. t3.small : 가성비 추천 (시스템 안정성 확보) # 3. c7i-flex.large (2cpu/4gb) : 연산 위주 # 4. m7i-flex.large (2cpu/8gb) : 메모리 여유 instanceType: t3.small minSize: 1 maxSize: 2 desiredCapacity: 1 # 비용 절감을 위해 노드 수를 1대로 시작 (필요 시 증가) privateNetworking: true iam: withAddonPolicies: imageBuilder: true autoScaler: true cloudWatch: true # 필수 애드온만 설치 addons: - name: vpc-cni - name: coredns - name: kube-proxy EOF # 클러스터 생성 시작 eksctl create cluster -f eks-freetier-setup.yaml # eksctl 로 쿠버네티스 생성시 cloudformation을 이용하여 생성하게 된다. (15분) kubectl get nodes 1 # 터미널 1 watch -d kubectl get hpa,no,deployment,rs,pods,svc # hpa는 metrics-server가 정상적으로 데이터를 수집하기 시작하면서 노드의 CPU와 메모리 사용량이 정상적으로 출력됨. # 터미널 2 watch -d kubectl top nodes Error from server (ServiceUnavailable): the server is currently unable to handle the request (get nodes.metrics.k8s.io) # 정상이다. 아직 세팅전이다. 2 # 터미널 3 # 모니터링 Pod들을 배포하기위해 노드를 미리 늘려 놓는다. # 노드 그룹 이름 확인 eksctl get nodegroup --cluster free-vpc-cluster # standard-nodes # 노드 개수를 2개로 늘리기 eksctl scale nodegroup --cluster free-vpc-cluster --name standard-nodes --nodes 2 3 # 공식 Metrics Server 배포 kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml kubectl get deployment metrics-server -n kube-system 4 # 노드 전체의 CPU/Memory 사용량 확인 # 1차 목표 = kubectl top nodes 동작하게 하기 kubectl top nodes Error from server (ServiceUnavailable): the server is currently unable to handle the request (get nodes.metrics.k8s.io) # 정상 5 kubectl top nodes 안되면 조치1 보안 그룹(Security Group) 4443 포트 개방 EKS 컨트롤 플레인(API Server)이 노드에 떠 있는 Metrics Server에게 데이터를 달라고 요청할 때 4443 포트를 사용합니다. 이 통로가 막혀 있으면 top nodes가 작동하지 않습니다. 아래 명령어로 노드 보안 그룹에 규칙을 추가하세요. # 1. 노드 보안 그룹 ID 가져오기 # 실행 중인 노드 인스턴스에서 직접 보안 그룹 ID 추출 export NODE_SG=$(aws ec2 describe-instances \ --filters "Name=instance-state-name,Values=running" "Name=tag:kubernetes.io/cluster/free-vpc-cluster,Values=owned" \ --query "Reservations[0].Instances[0].SecurityGroups[0].GroupId" \ --output text) # 제대로 가져왔는지 확인 (sg-xxxx 형태여야 합니다) echo $NODE_SG aws ec2 authorize-security-group-ingress \ --group-id $NODE_SG \ --protocol tcp \ --port 4443 \ --source-group $NODE_SG 6 3. 잘 나오면 아래 Pass 만약 여전히 'None'이 나온다면? 수동으로 보안 그룹 목록을 보고 직접 복사해서 변수에 넣는 것이 가장 빠릅니다. # 보안 그룹 목록 전체 보기 aws ec2 describe-security-groups --query "SecurityGroups[*].{Name:GroupName, ID:GroupId}" --output table 위 표에서 Nodes 또는 Worker 관련 이름이 들어간 sg-xxxxxxxx를 찾으신 후, 아래와 같이 직접 입력해 주세요. (예시: sg-0123456789) export NODE_SG=sg-직접입력한ID # 그 다음 2번의 authorize-security-group-ingress 명령 실행 7 4. Metrics Server 패치 (마지막 단계) 보안 그룹 설정 후, 인증서 무시 옵션도 꼭 적용해 주세요. kubectl patch deployment metrics-server -n kube-system --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]' 8 # 보안 그룹 목록에서 EKS 노드 관련 그룹 찾기 aws ec2 describe-security-groups --query "SecurityGroups[*].{Name:GroupName, ID:GroupId}" --output table Metrics Server 통신을 위해 설정해야 할 대상은 ClusterSharedNodeSecurityGroup입니다. sg-0bafa517d2a45caea 9 # 직접 복사한 ID를 입력하세요 (예: sg-0abc123...) export NODE_SG=sg-복사한ID입력 export NODE_SG=sg-0bafa517d2a45caea aws ec2 authorize-security-group-ingress \ --group-id $NODE_SG \ --protocol tcp \ --port 4443 \ --source-group $NODE_SG 10 # 1. 포드가 다시 Running이 되었는지 확인 kubectl get pods -n kube-system -l k8s-app=metrics-server No resources found in kube-system namespace. # 조치1 kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml # 5초 정도 기다린 후 실행하세요 sleep 5 kubectl patch deployment metrics-server -n kube-system --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]' kubectl get pods -n kube-system -l k8s-app=metrics-server k ns kube-system # 2. 메트릭 데이터 확인 kubectl top nodes ------------------ 11 kubectl patch deployment metrics-server -n kube-system --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/args", "value": [ "--cert-dir=/tmp", "--secure-port=4443", "--kubelet-preferred-address-types=InternalIP", "--kubelet-use-node-status-port", "--metric-resolution=15s", "--kubelet-insecure-tls" ]}]' # 포드 전체의 CPU/Memory 사용량 확인 kubectl top pods 12 조치2 kubectl delete deployment metrics-server -n kube-system kubectl delete svc metrics-server -n kube-system kubectl delete apiservice v1beta1.metrics.k8s.io 재설치 kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml 인증서및 ip 설정 sleep 10 kubectl patch deployment metrics-server -n kube-system --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/args", "value": [ "--cert-dir=/tmp", "--secure-port=4443", "--kubelet-preferred-address-types=InternalIP", "--kubelet-use-node-status-port", "--metric-resolution=15s", "--kubelet-insecure-tls" ]}]' 성공 kubectl top nodes NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% ip-192-168-147-238.ap-northeast-2.compute.internal 25m 1% 486Mi 33% ip-192-168-175-38.ap-northeast-2.compute.internal 30m 1% 479Mi 33% <3> 2048 배포 # 2. 확실한 이미지로 재배포 cat < 실습 순서 정리 1단계: 대상 배포(Deployment)에 리소스 제한(Requests) 설정 HPA는 포드가 "어느 정도의 CPU를 사용하는지"를 기준으로 작동합니다. 따라서 포드 설정에 반드시 resources 제한이 있어야 합니다. 아까 만든 2048 앱을 HPA 테스트용으로 업데이트하겠습니다. cat <으로 보일 수 있으며, 1분 정도 지나면 수치가 나옵니다.) 3단계: 부하 발생시키기 (Load Test) 별도의 임시 포드를 띄워 무한 루프로 2048 서비스에 요청을 보냄으로써 CPU 부하를 유도합니다. (새 터미널을 열어 실행하세요.) # 무한 루프로 요청을 보내는 부하 생성 포드 실행 kubectl run -i --tty load-generator --rm --image=busybox:1.28 -- restart=Never -- /bin/sh -c "while true; do wget -q -O- http://service-2048; done" 4단계: 실시간 모니터링 이제 다시 원래 터미널에서 아래 명령어를 입력하고 변화를 관찰하세요. [관찰 포인트] TARGETS 수치가 3% / 3%를 넘어서 올라갑니다. REPLICAS가 2에서 3, 4, 5로 점차 증가합니다. kubectl get pods에서 새로운 포드들이 ContainerCreating -> Running으로 바뀌는 것을 볼 수 있습니다. 5단계: 부하 중지 및 스케일 인(Scale-in) 확인 부하를 주던 터미널에서 Ctrl + C를 눌러 load-generator 포드를 종료합니다. 결과: 약 5분 정도(기본 쿨다운 시간) 지나면 CPU 사용량이 0%로 떨어지고, 포드 개수가 다시 2개로 줄어듭니다. 정리 HPA: 포드의 CPU/메모리 사용량에 따라 Replicas 수를 조절. Metrics Server: HPA가 판단할 수 있는 데이터 제공. 중요: 포드 설정에 resources.requests가 없으면 HPA는 작동하지 않습니다.