Cloud Architect/Kubernetes

AutoScaling [Part 01]

"Everything about infra" 2025. 7. 21. 17:49

01. EKS (Elastic Kubernetes Service) ์„ค์น˜

๐Ÿ’‍โ™‚๏ธ EKS ์†Œ๊ฐœ

Kubernetes Control plane์„ ๊ตฌ์„ฑํ•  ํ•„์š” ์—†์ด AWS์—์„œ Kubernetes๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ด€๋ฆฌํ˜• ์„œ๋น„์Šค.

์žฅ์ ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋ฆฌํŒฉํ† ๋ง์ด ํ•„์š”์—†๋‹ค.

EKSํ™˜๊ฒฝ์—์„œ ๊ตฌ๋™๋˜๋Š” Application์€ ํ‘œ์ค€ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํ™˜๊ฒฝ์—์„œ ๊ทธ๋Œ€๋กœ ๊ตฌ๋™ ๊ฐ€๋Šฅํ•˜๋ฉฐ,

๋ฐ˜๋Œ€๋กœ On-premise ํ™˜๊ฒฝ์— ์žˆ๋˜ ๊ตฌ์„ฑ์„ EKS ํ™˜๊ฒฝ์œผ๋กœ ์†์‰ฝ๊ฒŒ ์ ์šฉ ๊ฐ€๋Šฅํ•จ.

  • opensource ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์ ๊ทน์ ์œผ๋กœ ๊ธฐ์—ฌํ•œ๋‹ค.

eksctl, autoscaler, CNI ๊ฐœ๋ฐœ ๋“ฑ.

 

EKS Architecture

Control plane์€ AWS๊ฐ€ ๊ด€๋ฆฌํ•˜์—ฌ ๋ˆˆ์œผ๋กœ ํ™•์ธ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž์˜ ๊ด€๋ฆฌ์˜์—ญ์€ ์˜ค์ง worker node.

 

๋ฐ˜๋Œ€๋กœ, Kubernetes์™€ EKS์˜ ์ฐจ์ด์ ์€?

  • Kubernetes ์‚ฌ์šฉ์‹œ Control plane ๊ด€๋ฆฌ ๋ถ€๋‹ด์ด ํฌ๋‹ค (CNI ๊ตฌ์„ฑ, HA๊ตฌ์„ฑ ๋“ฑ..)
  • Managed node Group์ด ์—†๋‹ค (EKS์—์„œ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค)
  • version update ๋ถ€๋‹ด ๋“ฑ.

ํ•˜์ง€๋งŒ, ๊ด€๋ฆฌํ˜• ์„œ๋น„์Šค๊ฐ€ ๊ผญ ์ •๋‹ต๋งŒ์€ ์•„๋‹ˆ๋‹ค.

  • ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ์—ฌ์ง€๊ฐ€ ์‚ฌ๋ผ์ง€๋ฏ€๋กœ Platform์— ํ•„์š”ํ•œ ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ์„ ๊ฒฝ์šฐ ์˜คํžˆ๋ ค ๋ถˆํŽธํ•˜๋‹ค.
    • ex: ETCD์— ๋“ค์–ด๊ฐ€๋Š” ์ •๋ณด๋ฅผ ๋ณ„๋„๋กœ ๊ตฌ์ถ•ํ•ด์„œ ์•”ํ˜ธํ™”๋ฅผ ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ๋“ฑ..
  • ๋ณด์•ˆ, ์›Œํฌ๋กœ๋“œ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž์ถฐ์„œ ๊ตฌ์ถ•์ด ํ•„์š”ํ•˜๋ฏ€๋กœ Managed Service๊ฐ€ ์ •๋‹ต์€ ์•„๋‹ˆ๋‹ค.

 

๊ฐ„๋‹จํ•œ ์‹ค์Šต์— ํ•„์š”ํ•œ ์ •๋„๋กœ๋งŒ EKS๋ฅผ ์•Œ์•„๋ณด๊ธฐ๋กœ ํ•˜๊ณ , ์ž์„ธํ•œ๊ฑด ๋‚˜์ค‘์— Deep ํ•˜๊ฒŒ ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜์ž.

 


