Cloud Design 1st tobby - 100-hours-a-week/KTB4-1st-wiki GitHub Wiki

1. 1์ฐจ ๋ฐฐํฌ ์ƒํ™ฉ

๋ฌธ์ œ ์ •์˜: ์Šคํƒ€ํŠธ์—… ์„œ๋น„์Šค๋ฅผ ์ €๋ ดํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ๋ฐฐํฌํ•ด์•ผ ํ•œ๋‹ค.

1) ํšŒ์‚ฌ ์ƒํ™ฉ ๋ฐ ์ œ์•ฝ ์กฐ๊ฑด

  • ํšŒ์‚ฌ ๊ฐœ๋ฐœ ์ธ๋ ฅ 6๋ช…
  • 4๋ช…์€ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ๋‹ด๋‹น
  • 2๋ช…์€ ์ธํ”„๋ผ ๋‹ด๋‹น
  • ์Šคํƒ€ํŠธ์—…์ด๋ฏ€๋กœ ๋น„์šฉ๊ณผ ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•˜๋ฉฐ, ๋น„์šฉ์ด ์ ˆ๋Œ€์ ์œผ๋กœ ๋ถ€์กฑํ•จ

ํ˜„์žฌ ์„œ๋น„์Šค๋ฅผ ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•ด

  1. ์ ์€ ๋น„์šฉ
  2. ๋น ๋ฅด๊ฒŒ ๋ฐฐํฌ(์ ์€ ๋ณต์žก์„ฑ)

์ˆœ์œผ๋กœ ๊ธฐ์ค€์„ ์„ธ์› ๋‹ค.

์žฅ์•  ํ—ˆ์šฉ ์ˆ˜์ค€

1์ฐจ ๋ฐฐํฌ์—์„œ๋Š” ์žฅ์• ๋กœ ์ธํ•ด ์„œ๋น„์Šค ์ œ๊ณต์ด ์ž ์‹œ ์ค‘๋‹จ๋˜์–ด๋„ ๊ดœ์ฐฎ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.

์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” ์ดˆ๊ธฐ์— ๋ถ€ํŠธ์บ ํ”„ ๋‚ด๋ถ€์—์„œ๋งŒ ํ์‡„์ ์œผ๋กœ ๋ฐฐํฌ๋˜๋ฏ€๋กœ ์„œ๋น„์Šค๊ฐ€ ์ค‘๋‹จ๋˜๋”๋ผ๋„ ํฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

2) ์ดˆ๊ธฐ ์„œ๋น„์Šค ๊ทœ๋ชจ ์ •์˜

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 = ํ•˜๋ฃจ ์ด ์š”์ฒญ ์ˆ˜ รท ํŠธ๋ž˜ํ”ฝ ์ง‘์ค‘ ์‹œ๊ฐ„(์ดˆ)

1์ฐจ ํ•ต์‹ฌ User Flow

์‹ ๊ทœ ์œ ์ € Flow (DAU์˜ 70%)

๋ฒˆํ˜ธ 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

์žฌ๋ฐฉ๋ฌธ ์œ ์ € Flow (DAU์˜ 30%)

๋ฒˆํ˜ธ 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

ํ‰๊ท  RPS ๊ณ„์‚ฐ

ํ•˜๋ฃจ ์ด ์š”์ฒญ ์ˆ˜ = ์„ธ์…˜ ์ˆ˜ ร— ์„ธ์…˜ ํ‰๊ท  ์š”์ฒญ ์ˆ˜ = 30 ร— 21.23 = 636.9
ํ‰๊ท  RPS       = 636.9 รท 8,400 โ‰ˆ 0.076

