Cloud Design 1st tobby - 100-hours-a-week/KTB4-1st-wiki GitHub Wiki
๋ฌธ์ ์ ์: ์คํํธ์ ์๋น์ค๋ฅผ ์ ๋ ดํ๊ณ ๋น ๋ฅด๊ฒ ๋ฐฐํฌํด์ผ ํ๋ค.
- ํ์ฌ ๊ฐ๋ฐ ์ธ๋ ฅ 6๋ช
- 4๋ช ์ ๊ธฐ๋ฅ ๊ฐ๋ฐ ๋ด๋น
- 2๋ช ์ ์ธํ๋ผ ๋ด๋น
- ์คํํธ์ ์ด๋ฏ๋ก ๋น์ฉ๊ณผ ์๊ฐ์ด ๋ถ์กฑํ๋ฉฐ, ๋น์ฉ์ด ์ ๋์ ์ผ๋ก ๋ถ์กฑํจ
ํ์ฌ ์๋น์ค๋ฅผ ๋ฐฐํฌํ๊ธฐ ์ํด
- ์ ์ ๋น์ฉ
- ๋น ๋ฅด๊ฒ ๋ฐฐํฌ(์ ์ ๋ณต์ก์ฑ)
์์ผ๋ก ๊ธฐ์ค์ ์ธ์ ๋ค.
1์ฐจ ๋ฐฐํฌ์์๋ ์ฅ์ ๋ก ์ธํด ์๋น์ค ์ ๊ณต์ด ์ ์ ์ค๋จ๋์ด๋ ๊ด์ฐฎ๋ค๊ณ ํ๋จํ๋ค.
์ฐ๋ฆฌ ์๋น์ค๋ ์ด๊ธฐ์ ๋ถํธ์บ ํ ๋ด๋ถ์์๋ง ํ์์ ์ผ๋ก ๋ฐฐํฌ๋๋ฏ๋ก ์๋น์ค๊ฐ ์ค๋จ๋๋๋ผ๋ ํฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
| v1 | |
|---|---|
| ํ๊ฒ ์ ์ | ์นดํ ๋ถ ๊ต์ก์ (20๋ ์ค๋ฐ-30๋ ์ด๋ฐ) |
| SOM(๋ชฉํ ์์ฅ) | 120๋ช |
| MAU | 30๋ช |
| DAU | 30๋ช |
| ์ธ์ ์์ฒญ์ | 21.23 |
| ์ธ์ ์ | 30 (DAU์ ๋์ผ) |
| ํ๋ฃจ ์ด ์์ฒญ ์ | 636.9 |
| ํธ๋ํฝ ์ง์ค ์๊ฐ | 140๋ถ = 8,400์ด |
| ํ๊ท RPS | 0.076 |
| ํธ๋ํฝ/์์ ์ฌ์ฉ๋ ํฐ ๊ธฐ๋ฅ | ์ด๋ฏธ์ง ์ ๋ก๋, ๋ฌผํ ๋ฑ๋ก ๊ฒ์ฆ ์ AI API ํธ์ถ |
ํธ๋ํฝ ์ง์ค ์๊ฐ: ํ์ผ ์ฌ๋ ์๊ฐ(9:00โ18:00 ์ค ๋งค์ 50๋ถโ์ ๊ฐ, 9ํร10๋ถ=90๋ถ) + ์ ์ฌ์๊ฐ(12:00โ13:00, 60๋ถ) = 140๋ถ = 8,400์ด
v1์ ์ฌ์ฉ์ ์๊ฐ ์ ๊ณ ์ฌ์ฉ ์๊ฐ๋๊ฐ ๊ณ ์ ๋์ด ์์ด ํผํฌ RPS๋ณด๋ค ํ๊ท RPS๊ฐ ๋ ์ ์๋ฏธํ๋ค. ํ๊ท RPS = ํ๋ฃจ ์ด ์์ฒญ ์ รท ํธ๋ํฝ ์ง์ค ์๊ฐ(์ด)
| ๋ฒํธ | User Flow | ์์ฒญ | ์์ฒญ ์ |
|---|---|---|---|
| 1 | ๋์ค์ฝ๋ ์ง์ โ ์นด์นด์ค ๋ก๊ทธ์ธ โ ์ทจํฅ ์ค์ โ ๊ทธ๋ฃน ํ์ โ ๊ทธ๋ฃน ๊ฐ์ | ์นด์นด์ค ๋ก๊ทธ์ธ ๋ฆฌ๋ค์ด๋ ํธ 1, ์ธ์ฆ ์ฝ๋ฐฑ 1, ๊ฑฐ๋ ์ทจํฅ ์ค์ 1, ๊ทธ๋ฃน ํ์ 1, ๊ทธ๋ฃน ์ฐธ๊ฐ 1 | 5 |
| 2 | ๋ฌผ๊ฑด ๋ฑ๋ก | ์ด๋ฏธ์ง ์ ๋ก๋ 1, ๋ฑ๋ก ์ ์ฅ 1 | 2 |
| 3 | ๊ทธ๋ฃน ๋ด ๋ฌผ๊ฑด ํ์ โ ์์ธ ํ์ธ | ํ ๋ชฉ๋ก ์กฐํ 1, ๋ฌผ๊ฑด ์์ธ ์กฐํ 5 | 6 |
| 4 | ๊ตํ ์์ฒญ โ ์ฑํ ์กฐ์จ โ ์ง๊ฑฐ๋ | ๋ด ๋ฌผ๊ฑด ์ ํ ์กฐํ 1, ๊ตํ์์ฒญ ์์ฑ 1, ์ฑํ ๋ฐฉ ์์ฑ 1, ํ์คํ ๋ฆฌ ์กฐํ 1, ๋ฉ์์ง ์๋ณต 7 | 11 |
| 5 | ๊ตํ ์๋ฃ ์ฒ๋ฆฌ | ์๋ฃ ์ฒ๋ฆฌ 1, ์์ธ ์ฌ์กฐํ 1 | 2 |
| ํฉ๊ณ | 26 |
| ๋ฒํธ | User Flow | ์์ฒญ ์ | ํ๋ฅ | ๊ฐ์ค ์์ฒญ ์ |
|---|---|---|---|---|
| 1 | ์นด์นด์ค ๋ก๊ทธ์ธ โ ๋ชฉ๋ก ํ์ | 3 | 100% | 3.0 |
| 2 | ๋ฌผ๊ฑด ๋ฑ๋ก | 2 | 10% | 0.2 |
| 3 | ๋ฌผ๊ฑด ์์ธ ํ์ธ | 6 | 50% | 3.0 |
| 4 | ๊ตํ ์์ฒญ โ ์ฑํ ์กฐ์จ โ ์ง๊ฑฐ๋ | 11 | 30% | 3.3 |
| 5 | ๊ตํ ์๋ฃ ์ฒ๋ฆฌ | 2 | 30% | 0.6 |
| ํฉ๊ณ | 10.1 |
์ธ์ ํ๊ท ์์ฒญ์
| ๊ตฌ๋ถ | ๋น์จ | ์์ฒญ ์ |
|---|---|---|
| ์ ๊ท | 70% | 26 |
| ์ฌ๋ฐฉ๋ฌธ | 30% | 10.1 |
| ๊ฐ์ค ํ๊ท | 100% | 21.23 |
ํ๋ฃจ ์ด ์์ฒญ ์ = ์ธ์
์ ร ์ธ์
ํ๊ท ์์ฒญ ์ = 30 ร 21.23 = 636.9
ํ๊ท RPS = 636.9 รท 8,400 โ 0.076
- ์ฌ์ฉ์ ๊ท๋ชจ(DAU 30๋ช ): ์๊ท๋ชจ ์ด๊ธฐ ์๋น์ค์์ 30๋ช ์ ์์ด ํน์ ์๊ฐ์ ์ผ์ ํ ์ธ์ ์์ฒญ์ ์์๋ถ๋ ๊ทน๋จ์ ์ธ ํผํฌ ์ํฉ์ ๋นํ์ค์
- ๋ช ํํ ํ๋ ์๊ฐ๋: 24์๊ฐ ์์ ์ ์ ์๋น์ค๊ฐ ์๋๋ฏ๋ก, ์ค์ ์์ฒญ์ด ๋ฐ์ํ๋ ์ฃผ์ ํ๋ ์๊ฐ๋(์ฌ๋ ์๊ฐ + ์ ์ฌ์๊ฐ = 140๋ถ / 8,400์ด)๋ฅผ ๊ธฐ์ค์ผ๋ก ์ฐ์ ํด์ผ ํ์ค์ ์ธ ์ด๋น ๋ถํ๋ฅผ ํ์ ํ ์ ์์
- ๊ฒฐ๋ก : v1 ์ธํ๋ผ ์ฌ์ด์ง์ ํ์ค์ ์ธ ๊ธฐ์ค์ ๋นํ์ค์ ์ธ ์๊ฐ ํผํฌ๊ฐ ์๋, ์ง์ค ์๊ฐ๋ ํ๊ท RPS
1์ฐจ ๋ฐฐํฌ์ ๋ชฉํ: ์ ์ ๋น์ฉ๊ณผ ๋น ๋ฅธ ๋ฐฐํฌ์ฐ๋ฆฌ ์๋น์ค๋ ํด๋ผ์ฐ๋ ์๋น์ค๋ฅผ ์ฌ์ฉํด 1์ฐจ ๋ฐฐํฌํ๋ค.
- ๋ฐฐํฌ๋ ํฌ๊ฒ ์จ ํ๋ ๋ฏธ์ค์ ํด๋ผ์ฐ๋ ์๋น์ค๋ก ๋๋๋ค.
- ์จ ํ๋ ๋ฏธ์ค๋ ์ด๊ธฐ ํฌ์ ๋น์ฉ์ด ๋์ผ๋ฏ๋ก([N100 ๋ฏธ๋ PC 22๋ง์]((https://prod.danawa.com/info/?pcode=35770394&keyword=n100), ๊ณต์ ๊ธฐ 4.5๋ง์ , UPS 18๋ง์๋ฅผ ํฉ์ณ 44.5๋ง์) ํ์ฌ ์ํฉ์ ์ ํฉํ์ง ์์๋ค.
- ํด๋ผ์ฐ๋๋ ์จ ํ๋ ๋ฏธ์ค ๋๋น ์ ์ ๋น์ฉ(AWS EC2 t3.medium ๊ธฐ์ค ํ ๋ฌ ์ฝ 38๋ฌ๋ฌ)์ผ๋ก ์๋น์ค๋ฅผ ๋ฐฐํฌํ ์ ์์ด์ ์ด๊ธฐ ๋น์ฉ์ ์ค์ฌ์ผ ํ๋ ์ง๊ธ ์ํฉ์ ์ ๋ง์๋ค.
- ๋ฐ๋ผ์ 1์ฐจ ๋ฐฐํฌ๋ ํด๋ผ์ฐ๋ ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ค.
๋จ์ผ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ ๋, CSP ๊ฐ ๋น์ฉ ์ฐจ์ด๊ฐ ํฌ์ง ์์ผ๋ฏ๋ก ๋น ๋ฅธ ๋ฐฐํฌ๋ฅผ ์ํด ํ์์ ๊ฒฝํ์ด ์๋ AWS๋ฅผ ์ฌ์ฉํด ๋ฐฐํฌํ๋ค.
- ์ฐ๋ฆฌ ์๋น์ค๋ DAU๊ฐ 30๋ช ์ด๋ฏ๋ก ํ๋์ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ค. ๊ทธ๋ฐ๋ฐ ํ๋์ ์ธ์คํด์ค๋ง์ ์ฌ์ฉํ ๋์ CSP ๊ฐ์ ๋น์ฉ ์ฐจ์ด๊ฐ ์ ์๋ค.(ํ๋จ ๋น์ฉ ํ ์ฐธ์กฐ) ๋ฐ๋ผ์ '์ ์ ๋น์ฉ'์ด๋ผ๋ ๊ธฐ์ค์์๋ CSP๋ฅผ ๊ณ ๋ฅผ ์ ์๋ค๊ณ ํ๋จํ๋ค.
- '๋น ๋ฅธ ๋ฐฐํฌ' ๊ธฐ์ค์์๋ ์ ์ ์จ์ด ๋์ ๋ ํผ๋ฐ์ค๊ฐ ๋ง๊ณ ํ์ ๋ชจ๋์ ์ฌ์ฉ ๊ฒฝํ์ด ์๋ AWS๊ฐ ์ฐ์ํ๋ค๊ณ ํ๋จํ๋ค.
- ๋ฐ๋ผ์ CSP๋ก AWS๋ฅผ ์ ํํ๋ค.
- ๋์: ๋ํ CSP 3์ฌ(AWS, Azure, GCP)
- ๊ธฐ์ค ์กฐ๊ฑด: Ubuntu, ์จ๋๋งจ๋(Pay-As-You-Go), ํ ๋ฌ 730์๊ฐ ๊ฐ๋, ์์ ์ปดํจํ ์ธ์คํด์ค ๋น์ฉ๋ง ๊ณ ๋ ค
| ํด๋ผ์ฐ๋ (CSP) | ์ธ์คํด์ค ์ ํ | CPU / RAM ์ฌ์ | ์๊ฐ๋น ์๊ธ (USD) | ํ ๋ฌ ์๊ธ (USD) | ํน์ง ๋ฐ CPU ๋ฐฉ์ |
|---|---|---|---|---|---|
| AWS | t3.medium |
2 vCPU / 4 GiB | $0.052 | $37.96 | โข ๋ฒ์คํฐ๋ธ(Burstable) ์ธ์คํด์ค โข ๊ธฐ๋ณธ ์ฑ๋ฅ ๊ธฐ์ค ์ด๊ณผ ์ ํฌ๋ ๋ง ์๋ชจ |
| Azure | B2als v2 |
2 vCPU / 4 GiB | $0.052 | $37.96 | โข ํฌ๋ ๋ง ๊ธฐ๋ฐ ๋ฒ์คํธ ์ง์ โข AMD๊ฐ ๋ ์ ๋ ด(์ธํ ์ t3.medium๊ณผ ๋์ผ) |
| GCP | e2-medium |
2 vCPU / 4 GB | $0.04298286 | $31.38 | โข E2 ๊ณต์ ์ฝ์ด ๋ฐฉ์ โข ๊ธฐ๋ณธ ๋ถํ๊ฐ ์ ์ ์น/API ์๋ฒ์ ์ต์ ํ โข ์์ ์ก์ ๊ฐ์ ํ์ง ์์๋ ์๋์ผ๋ก ์ฌ์ฉ ๊ธฐ๊ฐ์ ๋ํด ํ ์ธ ์ ์ฉ |
๋ฒ์คํฐ๋ธ ํด๋์ค์ ํฌ๋ ๋ง ๊ฐ๋
- t3.medium, Standard_B2s๋ ํฌ๋ ๋ง ๊ธฐ๋ฐ์ด๋ผ ํฌ๋ ๋ง์ด ์์ผ๋ฉด baseline ์ฑ๋ฅ์ผ๋ก ๋์๊ฐ๊ฑฐ๋ ํฌ๋ ๋ง์ ์ฌ์ผ ํ๋ค.(aws t3 unlimited์ ๊ฒฝ์ฐ)
- e2-medium์ ๊ณต์ ์ฝ์ด ๋ฐฉ์์ด๋ผ ๋ฌผ๋ฆฌ ์๋ฒ์ ์ฌ์ ๊ฐ ์๋ ํ, ๊ณ์ํด์ ๋ฒ์คํธํ ์ ์๋ค.
- ์ฐ๋ฆฌ ์๋น์ค๋ ํน์ ์๊ฐ๋์ ์ฌ์ฉ๋๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋ฏ๋ก ํฌ๋ ๋ง์ ์ค์ํ ์์๊ฐ ์๋๋ผ๊ณ ํ๋จํ๋ค.
์ด๊ธฐ ๋ฐฐํฌ์์๋ ๋จ์ผ EC2 ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ๊ฒฝ์ ์ ์ด๊ณ ๋จ์ํ๋ค.
- ์ฐ๋ฆฌ ์๋น์ค๋ ์ ์ ์์ ์ฌ์ฉ์๊ฐ ์ฌ์ฉ(ํ๊ท RPS 0.076)ํ๋ฏ๋ก ์ ์ ๋น์ฉ์ผ๋ก ๋ฐฐํฌํด์ผ ํ๊ณ , ๋น ๋ฅด๊ฒ ๋ฐฐํฌํด์ผ ํ๋ฏ๋ก ํ๋์ ์ธ์คํด์ค์ ๋ชจ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌํ๋ ๊ฒ์ด ์ข๋ค๊ณ ํ๋จํ๋ค.
"EC2 1๋์ ๋ค ๋ฃ์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ์ง ์์๊ฐ?"๋ฅผ ๊ฒ์ฆํ๊ธฐ ์ํด, ์ฐ๋ฆฌ ์๋น์ค์์ ๋ฐฐํฌํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ๋ณธ ์ปจํ ์ด๋ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํด ๊ธฐ๋ณธ ๋ฉ๋ชจ๋ฆฌ(Idle) ์ ์ ์จ์ ์ค์ธกํ๋ค.
| ์ปดํฌ๋ํธ | ๊ธฐ๋ณธ๊ฐ(Default) Idle ์ค์ธก์น |
|---|---|
| PostgreSQL | 28.89 MB |
| Redis 7.0 | 9.168 MB |
| Spring Boot | 81.35 MB |
| FastAPI+AI | 10.89 MB |
| Nginx | 15.06 MB |
| ์ ์ฒด ํฉ๊ณ | 145.358 MB |
- ๋ชจ๋ ์ปจํ ์ด๋๊ฐ ๊ฐ๋๋ ์ํ์ IDLE ๋ฉ๋ชจ๋ฆฌ๋ 143MB์ด๋ฏ๋ก t3.medium ๋ฉ๋ชจ๋ฆฌ 4GiB์ ์ฝ 3.5%์ ๋ถ๊ณผํ๋ค.
- ๋จ, ๋จ์ผ EC2๊ฐ ๋ค์ด๋๋ฉด ์๋น์ค๊ฐ ์ค๋จ๋๋ ๋จ์ผ ์ฅ์ ์ ์ด ๋ฐ์ํ๋ค. ๊ทธ๋ฌ๋ v1์ ๋ด๋ถ ํ์์ ์๋น์ค์ด๋ฉฐ ์ผ์์ ์ฅ์ ๋ฅผ ์ฉ์ธํ๊ธฐ๋ก ํฉ์ํ์ผ๋ฏ๋ก, ๋น์ฉ์ ์๋ผ๊ณ ๋น ๋ฅด๊ฒ ๋ฐฐํฌํ๊ธฐ ์ํด ์ด ๊ฐ์ฉ์ฑ ๋ฆฌ์คํฌ๋ฅผ ๊ฐ์ํ๋ค.
1๋์ EC2 ์์ ์ฌ๋ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ๋ํ๋ฉด์ ๋ฐ์ํ๋ ํ๊ฒฝ ์ถฉ๋๊ณผ ์ฅ์ ์ ํ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ปจํ ์ด๋ ๊ฐ์ํ ๊ธฐ์ ๋ก Docker๋ฅผ ์ฌ์ฉํ๋ค.
- ๋จ์ผ EC2 ์ธ์คํด์ค ์์ ๋ฐฑ์๋(Java/Spring), AI(Python/FastAPI), ํ๋ก ํธ์๋(React), ๋ฐ์ดํฐ๋ฒ ์ด์ค(PostgreSQL), ์บ์(Redis) ๋ฑ ๋ค์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋์์ ๋ฐฐํฌํ๊ณ ์ด์ํด์ผ ํ๋ค.
- ์ฌ๋ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ง์ ์ค์นํ์ฌ ๋ฐฐํฌํ๋ ๊ฒฝ์ฐ ํ๊ฒฝ ์ถฉ๋์ด๋ ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฅ์ ๊ฐ ๋ค๋ฅธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํฅ์ ๋ฏธ์น ์ ์๋ค.
- ๋ฐ๋ผ์ ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ปจํ ์ด๋ ๊ธฐ์ Docker๋ฅผ ๋์ ํ๋ค.
- ํ๋ก ํธ์๋
- ํ๋ก ํธ์๋๋ ์ ์ ํ์ผ์ ๋น๋ํ์ฌ CSR ๋ฐฉ์์ผ๋ก ๋ฐฐํฌํ๋ค. ๋ฐ๋ผ์ React๋ฅผ ์ํด Node.js ์๋ฒ๋ฅผ ์์ ๊ตฌ๋ํ ํ์๊ฐ ์๋ค.
- [๊ฒฐ๋ก ]
- vercel์ ํ ํ๋ก์ ํธ๋ ์ ๋ก์ด๊ณ , Github Pages๋ SPA ์ ๊ทผ ์ ๋ฌธ์ ํด๊ฒฐ์ด ํ์ํ๋ฏ๋ก ์ ํํ์ง ์์๋ค.
- ๋ฐฑ์๋ & AI ์๋ฒ
- Java์ Python์ ์๋ก ๋ค๋ฅธ ๋ฐํ์ ์์กด์ฑ ์ถฉ๋์ ๋ฐฉ์งํ๋ฉฐ, ์ธ๋ถ LLM์ ํธ์ถํ๋ AI ์๋ฒ์ ๋ณ๋ชฉ์ด ๋ฐฑ์๋๋ก ์ ํ๋์ง ์์์ผ ํ๋ค.
- [๊ฒฐ๋ก ] ๋ฐ๋ผ์ ๋ฐฑ์๋์ AI ์๋ฒ๋ ๊ฐ๊ฐ ๋ ๋ฆฝ๋ Docker ์ปจํ ์ด๋๋ก ๋ฐฐํฌํ๋ค.
- DB(PostgreSQL, Redis)
- ์ปจํ ์ด๋๋ ์ข ๋ฃ ์ ๋ด๋ถ ๋ฐ์ดํฐ๊ฐ ์๋ฉธ๋๋ค. ๊ด๋ฆฌํ ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ถ๊ฐ ๋น์ฉ์ด ๋ฐ์๋๋ค.(RDS ์ $21)
- [๊ฒฐ๋ก ] ๋น์ฉ ์ ๊ฐ์ ์ํด PostgreSQL๊ณผ Redis๋ฅผ ๊ฐ๊ฐ ์ปจํ ์ด๋๋ก ์ง์ ๋์ฐ๋, ์ธ์คํด์ค์ ๋์คํฌ(EBS)์ ๋ณผ๋ฅจ์ ์ฐ๊ฒฐํด ๋ฐ์ดํฐ ์์์ฑ์ ๋ณด์ฅํ๋ค.
์ฌ๋ฌ ์ปจํ ์ด๋๋ฅผ ์ ์ธ์ ์ผ๋ก ์ผ๊ด ์ ์ดํ๊ณ ํ๊ฒฝ ์ค์ ์ค์๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด Docker Compose๋ฅผ ์ฌ์ฉํ๋ค.
- ๊ฐ๋ณ `docker run`์ผ๋ก ๊ด๋ฆฌํ๋ฉด ํฌํธ/๋ณผ๋ฅจ/ํ๊ฒฝ๋ณ์ ๋ฑ ๋ณต์กํ CLI ์ต์ ๋๋ฝ์ผ๋ก ํด๋จผ ์๋ฌ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ๊ณ , DB๊ฐ ์คํ๋๊ธฐ ์ ๋ฐฑ์๋๊ฐ ๋จผ์ ์์๋๋ ๋ฑ์ ์ปจํ ์ด๋ ๊ฐ ์คํ ์์์ ๋ด๋ถ ๋คํธ์ํฌ ์ฐ๊ฒฐ์ ์ผ์ผ์ด ์๋ ๊ด๋ฆฌํด์ผ ํ๋ ๋ฌธ์ ๊ฐ ์๋ค.
- Docker Compose๋ฅผ ํตํด ๋จ์ผ `yaml` ํ์ผ๋ก ์ ์ฒด ์๋น์ค์ ์ค์ ๊ณผ ์์กด ๊ด๊ณ๋ฅผ ๊ด๋ฆฌํ์ฌ ๋ช ๋ น์ด ํ ์ค๋ก ์ผ๊ด ์คํ ๋ฐ ์ฌํ์ด ๊ฐ๋ฅํ๋ค.
์๋น์ค ์์ฝ
- ์คํํธ์
์ด ์ต์ด๋ก ๋ฐฐํฌํ๋ ์๋น์ค, DAU 30, ํ๊ท RPS 0.07, ๋ถํธ์บ ํ ๋ด๋ถ ์ธ์์ ํ๊ฒ์ผ๋ก ๋ฐฐํฌ ์์
- AWS EC2 ํ ๋์ ๊ฐ ์๋น์ค ์ปดํฌ๋ํธ๋ฅผ ์ปจํ
์ด๋ํํ์ฌ Docker Compose๋ก ๋ฐฐํฌ์ฐ๋ฆฌ ์๋น์ค๋ ํ๋์ ์ธ์คํด์ค๋ก ๋ฐฐํฌํ๋ฏ๋ก AWS์ ๊ธฐ๋ณธ VPC์ ์๋ธ๋ท์ ์ฌ์ฉํ๋ค.
๊ธฐ๋ณธ VPC์ ํผ๋ธ๋ฆญ ์๋ธ๋ท์ ์ฌ์ฉํ์ฌ ์ธ์คํด์ค๊ฐ ์ธํฐ๋ท์ ์ง์ ๋ ธ์ถ๋๋ฏ๋ก, ์ ๊ทผ ๋ฒ์๋ฅผ ์ค์ด๊ณ ๋น์ธ๊ฐ ์ ๊ทผ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์๋น์ค ์ด์ ๋ฐ ๊ด๋ฆฌ์ ํ์ํ ์ต์ ํฌํธ๋ง ํ์ฉํ๋ค.
Inbound
- 80 TCP (HTTP) 0.0.0.0/0(์ ์ญ): ์ฌ์ฉ์์ HTTP ์์ฒญ, HTTPS๋ก ๋ฆฌ๋ค์ด๋ ์
ํ๋ค.
- 443 TCP (HTTPS) 0.0.0.0/0(์ ์ญ): ์ฌ์ฉ์์ HTTPS ์์ฒญ, ํธ๋ํฝ์ Nginx ์ปจํ
์ด๋๋ก ์ ๋ฌํด ์์ฒญ ๋ผ์ฐํ
์ฒ๋ฆฌํ๋ค.
- 22 TCP (SSH) ๊ฐ๋ฐIP: ํ์ฌ ์ธํ๋ผ ํ์ IP์์๋ง ์ ๊ทผํ๋๋ก ์ค์ ํ๋ค.์ฐ๋ฆฌ ํ์ ์ธํ๋ผ ๋ด๋น์ tobby์ janna 2์ธ์ด๋ค.
aws root ๊ณ์ ์ด ํ์ทจ๋๋ ๊ฒฝ์ฐ, ๋น์ผ EC2 ๋ฑ์ ์์ฑ/์ฌ์ฉํ์ฌ ์ธํ๋ผ ๋น์ฉ์ด ๊ณผ๋ํ๊ฒ ์ง์ถ๋ ์ ์๋ค.
๋ฐ๋ผ์ root ๊ณ์ ์ด ํ์ทจ๋์ง ์๋๋ก ํ๊ณ , root ๊ณ์ ์ ์ธํ๋ผ ๋ด๋น์๊ฐ ์ ๊ทผํ์ง ์๋๋ก ์ธํ๋ผ ๋ด๋น์ ๊ฐ์์ ๊ฐ๋ณ IAM User๋ฅผ ์์ฑํ๊ณ 'Infra-Admin' IAM ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด ์ ํ๋ ๊ถํ๋ง์ ๋ถ์ฌํด ์ฌ์ฉํ๋๋ก ํ๋ค.
AWS Account
โ
โโ Root
โ โโ ์ผ๋ฐ์ ์ผ๋ก ์์
์ ์ฌ์ฉํ์ง ์๋๋ค
โ
โโ IAM Group: Infra-Admin
โ โโ tobby
โ โโ janna
โ
โโ IAM Users
โโ tobby
โโ janna
์๋๋ 'Infra-Admin' IAM ๊ทธ๋ฃน ์ค์ ์ ํ์ํ ๋ด์ฉ์ด๋ค.
- MFA๊ฐ ์์ผ๋ฉด ๋ชจ๋ ์์ฒญ์ ๊ฑฐ๋ถ(MFA ๋ฑ๋ก ์ ์ธ)
- ๊ถํ ์์น(IAM ์์ ) ๋ถ๊ฐ
- ํ์ฉ๋ ์๋น์ค์๋ง ์ ๊ทผ ๊ฐ๋ฅํ๊ณ , ํ์ฉ๋ ๋ฆฌ์์ค๋ง ์์ฑํ ์ ์์
- ec2(t3), S3, CloudFront, CloudWatch, Billing(ํ์ฌ ๋น์ฉ ์ฝ๊ธฐ๋ง ํ์ฉ)
'Infra-Admin' IAM ๊ทธ๋ฃน์ ์ ์ฉํ JSON ์ ๋ฌธ (ํด๋ฆญํ์ฌ ํผ์น๊ธฐ)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListActions",
"Effect": "Allow",
"Action": [
"iam:ListUsers",
"iam:ListVirtualMFADevices"
],
"Resource": "*"
},
{
"Sid": "AllowUserToCreateVirtualMFADevice",
"Effect": "Allow",
"Action": "iam:CreateVirtualMFADevice",
"Resource": "arn:aws:iam::*:mfa/${aws:username}"
},
{
"Sid": "AllowUserToManageTheirOwnMFA",
"Effect": "Allow",
"Action": [
"iam:EnableMFADevice",
"iam:GetMFADevice",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowUserToDeactivateTheirOwnMFAOnlyWhenUsingMFA",
"Effect": "Allow",
"Action": "iam:DeactivateMFADevice",
"Resource": "arn:aws:iam::*:user/${aws:username}",
"Condition": {
"Bool": { "aws:MultiFactorAuthPresent": "true" }
}
},
{
"Sid": "BlockMostAccessUnlessSignedInWithMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ListUsers",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"iam:ChangePassword",
"iam:GetUser"
],
"Resource": "*",
"Condition": {
"BoolIfExists": { "aws:MultiFactorAuthPresent": "false" }
}
},
{
"Sid": "DenyIAMPrivilegeEscalation",
"Effect": "Deny",
"Action": [
"iam:CreateUser",
"iam:CreateRole",
"iam:CreateAccessKey",
"iam:CreateLoginProfile",
"iam:UpdateLoginProfile",
"iam:UpdateAssumeRolePolicy",
"iam:AttachUserPolicy",
"iam:AttachGroupPolicy",
"iam:AttachRolePolicy",
"iam:PutUserPolicy",
"iam:PutGroupPolicy",
"iam:PutRolePolicy",
"iam:CreatePolicy",
"iam:CreatePolicyVersion",
"iam:SetDefaultPolicyVersion",
"iam:AddUserToGroup",
"iam:PassRole"
],
"Resource": "*"
},
{
"Sid": "DenyExpensiveEC2Instances",
"Effect": "Deny",
"Action": [
"ec2:RunInstances",
"ec2:ModifyInstanceAttribute"
],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotLike": { "ec2:InstanceType": "t3.*" }
}
},
{
"Sid": "AllowEC2",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
},
{
"Sid": "AllowS3",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "AllowCloudFront",
"Effect": "Allow",
"Action": "cloudfront:*",
"Resource": "*"
},
{
"Sid": "AllowCloudWatch",
"Effect": "Allow",
"Action": "cloudwatch:*",
"Resource": "*"
},
{
"Sid": "AllowBillingReadOnly",
"Effect": "Allow",
"Action": [
"ce:Get*",
"ce:Describe*",
"billing:Get*",
"billing:List*",
"budgets:ViewBudget",
"budgets:DescribeBudget"
],
"Resource": "*"
}
]
}์ฌ์ฉ์๊ฐ ์ฐ๋ฆฌ ์๋น์ค๋ฅผ ๊ธฐ์ตํ๊ธฐ ์ฌ์ด ๊ณ ์ ๋ ์ฃผ์๋ก ๋ค์ด์์ผ ํ๋ฏ๋ก, ๋๋ฉ์ธ์ ๊ตฌ๋งคํ์ฌ ๊ณ ์ IP(Elastic IP)์ ์ฐ๊ฒฐํ๋ค.
- ์ฌ์ฉ์๋ IP์ฃผ์๊ฐ ์๋ ๊ธฐ์ตํ๊ธฐ ์ฌ์ด ๋๋ฉ์ธ ์ฃผ์๋ก ์ ๊ทผํ ์ ์์ด์ผ ํ๋ค.
- ๋๋ฉ์ธ ์ฃผ์๋ฅผ EC2 IP ์ฃผ์์ ์ฐ๊ฒฐํ ๋, EC2 ์ฌ์์ ์ IP ๋ณ๊ฒฝ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ณ ์ IP(Elastic IP)๋ฅผ ์ฌ์ฉํ๋ค.
์ถ๊ฐ ์ธํ๋ผ ๋น์ฉ์ ๋ฐ์์ํค์ง ์๊ณ ๋น ๋ฅธ ๋ฐฐํฌ๋ฅผ ์ํด, ALB๋ CloudFront ๋์ EC2 ๋ด๋ถ์ Nginx์ Let's Encrypt(Certbot)๋ฅผ ์ฌ์ฉํ์ฌ HTTPS๋ฅผ ์ ์ฉํ๋ค.
- ALB + ACM: ACM ๋ฌด๋ฃ ์ธ์ฆ์ ์ง์ ๋ฐ ๊ด๋ฆฌ๊ฐ ํธํ์ง๋ง, ALB ๊ธฐ๋ณธ ์๊ธ(์ ์ฝ $16~$22)์ด ๋ฐ์ํ์ฌ ๋น์ฉ ์ธก๋ฉด์์ ๋ถ๋ฆฌํ๊ณ , ๋จ์ผ ์ธ์คํด์ค ํ๊ฒฝ์์ ๋ก๋๋ฐธ๋ฐ์ฑ์ด ๋ถํ์ํ์ฌ ์ ์ธํจ
- CloudFront + ACM: 1TB ์ ์ก/10,000,000๊ฑด ๋ฌด๋ฃ, SSL ์ธ์ฆ์ ๊ฐฑ์ ์ด ์๋์ผ๋ก ๋์ง๋ง ์ด๋ฏธ ํ๋ก ํธ ๋ฐฐํฌ์ ์ธ์คํด์ค ๋ด๋ถ ๋ผ์ฐํ ์ ์ํด ์กด์ฌํ๋ Nginx๊ฐ ์๋ ์ํ์์ ์ธ์ฆ์ ๊ด๋ฆฌ๋ฅผ ์ํด Route53, CloudFront, ACM ์ค์ ์ ํ ํ์๊ฐ ์๋ค๊ณ ํ๋จํจ
- Nginx + Let's Encrypt: Let's Encrypt์ Certbot์ ์ฐ๋ํ์ฌ SSL ๋ฐ๊ธ๊ณผ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํจ. ์ธ์ฆ์ 90์ผ ๋ง๋ฃ ๊ด๋ฆฌ๋ Certbot ์๋ ๊ฐฑ์ ์ค์ผ์ค๋ฌ๋ฅผ ๋ฑ๋กํ์ฌ ์๋ํ๋ก ํด๊ฒฐ ๊ฐ๋ฅํ๊ณ , ์ด๋ฏธ ๋จ์ผ ์ธ์คํด์ค ๋ด ๋ผ์ฐํ ์ ์ํด Nginx ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ๋ฏ๋ก, ์ถ๊ฐ ๋น์ฉ ์์ด ๋น ๋ฅด๊ฒ ๋ฐฐํฌ๊ฐ ๊ฐ๋ฅํ Nginx๋ฅผ ์ ํํจ
์ฌ์ฉ์ (๋ธ๋ผ์ฐ์ )
โ
โโ [HTTP :80] โโ> Nginx โโ> HTTPS(:443)๋ก 301 ๋ฆฌ๋ค์ด๋ ํธ
โ
โโ [HTTPS :443] โโ> Nginx (SSL ์ข
๋ฃ ๋ฐ ๋ผ์ฐํ
)
โ
โโ [/] ์ ์ ํ์ด์ง โโ> React ๋น๋ ํ์ผ ์ง์ ์๋น
โ
โโ [/api] ์์ฒญ โโ> ๋ฐฑ์๋ ์ปจํ
์ด๋ (Spring Boot)
โ
โโ AI ๊ฒ์ฆ โโ> AI ์ปจํ
์ด๋ (FastAPI)
โโ ๋ฐ์ดํฐ โโ> PostgreSQL ์ปจํ
์ด๋
โโ ์บ์/์ธ์
โโ> Redis ์ปจํ
์ด๋
๋น์ฉ์ ์ค์ด๊ธฐ ์ํด, RDS ๊ฐ์ ๊ด๋ฆฌํ DB๋ฅผ ์ฐ์ง ์๊ณ ์ปจํ ์ด๋๋ก ์ง์ ๋์ฐ๋, ์ปจํ ์ด๋ ์ข ๋ฃ ์ ๋ฐ์ดํฐ ์๋ฉธ์ ๋ง๊ธฐ ์ํด EC2์ ๊ธฐ๋ณธ EBS ๋ณผ๋ฅจ์ ๋ง์ดํธํ์ฌ ์ถ๊ฐ ๋น์ฉ ์์ด ๋ฐ์ดํฐ ์์์ฑ์ ๋ณด์ฅํ๋ค.
- PostgreSQL RDS ์ ๋น์ฉ(์์ธ): ์ธ์คํด์ค(t4g.micro, $0.0250/์๊ฐ * 730์๊ฐ = $18.25) + ์คํ ๋ฆฌ์ง($0.131/GB * 20GB = 2.62) = $20.87 RDS ๋น์ฉ ๋ฌธ์
EC2 ์ง์ ์ ์ฅ์ ๋์คํฌ ์ฉ๋ ๊ณ ๊ฐ๊ณผ ์ธ์คํด์ค ๊ต์ฒด ์ ๋ฐ์ดํฐ ์ด์ ์ํ์ด ์์ผ๋ฏ๋ก, ํ์ฌ ๊ท๋ชจ์์ ๋น์ฉ์ด $0์ด๋ฉด์ ๋ฌด์ ํ ํ์ฅ์ด ๊ฐ๋ฅํ AWS S3์ ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ๋ค.
- EC2 ์ง์ ์ ์ฅ: S3 ์ฐ๋ ์ฝ๋๊ฐ ์์ด ์ด๊ธฐ์ ๋น ๋ฅด์ง๋ง, ์ฌ์ง์ด ์์ด๋ฉด EBS ์ฉ๋ ๋ถ์กฑ์ด ๋ฐ์ํ๊ณ ์๋ฒ ์ฌ๋ฐฐํฌ/๊ต์ฒด ์ ๋ฐ์ดํฐ ์ด์ ์ด ๋งค์ฐ ๋ฒ๊ฑฐ๋ก์.
- AWS S3: ํ์ฌ ๊ท๋ชจ์์(5GB ๋ฌด๋ฃ) ๋น์ฉ์ด ์์ผ๋ฉฐ, EC2 ๋์คํฌ ์ฉ๋ ๊ณ ๊ฐ ๊ฑฑ์ ์์ด ํ์ผ ์ ์ฅ์๋ฅผ ์ธ์คํด์ค์ ์์ ํ ๋ถ๋ฆฌํด ์์ ์ ์ผ๋ก ์ด์ํ ์ ์์.
-> ์ด๋ฏธ์ง๊ฐ ์ผ๋ง๋ ์์ผ์ง ๊ณ์ฐ์ ๋ค์ํด๋ด์ผํ ์ ์์ต๋๋ค. (๋น์ฉ ๊ณ์ฐ ๋ฐ ๋ ผ๋ฆฌ ๊ฒ์ฆ ํ์) e.g. 120๋ช ์ ์ ์ ๊ฐ ๋ฌผ๊ฑด์ 10๊ฐ, ๋ฌผ๊ฑด ๋น 3์ฅ์ ์ฌ์ง -> nGB
ํผ๋ธ๋ฆญ ์ด๋ฏธ์ง ๋ฐฐํฌ ์ ์ธ ๋๊ตฌ ๋ชจ๋ ๋ฌด๋ฃ์ด๋ฏ๋ก, ๋ณ๋์ ์ธ๋ถ ๊ณ์ ์ฐ๋์ด๋ ์ํฌ๋ฆฟ ๋ฐ๊ธ ์์ด ๋น ๋ฅด๊ณ ํธ๋ฆฌํ๊ฒ GitHub ์ํ๊ณ์์ ๊ด๋ฆฌํ ์ ์๋ GHCR์ ์ฌ์ฉํ๋ค.
- Public ์ปจํ ์ด๋ ๋ ์ง์คํธ๋ฆฌ, ์์์ docker ์ด๋ฏธ์ง ๋น๋/์ ๋ก๋ ์กฐ๊ฑด์์๋ Docker hub, AWS ECR, GHCR ์ธ ์ปจํ ์ด๋ ๋ ์ง์คํธ๋ฆฌ ๋ชจ๋ ๋ฌด๋ฃ
- CI/CD ๋จ๊ณ์์ Docker hub์ ECR์ ๊ฐ๊ฐ ์ํฌ๋ฆฟ ๊ด๋ฆฌ๊ฐ ํ์ํ์ง๋ง, GHCR๋ github์์ ์ ๊ณตํ๋ ์ธ์ฆ ํ ํฐ์ ์ฌ์ฉํ ์ ์์ด ํธ๋ฆฌํ๋ค.(
${{ secrets.GITHUB_TOKEN }})
ํ๋ก๋ฉํ ์ฐ์ค๋ ๊ทธ๋ผํ๋ ๊ฐ์ ๋ณ๋ ๋ชจ๋ํฐ๋ง ํด ๊ตฌ์ถ์ ๋ฆฌ์์ค ๋ญ๋น์ ์ด์ ๋ณต์ก๋๊ฐ ์ปค์ง๋ฏ๋ก, ์ถ๊ฐ ๋น์ฉ๊ณผ ์ค์น ์์ด EC2์ CPU/๋ฉ๋ชจ๋ฆฌ/๋คํธ์ํฌ ์ํ๋ฅผ ๊ธฐ๋ณธ ์ ๊ณตํ๋ AWS CloudWatch ๊ธฐ๋ณธ ๋ฉํธ๋ฆญ๊ณผ ์๋์ ์ฌ์ฉํ๋ค.
์ฐ๋ฆฌ ์๋น์ค๋ ์ ์ ๋น์ฉ๊ณผ ๋น ๋ฅธ ๋ฐฐํฌ๋ฅผ ํด์ผํ๋ ํ์ฌ ๋ชฉํ์, ์๋น์ค๊ฐ ํน์ ์ฌ์ฉ์์ ํน์ ์๊ฐ๋์ ์ฌ์ฉ๋ ๊ฒ์ ๊ณ ๋ คํ์๊ธฐ ๋๋ฌธ์ ์๋์ ํ๊ณ์ ์ ๊ฐ๋๋ค.
- ์ ์ฒด ์๋น์ค ์ค๋จ: EC2 ์ธ์คํด์ค 1๋์ ์ฅ์ ๊ฐ ๋ฐ์ํ๋ฉด ์น, API, DB, AI๊น์ง ๋ชจ๋ ์๋น์ค๊ฐ ์ฆ์ ์ค๋จ๋๋ค.
- ๋ฌด์ค๋จ ๋ฐฐํฌ ๋ถ๊ฐ: ๋จ์ผ ์ธ์คํด์ค๋ก ๋ฐฐํฌํ๋ฏ๋ก ์ ๋ฒ์ ์ ๋ฐฐํฌํ ๋ ์ปจํ ์ด๋ ์ฌ์์ ๋์ ์๋น์ค ์ค๋จ(๋ค์ดํ์)์ด ๋ฐ์ํ๋ค.
- ๋ณต๊ตฌ ๊ธฐ๋ฅ ๋ถ์ฌ: ๊ด๋ฆฌํ RDS๊ฐ ์ ๊ณตํ๋ ์๋ ๋ค์คํ(Multi-AZ), ์ค์๊ฐ ์์ ๋ณต์, ์๋ ์ฅ์ ๋ณต๊ตฌ๊ฐ ์ง์๋์ง ์๋๋ค.
- ํธ๋ํฝ์ด ๋์ด๋ฌ์ ๋ ์๋ฒ ๋์๋ฅผ ๋๋ ค ํธ๋ํฝ์ ๋ถ์ฐํ๋ ์คํ ์ค์ผ์ผ๋ง์ด ๋ถ๊ฐ๋ฅํ๋ฉฐ, ์ธ์คํด์ค ์ฒด๊ธ์ ์ฌ๋ฆฌ๋ Scale-up๋ง ๊ฐ๋ฅํ๋ค.