1-1. EKS ์„ค์น˜ ์ „ ์‚ฌ์ „ ์ค€๋น„๋ฌผ

โ–  awscli ์„ค์น˜

apt-get update
apt-get install -y unzip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version
aws configure

$aws configure
  AWS Access Key ID [None]: ๋ณด์•ˆ์— ์ค€์ˆ˜ํ•˜์—ฌ ์ž‘์„ฑํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  AWS Secret Access Key [None]: ์œ„ ๋‚ด์šฉ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
  Default region name [None]: ap-northeast-2
  Default output format [None]: json

--- ์ ์šฉ ํ™•์ธ ---
aws configure list
aws sts get-caller-identity

{
    "UserId": "339712771495",
    "Account": "339712771495",
    "Arn": "arn:aws:iam::339712771495:root"
}

 

โ–  eksctl ์„ค์น˜

์ฐธ๊ณ  ๋ฌธ์„œ : https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/eksctl.html

 

Amazon EKS๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ • - Amazon EKS

์ด ํŽ˜์ด์ง€์— ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ ์„ ์•Œ๋ ค ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์‹ค๋ง์‹œ์ผœ ๋“œ๋ ค ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ž ๊น ์‹œ๊ฐ„์„ ๋‚ด์–ด ์„ค๋ช…์„œ๋ฅผ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ง์”€ํ•ด ์ฃผ์‹ญ์‹œ์˜ค.

docs.aws.amazon.com

# ubuntu Linux EC2 ์— eksctl ์„ค์น˜

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
eksctl version
0.171.0

 

โ–  kubectl ์„ค์น˜

์ฐธ๊ณ  ๋ฌธ์„œ : https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/install-kubectl.html

# ubuntu Linux EC2 ์— k8s ๊ด€๋ฆฌํˆด์ธ kubectl ์„ค์น˜

curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc

-- ๋ฒ„์ „ ํ™•์ธ --
kubectl version --short --client 

-- ์ž๋™ ๋ช…๋ น ์Šคํฌ๋ฆฝํŠธ --
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >>~/.bashrc

 

1-2. EKS install

console์—์„œ ์ˆ˜๋™์œผ๋กœ ์„ค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๊ด€๋ฆฌ๋ฅผ ์šฉ์ดํ•˜๊ฒŒ yaml ํŒŒ์ผ๋กœ ์ž‘์„ฑํ•˜์—ฌ ์„ค์น˜

vi cluster.yaml

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: prd-eks-cluster
  region: ap-northeast-2
vpc:
  id: 'vpc-02172b18928eebff8'     
  subnets:
    private:
      ap-northeast-2a:
        id: 'subnet-09fd28d637e11b029'
      ap-northeast-2c:
        id: 'subnet-0ee462c61cd9b9395'

managedNodeGroups:
  - name: prd-eks-dataplane1
    labels: { role: workers }
    instanceType: t2.medium
    desiredCapacity: 1
    privateNetworking: true
    subnets:
      - subnet-09fd28d637e11b029
  - name: prd-eks-dataplane2
    labels: { role: workers }
    instanceType: t2.medium
    desiredCapacity: 1
    privateNetworking: true
    subnets:
      - subnet-0ee462c61cd9b9395
    iam:
      withAddonPolicies:
        imageBuilder: true
iam:
  withOIDC: true

 

๋ณธ์ธ VPC ํ™˜๊ฒฝ์— ๋งž์ถ”์–ด vpc-id, subnet-id ํ•ญ๋ชฉ์€ ์ˆ˜์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

  • ์„ค์น˜์™„๋ฃŒ ํ›„ node ์ƒ์„ฑ ํ™•์ธ
kubectl get nodes

 

์‹ค์Šต์ด ๋๋‚˜์‹  ํ›„ EKS ์‚ญ์ œ ๋ช…๋ น์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

eksctl delete cluster -f cluster.yaml --disable-nodegroup-eviction

 


02. HPA(Horizon Pod Autoscaler)