Peak RPS ๋Œ€์‹  ํ‰๊ท  RPS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

  1. ์‚ฌ์šฉ์ž ๊ทœ๋ชจ(DAU 30๋ช…): ์†Œ๊ทœ๋ชจ ์ดˆ๊ธฐ ์„œ๋น„์Šค์—์„œ 30๋ช… ์ „์›์ด ํŠน์ • ์ˆœ๊ฐ„์— ์ผ์ œํžˆ ์„ธ์…˜ ์š”์ฒญ์„ ์Ÿ์•„๋ถ“๋Š” ๊ทน๋‹จ์ ์ธ ํ”ผํฌ ์ƒํ™ฉ์€ ๋น„ํ˜„์‹ค์ 
  2. ๋ช…ํ™•ํ•œ ํ™œ๋™ ์‹œ๊ฐ„๋Œ€: 24์‹œ๊ฐ„ ์ƒ์‹œ ์ ‘์† ์„œ๋น„์Šค๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ, ์‹ค์ œ ์š”์ฒญ์ด ๋ฐœ์ƒํ•˜๋Š” ์ฃผ์š” ํ™œ๋™ ์‹œ๊ฐ„๋Œ€(์‰ฌ๋Š” ์‹œ๊ฐ„ + ์ ์‹ฌ์‹œ๊ฐ„ = 140๋ถ„ / 8,400์ดˆ)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์‚ฐ์ •ํ•ด์•ผ ํ˜„์‹ค์ ์ธ ์ดˆ๋‹น ๋ถ€ํ•˜๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Œ
  3. ๊ฒฐ๋ก : v1 ์ธํ”„๋ผ ์‚ฌ์ด์ง•์˜ ํ˜„์‹ค์ ์ธ ๊ธฐ์ค€์€ ๋น„ํ˜„์‹ค์ ์ธ ์ˆœ๊ฐ„ ํ”ผํฌ๊ฐ€ ์•„๋‹Œ, ์ง‘์ค‘ ์‹œ๊ฐ„๋Œ€ ํ‰๊ท  RPS

2. ๋ฐฐํฌ ๋ฐฉ์‹

1์ฐจ ๋ฐฐํฌ์˜ ๋ชฉํ‘œ: ์ ์€ ๋น„์šฉ๊ณผ ๋น ๋ฅธ ๋ฐฐํฌ

1) ์˜จํ”„๋ ˆ๋ฏธ์Šค vs ํด๋ผ์šฐ๋“œ

