๐Ÿ“ˆ ํŠธ๋ž˜ํ”ฝ ํญํƒ„์ด ์™€๋„ ๋„๋–ก์—†๋‹ค – HPA ์˜คํ† ์Šค์ผ€์ผ๋ง ์‹คํ—˜

์„œ๋ฒ„ ์šด์˜์—์„œ ๊ฐ€์žฅ ๋ฌด์„œ์šด ์ˆœ๊ฐ„์€ ์˜ˆ๊ณ  ์—†์ด ํŠธ๋ž˜ํ”ฝ์ด ๋ชฐ๋ฆด ๋•Œ์ž…๋‹ˆ๋‹ค. ๋ฏธ๋ฆฌ ํŒŒ๋“œ๋ฅผ ์ž”๋œฉ ๋„์›Œ๋‘๋ฉด ํ‰์†Œ์—” ์ž์› ๋‚ญ๋น„๊ณ , ๋„ˆ๋ฌด ์ ๊ฒŒ ๋‘๋ฉด ํญํƒ„์ด ํ„ฐ์ง‘๋‹ˆ๋‹ค. HPA(Horizontal Pod Autoscaler) ๋Š” ์ด ๋ฌธ์ œ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด๊ฒฐํ•ด์ค๋‹ˆ๋‹ค. CPU ์‚ฌ์šฉ๋ฅ ์„ ๋ณด๋‹ค๊ฐ€ ์ผ์ • ์ˆ˜์น˜๋ฅผ ๋„˜์œผ๋ฉด ํŒŒ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๋Š˜๋ฆฌ๊ณ , ํŠธ๋ž˜ํ”ฝ์ด ๋น ์ง€๋ฉด ๋‹ค์‹œ ์ค„์ž…๋‹ˆ๋‹ค.


๐ŸŽฏ ์‹คํ—˜ ์‹œ๋‚˜๋ฆฌ์˜ค

  • ํ‰์ƒ์‹œ: ํŒŒ๋“œ 1๊ฐœ ์œ ์ง€ (์ž์› ์ ˆ์•ฝ)
  • ํญ์ฃผ ์‹œ: CPU ์‚ฌ์šฉ๋ฅ ์ด 50%๋ฅผ ๋„˜์œผ๋ฉด ์ตœ๋Œ€ 10๊ฐœ๊นŒ์ง€ ์ž๋™ ์ฆ๊ฐ€
  • ๊ฒ€์ฆ: ๋ถ€ํ•˜ ์ƒ์„ฑ๊ธฐ๋กœ ์„œ๋ฒ„๋ฅผ ๊ณต๊ฒฉํ•ด์„œ ํŒŒ๋“œ๊ฐ€ ๋Š˜์–ด๋‚˜๋Š” ๊ฑธ ๋ˆˆ์œผ๋กœ ํ™•์ธ

๐Ÿ› ๏ธ ๊ตฌ์„ฑ ๊ณผ์ •

Step 1: Metrics Server ์„ค์น˜

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ CPU/๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ˆ˜์ง‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. HPA๊ฐ€ ์ž‘๋™ํ•˜๋ ค๋ฉด Metrics Server๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

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

# ๋ฒ ์–ด๋ฉ”ํƒˆ ํ™˜๊ฒฝ์—์„œ ์ธ์ฆ์„œ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ํŒจ์น˜
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 top nodes

Step 2: ํ…Œ์ŠคํŠธ์šฉ ์•ฑ ๋ฐฐํฌ

๊ตฌ๊ธ€์ด HPA ํ…Œ์ŠคํŠธ์šฉ์œผ๋กœ ๋งŒ๋“  php-apache ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. requests ์„ค์ •์ด ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. HPA๋Š” requests ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉ๋ฅ ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

# php-apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  replicas: 1
  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:
          requests:
            cpu: "200m"    # ๊ธฐ์ค€์ : ์ด ๊ฐ’์˜ 50%๋ฅผ ๋„˜์œผ๋ฉด ์Šค์ผ€์ผ ์•„์›ƒ
          limits:
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: php-apache
spec:
  selector:
    run: php-apache
  ports:
  - port: 80
kubectl apply -f php-apache.yaml

Step 3: HPA ๊ทœ์น™ ์„ค์ •

kubectl autoscale deployment php-apache \
  --cpu-percent=50 \   # CPU 50% ๋„˜์œผ๋ฉด ์Šค์ผ€์ผ ์•„์›ƒ
  --min=1 \            # ์ตœ์†Œ 1๊ฐœ
  --max=10             # ์ตœ๋Œ€ 10๊ฐœ

# HPA ์ƒํƒœ ํ™•์ธ
kubectl get hpa

๐Ÿ”ฅ ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ โ€” ์„œ๋ฒ„ ๊ณต๊ฒฉ ๊ฐœ์‹œ

๋ณ„๋„ ํ„ฐ๋ฏธ๋„์—์„œ busybox ํŒŒ๋“œ๋กœ ๋ฌดํ•œ ๋ฃจํ”„ ๊ณต๊ฒฉ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

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"

์•ฝ 1๋ถ„ ํ›„ HPA๋ฅผ ๊ด€์ฐฐํ•ฉ๋‹ˆ๋‹ค.