Pod์— ๋Œ€ํ•œ Client Connection์ด ๋งŽ์•„์ง€๊ฑฐ๋‚˜ ์ ์–ด์ง€๋ฉด ๋ฆฌ์†Œ์Šค ์ •๋ณด๋ฅผ ํ™•์ธํ•˜์—ฌ Pod๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๊ฑฐ๋‚˜ ์ถ•์†Œ์‹œํ‚ค๋Š” ๊ธฐ์ˆ 

  • Scal in/out ์„ ํ†ตํ•ด ํŒŒ๋“œ ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๊ฑฐ๋‚˜ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•
  • Metric์— ๋”ฐ๋ผ (CPU ์‚ฌ์šฉ๋ฅ ) ํŒŒ๋“œ ์ˆ˜๋ฅผ ์ž๋™์œผ๋กœ ์กฐ์ ˆํ•œ๋‹ค.
  • ํŒŒ๋“œ ์ˆ˜๋ฅผ ๋Š˜๋ฆผ์œผ๋กœ์จ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ๋†’์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•˜์—ฌ ๋น„์šฉ ํšจ์œจ์„ฑ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

์Šค์ผ€์ค„๋ง ์‹œ๊ฐ„

kube-controller-manager์—์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, master node์— ์ ‘๊ทผํ•˜์—ฌ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ

์šฐ๋ฆฌ๋Š” AWS์—์„œ EKS๋ฅผ ๋™์ž‘์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์— master node๋Š” AWS์—์„œ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ, ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅ ํ•˜๋‹ˆ ์ฐธ๊ณ !

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
apiServer:
  extraArgs:
    horizontal-pod-autoscaler-sync-period: "15s"
    horizontal-pod-autoscaler-downscale-stabilization: "5m"

 

sync-period : HPA๊ฐ€ Pod์˜ CPU์‚ฌ์šฉ๋ฅ ์„ Check ํ•˜๋Š” ์ฃผ๊ธฐ(์‹œ๊ฐ„)์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, Default๊ฐ’์œผ๋กœ 15์ดˆ.

downscale-stabilization : Pod๋ฅผ ์ค„์ผ ๋•Œ ํŠน์ • ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, Default ๊ฐ’์œผ๋กœ 5๋ถ„์ด๋‹ค.

 

 

๐Ÿ’‍โ™‚๏ธ ์‹œ์ž‘์ „ ๊ตฌ์„ฑ์š”์†Œ

  • eksctl, kubectl
  • worker node 2๊ฐœ ์ด์ƒ์ธ cluster
  • Metrics Server๊ฐ€ ๋ฐฐํฌ๋œ cluster
  • kubernetes version : 1.23 ์ด์ƒ.

 

โ–  Metrics Server install

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

์œ„ config๋กœ install ํ›„ ์•„๋ž˜์™€ ๊ฐ™์ด ํ™•์ธ

kubectl get deployment metrics-server -n kube-system
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
metrics-server   1/1     1            1           31s

 


2-1. ํ…Œ์ŠคํŠธ์šฉ Pod & Service ๋ฐฐํฌ

โ–  apache ๋ฐฐํฌ

apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  selector:
    matchLabels:
      run: php-apache
  template:
    metadata:
      labels:
        run: php-apache
    spec:
      containers:
      - name: php-apache
        image: registry.k8s.io/hpa-example
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 500m
          requests:
            cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
  name: php-apache
  labels:
    run: php-apache
spec:
  ports:
  - port: 80
  selector:
    run: php-apache

 

ํ•ด๋‹น yaml ํŒŒ์ผ์„ ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜ ๋ช…๋ น์ค„์„ ์ž…๋ ฅํ•˜์ž.

kubectl apply -f https://k8s.io/examples/application/php-apache.yaml

 

HPA ๋™์ž‘ ๋ฐฉ์‹

ํ‰๊ท ์ ์œผ๋กœ ์ œ์–ด ์žฅ์น˜์˜ ๋ชจ๋“  Pod์˜ ํ‰๊ท  CPU ์‚ฌ์šฉ๋ฅ ์„ 50%๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฐํฌ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜์—ฌ