์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•ด 1์ฐจ ๋ฐฐํฌํ•œ๋‹ค.

  • ๋ฐฐํฌ๋Š” ํฌ๊ฒŒ ์˜จ ํ”„๋ ˆ๋ฏธ์Šค์™€ ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค๋กœ ๋‚˜๋‰œ๋‹ค.
  1. ์˜จ ํ”„๋ ˆ๋ฏธ์Šค๋Š” ์ดˆ๊ธฐ ํˆฌ์ž ๋น„์šฉ์ด ๋†’์œผ๋ฏ€๋กœ([N100 ๋ฏธ๋‹ˆ PC 22๋งŒ์›]((https://prod.danawa.com/info/?pcode=35770394&keyword=n100), ๊ณต์œ ๊ธฐ 4.5๋งŒ์› , UPS 18๋งŒ์›๋ฅผ ํ•ฉ์ณ 44.5๋งŒ์›) ํ˜„์žฌ ์ƒํ™ฉ์— ์ ํ•ฉํ•˜์ง€ ์•Š์•˜๋‹ค.
  2. ํด๋ผ์šฐ๋“œ๋Š” ์˜จ ํ”„๋ ˆ๋ฏธ์Šค ๋Œ€๋น„ ์ ์€ ๋น„์šฉ(AWS EC2 t3.medium ๊ธฐ์ค€ ํ•œ ๋‹ฌ ์•ฝ 38๋‹ฌ๋Ÿฌ)์œผ๋กœ ์„œ๋น„์Šค๋ฅผ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ดˆ๊ธฐ ๋น„์šฉ์„ ์ค„์—ฌ์•ผ ํ•˜๋Š” ์ง€๊ธˆ ์ƒํ™ฉ์— ์ž˜ ๋งž์•˜๋‹ค.
  • ๋”ฐ๋ผ์„œ 1์ฐจ ๋ฐฐํฌ๋Š” ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

2) CSP

๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ, CSP ๊ฐ„ ๋น„์šฉ ์ฐจ์ด๊ฐ€ ํฌ์ง€ ์•Š์œผ๋ฏ€๋กœ ๋น ๋ฅธ ๋ฐฐํฌ๋ฅผ ์œ„ํ•ด ํŒ€์›์˜ ๊ฒฝํ—˜์ด ์žˆ๋Š” AWS๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐฐํฌํ•œ๋‹ค.

  1. ์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” DAU๊ฐ€ 30๋ช…์ด๋ฏ€๋กœ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ์„ ์‚ฌ์šฉํ•  ๋•Œ์˜ CSP ๊ฐ„์˜ ๋น„์šฉ ์ฐจ์ด๊ฐ€ ์ ์—ˆ๋‹ค.(ํ•˜๋‹จ ๋น„์šฉ ํ‘œ ์ฐธ์กฐ) ๋”ฐ๋ผ์„œ '์ ์€ ๋น„์šฉ'์ด๋ผ๋Š” ๊ธฐ์ค€์—์„œ๋Š” CSP๋ฅผ ๊ณ ๋ฅผ ์ˆ˜ ์—†๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.
  2. '๋น ๋ฅธ ๋ฐฐํฌ' ๊ธฐ์ค€์—์„œ๋Š” ์ ์œ ์œจ์ด ๋†’์•„ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๋งŽ๊ณ  ํŒ€์› ๋ชจ๋‘์˜ ์‚ฌ์šฉ ๊ฒฝํ—˜์ด ์žˆ๋Š” AWS๊ฐ€ ์šฐ์ˆ˜ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ CSP๋กœ AWS๋ฅผ ์„ ํƒํ–ˆ๋‹ค.

๋Œ€ํ‘œ ํด๋ผ์šฐ๋“œ 3์‚ฌ t3.medium ๊ธ‰ ์ธ์Šคํ„ด์Šค ๋น„๊ต

  • ๋Œ€์ƒ: ๋Œ€ํ‘œ 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์€ ๊ณต์œ  ์ฝ”์–ด ๋ฐฉ์‹์ด๋ผ ๋ฌผ๋ฆฌ ์„œ๋ฒ„์— ์—ฌ์œ ๊ฐ€ ์žˆ๋Š” ํ•œ, ๊ณ„์†ํ•ด์„œ ๋ฒ„์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” ํŠน์ • ์‹œ๊ฐ„๋Œ€์— ์‚ฌ์šฉ๋˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋ฏ€๋กœ ํฌ๋ ˆ๋”ง์€ ์ค‘์š”ํ•œ ์š”์†Œ๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.

3) ์ธ์Šคํ„ด์Šค ๊ฐœ์ˆ˜

์ดˆ๊ธฐ ๋ฐฐํฌ์—์„œ๋Š” ๋‹จ์ผ 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์€ ๋‚ด๋ถ€ ํ์‡„์  ์„œ๋น„์Šค์ด๋ฉฐ ์ผ์‹œ์  ์žฅ์• ๋ฅผ ์šฉ์ธํ•˜๊ธฐ๋กœ ํ•ฉ์˜ํ–ˆ์œผ๋ฏ€๋กœ, ๋น„์šฉ์„ ์•„๋ผ๊ณ  ๋น ๋ฅด๊ฒŒ ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•ด ์ด ๊ฐ€์šฉ์„ฑ ๋ฆฌ์Šคํฌ๋ฅผ ๊ฐ์ˆ˜ํ•œ๋‹ค.

3. ๋‹จ์ผ ์ธ์Šคํ„ด์Šค ๋ฐฐํฌ

1) ์ปจํ…Œ์ด๋„ˆํ™”

1๋Œ€์˜ EC2 ์•ˆ์— ์—ฌ๋Ÿฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ๋™ํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•˜๋Š” ํ™˜๊ฒฝ ์ถฉ๋Œ๊ณผ ์žฅ์•  ์ „ํŒŒ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ปจํ…Œ์ด๋„ˆ ๊ฐ€์ƒํ™” ๊ธฐ์ˆ ๋กœ Docker๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

  • ๋‹จ์ผ EC2 ์ธ์Šคํ„ด์Šค ์œ„์— ๋ฐฑ์—”๋“œ(Java/Spring), AI(Python/FastAPI), ํ”„๋ก ํŠธ์—”๋“œ(React), ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(PostgreSQL), ์บ์‹œ(Redis) ๋“ฑ ๋‹ค์–‘ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋™์‹œ์— ๋ฐฐํฌํ•˜๊ณ  ์šด์˜ํ•ด์•ผ ํ•œ๋‹ค.
  • ์—ฌ๋Ÿฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ง์ ‘ ์„ค์น˜ํ•˜์—ฌ ๋ฐฐํฌํ•˜๋Š” ๊ฒฝ์šฐ ํ™˜๊ฒฝ ์ถฉ๋Œ์ด๋‚˜ ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์žฅ์• ๊ฐ€ ๋‹ค๋ฅธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ปจํ…Œ์ด๋„ˆ ๊ธฐ์ˆ  Docker๋ฅผ ๋„์ž…ํ•œ๋‹ค.