kubectl get hpa -w    # -w ๋กœ ์‹ค์‹œ๊ฐ„ ๋ณ€ํ™” ๊ด€์ฐฐ

๐Ÿ“Š ์‹คํ—˜ ๊ฒฐ๊ณผ

์‹œ๊ฐ„ ๊ฒฝ๊ณผCPU ๋ถ€ํ•˜ (TARGETS)ํŒŒ๋“œ ๊ฐœ์ˆ˜ (REPLICAS)์ƒํƒœ
0๋ถ„ (๋Œ€๊ธฐ)0% / 50%1๊ฐœํ‰์˜จ ๐Ÿ˜Œ
1๋ถ„ (๊ณต๊ฒฉ!)200% / 50% ๐Ÿšจ1๊ฐœ โ†’ 4๊ฐœ๊ธ‰๊ฒฉํ•œ ํ™•์žฅ
3๋ถ„ (์•ˆ์ •)50% / 50%4~5๊ฐœ๋ถ„์‚ฐ ์ฒ˜๋ฆฌ ์ค‘ ๐Ÿค

๐Ÿงฎ “์™œ ํ•˜ํ•„ 4๊ฐœ๋กœ ๋Š˜์–ด๋‚ฌ์„๊นŒ?” โ€” HPA ๊ณ„์‚ฐ ๊ณต์‹

HPA๋Š” ๊ฐ์ด ์•„๋‹ˆ๋ผ ์ •ํ™•ํ•œ ๋น„๋ก€์‹์œผ๋กœ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

$$\text{๋ชฉํ‘œ ํŒŒ๋“œ ์ˆ˜} = \lceil \text{ํ˜„์žฌ ํŒŒ๋“œ ์ˆ˜} \times \frac{\text{ํ˜„์žฌ ์‚ฌ์šฉ๋Ÿ‰}}{\text{๋ชฉํ‘œ ์‚ฌ์šฉ๋Ÿ‰}} \rceil$$

์‹ค์ œ ๊ฐ’์„ ๋Œ€์ž…ํ•˜๋ฉด:

1๊ฐœ ร— (200% / 50%) = 4๊ฐœ

ํŒŒ๋“œ 1๊ฐœ๊ฐ€ ๋ชฉํ‘œ์น˜์˜ 4๋ฐฐ๋กœ ํž˜๋“œ๋‹ˆ๊นŒ, ์‚ฌ๋žŒ(ํŒŒ๋“œ)๋„ 4๋ฐฐ ๋ฝ‘๋Š”๋‹ค๋Š” ๊ณ„์‚ฐ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ •ํ™•ํžˆ 4๊ฐœ๊ฐ€ ์ƒ์„ฑ๋์Šต๋‹ˆ๋‹ค.


๐Ÿ“ ๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด์— ์ ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•  ์ 

ํด๋ผ์šฐ๋“œ์™€ ๋‹ฌ๋ฆฌ ๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด๋Š” ์ž์›์ด ์•„์ฃผ ์ ์Šต๋‹ˆ๋‹ค. HPA๊ฐ€ ๋„ˆ๋ฌด ๊ณต๊ฒฉ์ ์œผ๋กœ ๋Š˜๋ฆฌ๋ฉด ์˜คํžˆ๋ ค ๋…ธ๋“œ๊ฐ€ OOM(Out Of Memory)์œผ๋กœ ์ฃฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด์šฉ ๋ณด์ˆ˜์ ์ธ HPA ์„ค์ •
kubectl autoscale deployment myapp \
  --cpu-percent=70 \   # ์ž„๊ณ„๊ฐ’์„ ๋†’์—ฌ์„œ ๋œ ๋ฏผ๊ฐํ•˜๊ฒŒ
  --min=1 \
  --max=3              # ์ตœ๋Œ€๋ฅผ 3๊ฐœ๋กœ ์ œํ•œ

์•ˆ์ •์„ฑ์ด ํ™•์žฅ์„ฑ๋ณด๋‹ค ์šฐ์„ ์ธ ํ™˜๊ฒฝ์—์„  Fixed Replicas ๋ฐฉ์‹์„ ์“ฐ๋Š” ๊ฒŒ ๋‚˜์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.


โœ… ์ •๋ฆฌ

HPA๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ ์ž๊ธฐ ์น˜์œ (Self-healing) + ์ž๋™ ํ™•์žฅ(Auto-scaling) ์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ์ด 24์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์ง€ ์•Š์•„๋„ ์‹œ์Šคํ…œ์ด ์Šค์Šค๋กœ ํŠธ๋ž˜ํ”ฝ์— ๋Œ€์‘ํ•ฉ๋‹ˆ๋‹ค.

K8s ์‹ค์Šต ์‹œ๋ฆฌ์ฆˆ๋Š” ์—ฌ๊ธฐ๊นŒ์ง€์ž…๋‹ˆ๋‹ค. kubeadm์œผ๋กœ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ง์ ‘ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ๋ถ€ํ„ฐ, Pod, Deployment, Service, Ingress, StatefulSet, RBAC, HPA๊นŒ์ง€ โ€” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋ฅผ ์‹ค์ „์—์„œ ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฐ˜์„ ๋‹ค์กŒ์Šต๋‹ˆ๋‹ค.