๋ณต์ œ๋ณธ ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๊ฑฐ๋‚˜ ์ค„์ด๊ฒŒ ๋œ๋‹ค. ๊ทธ ํ›„, ReplicaSet๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.

  • ์œ„ example yaml์˜ resources๋ฅผ ์ฐธ๊ณ ํ•ด๋ณด๋ฉด ๊ฐ Pods๋Š” ์ตœ์†Œ 200๋ฐ€๋ฆฌ ์ฝ”์–ด๋ฅผ ์š”์ฒญํ•˜๋ฏ€๋กœ, ํ‰๊ท  CPU ์‚ฌ์šฉ๋Ÿ‰์ด 100๋ฐ€๋ฆฌ ์ฝ”์ž„์„ ์˜๋ฏธํ•œ๋‹ค.

 

โ–  HPA ์ƒ์„ฑ

์ƒ์„ฑ ํ•˜๊ธฐ์— ์•ž์„œ, apache pod, service ํ™•์ธ

kubectl get deployments.apps php-apache  
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
php-apache   1/1     1            1           8m17s

kubectl get svc php-apache 
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
php-apache   ClusterIP   172.20.120.152   <none>        80/TCP    8m30s

 

โ–  ๋ณต์ œ๋ณธ์„ 1 - 5๊ฐœ๋ฅผ ์œ ์ง€ํ•˜๋Š” HPA ์ƒ์„ฑ ๋ฐ ํ™•์ธ

kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=5

kubectl get hpa php-apache
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         5         1          35s

 

2-2. HPA์— ๋ถ€ํ•˜ ์ฆ๊ฐ€ ํ…Œ์ŠคํŠธ

๋ถ€ํ•˜๋ฅผ ์คŒ์œผ๋กœ์จ ์–ด๋–ป๊ฒŒ AutoScaling์ด ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž.

 

1. Client ์—ญํ• ์„ ํ•  Pod ์ƒ์„ฑ

  • Pod๋‚ด์˜ Container๋Š” ๋ฌดํ•œ ๋ฃจํ”„๋กœ ๋™์ž‘ํ•˜๋ฉฐ php-apache ์„œ๋น„์Šค์— ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋ƒ„.
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"
  • Client Connection์ด ์ฆ๊ฐ€ํ•˜๋ฉด์„œ ๋ถ€ํ•˜๋ฅผ ์–ผ๋งˆ๋‚˜ ์ฃผ๋Š”์ง€ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด๋ณด์ž.
kubectl get hpa php-apache --watch

์œ„ ํ™”๋ฉด์„ ๋ณด์‹œ๋‹ค ์‹ถ์ด CPU ๋กœ๋“œ๊ฐ€ ๋†’์•„์ง€๋Š” ๊ฒƒ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค. ์•„๋ž˜ ํ™”๋ฉด์€ ๋ฌดํ•œ ๋ฃจํ”„ ์ฟผ๋ฆฌ ๋ช…๋ น์„ ์‹คํ–‰ํ•œ ๊ฒƒ์ด๋‹ค.

 

2. Pod ๋ณต์ œ ์ˆ˜ ํ™•์ธ

  • CPU ์‚ฌ์šฉ๋ฅ ์„ ์ฐธ๊ณ ํ•˜์—ฌ Pod ๋ณต์ œ๋ณธ ์ˆ˜๋ฅผ ๋Š˜๋ ค ReplicaSet์— ์—…๋ฐ์ดํŠธ

deployment๊ฐ€ 1๊ฐœ -> 5๊ฐœ๋กœ ๋Š˜์–ด๋‚œ ๊ฒƒ์„ ํ™•์ธ ๊ฐ€๋Šฅ.

 

 

์š”๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Pod์— ๋Œ€ํ•œ AutoScaling ๋™์ž‘์— ๋Œ€ํ•˜์—ฌ ์•Œ์•„๋ณด์•˜๊ณ ,

๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” Node์— ๋Œ€ํ•œ AutoScaling ๋™์ž‘์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!