2) ์ปดํฌ๋„ŒํŠธ๋ณ„ ๋ฐฐํฌ ๋ฐฉ์‹

  • ํ”„๋ก ํŠธ์—”๋“œ
    • ํ”„๋ก ํŠธ์—”๋“œ๋Š” ์ •์  ํŒŒ์ผ์„ ๋นŒ๋“œํ•˜์—ฌ CSR ๋ฐฉ์‹์œผ๋กœ ๋ฐฐํฌํ•œ๋‹ค. ๋”ฐ๋ผ์„œ React๋ฅผ ์œ„ํ•ด Node.js ์„œ๋ฒ„๋ฅผ ์ƒ์‹œ ๊ตฌ๋™ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
    • [๊ฒฐ๋ก ]
      • vercel์€ ํŒ€ ํ”„๋กœ์ ํŠธ๋Š” ์œ ๋กœ์ด๊ณ , Github Pages๋Š” SPA ์ ‘๊ทผ ์‹œ ๋ฌธ์ œ ํ•ด๊ฒฐ์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ์„ ํƒํ•˜์ง€ ์•Š์•˜๋‹ค.
  • ๋ฐฑ์—”๋“œ & AI ์„œ๋ฒ„
    • Java์™€ Python์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๋Ÿฐํƒ€์ž„ ์˜์กด์„ฑ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๋ฉฐ, ์™ธ๋ถ€ LLM์„ ํ˜ธ์ถœํ•˜๋Š” AI ์„œ๋ฒ„์˜ ๋ณ‘๋ชฉ์ด ๋ฐฑ์—”๋“œ๋กœ ์ „ํŒŒ๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
    • [๊ฒฐ๋ก ] ๋”ฐ๋ผ์„œ ๋ฐฑ์—”๋“œ์™€ AI ์„œ๋ฒ„๋Š” ๊ฐ๊ฐ ๋…๋ฆฝ๋œ Docker ์ปจํ…Œ์ด๋„ˆ๋กœ ๋ฐฐํฌํ•œ๋‹ค.
  • DB(PostgreSQL, Redis)
    • ์ปจํ…Œ์ด๋„ˆ๋Š” ์ข…๋ฃŒ ์‹œ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์†Œ๋ฉธ๋œ๋‹ค. ๊ด€๋ฆฌํ˜• ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ถ”๊ฐ€ ๋น„์šฉ์ด ๋ฐœ์ƒ๋œ๋‹ค.(RDS ์›” $21)
    • [๊ฒฐ๋ก ] ๋น„์šฉ ์ ˆ๊ฐ์„ ์œ„ํ•ด PostgreSQL๊ณผ Redis๋ฅผ ๊ฐ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋กœ ์ง์ ‘ ๋„์šฐ๋˜, ์ธ์Šคํ„ด์Šค์˜ ๋””์Šคํฌ(EBS)์™€ ๋ณผ๋ฅจ์„ ์—ฐ๊ฒฐํ•ด ๋ฐ์ดํ„ฐ ์˜์†์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

3) ์ปจํ…Œ์ด๋„ˆ ์ž์› ํ• ๋‹น

4) ๋‹ค์ค‘ ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ

