목차
1. HPA 환경 구성 및 동작 확인
    1.1. HPA 환경 구성
    1.2. HPA 동작 확인
    1.3. HPA 실습 자원 삭제
2. VPA 환경 구성 및 동작 확인
    2.1. VPA 환경 구성
    2.2. VPA 동작 확인
    2.3. VPA 실습 자원 삭제
3. CA 환경 구성 및 동작 확인
    3.1. CA 환경 구성
    3.2. CA 동작 확인
    3.3. CA 실습 자원 삭제
4. 실습 환경 삭제


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 구성 하기 실습을 마칩니다.
수고하셨습니다 :)