1. HPA 환경 구성 및 동작 확인
이번 실습은 5장 Amazon EKS 원클릭 배포 환경에서 진행합니다.
인프라 배포를 진행하지 않은 경우 링크를 통해 배포 후 복귀 바랍니다.
그리고 새롭게 인프라를 배포하면 아래 기본 설정 명령을 입력 후 진행 바랍니다.
기본 설정 명령어
Default 네임 스페이스 변경
1
kubectl ns default
워커 노드의 IP 변수 선언
1
2
3
4
5
6
7
8
9
10
11
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
작업용 인스턴스에서 노드로 보안 그룹 설정
1
2
3
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
노드에 SSH 접근
1
for node in $N1 $N2 $N3; do ssh ec2-user@$node hostname; done
AWS Load Balancer Controller 설치
1
2
3
4
5
6
7
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
ExternalDNS 설치
1
2
3
4
5
6
7
8
9
10
// 자신의 도메인 주소로 설정
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 -
kube-ops-view 설치
1
2
3
4
5
6
7
8
9
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"
ACM 인증서 변수 선언
1
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`; echo $CERT_ARN
프로메테우스 스택 설치
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// 네임 스페이스 생성
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
메트릭 서버 설치
1
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
EKS Node View 설치
1
2
3
4
5
6
7
8
9
10
// 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 설치
1
2
3
4
5
6
7
8
9
10
// 테스트용 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
모니터링 - 신규 터미널
1
2
// 모니터링 - 신규 터미널 (hpa, 파드 메트릭, 노드 메트릭)
watch -d 'kubectl get hpa,pod;echo;kubectl top pod;echo;kubectl top node'
접속 확인
1
2
3
PODIP=$(kubectl get pod -l run=php-apache -o jsonpath={.items[0].status.podIP})
curl -s $PODIP; echo
HPA 생성
1
2
3
4
5
// 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에 부하 발생
1
2
// 부하 발생 - 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 실습 자원 삭제
실습 자원 삭제
1
kubectl delete deploy,svc,hpa,pod --all
2. VPA 환경 구성 및 동작 확인
2.1. VPA 환경 구성
네임 스페이스 추가 및 모니터링 - 신규 터미널
1
2
3
4
5
// 네임 스페이스 추가
kubectl create ns vpa
// 모니터링 - 신규터미널 (VPA 생성 자원 확인)
watch -d 'kubectl get pod -n vpa'
VPA 설치
1
2
3
4
5
6
7
8
// 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 동작 확인
모니터링 - 신규 터미널
1
2
// 모니터링 - 신규 터미널 (파드 메트릭 수집)
watch -d kubectl top pod
테스트용 자원 설치
1
2
3
4
5
6
7
// 테스트용 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 동작 정보 확인
1
2
3
4
5
// 파드 리소스 요구 사항 확인
kubectl describe pod | grep Requests: -A2
// VPA에 의해 파드 삭제 및 생성 이벤트 확인
kubectl get events --sort-by=".metadata.creationTimestamp" | grep VPA
2.3. VPA 실습 자원 삭제
실습 자원 삭제
1
2
3
4
5
// 테스트용 hamster 삭제
kubectl delete -f hamster.yaml
// VPA 삭제
helm uninstall vpa -n vpa
3. CA 환경 구성 및 동작 확인
3.1. CA 환경 구성
ASG 확인 및 조정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 현재 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 설치 및 확인
1
2
3
4
5
6
7
8
9
10
// 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 동작 확인
테스트용 자원 설치
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 테스트용 디플로이먼트 생성
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 확인
1
2
3
4
5
6
7
// 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 확인
1
2
3
4
5
6
7
// 테스트용 디플로이먼트 삭제 (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 실습 자원 삭제
실습 자원 삭제
1
2
// CA 삭제
kubectl delete -f cluster-autoscaler-autodiscover.yaml
4. 실습 환경 삭제
5장 HPA, VPA, CA 실습이 종료되어 Amazon EKS 원클릭 배포를 삭제해 모든 실습 환경을 삭제합니다.
실습 종료 후 자원 삭제
1
2
3
4
5
6
7
8
// 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 구성 하기 실습을 마칩니다.
수고하셨습니다 :)