์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ผ๊ด„ ์ œ์–ดํ•˜๊ณ  ํ™˜๊ฒฝ ์„ค์ • ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด Docker Compose๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

  • ๊ฐœ๋ณ„ `docker run`์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ํฌํŠธ/๋ณผ๋ฅจ/ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋“ฑ ๋ณต์žกํ•œ CLI ์˜ต์…˜ ๋ˆ„๋ฝ์œผ๋กœ ํœด๋จผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฝ๊ณ , DB๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „ ๋ฐฑ์—”๋“œ๊ฐ€ ๋จผ์ € ์‹œ์ž‘๋˜๋Š” ๋“ฑ์˜ ์ปจํ…Œ์ด๋„ˆ ๊ฐ„ ์‹คํ–‰ ์ˆœ์„œ์™€ ๋‚ด๋ถ€ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ์ผ์ผ์ด ์ˆ˜๋™ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.
  • Docker Compose๋ฅผ ํ†ตํ•ด ๋‹จ์ผ `yaml` ํŒŒ์ผ๋กœ ์ „์ฒด ์„œ๋น„์Šค์˜ ์„ค์ •๊ณผ ์˜์กด ๊ด€๊ณ„๋ฅผ ๊ด€๋ฆฌํ•˜์—ฌ ๋ช…๋ น์–ด ํ•œ ์ค„๋กœ ์ผ๊ด„ ์‹คํ–‰ ๋ฐ ์žฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Docker Compose ๊ตฌ์„ฑ

4. AWS ํ™˜๊ฒฝ ๋ฐฐํฌ ๋ฐ ์šด์˜

์„œ๋น„์Šค ์š”์•ฝ
- ์Šคํƒ€ํŠธ์—…์ด ์ตœ์ดˆ๋กœ ๋ฐฐํฌํ•˜๋Š” ์„œ๋น„์Šค, DAU 30, ํ‰๊ท  RPS 0.07, ๋ถ€ํŠธ์บ ํ”„ ๋‚ด๋ถ€ ์ธ์›์„ ํƒ€๊ฒŸ์œผ๋กœ ๋ฐฐํฌ ์‹œ์ž‘
- AWS EC2 ํ•œ ๋Œ€์— ๊ฐ ์„œ๋น„์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ปจํ…Œ์ด๋„ˆํ™”ํ•˜์—ฌ Docker Compose๋กœ ๋ฐฐํฌ

1) ๋„คํŠธ์›Œํฌ ๋ฐ ๋ณด์•ˆ

(1) VPC์™€ ์„œ๋ธŒ๋„ท

์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋กœ ๋ฐฐํฌํ•˜๋ฏ€๋กœ AWS์˜ ๊ธฐ๋ณธ VPC์™€ ์„œ๋ธŒ๋„ท์„ ์‚ฌ์šฉํ•œ๋‹ค.

(2) ๋ณด์•ˆ ๊ทธ๋ฃน ์ธ๋ฐ”์šด๋“œ ์ตœ์†Œํ™”

๊ธฐ๋ณธ 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์—์„œ๋งŒ ์ ‘๊ทผํ•˜๋„๋ก ์„ค์ •ํ•œ๋‹ค.

(3) ์ธํ”„๋ผ ์ ‘๊ทผ ๊ถŒํ•œ ํ†ต์ œ

์šฐ๋ฆฌ ํŒ€์˜ ์ธํ”„๋ผ ๋‹ด๋‹น์€ 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": "*"
    }
  ]
}

2) ์›น ์ ‘์†(HTTPS)๊ณผ ํŠธ๋ž˜ํ”ฝ ๋ผ์šฐํŒ…

(1) ์ ‘์† ์ฃผ์†Œ ๊ณ ์ •

์‚ฌ์šฉ์ž๊ฐ€ ์šฐ๋ฆฌ ์„œ๋น„์Šค๋ฅผ ๊ธฐ์–ตํ•˜๊ธฐ ์‰ฌ์šด ๊ณ ์ •๋œ ์ฃผ์†Œ๋กœ ๋“ค์–ด์™€์•ผ ํ•˜๋ฏ€๋กœ, ๋„๋ฉ”์ธ์„ ๊ตฌ๋งคํ•˜์—ฌ ๊ณ ์ • IP(Elastic IP)์— ์—ฐ๊ฒฐํ•œ๋‹ค.

  • ์‚ฌ์šฉ์ž๋Š” IP์ฃผ์†Œ๊ฐ€ ์•„๋‹Œ ๊ธฐ์–ตํ•˜๊ธฐ ์‰ฌ์šด ๋„๋ฉ”์ธ ์ฃผ์†Œ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ๋„๋ฉ”์ธ ์ฃผ์†Œ๋ฅผ EC2 IP ์ฃผ์†Œ์— ์—ฐ๊ฒฐํ•  ๋•Œ, EC2 ์žฌ์‹œ์ž‘ ์‹œ IP ๋ณ€๊ฒฝ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ์ • IP(Elastic IP)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

