[EKS] HPA, VPA, CA 구성하기
1. HPA 환경 구성 및 동작 확인
이번 실습은 5장 Amazon EKS 원클릭 배포 환경에서 진행합니다. Default 네임 스페이스 변경 워커 노드의 IP 변수 선언 작업용 인스턴스에서 노드로 보안 그룹 설정 노드에 SSH 접근 AWS Load Balancer Controller 설치 ExternalDNS 설치 kube-ops-view 설치 ACM 인증서 변수 선언 프로메테우스 스택 설치 메트릭 서버 설치 EKS Node View 설치
인프라 배포를 진행하지 않은 경우 링크를 통해 배포 후 복귀 바랍니다.
그리고 새롭게 인프라를 배포하면 아래 기본 설정 명령을 입력 후 진행 바랍니다. 기본 설정 명령어
kubectl ns default
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo "export N1=$N1" >> /etc/profile
echo "export N2=$N2" >> /etc/profile
echo "export N3=$N3" >> /etc/profile
NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*ng1* --query "SecurityGroups[*].[GroupId]" --output text)
aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32
for node in $N1 $N2 $N3; do ssh ec2-user@$node hostname; done
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm 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
// 자신의 도메인 주소로 설정
MyDomain=<자신의 도메인>
MyDnsHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)
echo $MyDomain, $MyDnsHostedZoneId
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/externaldns.yaml
MyDomain=$MyDomain MyDnsHostedZoneId=$MyDnsHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'
kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`; echo $CERT_ARN
// 네임 스페이스 생성
kubectl create ns monitoring
// helm chart repo 추가
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
// 프로메테우스 파라미터 구성
cat <<EOT > monitor-values.yaml
prometheus:
prometheusSpec:
podMonitorSelectorNilUsesHelmValues: false
serviceMonitorSelectorNilUsesHelmValues: false
retention: 5d
retentionSize: "10GiB"
verticalPodAutoscaler:
enabled: true
ingress:
enabled: true
ingressClassName: alb
hosts:
- prometheus.$MyDomain
paths:
- /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
grafana:
defaultDashboardsTimezone: Asia/Seoul
adminPassword: prom-operator
ingress:
enabled: true
ingressClassName: alb
hosts:
- grafana.$MyDomain
paths:
- /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
defaultRules:
create: false
kubeControllerManager:
enabled: false
kubeEtcd:
enabled: false
kubeScheduler:
enabled: false
alertmanager:
enabled: false
EOT
// 프로메테우스 스택 배포
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.27.2 \
--set prometheus.prometheusSpec.scrapeInterval='15s' \
--set prometheus.prometheusSpec.evaluationInterval='15s' \
-f monitor-values.yaml --namespace monitoring
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
// go 설치
yum install -y go
// EKS Node Viewer 설치 (2분 이상 소요)
go install github.com/awslabs/eks-node-viewer/cmd/eks-node-viewer@v0.5.0
// 신규 터미널에서 실행
cd ~/go/bin
./eks-node-viewer
1.1. HPA 환경 구성
테스트용 php-apache 설치
// 테스트용 php-apache 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/application/php-apache.yaml
cat php-apache.yaml | yh
// 테스트용 php-apache 배포
kubectl apply -f php-apache.yaml
// php-apache 동작 확인
kubectl exec -it deploy/php-apache -- cat /var/www/html/index.php
모니터링 - 신규 터미널
// 모니터링 - 신규 터미널 (hpa, 파드 메트릭, 노드 메트릭)
watch -d 'kubectl get hpa,pod;echo;kubectl top pod;echo;kubectl top node'
접속 확인
PODIP=$(kubectl get pod -l run=php-apache -o jsonpath={.items[0].status.podIP})
curl -s $PODIP; echo
HPA 생성
// HPA 생성 - 파드의 요청 CPU의 50% 이상일 경우 스케일링 수행
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
// HPA 확인
kubectl describe hpa
1.2. HPA 동작 확인
그라파나 대시보드 생성
- Kubernetes / Horizontal Pod Autoscaler ID : 17125
- Absolute time range : Last 15 minutes
php-apache에 부하 발생
// 부하 발생 - scale-out 확인
kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
php-apache에 부하 중지
- 부하 중지 : 5분 후 scale-in 확인
- Ctrl + C
1.3. HPA 실습 자원 삭제
실습 자원 삭제
kubectl delete deploy,svc,hpa,pod --all
2. VPA 환경 구성 및 동작 확인
2.1. VPA 환경 구성
네임 스페이스 추가 및 모니터링 - 신규 터미널
// 네임 스페이스 추가
kubectl create ns vpa
// 모니터링 - 신규터미널 (VPA 생성 자원 확인)
watch -d 'kubectl get pod -n vpa'
VPA 설치
// helm chart repository 추가
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
// VPA 설치
helm install vpa fairwinds-stable/vpa --namespace vpa
// vpa crd 정보 확인
kubectl get crd | grep autoscaling
2.2. VPA 동작 확인
모니터링 - 신규 터미널
// 모니터링 - 신규 터미널 (파드 메트릭 수집)
watch -d kubectl top pod
테스트용 자원 설치
// 테스트용 hamster 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/hamster.yaml
cat hamster.yaml | yh
// 테스트용 hamster 설치
kubectl apply -f hamster.yaml && kubectl get vpa -w
VPA 동작 정보 확인
// 파드 리소스 요구 사항 확인
kubectl describe pod | grep Requests: -A2
// VPA에 의해 파드 삭제 및 생성 이벤트 확인
kubectl get events --sort-by=".metadata.creationTimestamp" | grep VPA
2.3. VPA 실습 자원 삭제
실습 자원 삭제
// 테스트용 hamster 삭제
kubectl delete -f hamster.yaml
// VPA 삭제
helm uninstall vpa -n vpa
3. CA 환경 구성 및 동작 확인
3.1. CA 환경 구성
ASG 확인 및 조정
// 현재 ASG 정보 확인
aws autoscaling describe-auto-scaling-groups \
--query "AutoScalingGroups[? Tags[? (Key=='eks:cluster-name') && Value=='myeks']].[AutoScalingGroupName, MinSize, MaxSize,DesiredCapacity]" \
--output table
// ASG 이름 변수 선언
export ASG_NAME=$(aws autoscaling describe-auto-scaling-groups --query "AutoScalingGroups[? Tags[? (Key=='eks:cluster-name') && Value=='myeks']].AutoScalingGroupName" --output text); echo $ASG_NAME
// ASG MaxSize를 6으로 변경
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name ${ASG_NAME} \
--min-size 3 \
--max-size 6 \
--desired-capacity 3
CA 설치 및 확인
// CA 설치 파일 다운로드 및 변수 치환
curl -s -O https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
sed -i "s/<YOUR CLUSTER NAME>/$CLUSTER_NAME/g" cluster-autoscaler-autodiscover.yaml
// CA 배포
kubectl apply -f cluster-autoscaler-autodiscover.yaml
// CA 확인
kubectl get pod -n kube-system | grep cluster-autoscaler
3.2. CA 동작 확인
테스트용 자원 설치
// 테스트용 디플로이먼트 생성
cat <<EoF> nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-to-scaleout
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
service: nginx
app: nginx
spec:
containers:
- image: nginx
name: nginx-to-scaleout
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 500m
memory: 512Mi
EoF
// 테스트용 디플로이먼트 설치
kubectl apply -f nginx.yaml
// 테스트용 디플로이먼트 정보 확인
kubectl get deployment/nginx-to-scaleout
노드 scale-out 확인
// replica를 15로 조정 (scale-out 확인)
kubectl scale --replicas=15 deployment/nginx-to-scaleout && date
// 현재 ASG 정보 확인
aws autoscaling describe-auto-scaling-groups \
--query "AutoScalingGroups[? Tags[? (Key=='eks:cluster-name') && Value=='myeks']].[AutoScalingGroupName, MinSize, MaxSize,DesiredCapacity]" \
--output table
노드 scale-in 확인
// 테스트용 디플로이먼트 삭제 (scale-in 확인 - 10분 이상 소요)
kubectl delete -f nginx.yaml && date
// 현재 ASG 정보 확인
aws autoscaling describe-auto-scaling-groups \
--query "AutoScalingGroups[? Tags[? (Key=='eks:cluster-name') && Value=='myeks']].[AutoScalingGroupName, MinSize, MaxSize,DesiredCapacity]" \
--output table
3.3. CA 실습 자원 삭제
실습 자원 삭제
// CA 삭제
kubectl delete -f cluster-autoscaler-autodiscover.yaml
4. 실습 환경 삭제
5장 HPA, VPA, CA 실습이 종료되어 Amazon EKS 원클릭 배포를 삭제해 모든 실습 환경을 삭제합니다.
실습 종료 후 자원 삭제
// helm chart 삭제
helm uninstall -n monitoring kube-prometheus-stack
helm uninstall -n kube-system kube-ops-view
// Amazon EKS 원클릭 배포 삭제
eksctl delete cluster --name $CLUSTER_NAME \
&& aws cloudformation delete-stack --stack-name $CLUSTER_NAME
Warning: Amazon EKS 원클릭 배포의 삭제는 약 15분 정도 소요됩니다. 삭제가 완료될 때 까지 SSH 연결 세션을 유지합니다.
Warning: 만약에 CloudFormation 스택이 삭제되지 않는다면 수동으로 VPC(myeks-VPC)를 삭제 후 CloudFormation 스택을 다시 삭제해 주세요.
여기까지 5장 HPA, VPA, CA 구성 하기 실습을 마칩니다.
수고하셨습니다 :)