μ΄μν : Autoscaler λ° metric μμ§ κ΅¬ν
λ°μ¬μΌ : Loadbalancer (with health check) ꡬν
κΉλλ¦Ό : Grafana μκ°ν λ° λ°±μλ μλ² κ΅¬ν
λ³Έ νλ‘μ νΈλ μ΅μνμ μμμΌλ‘ μμ μ μΈ μλΉμ€ μ 곡μ μν΄, νΈλν½ λΆμ°μ λ΄λΉνλ λ‘λλ°Έλ°μμ κ°λ° λ° μλ² μμ μλ νμ₯μ μν μ€ν μ€μΌμΌλ§ κΈ°λ₯μ ν΅ν©μ μΌλ‘ ꡬννκ³ μ΄λ₯Ό μκ°ννλ κ²μ λͺ©νλ‘ ν©λλ€. λ‘λλ°Έλ°μλ ν¬μ€ μ²΄ν¬ κΈ°λ₯μ ν΅ν΄ λ°±μλ μλ²μ μνλ₯Ό μ£ΌκΈ°μ μΌλ‘ νμΈνκ³ , μλ΅μ΄ μκ±°λ λΉμ μμ μΈ μλ²λ₯Ό μλμΌλ‘ νΈλν½ λΆμ° λμμμ μ μΈν¨μΌλ‘μ¨ μμ μ±μ ν보ν©λλ€. λν, λ¨μ λΌμ΄λλ‘λΉ λ°©μμ λν΄ μλ² λΆν μ 보λ₯Ό λ°μν λΆμ° μκ³ λ¦¬μ¦μ λμ νμ¬, μμ² μ²λ¦¬ ν¨μ¨μ λμ λλ€. μ€ν μ€μΌμΌλ¬ λͺ¨λμ νλ‘λ©ν μ°μ€λ‘λΆν° μ¬μ μ€μ λ κΈ°κ°λ§λ€ μμ§λ 컨ν μ΄λλ³ CPU μ¬μ©λ₯ μ κΈ°λ°μΌλ‘, docker-compose.yml νμΌμ μ€μ λ μκ³μΉ μ΄μμ μ¬μ©λ₯ μ΄ 3λΆ μ΄μ μ§μλλ©΄ scale-out νκ³ μκ³μΉμ μ λ° λ―Έλ§μ μ¬μ©λ₯ μ΄ 1λΆ μ΄μ μ§μλλ©΄ scale-in ν©λλ€. μ΄ λͺ¨λμ μ¬μ©νμ¬ λ³λμ μλμ μΈ κ°μ μμ΄ μμ€ν μ νΈλν½/λΆν λ³νμ λ°λΌ μλμΌλ‘ 컨ν μ΄λμ μλ₯Ό μ‘°μ νμ¬ λΉμ© ν¨μ¨μ μΈ μ΄μμ κ°λ₯νκ² ν©λλ€. λν νλ‘λ©ν μ°μ€λ₯Ό ν΅ν΄ μμ§ν λ©νΈλ¦λ€μ Grafanaλ₯Ό νμ©ν΄ νλ‘ νΈμλλ‘ νκΈ°ν©λλ€. νλ‘ νΈμλμ°½μμλ CPU μ¬μ©λ λ° νμ¬ μλ²μ μ λ±μ μκ°μ μΌλ‘ νμΈ κ°λ₯νκ³ , μΈν°νμ΄μ€μ λ²νΌμ μ΄μ©ν΄ μμ½κ² λΆνλ₯Ό κ°ν μ μμ΅λλ€.
ν¨μ¨μ μΈ λ¦¬μμ€ μ¬μ©
κ³ μ λ μλ² κ°μλ‘ νμ μ΅λ νΈλν½μ κ°λΉνλλ‘ κ΅¬μ±νλ©΄, νΈλν½μ΄ μ μ λμλ λΆνμνκ² μμμ΄ λλΉλ©λλ€.
μ€ν μ€μΌμΌλ§ κΈ°λ₯μ ν΅ν΄ νΈλν½ λ³νμ λ°λΌ λμ μΌλ‘ μΈμ€ν΄μ€ μλ₯Ό μ‘°μ ν¨μΌλ‘μ¨, μ΅μνμ μμμΌλ‘ μμ μ μΈ μλΉμ€ μ κ³΅μ΄ κ°λ₯ν©λλ€.
μμ μ μΈ νΈλν½ λΆμ°
λ¨μ Round-Robin λ°©μμ μλ²μ μ€μκ° λΆν μνλ₯Ό κ³ λ €νμ§ μκΈ° λλ¬Έμ, νΉμ μλ²μ κ³ΌλΆνκ° μ§μ€λ μ μμ΅λλ€. μ΄μ latency λͺ¨λλ₯Ό μΆκ°νμ¬ μ±λ₯μ΄ μ°μν μλ²κ° λ λ§μ λΆνλ₯Ό κ°λΉνλλ‘ μ€κ³λμμ΅λλ€.
λν, ν¬μ€μ²΄ν¬κ° ꡬνλ λ‘λλ°Έλ°μλ₯Ό μ¬μ©νλ©΄, μλ΅ μ§μ° λλ μ₯μ κ° λ°μν μλ²λ₯Ό μλμΌλ‘ ννΌνμ¬ νΈλν½μ λΆμ°μν¬ μ μμ΄ κ°μ©μ±μ λμ
λλ€.
μ΄μ νΈμμ± λ° κ°μμ± ν보
Prometheusμ Grafanaλ₯Ό ν΅ν λͺ¨λν°λ§ λ° μκ°ν μμ€ν
μ κ°μΆλ©΄, μ΄μμλ νμ¬ μλ² μνλ₯Ό μ€μκ°μΌλ‘ νμ
νκ³ , μ₯μ λ κ³ΌλΆν λ°μ μ μ¦μ λμν μ μμ΅λλ€. λν νμ΅μ μν΄ λΆν λ²νΌμ ν΅ν΄μ μμ½κ² λ‘λλ°Έλ°μμ μ€ν μ€μΌμΌλ§ κ³Όμ μ μκ°μ μΌλ‘ νμΈ κ°λ₯ν©λλ€.
Docker / Docker Compose
κ° μ»΄ν¬λνΈ(λ°±μλ, λ‘λλ°Έλ°μ, μ€ν μ€μΌμΌλ¬, Prometheus, Grafana)λ₯Ό 컨ν
μ΄λννμ¬ λΆλ¦¬λ νκ²½μμ λ
립μ μΌλ‘ μ€νν©λλ€.
docker-compose.ymlμ ν΅ν΄ μ 체 μ€νμ νλ²μ κΈ°λ/μ’
λ£ν μ μλλ‘ κ΅¬μ±νμ΅λλ€.
Prometheus
μ€νμμ€ μκ³μ΄ λ°μ΄ν°λ² μ΄μ€ λ° λͺ¨λν°λ§ μμ€ν
μ
λλ€.
HTTP κΈ°λ°μ νΈμ(Push) λ°©μμ΄ μλ, ꡬμ±λ λμ(Target)μΌλ‘λΆν° λ©νΈλ¦μ ν΄λ§(Pull)νμ¬ μμ§ν©λλ€.
μ€ν μ€μΌμΌλ¬μ λ°±μλ μλ²μμ μ 곡νλ λ©νΈλ¦ μλν¬μΈνΈ(/metrics)λ₯Ό μ€ν¬λ μ΄ννμ¬ CPU μ¬μ©λ₯ , λ©λͺ¨λ¦¬ μ¬μ©λ, μλ΅ μ§μ° μκ° λ±μ μμ§ν©λλ€.
Grafana
Prometheusμ μ μ₯λ λ©νΈλ¦μ μκ°ννλ λμ보λ λꡬμ
λλ€.
λ€μν κ·Έλν, μ°¨νΈ, μλ μ€μ μ ν΅ν΄ μ΄μμκ° μ€μκ°μΌλ‘ μμ€ν
μνλ₯Ό λͺ¨λν°λ§νκ³ , μ΄μ μ§νλ₯Ό κ°μ§ν μ μλλ‘ μ§μν©λλ€.
Python 3.x
νλ‘μ νΈμ λλΆλΆμ λͺ¨λλ€μ΄ λͺ¨λ Python μΈμ΄λ‘ ꡬνλμμ΅λλ€.
requests λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©ν΄ Prometheus HTTP APIμμ λ©νΈλ¦μ μ‘°ννκ³ , Docker SDK (docker ν¨ν€μ§)λ₯Ό ν΅ν΄ 컨ν
μ΄λ μ μ΄(μμ±, μμ , μν μ‘°ν) κΈ°λ₯μ μ 곡ν©λλ€.
HTTP μλ² νλ μμν¬ (Flask)
λ‘λλ°Έλ°μμ ν¬μ€μ²΄ν¬ μλν¬μΈνΈ λ° μμ² λΆλ°°μ© HTTP μλ²(loadbalancer/server.py)λ Python κΈ°λ° νλ μμν¬λ₯Ό μ¬μ©ν©λλ€.
ν¬μ€μ²΄ν¬λ₯Ό μν κ°λ¨ν GET μμ² νΈλ€λ¬μ, ν΄λΌμ΄μΈνΈ μμ²μ λ°±μλλ‘ μ λ¬νλ Reverse Proxy μν μ μνν©λλ€.
λ‘컬 λ€νΈμν¬ λ° λ¦¬λ μ€ νκ²½
μ 체 μ€νμ 리λ
μ€(νΉμ WSL2) κΈ°λ°μμ Dockerλ‘ μ€νλ©λλ€.
λ‘λλ°Έλ°μκ° λ°±μλ 컨ν
μ΄λλ€μ IPμ ν¬νΈλ₯Ό λμ μΌλ‘ κ°μ§νμ¬ νΈλν½μ λΆμ°μν€κΈ° λλ¬Έμ, λ€νΈμν¬ μ€μ μ λν κΈ°λ³Έ μ΄ν΄κ° νμν©λλ€.
PNU_cloud_computing/
βββ backend/
β βββ Dockerfile
β βββ src/
β βββ server.py
β βββrequirements.txt
β
βββ autoscaler/
β βββ __init__.py
β βββ autoscaler.py
β βββ metrics.py
β βββ Dockerfile
β
βββ load_balancer/
β βββ __init__.py
β βββ health_check.py
β βββ balancer.py
β βββ server.py
β βββ Dockerfile
β βββ requirements.txt
β
βββ prometheus/
β βββ targets/
β β βββ flask.json
β βββ prometheus.yml
β
βββ grafana/
β βββ plugins/
β βββ grafana.db
βββ .grafana.ini
β
βββ fe/
β βββ ...
β
βββ docker-compose.ymlbackend/
μ€μ μλΉμ€ λ‘μ§μ μ€ννλ λ°±μλ μ ν리μΌμ΄μ
μμ€ μ½λκ° μμΉν©λλ€.
νμ¬ νλ‘μ νΈμμλ λ¨μν λ°±μλμ κΈ°λ³Έμ μΈ κΈ°λ₯λ§νλλ‘ μμ±λμμ΅λλ€.
autoscaler/
autoscaler.py: μ£ΌκΈ°μ μΌλ‘ Docker 컨ν
μ΄λμ CPU μ¬μ©λ₯ λ±μ μ€μκ°μΌλ‘ μ‘°νν λ€, νμ₯/μΆμ λ‘μ§μ λ°λΌ μλ‘μ΄ μ»¨ν
μ΄λλ₯Ό μμ±νκ±°λ, μ κ±°ν©λλ€.
metrics.py: Prometheusλ‘λΆν° λ©νΈλ¦μ μ‘°ννλ PrometheusClient ν΄λμ€μ, Docker 컨ν
μ΄λλ₯Ό μ μ΄νλ DockerManager ν΄λμ€λ₯Ό ν¬ν¨ν©λλ€.
- Scale-Out: μ§μ λ CPU μκ³μΉ(μ: 70%)λ₯Ό μΌμ μκ°(μ: 3λΆ) μ΄κ³Όνλ©΄ μΈμ€ν΄μ€λ₯Ό μΆκ°
- Scale-In: CPU μκ³μΉμ μ λ°(μ: 35%) μ΄νλ‘ μΌμ μκ°(μ: 1λΆ) μ°μ μ μ§λλ©΄ μΈμ€ν΄μ€λ₯Ό μ κ±°
μ΅μ/μ΅λ μΈμ€ν΄μ€ κ°μλ₯Ό μ€μ νμ¬, 무ν νμ₯μ λ°©μ§ν©λλ€.
loadbalancer/
health_check.py: κ° λ°±μλ λ
Έλ(컨ν
μ΄λ)μ ν¬μ€μ²΄ν¬λ₯Ό μννλ λ‘μ§μ μ μν©λλ€. μ£ΌκΈ°μ μΌλ‘ HTTP μμ²μ 보λ΄κ³ , μλ΅ μ½λλ₯Ό κΈ°λ°μΌλ‘ μ μ/λΉμ μ μνλ₯Ό νμ ν©λλ€.
balancer.py: λΌμ΄λλ‘λΉ λ°©μκ³Ό νμ¬ κ° μλ²μ λΆν(μ: CPU μ¬μ©λ₯ λλ μλ΅ μκ°)λ₯Ό κ³ λ €ν κ°μ€μΉ κΈ°λ° λΆμ° μκ³ λ¦¬μ¦μ λͺ¨λ μ§μν©λλ€.
server.py: ν΄λΌμ΄μΈνΈλ‘λΆν° λ€μ΄μ€λ μμ²μ λ°μ, balancer.pyμμ μ νλ λ°±μλ λ
Έλλ‘ μμ²μ μ λ¬(νλ‘μ)νλ λΌμ°ν
μν μ μνν©λλ€λ€. λμμ, /health μλν¬μΈνΈλ₯Ό μ 곡νμ¬ μΈλΆμμ λ‘λλ°Έλ°μ μ체 μνλ₯Ό 체ν¬ν μ μμ΅λλ€.
prometheus/
targets/flask.json: μ€μΌμΌλ§λ λ°±μλ νμ κ΄λ¦¬νλ νμΌμ
λλ€.
prometheus.yml: Prometheusκ° λ©νΈλ¦μ μμ§ν λμ(autoscaler, backend, loadbalancer λ±)μ μ μνλ μ€μ νμΌμ
λλ€.
grafana/
Grafana dashboard μΆλ ₯μ μν κΈ°λ³Έ μ€μ νμΌλ€μ
λλ€.
fe/
localhost:3000μΌλ‘ μ μμ ννλλ νλ‘ νΈμλ νλ©΄μ ꡬμ±νλ νμΌλ€μ
λλ€.
docker-compose.yml
Prometheus, Grafana, Loadbalancer, Backend, Autoscalerλ₯Ό νλμ λ€νΈμν¬λ‘ λ¬Άμ΄ λμμ κΈ°λν μ μλλ‘ μ μλ Compose νμΌμ
λλ€.
μλΉμ€λ³λ‘ νμν νκ²½ λ³μ, λ³Όλ₯¨, ν¬νΈ λ§€ν λ±μ λͺ¨λ κΈ°μ ν΄ λμ΄, λ‘컬 νΉμ ν΄λΌμ°λ VMμμ λ¨λ²μ μ 체 μ€νμ μ€νν μ μλλ‘ ν©λλ€.
Docker Engine β₯ 20.x
Docker Compose β₯ 1.29.x
$ git clone https://github.com/JAEIL1999/PNU_cloud_computing.git
$ cd PNU_cloud_computing# 1) Docker Composeλ‘ μ 체 μ€ν κΈ°λ
$ docker-compose up -d
# (μ ν) λͺ¨λ 컨ν
μ΄λκ° μ μ μνμΈμ§ νμΈ
$ docker ps
# 2) μ€μκ° CPU μ¬μ©λ νμΈ
$ docker-compose logs -f autoscalerμ λ΄μ©λ€μ΄ νμΈ λμλ€λ©΄ μλ μ£Όμλ₯Ό ν΅ν΄μ λ©νΈλ¦ μμ§ λ΄μ©λ€μ μκ°μ μΌλ‘ νμΈ κ°λ₯ν©λλ€. λν ν°λ―Έλμ λ‘κ·Έλ₯Ό ν΅ν΄μλ μ€μκ°μΌλ‘ CPU μ¬μ©λμ νμΈ κ°λ₯ν©λλ€.
http://localhost:3000νμ΅μ© λ°λͺ¨ νκ²½
μ€ν μ€μΌμΌλ§κ³Ό λ‘λλ°Έλ°μ±μ κΈ°λ³Έ κ°λ
μ μ΄ν΄νκ³ μ€μ΅νκΈ° μν νμ΅μ© νκ²½μΌλ‘ νμ©ν μ μμ΅λλ€.
Prometheusμ Grafanaλ₯Ό ν¨κ» ꡬμ±ν¨μΌλ‘μ¨, λͺ¨λν°λ§ λμ보λλ₯Ό ꡬμ±νλ κ³Όμ μ μ§μ μ€μ΅ν΄ λ³Ό μ μμ΅λλ€.
μκ·λͺ¨ μΉ μλΉμ€ νΈμ€ν
VPS(κ°μ μ¬μ€ μλ²)λ μ¨νλ λ―Έμ€ νκ²½μμλ Dockerλ₯Ό μ§μνλ€λ©΄, ν΄λΉ μ루μ
μ κ·Έλλ‘ λ°°ν¬νμ¬ μκ·λͺ¨ μΉ μ ν리μΌμ΄μ
μ μμ μ μΌλ‘ μ΄μν μ μμ΅λλ€.
νΈλν½ ν¨ν΄μ΄ μ λμ μΈ μλΉμ€(μ: κ°μΈ λΈλ‘κ·Έ, ν¬νΈν΄λ¦¬μ€ μ¬μ΄νΈ)μμ 리μμ€λ₯Ό ν¨κ³Όμ μΌλ‘ κ΄λ¦¬ν μ μμ΅λλ€.
컀μ€ν νμ₯ κΈ°λ₯ κ°λ°
νλ‘μ νΈμ ν΅μ¬ λ‘μ§(μ: μ€ν μ€μΌμΌλ¬ μ€μΌμ€λ§ μκ³ λ¦¬μ¦, ν¬μ€μ²΄ν¬ κΈ°μ€)μ μμ λ‘κ² μμ νμ¬, νΉμ μλΉμ€ μꡬμ¬νμ λ§λ νΉνλ νμ₯ μ μ±
μ μ€νν μ μμ΅λλ€.
μλ₯Ό λ€μ΄, CPU μΈμλ λ©λͺ¨λ¦¬ μ¬μ©λ, λ€νΈμν¬ λμν, μμ² μ²λ¦¬ λκΈ° μκ° λ±μ κΈ°μ€μΌλ‘ νμ₯ μ μ±
μ λ€μ€ μ§ν(Multi-criteria) κΈ°λ°μΌλ‘ νμ₯νλλ‘ κΈ°λ₯μ μΆκ°ν μ μμ΅λλ€.