(2) HTTPS

์ถ”๊ฐ€ ์ธํ”„๋ผ ๋น„์šฉ์„ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๊ณ  ๋น ๋ฅธ ๋ฐฐํฌ๋ฅผ ์œ„ํ•ด, 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๋ฅผ ์„ ํƒํ•จ

(3) ํŠธ๋ž˜ํ”ฝ ํ๋ฆ„

์‚ฌ์šฉ์ž (๋ธŒ๋ผ์šฐ์ €)
   โ”‚
   โ”œโ”€ [HTTP :80]  โ”€โ”€> Nginx โ”€โ”€> HTTPS(:443)๋กœ 301 ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
   โ”‚
   โ””โ”€ [HTTPS :443] โ”€โ”€> Nginx (SSL ์ข…๋ฃŒ ๋ฐ ๋ผ์šฐํŒ…)
                          โ”‚
                          โ”œโ”€ [/] ์ •์  ํŽ˜์ด์ง€  โ”€โ”€> React ๋นŒ๋“œ ํŒŒ์ผ ์ง์ ‘ ์„œ๋น™
                          โ”‚
                          โ””โ”€ [/api] ์š”์ฒญ โ”€โ”€> ๋ฐฑ์—”๋“œ ์ปจํ…Œ์ด๋„ˆ (Spring Boot)
                                                     โ”‚
                                                     โ”œโ”€ AI ๊ฒ€์ฆ โ”€โ”€> AI ์ปจํ…Œ์ด๋„ˆ (FastAPI)
                                                     โ”œโ”€ ๋ฐ์ดํ„ฐ   โ”€โ”€> PostgreSQL ์ปจํ…Œ์ด๋„ˆ
                                                     โ””โ”€ ์บ์‹œ/์„ธ์…˜ โ”€โ”€> Redis ์ปจํ…Œ์ด๋„ˆ

3) EC2์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์–ด๋–ป๊ฒŒ ์•ˆ์ •์ ์œผ๋กœ ์šด์˜ํ•  ๊ฒƒ์ธ๊ฐ€?

(1) DB ๋ฐ์ดํ„ฐ ์˜์†์„ฑ ๋ณด์กด

๋น„์šฉ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด, RDS ๊ฐ™์€ ๊ด€๋ฆฌํ˜• DB๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  ์ปจํ…Œ์ด๋„ˆ๋กœ ์ง์ ‘ ๋„์šฐ๋˜, ์ปจํ…Œ์ด๋„ˆ ์ข…๋ฃŒ ์‹œ ๋ฐ์ดํ„ฐ ์†Œ๋ฉธ์„ ๋ง‰๊ธฐ ์œ„ํ•ด EC2์˜ ๊ธฐ๋ณธ EBS ๋ณผ๋ฅจ์„ ๋งˆ์šดํŠธํ•˜์—ฌ ์ถ”๊ฐ€ ๋น„์šฉ ์—†์ด ๋ฐ์ดํ„ฐ ์˜์†์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

  • PostgreSQL RDS ์›” ๋น„์šฉ(์„œ์šธ): ์ธ์Šคํ„ด์Šค(t4g.micro, $0.0250/์‹œ๊ฐ„ * 730์‹œ๊ฐ„ = $18.25) + ์Šคํ† ๋ฆฌ์ง€($0.131/GB * 20GB = 2.62) = $20.87 RDS ๋น„์šฉ ๋ฌธ์„œ

(2) ์‚ฌ์šฉ์ž ๋ฌผํ’ˆ ์‚ฌ์ง„ ์ €์žฅ

EC2 ์ง์ ‘ ์ €์žฅ์€ ๋””์Šคํฌ ์šฉ๋Ÿ‰ ๊ณ ๊ฐˆ๊ณผ ์ธ์Šคํ„ด์Šค ๊ต์ฒด ์‹œ ๋ฐ์ดํ„ฐ ์ด์ „ ์œ„ํ—˜์ด ์žˆ์œผ๋ฏ€๋กœ, ํ˜„์žฌ ๊ทœ๋ชจ์—์„œ ๋น„์šฉ์ด $0์ด๋ฉด์„œ ๋ฌด์ œํ•œ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•œ AWS S3์— ์ด๋ฏธ์ง€๋ฅผ ์ €์žฅํ•œ๋‹ค.

  • EC2 ์ง์ ‘ ์ €์žฅ: S3 ์—ฐ๋™ ์ฝ”๋“œ๊ฐ€ ์—†์–ด ์ดˆ๊ธฐ์—” ๋น ๋ฅด์ง€๋งŒ, ์‚ฌ์ง„์ด ์Œ“์ด๋ฉด EBS ์šฉ๋Ÿ‰ ๋ถ€์กฑ์ด ๋ฐœ์ƒํ•˜๊ณ  ์„œ๋ฒ„ ์žฌ๋ฐฐํฌ/๊ต์ฒด ์‹œ ๋ฐ์ดํ„ฐ ์ด์ „์ด ๋งค์šฐ ๋ฒˆ๊ฑฐ๋กœ์›€.
  • AWS S3: ํ˜„์žฌ ๊ทœ๋ชจ์—์„œ(5GB ๋ฌด๋ฃŒ) ๋น„์šฉ์ด ์—†์œผ๋ฉฐ, EC2 ๋””์Šคํฌ ์šฉ๋Ÿ‰ ๊ณ ๊ฐˆ ๊ฑฑ์ • ์—†์ด ํŒŒ์ผ ์ €์žฅ์†Œ๋ฅผ ์ธ์Šคํ„ด์Šค์™€ ์™„์ „ํžˆ ๋ถ„๋ฆฌํ•ด ์•ˆ์ •์ ์œผ๋กœ ์šด์˜ํ•  ์ˆ˜ ์žˆ์Œ.

-> ์ด๋ฏธ์ง€๊ฐ€ ์–ผ๋งˆ๋‚˜ ์Œ“์ผ์ง€ ๊ณ„์‚ฐ์„ ๋‹ค์‹œํ•ด๋ด์•ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๋น„์šฉ ๊ณ„์‚ฐ ๋ฐ ๋…ผ๋ฆฌ ๊ฒ€์ฆ ํ•„์š”) e.g. 120๋ช…์˜ ์œ ์ €๊ฐ€ ๋ฌผ๊ฑด์„ 10๊ฐœ, ๋ฌผ๊ฑด ๋‹น 3์žฅ์˜ ์‚ฌ์ง„ -> nGB

(3) ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ์ €์žฅ

ํผ๋ธ”๋ฆญ ์ด๋ฏธ์ง€ ๋ฐฐํฌ ์‹œ ์„ธ ๋„๊ตฌ ๋ชจ๋‘ ๋ฌด๋ฃŒ์ด๋ฏ€๋กœ, ๋ณ„๋„์˜ ์™ธ๋ถ€ ๊ณ„์ • ์—ฐ๋™์ด๋‚˜ ์‹œํฌ๋ฆฟ ๋ฐœ๊ธ‰ ์—†์ด ๋น ๋ฅด๊ณ  ํŽธ๋ฆฌํ•˜๊ฒŒ GitHub ์ƒํƒœ๊ณ„์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” GHCR์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • Public ์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ, ์†Œ์ˆ˜์˜ docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ/์—…๋กœ๋“œ ์กฐ๊ฑด์—์„œ๋Š” Docker hub, AWS ECR, GHCR ์„ธ ์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋ชจ๋‘ ๋ฌด๋ฃŒ
  • CI/CD ๋‹จ๊ณ„์—์„œ Docker hub์™€ ECR์€ ๊ฐ๊ฐ ์‹œํฌ๋ฆฟ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ, GHCR๋Š” github์—์„œ ์ œ๊ณตํ•˜๋Š” ์ธ์ฆ ํ† ํฐ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ํŽธ๋ฆฌํ•˜๋‹ค.(${{ secrets.GITHUB_TOKEN }})

(4) ๋ฉ”ํŠธ๋ฆญ ๊ธฐ๋ฐ˜ ์žฅ์•  ์ธ์ง€

ํ”„๋กœ๋ฉ”ํ…Œ์šฐ์Šค๋‚˜ ๊ทธ๋ผํŒŒ๋‚˜ ๊ฐ™์€ ๋ณ„๋„ ๋ชจ๋‹ˆํ„ฐ๋ง ํˆด ๊ตฌ์ถ•์€ ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„์™€ ์šด์˜ ๋ณต์žก๋„๊ฐ€ ์ปค์ง€๋ฏ€๋กœ, ์ถ”๊ฐ€ ๋น„์šฉ๊ณผ ์„ค์น˜ ์—†์ด EC2์˜ CPU/๋ฉ”๋ชจ๋ฆฌ/๋„คํŠธ์›Œํฌ ์ƒํƒœ๋ฅผ ๊ธฐ๋ณธ ์ œ๊ณตํ•˜๋Š” AWS CloudWatch ๊ธฐ๋ณธ ๋ฉ”ํŠธ๋ฆญ๊ณผ ์•Œ๋žŒ์„ ์‚ฌ์šฉํ•œ๋‹ค.

5. 1์ฐจ ๋ฐฐํฌ ๊ตฌ์กฐ์˜ ํ•œ๊ณ„

์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” ์ ์€ ๋น„์šฉ๊ณผ ๋น ๋ฅธ ๋ฐฐํฌ๋ฅผ ํ•ด์•ผํ•˜๋Š” ํ˜„์žฌ ๋ชฉํ‘œ์™€, ์„œ๋น„์Šค๊ฐ€ ํŠน์ • ์‚ฌ์šฉ์ž์™€ ํŠน์ • ์‹œ๊ฐ„๋Œ€์— ์‚ฌ์šฉ๋  ๊ฒƒ์„ ๊ณ ๋ คํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์˜ ํ•œ๊ณ„์ ์„ ๊ฐ–๋Š”๋‹ค.

1) ๋‹จ์ผ ์žฅ์• ์ (SPOF)๊ณผ ๋ฐฐํฌ ์‹œ ์„œ๋น„์Šค ์ค‘๋‹จ

  • ์ „์ฒด ์„œ๋น„์Šค ์ค‘๋‹จ: EC2 ์ธ์Šคํ„ด์Šค 1๋Œ€์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์›น, API, DB, AI๊นŒ์ง€ ๋ชจ๋“  ์„œ๋น„์Šค๊ฐ€ ์ฆ‰์‹œ ์ค‘๋‹จ๋œ๋‹ค.
  • ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ๋ถˆ๊ฐ€: ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋กœ ๋ฐฐํฌํ•˜๋ฏ€๋กœ ์ƒˆ ๋ฒ„์ „์„ ๋ฐฐํฌํ•  ๋•Œ ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘ ๋™์•ˆ ์„œ๋น„์Šค ์ค‘๋‹จ(๋‹ค์šดํƒ€์ž„)์ด ๋ฐœ์ƒํ•œ๋‹ค.

2) ๋ฐ์ดํ„ฐ ์•ˆ์ •์„ฑ ๋ฐ ๋ฐฑ์—… ํ•œ๊ณ„

  • ๋ณต๊ตฌ ๊ธฐ๋Šฅ ๋ถ€์žฌ: ๊ด€๋ฆฌํ˜• RDS๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ž๋™ ๋‹ค์ค‘ํ™”(Multi-AZ), ์‹ค์‹œ๊ฐ„ ์‹œ์  ๋ณต์›, ์ž๋™ ์žฅ์•  ๋ณต๊ตฌ๊ฐ€ ์ง€์›๋˜์ง€ ์•Š๋Š”๋‹ค.

4) ์ˆ˜ํ‰์  ํ™•์žฅ(Scale-out) ๋ถˆ๊ฐ€

  • ํŠธ๋ž˜ํ”ฝ์ด ๋Š˜์–ด๋‚ฌ์„ ๋•Œ ์„œ๋ฒ„ ๋Œ€์ˆ˜๋ฅผ ๋Š˜๋ ค ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„์‚ฐํ•˜๋Š” ์˜คํ† ์Šค์ผ€์ผ๋ง์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ธ์Šคํ„ด์Šค ์ฒด๊ธ‰์„ ์˜ฌ๋ฆฌ๋Š” Scale-up๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.
โš ๏ธ **GitHub.com Fallback** โš ๏ธ