๐ŸŽฏ 20์ฃผ์ฐจ ํ•™์Šต ์ปค๋ฆฌํ˜๋Ÿผ โ€” HTTP/๋„คํŠธ์›Œํฌ + DevOps + Observability

Psjยท6์ผ ์ „

F-lab

๋ชฉ๋ก ๋ณด๊ธฐ
21/50

๐ŸŽฏ 20์ฃผ์ฐจ ํ•™์Šต ์ปค๋ฆฌํ˜๋Ÿผ โ€” HTTP/๋„คํŠธ์›Œํฌ + DevOps + Observability

19์ฃผ์ฐจ(ํ…Œ์ŠคํŠธ ์‹ฌํ™”) ์ดํ›„ Claude๊ฐ€ ์ž„์˜๋กœ ๊ตฌ์„ฑํ•œ ํ•™์Šต ์—ฌ์ •์˜ ์ตœ์ข… ์ฃผ์ฐจ.
1~19์ฃผ์ฐจ์˜ ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌ๋˜๊ณ  ์šด์˜๋˜๋Š” ์˜์—ญ ์„ ์ •๋ณตํ•œ๋‹ค.

  • HTTP/๋„คํŠธ์›Œํฌ ๊นŠ์ด โ€” ๋ฐฑ์—”๋“œ์˜ ํ† ๋Œ€
  • ์ปจํ…Œ์ด๋„ˆ์™€ Kubernetes โ€” ํ˜„๋Œ€ ๋ฐฐํฌ์˜ ํ‘œ์ค€
  • CI/CD โ€” ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ๋‹ค๋ฆฌ
  • Observability โ€” ์šด์˜ ์ค‘ ์ผ์–ด๋‚˜๋Š” ์ผ์„ ๋ณด๋Š” ๋ˆˆ

4๋…„์ฐจ ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹œ๋‹ˆ์–ด/๋ฆฌ๋“œ ๋กœ ๊ฐ€๋Š” ๋งˆ์ง€๋ง‰ ๊ด€๋ฌธ.


๐Ÿค” ์™œ 20์ฃผ์ฐจ์— ์ด ์ฃผ์ œ๋“ค์ธ๊ฐ€

1~19์ฃผ์ฐจ์˜ ์œ„์น˜:

  • ์ฝ”๋“œ๋ฅผ ์ž˜ ๋งŒ๋“œ๋Š” ๋ฒ• ์€ ์ถฉ๋ถ„ํžˆ ํ•™์Šต
  • ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ ์ฝ”๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋„๋‹ฌํ•˜๊ณ , ์–ด๋–ป๊ฒŒ ์šด์˜๋˜๋Š”์ง€ ๋Š” ๋ฏธํ•™์Šต

์™œ ์ด ์‹œ์ ์— ๊ฒฐ์ •์ ์ธ๊ฐ€:

  1. ์‹œ๋‹ˆ์–ด ๋ฉด์ ‘ ์ฐจ๋ณ„ํ™” โ€” "์žฅ์•  ๋Œ€์‘ ๊ฒฝํ—˜์€?" "K8s ์จ๋ณด์…จ๋‚˜์š”?" "TLS handshake ์„ค๋ช…?"
  2. ์‹ค๋ฌด 80%๊ฐ€ ์ฝ”๋“œ ์ž‘์„ฑ ์™ธ ์˜์—ญ โ€” 4๋…„์ฐจ์—์„œ ์‹œ๋‹ˆ์–ด๋กœ ๊ฐ€๋Š” ํ•ต์‹ฌ ์ฐจ์ด
  3. ILIC ์šด์˜์˜ ํ† ๋Œ€ โ€” 102 ํ…Œ์ด๋ธ”, 431 API๊ฐ€ ์•ˆ์ •์ ์œผ๋กœ ๋Œ์•„๊ฐ€๋ ค๋ฉด ํ•„์ˆ˜
  4. ๋ฉด์ ‘ ์ถœ์ œ ๋นˆ๋„ ๋†’์Œ โ€” "RESTful API"๋ถ€ํ„ฐ "K8s ์ปจ์…‰"๊นŒ์ง€

ILIC ๊ด€์ :

  • ํ˜„์žฌ Docker ์‚ฌ์šฉ ์ถ”์ • (CLAUDE.md ์ปจํ…์ŠคํŠธ์—์„œ ์–ธ๊ธ‰)
  • ๊ทธ๋Ÿฌ๋‚˜ K8s, ๋ชจ๋‹ˆํ„ฐ๋ง, ๋ถ„์‚ฐ ์ถ”์  ๋„์ž… ์—ฌ๋ถ€๋Š” ๋ฏธ์ง€์ˆ˜
  • ๋„์ž…ํ•œ๋‹ค๋ฉด ํฐ ๊ฐ€์น˜, ์•ˆ ํ–ˆ๋‹ค๋ฉด ๋ฉด์ ‘ ๋‹ต๋ณ€ ๋ณด๊ฐ• ํ•„์š”

๐Ÿ“Š ํ•™์Šต ๊ฒฝ๋กœ ํ•œ๋ˆˆ์— ๋ณด๊ธฐ

[Part A โ€” ๋„คํŠธ์›Œํฌ ๊ธฐ์ดˆ (Day 1-2)]
  [Phase 1] HTTP ๊นŠ์ด (HTTP/1.1, HTTP/2, HTTP/3)
     โ†“
  [Phase 2] TCP/IP์™€ TLS โ—„ ์ •์  1

[Part B โ€” DevOps์™€ ์ปจํ…Œ์ด๋„ˆ (Day 3-4)]
  [Phase 3] Docker ๊นŠ์ด
     โ†“
  [Phase 4] Kubernetes ํ•ต์‹ฌ โ—„ ์ •์  2

[Part C โ€” CI/CD์™€ ์šด์˜ (Day 5-6)]
  [Phase 5] CI/CD ํŒŒ์ดํ”„๋ผ์ธ
     โ†“
  [Phase 6] 12-Factor App๊ณผ ์šด์˜ ์›์น™

[Part D โ€” Observability (Day 7)]
  [Phase 7] 3 Pillars (Logs, Metrics, Traces) โ—„ ์ •์  3
     โ†“
  [Phase 8] ์žฅ์•  ๋Œ€์‘๊ณผ ์‚ฌ๊ณ  ๋ถ„์„

์ด 8 Phase ร— 28 Unit โ€” ์ •์  3๊ฐœ๋ฅผ ๊ฐ€์ง„ ์••์ถ• ๋‹จ์ผ ์ฃผ์ฐจ.

๐Ÿ”— 1~20์ฃผ์ฐจ ํ๋ฆ„ ์ •๋ฆฌ โ€” ํ•™์Šต ์—ฌ์ •์˜ ์™„์„ฑ

์˜์—ญ์ฃผ์ฐจ์˜๋ฏธ
Java ์–ธ์–ด1-3๊ธฐ์ดˆ
๋™์‹œ์„ฑ4๋‹จ์ผ JVM
Spring ์ƒํƒœ๊ณ„5-10ํ”„๋ ˆ์ž„์›Œํฌ
JPA11-12์˜์†์„ฑ
DB13-14๋ฐ์ดํ„ฐ
Spring MVC15์›น ๊ณ„์ธต
๋ถ„์‚ฐ ์‹œ์Šคํ…œ16-17์‹œ์Šคํ…œ ํ™•์žฅ
Spring Security18๋ณด์•ˆ
ํ…Œ์ŠคํŠธ19๊ฒ€์ฆ
HTTP/DevOps/Observability20์šด์˜

โ†’ ์‹œ๋‹ˆ์–ด ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•Œ์•„์•ผ ํ•  ๊ฑฐ์˜ ๋ชจ๋“  ์˜์—ญ


๐Ÿ—“๏ธ ๊ถŒ์žฅ ํ•™์Šต ์ผ์ • (์••์ถ• 7์ผ)

DayPhaseํ•™์Šต ๋ชฉํ‘œ
1์ผ์ฐจPhase 1HTTP ๊นŠ์ด
2์ผ์ฐจPhase 2TCP/IP + TLS (โ˜…)
3์ผ์ฐจPhase 3Docker ๊นŠ์ด
4์ผ์ฐจPhase 4Kubernetes (โ˜…)
5์ผ์ฐจPhase 5 + 6CI/CD + 12-Factor
6์ผ์ฐจPhase 7Observability 3 Pillars (โ˜…)
7์ผ์ฐจPhase 8 + ์ข…ํ•ฉ์žฅ์•  ๋Œ€์‘ + ์ž๊ธฐ ์ ๊ฒ€

์—ฌ์œ  ์ผ์ • (14์ผ): ๊ฐ Part์— +1-2์ผ. ํŠนํžˆ Phase 4, 7์€ ์ง์ ‘ ์‹ค์Šต ๊ถŒ์žฅ.


๐ŸŒ Part A โ€” ๋„คํŠธ์›Œํฌ ๊ธฐ์ดˆ (Day 1-2)

๐Ÿ“š Phase 1 โ€” HTTP ๊นŠ์ด

๋ชฉํ‘œ: ๋งค์ผ ์“ฐ์ง€๋งŒ ๊นŠ์ด ๋ชจ๋ฅด๋Š” HTTP๋ฅผ ์ •ํ™•ํžˆ ์ดํ•ดํ•œ๋‹ค.

Unit 1.1 โ€” HTTP์˜ ๋ณธ์งˆ๊ณผ ๋ฉ”์‹œ์ง€ ๊ตฌ์กฐ

์„ ์ˆ˜ ์ง€์‹: 6์ฃผ์ฐจ Phase 7 (์›น ์ธํ”„๋ผ), 15์ฃผ์ฐจ (Spring MVC)

HTTP (HyperText Transfer Protocol):

"TCP ์œ„์˜ ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜ ์š”์ฒญ-์‘๋‹ต ํ”„๋กœํ† ์ฝœ"

ํ•ต์‹ฌ ํŠน์„ฑ โญ :
1. Stateless โ€” ๋งค ์š”์ฒญ ๋…๋ฆฝ
2. Request-Response โ€” ํด๋ผ์ด์–ธํŠธ ์‹œ์ž‘
3. Text-based โ€” ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ์Œ (HTTP/2 ์ „๊นŒ์ง€)
4. Connection-less โ€” ์‘๋‹ต ํ›„ ์—ฐ๊ฒฐ ์ข…๋ฃŒ (๊ธฐ๋ณธ)


HTTP ๋ฉ”์‹œ์ง€ ๊ตฌ์กฐ:

Request:

GET /api/fares/1 HTTP/1.1                    โ† Start Line
Host: api.ilic.com                           โ† Headers
Accept: application/json
Authorization: Bearer eyJ...
                                              โ† ๋นˆ ์ค„
                                              โ† Body (POST/PUT ์‹œ)

Response:

HTTP/1.1 200 OK                              โ† Status Line
Content-Type: application/json               โ† Headers
Content-Length: 256
Cache-Control: max-age=60
                                              โ† ๋นˆ ์ค„
{"id": 1, "amount": 50000}                   โ† Body

HTTP ๋ฉ”์„œ๋“œ ์˜๋ฏธ (15์ฃผ์ฐจ ๋ณต์Šต + ์‹ฌํ™”):

๋ฉ”์„œ๋“œ์˜๋ฏธ๋ฉฑ๋“ฑ์„ฑ์•ˆ์ „์„ฑBody
GET์กฐํšŒโœ…โœ…๊ถŒ์žฅ X
POST์ƒ์„ฑโŒโŒโœ…
PUT์ „์ฒด ์ˆ˜์ •โœ…โŒโœ…
PATCH๋ถ€๋ถ„ ์ˆ˜์ •โŒ*โŒโœ…
DELETE์‚ญ์ œโœ…โŒ์˜ต์…˜
HEAD๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒโœ…โœ…X
OPTIONS๋ฉ”์„œ๋“œ ํ™•์ธโœ…โœ…X

์•ˆ์ „์„ฑ(Safe): ์„œ๋ฒ„ ์ƒํƒœ ๋ณ€๊ฒฝ X
๋ฉฑ๋“ฑ์„ฑ(Idempotent): ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•ด๋„ ๊ฒฐ๊ณผ ๋™์ผ


์ž์ฃผ ํ—ท๊ฐˆ๋ฆฌ๋Š” ํ—ค๋” โญ :

ํ—ค๋”์˜๋ฏธ
Content-Type์š”์ฒญ/์‘๋‹ต body์˜ ํƒ€์ž…
Acceptํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…
Authorization์ธ์ฆ ์ •๋ณด
Cache-Control์บ์‹ฑ ์ •์ฑ…
ETag๋ฆฌ์†Œ์Šค ๋ฒ„์ „ ์‹๋ณ„
Content-Lengthbody ํฌ๊ธฐ
Connection์—ฐ๊ฒฐ ์œ ์ง€ (keep-alive)
Host๊ฐ€์ƒ ํ˜ธ์ŠคํŒ…์šฉ
User-Agentํด๋ผ์ด์–ธํŠธ ์ •๋ณด
Referer์ด์ „ ํŽ˜์ด์ง€
Set-Cookie / Cookie์ฟ ํ‚ค ์„ค์ •/์ „์†ก

์ž๊ธฐ ์ ๊ฒ€

  • HTTP๊ฐ€ ์™œ Stateless์ธ๊ฐ€? (ํžŒํŠธ: ์„œ๋ฒ„ ๋ถ€๋‹ด โ†“, ํ™•์žฅ์„ฑ โ†‘)
  • ILIC API๊ฐ€ ๋ฉฑ๋“ฑ์„ฑ์„ ์–ด๋–ป๊ฒŒ ๋ณด์žฅํ•˜๋Š”๊ฐ€? (ํžŒํŠธ: PUT/DELETE ๋ณธ์งˆ, POST๋Š” Idempotency Key)

Unit 1.2 โ€” HTTP ์ƒํƒœ ์ฝ”๋“œ 5๊ณ„์—ด + ํ”ํ•œ ์˜คํ•ด

์„ ์ˆ˜ ์ง€์‹: Unit 1.1, 15์ฃผ์ฐจ Phase 4

5๊ณ„์—ด โญ :

๊ณ„์—ด์˜๋ฏธ
1xx์ •๋ณด (๋“œ๋ฌผ๊ฒŒ ์‚ฌ์šฉ)
2xx์„ฑ๊ณต
3xx๋ฆฌ๋‹ค์ด๋ ‰์…˜
4xxํด๋ผ์ด์–ธํŠธ ์˜ค๋ฅ˜
5xx์„œ๋ฒ„ ์˜ค๋ฅ˜

์ž์ฃผ ์“ฐ๋Š” ์ฝ”๋“œ + ํ”ํ•œ ์˜คํ•ด โญโญ :

2xx โ€” ์„ฑ๊ณต

  • 200 OK โ€” ์ผ๋ฐ˜ ์„ฑ๊ณต
  • 201 Created โ€” POST ํ›„ (Location ํ—ค๋” ๊ถŒ์žฅ)
  • 204 No Content โ€” ์„ฑ๊ณต, body ์—†์Œ (DELETE ํ›„)
  • 206 Partial Content โ€” Range ์š”์ฒญ

3xx โ€” ๋ฆฌ๋‹ค์ด๋ ‰์…˜

  • 301 Moved Permanently โ€” ์˜๊ตฌ ์ด๋™ (์บ์‹œ๋จ)
  • 302 Found โ€” ์ž„์‹œ ์ด๋™ (์บ์‹œ X)
  • 304 Not Modified โ€” ์บ์‹œ ์œ ํšจ (ETag ๋งค์นญ) โญ
  • 307 Temporary Redirect โ€” ๋ฉ”์„œ๋“œ ๋ณด์กด
  • 308 Permanent Redirect โ€” ๋ฉ”์„œ๋“œ ๋ณด์กด

ํ”ํ•œ ์˜คํ•ด โš ๏ธ :

  • 301 vs 302: ๊ฒ€์ƒ‰์—”์ง„ SEO์— ์˜ํ–ฅ (301์€ PageRank ์ „๋‹ฌ)
  • 302 vs 307: 307์€ ๋ฉ”์„œ๋“œ ๋ณด์กด (POST โ†’ POST)

4xx โ€” ํด๋ผ์ด์–ธํŠธ ์˜ค๋ฅ˜

  • 400 Bad Request โ€” ํ˜•์‹ ์˜ค๋ฅ˜
  • 401 Unauthorized โ€” ์ธ์ฆ ํ•„์š” (18์ฃผ์ฐจ)
  • 403 Forbidden โ€” ์ธ๊ฐ€ ๊ฑฐ๋ถ€ (18์ฃผ์ฐจ)
  • 404 Not Found โ€” ๋ฆฌ์†Œ์Šค ์—†์Œ
  • 405 Method Not Allowed โ€” ๋ฉ”์„œ๋“œ ๋ฏธ์ง€์›
  • 409 Conflict โ€” ์ถฉ๋Œ (์ค‘๋ณต ๋“ฑ๋ก)
  • 422 Unprocessable Entity โ€” Validation ์‹คํŒจ
  • 429 Too Many Requests โ€” Rate Limit โญ

ํ”ํ•œ ์˜คํ•ด:

  • 401 vs 403: 18์ฃผ์ฐจ์—์„œ ๋‹ค๋ฃธ โ€” ๊ฑฐ์˜ ๋งค ๋ฉด์ ‘ ์ถœ์ œ
  • 400 vs 422: ๋‘˜ ๋‹ค ํด๋ผ์ด์–ธํŠธ ์˜ค๋ฅ˜, 422๊ฐ€ ๋” ๊ตฌ์ฒด์  (์‹œ๋งจํ‹ฑ ์˜ค๋ฅ˜)
  • 404๋ฅผ ๋ณด์•ˆ์šฉ์œผ๋กœ? โ€” ๊ถŒํ•œ ์—†๋Š” ๋ฆฌ์†Œ์Šค์— 404 ๋ฐ˜ํ™˜ (์ •๋ณด ๋…ธ์ถœ ๋ฐฉ์ง€)

5xx โ€” ์„œ๋ฒ„ ์˜ค๋ฅ˜

  • 500 Internal Server Error โ€” ์ผ๋ฐ˜ ์„œ๋ฒ„ ์˜ค๋ฅ˜
  • 502 Bad Gateway โ€” ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ๋ฐ›์€ ์‘๋‹ต์ด ์ž˜๋ชป๋จ โญ
  • 503 Service Unavailable โ€” ์ผ์‹œ ๋‹ค์šด (์žฌ์‹œ๋„ ๊ถŒ์žฅ)
  • 504 Gateway Timeout โ€” ๊ฒŒ์ดํŠธ์›จ์ด ํƒ€์ž„์•„์›ƒ

ํ”ํ•œ ์˜คํ•ด โš ๏ธ :

  • 502: ๋ณดํ†ต upstream ์„œ๋น„์Šค ๋‹ค์šด (์˜ˆ: Nginx โ†’ Spring Boot ๋‹ค์šด)
  • 503: ๋ช…์‹œ์  ์ ๊ฒ€/๊ณผ๋ถ€ํ•˜ (Retry-After ํ—ค๋” ๊ฐ€๋Šฅ)
  • 504: Nginx โ†’ Spring Boot ์‘๋‹ต์ด ๋„ˆ๋ฌด ๋А๋ฆผ (timeout)

ILIC ์‹œ๋‚˜๋ฆฌ์˜ค โญ :

์‚ฌ์šฉ์ž: ์šด์ž„ ๊ฒฌ์  ๋“ฑ๋ก
  โ†“
404 โ†’ ์ž˜๋ชป๋œ ID
401 โ†’ ํ† ํฐ ๋งŒ๋ฃŒ โ†’ ์žฌ๋กœ๊ทธ์ธ
403 โ†’ ๊ถŒํ•œ ๋ถ€์กฑ
409 โ†’ ์ด๋ฏธ ๋“ฑ๋ก๋œ ๊ฒฌ์ 
422 โ†’ ํ•„์ˆ˜ ํ•„๋“œ ๋ˆ„๋ฝ
429 โ†’ API ํ˜ธ์ถœ ํ•œ๋„ ์ดˆ๊ณผ
500 โ†’ ์„œ๋ฒ„ ๋‚ด๋ถ€ ๋ฒ„๊ทธ
502 โ†’ ๊ฒฐ์ œ ์„œ๋น„์Šค ๋‹ค์šด
504 โ†’ DB ์ฟผ๋ฆฌ ํƒ€์ž„์•„์›ƒ

์ž๊ธฐ ์ ๊ฒ€

  • 502์™€ 504์˜ ์ฐจ์ด๋Š”? (ํžŒํŠธ: ์‘๋‹ต ๋ฐ›์Œ vs ์‘๋‹ต ๋ชป ๋ฐ›์Œ)
  • ILIC์—์„œ 5xx ์—๋Ÿฌ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋Š”๊ฐ€?

Unit 1.3 โ€” HTTP/1.1 โ†’ HTTP/2 โ†’ HTTP/3 โญ

์„ ์ˆ˜ ์ง€์‹: Unit 1.2

์ง„ํ™” ๊ณผ์ •:

HTTP/1.0 (1996)

  • ๋งค ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ TCP ์—ฐ๊ฒฐ
  • ๋งค์šฐ ๋น„ํšจ์œจ์ 

HTTP/1.1 (1997, ์‚ฌ์‹ค์ƒ ํ‘œ์ค€)

  • Keep-Alive โ€” ํ•œ ์—ฐ๊ฒฐ๋กœ ์—ฌ๋Ÿฌ ์š”์ฒญ
  • Pipelining (๊ทธ๋Ÿฌ๋‚˜ ๊ฑฐ์˜ ์‚ฌ์šฉ X)
  • Host ํ—ค๋” โ€” ๊ฐ€์ƒ ํ˜ธ์ŠคํŒ…
  • ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜

ํ•œ๊ณ„:

  • Head-of-Line Blocking (HOL) โš ๏ธ
    • ํ•œ ์—ฐ๊ฒฐ์— ์š”์ฒญ A, B ๋ณด๋ƒ„
    • A ์‘๋‹ต ๋Šฆ์œผ๋ฉด B๋„ ๋Œ€๊ธฐ
  • ํ—ค๋” ์ค‘๋ณต ์ „์†ก (๋งค ์š”์ฒญ๋งˆ๋‹ค ๊ฐ™์€ ํ—ค๋”)

HTTP/2 (2015) โญ

ํ•ต์‹ฌ ๊ฐœ์„ :

1. ๋ฐ”์ด๋„ˆ๋ฆฌ ํ”„๋ ˆ์ด๋ฐ

  • ํ…์ŠคํŠธ โ†’ ๋ฐ”์ด๋„ˆ๋ฆฌ
  • ํŒŒ์‹ฑ ๋น ๋ฆ„

2. Multiplexing (๋ฉ€ํ‹ฐํ”Œ๋ ‰์‹ฑ) โญโญ

"ํ•œ ์—ฐ๊ฒฐ์— ์—ฌ๋Ÿฌ ์š”์ฒญ/์‘๋‹ต์„ ๋™์‹œ์—"

HTTP/1.1:

Connection 1: [Req A] โ†’ [Res A]
Connection 2: [Req B] โ†’ [Res B]  (๋ณ„๋„ ์—ฐ๊ฒฐ ํ•„์š”)

HTTP/2:

Connection 1: [Req A, Req B, Req C ๋™์‹œ]
              [Res A, Res B, Res C ์ˆœ์„œ ๋ฌด๊ด€]

โ†’ HOL Blocking ํ•ด๊ฒฐ (Application ๊ณ„์ธต)

3. Header Compression (HPACK)

  • ํ—ค๋”๋ฅผ ์ธ๋ฑ์Šค๋กœ ์••์ถ•
  • ๋งค ์š”์ฒญ ๊ฐ™์€ ํ—ค๋” โ†’ ์ธ๋ฑ์Šค๋งŒ ์ „์†ก

4. Server Push

  • ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ์ „์— ์„œ๋ฒ„๊ฐ€ ๋ฏธ๋ฆฌ ๋ณด๋ƒ„
  • ์˜ˆ: HTML ์‘๋‹ต + CSS/JS ๋ฏธ๋ฆฌ ์ „์†ก
  • ๊ทธ๋Ÿฌ๋‚˜ ์ž˜ ์•ˆ ์“ฐ์ž„ (์บ์‹œ์™€ ์ถฉ๋Œ)

HTTP/3 (2022) โญ

ํ•ต์‹ฌ ๋ณ€ํ™”:

  • TCP โ†’ QUIC (UDP ๊ธฐ๋ฐ˜)
  • TCP ์ž์ฒด์˜ HOL Blocking ํ•ด๊ฒฐ

HTTP/2์˜ ํ•œ๊ณ„ (TCP ๋•Œ๋ฌธ):

  • TCP๋Š” ์ˆœ์„œ ๋ณด์žฅ
  • ํŒจํ‚ท 1 ์†์‹ค โ†’ ํŒจํ‚ท 2, 3 ๋„์ฐฉํ–ˆ์–ด๋„ ๋Œ€๊ธฐ
  • โ†’ TCP Layer์˜ HOL Blocking โš ๏ธ

HTTP/3 (QUIC):

  • ๊ฐ ์ŠคํŠธ๋ฆผ์ด ๋…๋ฆฝ์ 
  • ํ•œ ์ŠคํŠธ๋ฆผ ํŒจํ‚ท ์†์‹ค โ†’ ๋‹ค๋ฅธ ์ŠคํŠธ๋ฆผ ์˜ํ–ฅ X
  • ์—ฐ๊ฒฐ ํ•ธ๋“œ์…ฐ์ดํฌ ๋น ๋ฆ„ (0-RTT)

์ฑ„ํƒ ํ˜„ํ™ฉ:

  • Google, Cloudflare, YouTube ๋“ฑ ์‚ฌ์šฉ
  • ์ ์ฐจ ํ™•๋Œ€ ์ค‘

๋น„๊ต ๋งคํŠธ๋ฆญ์Šค โญ :

HTTP/1.1HTTP/2HTTP/3
์ „์†ก ๋ฐฉ์‹ํ…์ŠคํŠธ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฐ”์ด๋„ˆ๋ฆฌ
๋ฉ€ํ‹ฐํ”Œ๋ ‰์‹ฑX (HOL)โœ…โœ…
ํ—ค๋” ์••์ถ•XHPACKQPACK
์ „์†ก ๊ณ„์ธตTCPTCPQUIC (UDP)
TCP HOL์žˆ์Œ์žˆ์Œํ•ด๊ฒฐ
ํ•ธ๋“œ์…ฐ์ดํฌ1-2 RTT1-2 RTT0-1 RTT

ILIC ์ ์šฉ:

  • Spring Boot โ€” HTTP/2 ์ง€์› (Tomcat ๊ธฐ๋ณธ)
  • ํ™œ์„ฑํ™”:
server:
  http2:
    enabled: true
  • HTTP/3 โ€” ์•„์ง ์ผ๋ฐ˜์  X (CDN/๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ํ™œ์šฉ)

์ž๊ธฐ ์ ๊ฒ€

  • HTTP/2์—์„œ๋„ TCP HOL์ด ๋‚จ๋Š” ์ด์œ ๋Š”? (ํžŒํŠธ: ์ „์†ก ๊ณ„์ธต ์ž์ฒด)
  • ILIC๊ฐ€ HTTP/2๋ฅผ ์ผœ๋ฉด ์–ด๋–ค ํšจ๊ณผ? (ํžŒํŠธ: ๋ชจ๋ฐ”์ผ ํด๋ผ์ด์–ธํŠธ ์‘๋‹ต ์‹œ๊ฐ„ โ†“)

๐Ÿ“š Phase 2 โ€” TCP/IP์™€ TLS (โ˜… ์ •์  1)

๋ชฉํ‘œ: ๋ฉด์ ‘ ๋‹จ๊ณจ โ€” ๋„คํŠธ์›Œํฌ ํ† ๋Œ€๋ฅผ ๊นŠ์ด ์ดํ•ดํ•œ๋‹ค.

Unit 2.1 โ€” OSI 7๊ณ„์ธต๊ณผ TCP/IP 4๊ณ„์ธต โญ

์„ ์ˆ˜ ์ง€์‹: ์ปดํ“จํ„ฐ ๊ธฐ์ดˆ

OSI 7๊ณ„์ธต (์ด๋ก ):

๊ณ„์ธต์ด๋ฆ„์˜ˆ
7ApplicationHTTP, FTP, SMTP
6PresentationTLS, SSL, JPEG
5SessionNetBIOS
4TransportTCP, UDP โญ
3NetworkIP, ICMP โญ
2Data LinkEthernet, Wi-Fi
1Physical์ผ€์ด๋ธ”, ๊ด‘์„ฌ์œ 

TCP/IP 4๊ณ„์ธต (์‹ค์ œ):

๊ณ„์ธตOSI ๋งคํ•‘
Application7-5
Transport4
Internet3
Network Access2-1

ํ•ต์‹ฌ ์บก์Аํ™” โญ :

[HTTP Request ๋ฐ์ดํ„ฐ]
  โ†“ Application Layer
[HTTP + ๋ฐ์ดํ„ฐ]
  โ†“ Transport Layer (TCP)
[TCP ํ—ค๋” + HTTP + ๋ฐ์ดํ„ฐ] = TCP ์„ธ๊ทธ๋จผํŠธ
  โ†“ Internet Layer (IP)
[IP ํ—ค๋” + TCP ์„ธ๊ทธ๋จผํŠธ] = IP ํŒจํ‚ท
  โ†“ Network Access
[Ethernet ํ—ค๋” + IP ํŒจํ‚ท] = Frame
  โ†“
[์ „์†ก]

์ž๊ธฐ ์ ๊ฒ€

  • HTTP๋Š” OSI ๋ช‡ ๊ณ„์ธต? (ํžŒํŠธ: 7)
  • TLS๋Š” ์–ด๋””์— ์œ„์น˜? (ํžŒํŠธ: 5-6 ์‚ฌ์ด โ€” ๋˜๋Š” Transport ์œ„)

Unit 2.2 โ€” TCP 3-way Handshake โญโญโญ (๋ฉด์ ‘ 100% ์ถœ์ œ)

์„ ์ˆ˜ ์ง€์‹: Unit 2.1

TCP:

"์—ฐ๊ฒฐ ์ง€ํ–ฅ์ , ์‹ ๋ขฐ์„ฑ ์žˆ๋Š” ์ „์†ก ํ”„๋กœํ† ์ฝœ"

3-way Handshake โ€” ์—ฐ๊ฒฐ ์ˆ˜๋ฆฝ โญ :

Client                    Server
  |                          |
  |โ”€โ”€โ”€ SYN (seq=x) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|  1. "์—ฐ๊ฒฐํ• ๊ฒŒ"
  |                          |
  |โ†โ”€โ”€ SYN-ACK (seq=y, โ”€โ”€โ”€โ”€โ”€|  2. "OK, ๋„ˆ๋„ OK?"
  |    ack=x+1)              |
  |                          |
  |โ”€โ”€โ”€ ACK (ack=y+1) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|  3. "OK"
  |                          |
  |โ•โ•โ• ์—ฐ๊ฒฐ ์ˆ˜๋ฆฝ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•|
  |                          |
  |โ”€โ”€โ”€ HTTP Request โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|
  |โ†โ”€โ”€ HTTP Response โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€|

์™œ 3๋ฒˆ? โญ :

  • ์–‘์ชฝ ๋ชจ๋‘ "์†ก์‹ /์ˆ˜์‹  ๋Šฅ๋ ฅ ํ™•์ธ"
  • 2๋ฒˆ์ด๋ฉด ํ•œ ์ชฝ๋งŒ ํ™•์ธ๋จ
  • 4๋ฒˆ์ด๋ฉด ์ค‘๋ณต

4-way Handshake โ€” ์—ฐ๊ฒฐ ์ข…๋ฃŒ โญ :

Client                    Server
  |                          |
  |โ”€โ”€โ”€ FIN โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|  1. "๋๋‚ผ๊ฒŒ"
  |                          |
  |โ†โ”€โ”€ ACK โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€|  2. "OK"
  |                          |
  |   (์„œ๋ฒ„ ์ž‘์—… ๋งˆ๋ฌด๋ฆฌ)      |
  |                          |
  |โ†โ”€โ”€ FIN โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€|  3. "๋‚˜๋„ ๋"
  |                          |
  |โ”€โ”€โ”€ ACK โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|  4. "OK"
  |                          |
  |โ•โ•โ• TIME_WAIT (Client) โ•โ•|

TIME_WAIT โญ :

  • Client๊ฐ€ ๋งˆ์ง€๋ง‰ ACK ํ›„ ์ผ์ • ์‹œ๊ฐ„ ๋Œ€๊ธฐ (๋ณดํ†ต 2MSL = 1-4๋ถ„)
  • ๋งˆ์ง€๋ง‰ ACK ์†์‹ค ์‹œ ์žฌ์ „์†ก ๊ฐ€๋Šฅ
  • โ†’ Client ์ธก์— TIME_WAIT ์†Œ์ผ“ ๋ˆ„์ 
  • ๋ถ€ํ•˜ ํฐ ํด๋ผ์ด์–ธํŠธ (์˜ˆ: ํ”„๋ก์‹œ)์—์„œ ๋ฌธ์ œ

TIME_WAIT ํ•ด๊ฒฐ:

  • SO_REUSEADDR ์˜ต์…˜
  • Connection Pool๋กœ ์žฌ์‚ฌ์šฉ

TCP์˜ ์‹ ๋ขฐ์„ฑ ๋ณด์žฅ ๋ฉ”์ปค๋‹ˆ์ฆ˜ โญ :

1. Sequence Number

  • ๊ฐ ๋ฐ”์ดํŠธ์— ๋ฒˆํ˜ธ
  • ์ˆœ์„œ ๋ณด์žฅ

2. ACK

  • ๋ฐ›์€ ๋ฐ์ดํ„ฐ ํ™•์ธ
  • ๋ฏธ์ˆ˜์‹  ์‹œ ์žฌ์ „์†ก

3. Checksum

  • ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ

4. Flow Control (ํ๋ฆ„ ์ œ์–ด)

  • Sliding Window
  • ์ˆ˜์‹ ์ž ์ฒ˜๋ฆฌ ์†๋„ ๋งž์ถค

5. Congestion Control (ํ˜ผ์žก ์ œ์–ด)

  • Slow Start, Congestion Avoidance
  • ๋„คํŠธ์›Œํฌ ํ˜ผ์žก ์‹œ ์†๋„ โ†“

TCP vs UDP โญ :

TCPUDP
์—ฐ๊ฒฐ์—ฐ๊ฒฐ ์ง€ํ–ฅ๋น„์—ฐ๊ฒฐ
์‹ ๋ขฐ์„ฑโœ…X
์ˆœ์„œ๋ณด์žฅ๋ณด์žฅ X
์†๋„๋А๋ฆผ๋น ๋ฆ„
Header20+ bytes8 bytes
์šฉ๋„HTTP, DBDNS, ๊ฒŒ์ž„, VoIP

๋ฉด์ ‘ ๋ชจ์˜ ๋‹ต๋ณ€ โญ :

"TCP๋Š” ์—ฐ๊ฒฐ ์ง€ํ–ฅ์ ์ด๊ณ  ์‹ ๋ขฐ์„ฑ ์žˆ๋Š” ์ „์†ก ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ์ˆ˜๋ฆฝ ์‹œ 3-way handshake๋ฅผ ๊ฑฐ์น˜๋Š”๋ฐ, SYN, SYN-ACK, ACK ์„ธ ๋ฒˆ์˜ ๋ฉ”์‹œ์ง€๋กœ ์–‘์ชฝ ๋ชจ๋‘์˜ ์†ก์ˆ˜์‹  ๋Šฅ๋ ฅ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ข…๋ฃŒ ์‹œ์—๋Š” 4-way handshake๋กœ, ์–‘์ชฝ์ด ๊ฐ๊ฐ FIN๊ณผ ACK๋ฅผ ์ฃผ๊ณ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ๋งˆ์ง€๋ง‰ ACK ์†์‹ค์— ๋Œ€๋น„ํ•ด TIME_WAIT ์ƒํƒœ๋กœ ์ผ์ • ์‹œ๊ฐ„ ๋Œ€๊ธฐํ•˜๋Š”๋ฐ, ์ด๊ฒŒ ๋ˆ„์ ๋˜๋ฉด ์†Œ์ผ“ ๊ณ ๊ฐˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด SO_REUSEADDR ์˜ต์…˜์ด๋‚˜ Connection Pool๋กœ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

TCP๋Š” ์‹ ๋ขฐ์„ฑ์„ ์œ„ํ•ด Sequence Number, ACK, Checksum, Flow Control, Congestion Control์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•Œ๋ฌธ์— UDP๋ณด๋‹ค ๋А๋ฆฌ์ง€๋งŒ, ์ •ํ™•์„ฑ์ด ์ค‘์š”ํ•œ HTTP, DB ํ†ต์‹  ๋“ฑ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค."

์ž๊ธฐ ์ ๊ฒ€

  • ์™œ 3-way์ด๊ณ  4-way์ธ๊ฐ€์˜ ์ฐจ์ด๋Š”? (ํžŒํŠธ: ์ข…๋ฃŒ๋Š” ์–‘์ชฝ์ด ๋…๋ฆฝ์ ์œผ๋กœ ๋๋‚จ)
  • TIME_WAIT๊ฐ€ ๋ถ€ํ•˜๊ฐ€ ๋˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๋Š”? (ํžŒํŠธ: ํ”„๋ก์‹œ, ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ)

Unit 2.3 โ€” HTTPS์™€ TLS Handshake โญโญ

์„ ์ˆ˜ ์ง€์‹: Unit 2.2, 18์ฃผ์ฐจ (Security)

HTTPS:

"HTTP + TLS โ€” ์•”ํ˜ธํ™”๋œ HTTP"

์™œ ํ•„์š”ํ•œ๊ฐ€:

  • HTTP๋Š” ํ‰๋ฌธ โ†’ ๋ˆ„๊ตฌ๋‚˜ ๋„์ฒญ ๊ฐ€๋Šฅ
  • ๋น„๋ฐ€๋ฒˆํ˜ธ, ์นด๋“œ ์ •๋ณด ๋…ธ์ถœ ์œ„ํ—˜
  • ํ˜„๋Œ€ ์›น์€ ์‚ฌ์‹ค์ƒ HTTPS ํ•„์ˆ˜

TLS (Transport Layer Security):

  • SSL์˜ ํ›„์† (SSL 3.0 โ†’ TLS 1.0/1.1/1.2/1.3)
  • ํ˜„์žฌ ํ‘œ์ค€: TLS 1.2, 1.3 (1.0/1.1์€ deprecated)

TLS 1.2 Handshake (์ „ํ†ต):

Client                            Server
  |                                  |
  |โ”€โ”€โ”€ ClientHello โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|  ์ง€์› ์•”ํ˜ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜
  |                                  |
  |โ†โ”€โ”€ ServerHello โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€|  ์„ ํƒํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
  |โ†โ”€โ”€ Certificate (์ธ์ฆ์„œ) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€|  ์„œ๋ฒ„ ์ธ์ฆ์„œ
  |โ†โ”€โ”€ ServerHelloDone โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€|
  |                                  |
  |   [์ธ์ฆ์„œ ๊ฒ€์ฆ]                  |
  |                                  |
  |โ”€โ”€โ”€ ClientKeyExchange โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|  Pre-Master Secret ์ „์†ก
  |โ”€โ”€โ”€ ChangeCipherSpec โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|
  |โ”€โ”€โ”€ Finished โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|
  |                                  |
  |โ†โ”€โ”€ ChangeCipherSpec โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€|
  |โ†โ”€โ”€ Finished โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€|
  |                                  |
  |โ•โ•โ• ์•”ํ˜ธํ™”๋œ ํ†ต์‹  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•|

RTT: 2 RTT (์™•๋ณต 2๋ฒˆ)


TLS 1.3 Handshake (2018) โญ :

Client                            Server
  |                                  |
  |โ”€โ”€โ”€ ClientHello + Key Share โ”€โ”€โ”€โ”€โ”€โ†’|
  |                                  |
  |โ†โ”€โ”€ ServerHello + Cert + Key + โ”€โ”€|
  |    Finished                      |
  |                                  |
  |โ”€โ”€โ”€ Finished โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’|
  |                                  |
  |โ•โ•โ• ์•”ํ˜ธํ™”๋œ ํ†ต์‹  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•|

RTT: 1 RTT
0-RTT ๋ชจ๋“œ: ์ด์ „ ์„ธ์…˜ ์žฌ๊ฐœ ์‹œ ์ฆ‰์‹œ

๊ฐœ์„ ์ :

  • ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ œ๊ฑฐ (RC4, MD5, SHA-1 ๋“ฑ)
  • Forward Secrecy ๊ฐ•์ œ
  • ๋” ๋น ๋ฆ„

ํ•ต์‹ฌ ์›๋ฆฌ โญ :

1. ๋น„๋Œ€์นญ ์•”ํ˜ธํ™” (Asymmetric)

  • ๊ณต๊ฐœํ‚ค + ๊ฐœ์ธํ‚ค
  • ์ธ์ฆ์„œ ๊ฒ€์ฆ + ์„ธ์…˜ํ‚ค ๊ตํ™˜ ์— ์‚ฌ์šฉ
  • RSA, ECDSA

2. ๋Œ€์นญ ์•”ํ˜ธํ™” (Symmetric)

  • ๋‹จ์ผ ํ‚ค
  • ์‹ค์ œ ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™” ์— ์‚ฌ์šฉ
  • AES, ChaCha20

์™œ ๋‘˜ ๋‹ค?:

  • ๋น„๋Œ€์นญ์€ ์•ˆ์ „ํ•˜์ง€๋งŒ ๋А๋ฆผ
  • ๋Œ€์นญ์€ ๋น ๋ฅด์ง€๋งŒ ํ‚ค ๊ตํ™˜ ์–ด๋ ค์›€
  • โ†’ ๋น„๋Œ€์นญ์œผ๋กœ ํ‚ค ๊ตํ™˜, ๋Œ€์นญ์œผ๋กœ ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™”

3. ์ธ์ฆ์„œ (Certificate)

  • ์„œ๋ฒ„์˜ ์‹ ์› ๋ณด์ฆ
  • CA (Certificate Authority) ๊ฐ€ ์„œ๋ช…
  • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ CA์˜ ๊ณต๊ฐœํ‚ค๋กœ ๊ฒ€์ฆ

์ธ์ฆ์„œ ์ฒด์ธ:

Root CA (๋ธŒ๋ผ์šฐ์ €์— ๋‚ด์žฅ)
  โ†“ ์„œ๋ช…
Intermediate CA
  โ†“ ์„œ๋ช…
Leaf Certificate (์‹ค์ œ ์‚ฌ์ดํŠธ)

Let's Encrypt:

  • ๋ฌด๋ฃŒ ์ธ์ฆ์„œ ๋ฐœ๊ธ‰
  • 90์ผ ์œ ํšจ + ์ž๋™ ๊ฐฑ์‹ 

HTTPS ๋น„์šฉ โš ๏ธ :

  • ํ•ธ๋“œ์…ฐ์ดํฌ ์ถ”๊ฐ€ RTT (TLS 1.3๋กœ ์™„ํ™”)
  • CPU ์‚ฌ์šฉ๋Ÿ‰ (๋Œ€์นญ ์•”ํ˜ธํ™”๋Š” ๋งค์šฐ ๋น ๋ฆ„)
  • ์ธ์ฆ์„œ ๋น„์šฉ (Let's Encrypt๋กœ ํ•ด๊ฒฐ)

ํ˜„๋Œ€ ๊ฒฐ๋ก :

  • ๋ชจ๋“  HTTP๋Š” HTTPS์—ฌ์•ผ ํ•จ
  • HSTS ํ—ค๋”๋กœ ๊ฐ•์ œ

ILIC ์ ์šฉ:

  • ์šด์˜: Nginx/ALB์—์„œ TLS ์ข…๋ฃŒ (SSL Termination)
  • ๋‚ด๋ถ€ ํ†ต์‹ : ๋ณดํ†ต HTTP (๋ณ„๋„ ๋ณด์•ˆ ์˜์—ญ)
  • TLS 1.2+ ๊ฐ•์ œ

์ž๊ธฐ ์ ๊ฒ€

  • ์™œ ๋น„๋Œ€์นญ๊ณผ ๋Œ€์นญ์„ ์„ž๋Š”๊ฐ€? (ํžŒํŠธ: ์†๋„ + ๋ณด์•ˆ)
  • "Let's Encrypt๊ฐ€ ๋ฌด๋ฃŒ์ธ๋ฐ ์•ˆ์ „ํ•œ๊ฐ€?" (ํžŒํŠธ: ์•ˆ์ „ โ€” CA ๊ฒ€์ฆ ๊ฑฐ์นจ)

Unit 2.4 โ€” DNS์™€ Load Balancing

์„ ์ˆ˜ ์ง€์‹: Unit 2.3

DNS (Domain Name System):

"๋„๋ฉ”์ธ ์ด๋ฆ„ โ†” IP ์ฃผ์†Œ ๋ณ€ํ™˜"

api.ilic.com โ†’ 203.0.113.42

DNS ์กฐํšŒ ํ๋ฆ„:

1. Browser Cache ํ™•์ธ
2. OS Cache ํ™•์ธ
3. Router Cache ํ™•์ธ
4. ISP DNS ์„œ๋ฒ„ ์กฐํšŒ
5. Root โ†’ TLD โ†’ Authoritative DNS

DNS ๋ ˆ์ฝ”๋“œ ํƒ€์ž… โญ :

ํƒ€์ž…์˜๋ฏธ
A๋„๋ฉ”์ธ โ†’ IPv4
AAAA๋„๋ฉ”์ธ โ†’ IPv6
CNAME๋„๋ฉ”์ธ โ†’ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ (๋ณ„์นญ)
MX๋ฉ”์ผ ์„œ๋ฒ„
TXTํ…์ŠคํŠธ (SPF, DKIM, ์ธ์ฆ)
NS๋„ค์ž„์„œ๋ฒ„
SRV์„œ๋น„์Šค (ํฌํŠธ ํฌํ•จ)

Load Balancing โญ :

์—ญํ• :

  • ์—ฌ๋Ÿฌ ์„œ๋ฒ„์— ํŠธ๋ž˜ํ”ฝ ๋ถ„์‚ฐ
  • ์žฅ์•  ์ž๋™ ์šฐํšŒ (Health Check)
  • SSL Termination

์•Œ๊ณ ๋ฆฌ์ฆ˜:

์•Œ๊ณ ๋ฆฌ์ฆ˜ํŠน์ง•
Round Robin์ˆœ์ฐจ ๋ถ„๋ฐฐ
Least Connections์—ฐ๊ฒฐ ์ˆ˜ ์ ์€ ๊ณณ
IP Hash๊ฐ™์€ IP๋Š” ๊ฐ™์€ ์„œ๋ฒ„ (Sticky)
Weighted๊ฐ€์ค‘์น˜ ๊ธฐ๋ฐ˜

Layer 4 vs Layer 7 LB โญ :

L4 (Transport)L7 (Application)
๊ธฐ์ค€IP, PortURL, Header, Cookie
์†๋„๋น ๋ฆ„๋А๋ฆผ
๊ธฐ๋Šฅ๋‹จ์ˆœํ’๋ถ€ (Path ๋ผ์šฐํŒ… ๋“ฑ)
์˜ˆAWS NLBAWS ALB, Nginx

ILIC ์‹œ๋‚˜๋ฆฌ์˜ค:

  • AWS ALB๋กœ SSL ์ข…๋ฃŒ + Path ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ…
  • /api/* โ†’ Spring Boot
  • /static/* โ†’ CDN

Sticky Session โš ๏ธ :

  • ๊ฐ™์€ ์‚ฌ์šฉ์ž๋ฅผ ๊ฐ™์€ ์„œ๋ฒ„๋กœ
  • Session ๊ธฐ๋ฐ˜ ์ธ์ฆ ์‹œ ํ•„์š”
  • โ†’ JWT (Stateless)๋ฉด ๋ถˆํ•„์š” (18์ฃผ์ฐจ)

์ž๊ธฐ ์ ๊ฒ€

  • DNS Cache TTL์„ ์งง๊ฒŒ ํ•˜๋ฉด ์–ด๋–ค ํšจ๊ณผ? (ํžŒํŠธ: ๋น ๋ฅธ ๋ณ€๊ฒฝ, ๊ทธ๋Ÿฌ๋‚˜ ๋ถ€ํ•˜)
  • L4์™€ L7 ์ค‘ ILIC์— ์ ํ•ฉํ•œ ๊ฒƒ์€? (ํžŒํŠธ: API ๊ฒฝ๋กœ ๋ผ์šฐํŒ… โ†’ L7)

๐Ÿณ Part B โ€” DevOps์™€ ์ปจํ…Œ์ด๋„ˆ (Day 3-4)

๐Ÿ“š Phase 3 โ€” Docker ๊นŠ์ด

๋ชฉํ‘œ: ILIC๊ฐ€ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ผ ๊ฐ€๋Šฅ์„ฑ ๋†’์ง€๋งŒ ๊นŠ์ด ์ •๋ฆฌํ•œ๋‹ค.

Unit 3.1 โ€” ์ปจํ…Œ์ด๋„ˆ vs VM๊ณผ Docker์˜ ๋ณธ์งˆ

์„ ์ˆ˜ ์ง€์‹: ์šด์˜์ฒด์ œ ๊ธฐ์ดˆ

์ „ํ†ต ๋ฐฐํฌ์˜ ๋ฌธ์ œ:

  • "๋‚ด ์ปดํ“จํ„ฐ์—์„œ๋Š” ๋Œ์•„๊ฐ„๋‹ค" ๐Ÿ˜…
  • OS, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „ ์ฐจ์ด
  • ํ™˜๊ฒฝ ๊ฒฉ๋ฆฌ ์–ด๋ ค์›€

๊ฐ€์ƒํ™”์˜ ์ง„ํ™”:

VM (Virtual Machine)

[App A] [App B] [App C]
[Guest OS] [Guest OS] [Guest OS]    โ† ๋ฌด๊ฑฐ์›€
[Hypervisor]
[Host OS]
[Hardware]

์ปจํ…Œ์ด๋„ˆ (Container)

[App A] [App B] [App C]
[Bin/Lib] [Bin/Lib] [Bin/Lib]
[Container Runtime (Docker)]
[Host OS]                            โ† ๊ณต์œ 
[Hardware]

ํ•ต์‹ฌ ์ฐจ์ด:

  • VM: OS ์ž์ฒด ๊ฐ€์ƒํ™” โ€” GB
  • Container: ํ”„๋กœ์„ธ์Šค ๊ฒฉ๋ฆฌ โ€” MB

Docker์˜ ํ•ต์‹ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜ โญ :

1. Namespace (๊ฒฉ๋ฆฌ)

  • PID, Network, Mount, User ๋“ฑ ๋ถ„๋ฆฌ
  • ์ปจํ…Œ์ด๋„ˆ๋ผ๋ฆฌ ์•ˆ ๋ณด์ž„

2. cgroups (์ œํ•œ)

  • CPU, ๋ฉ”๋ชจ๋ฆฌ, I/O ํ•œ๊ณ„

3. Union File System

  • ๋ ˆ์ด์–ด ๊ธฐ๋ฐ˜
  • ๋ณ€๊ฒฝ๋ถ„๋งŒ ์ถ”๊ฐ€
  • โ†’ ๋น ๋ฅด๊ณ  ํšจ์œจ์ 

3๊ฐ€์ง€ ํ•ต์‹ฌ ๊ฐœ๋… โญ :

Image (์ด๋ฏธ์ง€)

  • ์ •์  โ€” ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€
  • ๋ ˆ์ด์–ด๋“ค์˜ ์กฐํ•ฉ
  • Dockerfile๋กœ ์ƒ์„ฑ

Container (์ปจํ…Œ์ด๋„ˆ)

  • ์ด๋ฏธ์ง€์˜ ์‹คํ–‰ ์ธ์Šคํ„ด์Šค
  • ๋™์  โ€” ์ƒํƒœ ๊ฐ€์ง
  • ์ข…๋ฃŒ ์‹œ ๋ณ€๊ฒฝ ์‚ฌ๋ผ์ง (volume ์™ธ)

Registry (์ €์žฅ์†Œ)

  • ์ด๋ฏธ์ง€ ์ €์žฅ
  • Docker Hub, ECR, GCR

์ž๊ธฐ ์ ๊ฒ€

  • VM๊ณผ Container์˜ ๊ฒฐ์ •์  ์ฐจ์ด๋Š”? (ํžŒํŠธ: OS ๊ณต์œ )
  • ์™œ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋นจ๋ฆฌ ์‹œ์ž‘ํ•˜๋Š”๊ฐ€? (ํžŒํŠธ: ํ”„๋กœ์„ธ์Šค ์‹œ์ž‘)

Unit 3.2 โ€” Dockerfile๊ณผ ์ด๋ฏธ์ง€ ์ตœ์ ํ™” โญ

์„ ์ˆ˜ ์ง€์‹: Unit 3.1

๊ธฐ๋ณธ Dockerfile (Spring Boot):

FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/ilic.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]

๋ฌธ์ œ:

  • ๋งค๋ฒˆ jar ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฅผ ํ†ต์งธ๋กœ ๋ณต์‚ฌ โ†’ ์ฝ”๋“œ 1์ค„ ์ˆ˜์ •ํ•ด๋„ ์ „์ฒด ๋ ˆ์ด์–ด ์žฌ์ƒ์„ฑ
  • ์ด๋ฏธ์ง€ ํฌ๊ธฐ โ†‘

Multi-stage Build โญ โ€” ๋นŒ๋“œ์™€ ์‹คํ–‰ ๋ถ„๋ฆฌ:

# ๋นŒ๋“œ ์Šคํ…Œ์ด์ง€
FROM gradle:8-jdk17 AS builder
WORKDIR /build
COPY . .
RUN gradle build -x test

# ์‹คํ–‰ ์Šคํ…Œ์ด์ง€
FROM openjdk:17-jre-slim
WORKDIR /app
COPY --from=builder /build/libs/ilic.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]

ํšจ๊ณผ:

  • ์ตœ์ข… ์ด๋ฏธ์ง€๋Š” jdk๊ฐ€ ์•„๋‹Œ jre
  • gradle, ์†Œ์Šค์ฝ”๋“œ ๋“ฑ ์ œ์™ธ
  • 1GB โ†’ 200MB ๊ฐ€๋Šฅ

๋ ˆ์ด์–ด ์บ์‹ฑ ํ™œ์šฉ โญ :

๋‚˜์œ ์˜ˆ:

COPY . .
RUN gradle build  # ์ฝ”๋“œ 1์ค„ ๋ณ€๊ฒฝํ•ด๋„ ์ฒ˜์Œ๋ถ€ํ„ฐ

์ข‹์€ ์˜ˆ (Spring Boot ๊ถŒ์žฅ):

# ์˜์กด์„ฑ๋งŒ ๋จผ์ €
COPY build.gradle settings.gradle ./
RUN gradle dependencies

# ๊ทธ ๋‹ค์Œ ์†Œ์Šค
COPY src ./src
RUN gradle build

โ†’ ์˜์กด์„ฑ ๋ณ€๊ฒฝ ์—†์œผ๋ฉด ์บ์‹œ ํ™œ์šฉ


Spring Boot Layered JAR โญ :
Spring Boot 2.3+๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ตœ์ ํ™”:

FROM openjdk:17-jre-slim
WORKDIR /app
ARG JAR_FILE=target/ilic.jar
COPY ${JAR_FILE} app.jar
RUN java -Djarmode=layertools -jar app.jar extract

FROM openjdk:17-jre-slim
WORKDIR /app
COPY --from=builder /app/dependencies/ ./
COPY --from=builder /app/spring-boot-loader/ ./
COPY --from=builder /app/snapshot-dependencies/ ./
COPY --from=builder /app/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

ํšจ๊ณผ:

  • ์˜์กด์„ฑ๊ณผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ๋ถ„๋ฆฌ
  • ์ฝ”๋“œ๋งŒ ๋ณ€๊ฒฝ ์‹œ ๋งค์šฐ ๋น ๋ฅธ ์žฌ๋นŒ๋“œ

๋ณด์•ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€ โญ :

1. non-root ์‚ฌ์šฉ์ž

RUN useradd -ms /bin/bash appuser
USER appuser

2. ์ตœ์†Œ ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€

  • alpine ๋˜๋Š” slim ๋ณ€ํ˜•
  • distroless (Google) โ€” ๋” ์ž‘์Œ

3. .dockerignore

.git
.gradle
target
*.md

4. ๋ช…์‹œ์  ๋ฒ„์ „

FROM openjdk:17.0.9-jre-slim   # โŒ latest ๊ธˆ์ง€

ILIC ์‹œ๋‚˜๋ฆฌ์˜ค:

  • Multi-stage + Layered JAR
  • non-root ์‚ฌ์šฉ์ž
  • ์ด๋ฏธ์ง€ ํฌ๊ธฐ 200MB ์ดํ•˜ ๋ชฉํ‘œ

์ž๊ธฐ ์ ๊ฒ€

  • ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ 1/5๋กœ ์ค„์ด๋Š” ๋ฐฉ๋ฒ• 3๊ฐ€์ง€๋Š”?
  • ILIC๊ฐ€ latest ํƒœ๊ทธ๋ฅผ ์“ฐ๋ฉด ์–ด๋–ค ์œ„ํ—˜? (ํžŒํŠธ: ์žฌํ˜„ ๋ถˆ๊ฐ€๋Šฅ, ์˜๋„์น˜ ์•Š์€ ์—…๋ฐ์ดํŠธ)

Unit 3.3 โ€” Docker Compose

์„ ์ˆ˜ ์ง€์‹: Unit 3.2

๋ฌธ์ œ:

  • ILIC๋Š” Spring Boot + MySQL + Redis + Kafka...
  • ๊ฐ๊ฐ docker run ๋ช…๋ น์–ด 6๊ฐœ?

Docker Compose:

"์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ YAML๋กœ ์ •์˜ + ํ•œ ๋ฒˆ์— ์‹คํ–‰"

version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/ilic
      - SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD}
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - ilic-network
  
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_DATABASE: ilic
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - ilic-network
  
  redis:
    image: redis:7-alpine
    networks:
      - ilic-network
  
  kafka:
    image: confluentinc/cp-kafka:latest
    networks:
      - ilic-network

volumes:
  mysql-data:

networks:
  ilic-network:

์‹คํ–‰:

docker-compose up -d
docker-compose down
docker-compose logs -f app

Compose vs Kubernetes:

  • ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ: Compose
  • ์šด์˜: Kubernetes (Phase 4)

ILIC ํ™œ์šฉ:

  • ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๊ตฌ์„ฑ
  • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ (19์ฃผ์ฐจ Testcontainers์˜ ๋ณด์™„)

์ž๊ธฐ ์ ๊ฒ€

  • depends_on์˜ healthcheck๊ฐ€ ์™œ ์ค‘์š”? (ํžŒํŠธ: MySQL ์‹œ์ž‘๊ณผ ready์˜ ์ฐจ์ด)
  • volumes๋ฅผ ์•ˆ ์“ฐ๋ฉด? (ํžŒํŠธ: ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘ ์‹œ ๋ฐ์ดํ„ฐ ์†์‹ค)

๐Ÿ“š Phase 4 โ€” Kubernetes ํ•ต์‹ฌ (โ˜… ์ •์  2)

๋ชฉํ‘œ: ํ˜„๋Œ€ ์šด์˜์˜ ํ‘œ์ค€ โ€” K8s์˜ ํ•ต์‹ฌ ์ปจ์…‰์„ ๋ฉด์ ‘ ๋‹ต๋ณ€ ๊ฐ€๋Šฅ ์ˆ˜์ค€์œผ๋กœ.

Unit 4.1 โ€” ์™œ Kubernetes์ธ๊ฐ€

์„ ์ˆ˜ ์ง€์‹: Phase 3

Docker๋งŒ์œผ๋กœ์˜ ํ•œ๊ณ„:

  • ์„œ๋ฒ„ 1๋Œ€์— ์ปจํ…Œ์ด๋„ˆ 100๊ฐœ? ๊ด€๋ฆฌ ์–ด๋ ค์›€
  • ์ปจํ…Œ์ด๋„ˆ ์ž๋™ ์žฌ์‹œ์ž‘?
  • ํŠธ๋ž˜ํ”ฝ ํญ์ฆ ์‹œ ์ž๋™ ํ™•์žฅ?
  • ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ?

Kubernetes (K8s):

"์ปจํ…Œ์ด๋„ˆ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ํ‘œ์ค€"


ํ•ต์‹ฌ ๊ธฐ๋Šฅ โญ :

1. Self-healing

  • ์ปจํ…Œ์ด๋„ˆ ๋‹ค์šด ์‹œ ์ž๋™ ์žฌ์‹œ์ž‘
  • ๋…ธ๋“œ ๋‹ค์šด ์‹œ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ์ด์ „

2. Auto-scaling

  • ๋ถ€ํ•˜์— ๋”ฐ๋ผ ์ž๋™ ํ™•์žฅ/์ถ•์†Œ
  • HPA (Horizontal Pod Autoscaler)

3. Service Discovery

  • ์„œ๋น„์Šค ์ด๋ฆ„์œผ๋กœ ํ†ต์‹ 
  • 17์ฃผ์ฐจ์˜ Service Discovery๊ฐ€ K8s์—์„œ๋Š” ์ž๋™

4. Load Balancing

  • Service๊ฐ€ ์ž๋™ LB

5. Rolling Update

  • ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ
  • ์ ์ง„์  ๊ต์ฒด

6. Configuration Management

  • ConfigMap, Secret์œผ๋กœ ์„ค์ • ๋ถ„๋ฆฌ

Cluster ๊ตฌ์กฐ โญ :

[Control Plane (Master)]
โ”œโ”€โ”€ API Server  โ† ๋ชจ๋“  ๋ช…๋ น์˜ ์ž…๊ตฌ
โ”œโ”€โ”€ etcd        โ† ์ƒํƒœ ์ €์žฅ (17์ฃผ์ฐจ ํ•ฉ์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜)
โ”œโ”€โ”€ Scheduler   โ† Pod ๋ฐฐ์น˜ ๊ฒฐ์ •
โ””โ”€โ”€ Controller Manager  โ† ์ƒํƒœ ์œ ์ง€

[Worker Nodes]
โ”œโ”€โ”€ Node 1
โ”‚   โ”œโ”€โ”€ kubelet      โ† ๋…ธ๋“œ ์—์ด์ „ํŠธ
โ”‚   โ”œโ”€โ”€ kube-proxy   โ† ๋„คํŠธ์›Œํฌ
โ”‚   โ””โ”€โ”€ Pods (containers)
โ”œโ”€โ”€ Node 2
โ””โ”€โ”€ Node 3

์ž๊ธฐ ์ ๊ฒ€

  • K8s๊ฐ€ ๋“ฑ์žฅํ•œ ํ•ต์‹ฌ ๋™๊ธฐ๋Š”?
  • ILIC ๊ฐ™์€ ๋‹จ์ผ ์•ฑ์ด K8s๋ฅผ ์“ธ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”๊ฐ€? (ํžŒํŠธ: ์ž‘์œผ๋ฉด Compose๋„ ์ถฉ๋ถ„)

Unit 4.2 โ€” Pod, Deployment, Service โญโญ (๋ฉด์ ‘ ๋‹จ๊ณจ)

์„ ์ˆ˜ ์ง€์‹: Unit 4.1

3๊ฐ€์ง€ ํ•ต์‹ฌ ๋ฆฌ์†Œ์Šค โญ :

1. Pod โ€” ๊ฐ€์žฅ ์ž‘์€ ๋ฐฐํฌ ๋‹จ์œ„

apiVersion: v1
kind: Pod
metadata:
  name: ilic-pod
spec:
  containers:
  - name: ilic-app
    image: ilic:1.0.0
    ports:
    - containerPort: 8080

ํŠน์ง•:

  • ์ปจํ…Œ์ด๋„ˆ 1๊ฐœ ๋˜๋Š” ๊ทธ ์ด์ƒ
  • ๊ฐ™์€ Pod ์ปจํ…Œ์ด๋„ˆ๋Š” IP/Volume ๊ณต์œ 
  • ์ˆ˜๋ช…์ด ์ผ์‹œ์  (๋‹ค์‹œ ๋งŒ๋“ค๋ฉด IP ๋ณ€๊ฒฝ)

์™œ Pod์ธ๊ฐ€ (๊ทธ๋ƒฅ ์ปจํ…Œ์ด๋„ˆ ์•„๋‹ˆ๊ณ ):

  • ์‚ฌ์ด๋“œ์นด ํŒจํ„ด (๋กœ๊น… ์ปจํ…Œ์ด๋„ˆ, ํ”„๋ก์‹œ ๋“ฑ)
  • ์˜์กด์„ฑ ๊ฐ•ํ•œ ์ปจํ…Œ์ด๋„ˆ ๋ฌถ๊ธฐ

2. Deployment โ€” Pod์˜ ๊ด€๋ฆฌ์ž

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ilic-deployment
spec:
  replicas: 3                     โ† 3๊ฐœ Pod
  selector:
    matchLabels:
      app: ilic
  template:
    metadata:
      labels:
        app: ilic
    spec:
      containers:
      - name: ilic-app
        image: ilic:1.0.0
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"

์—ญํ•  โญ :

  • Replicas ๊ด€๋ฆฌ โ€” N๊ฐœ Pod ๋ณด์žฅ
  • Rolling Update โ€” ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ
  • Rollback โ€” ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋ณต๊ตฌ
  • Self-healing โ€” Pod ๋‹ค์šด ์‹œ ์žฌ์ƒ์„ฑ

Rolling Update ํ๋ฆ„:

v1: [Pod1] [Pod2] [Pod3]
       โ†“
v2 ์‹œ์ž‘: [Pod1] [Pod2] [Pod3] [Pod4(v2)]
       โ†“
[Pod2] [Pod3] [Pod4(v2)] [Pod5(v2)]  โ† Pod1 ์ข…๋ฃŒ
       โ†“
[Pod4(v2)] [Pod5(v2)] [Pod6(v2)]

3. Service โ€” Pod ๋…ธ์ถœ

๋ฌธ์ œ: Pod IP๋Š” ๋ณ€ํ•จ โ†’ ์–ด๋–ป๊ฒŒ ์ ‘๊ทผ?

Service:

"Pod ๊ทธ๋ฃน์˜ ์•ˆ์ •์ ์ธ ์ ‘๊ทผ์ "

apiVersion: v1
kind: Service
metadata:
  name: ilic-service
spec:
  selector:
    app: ilic                โ† ์ด ๋ผ๋ฒจ์˜ Pod ๋ฌถ์Œ
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP

Service Type โญ :

Type์˜๋ฏธ
ClusterIPํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€๋งŒ (๊ธฐ๋ณธ)
NodePort๋…ธ๋“œ์˜ ํŠน์ • ํฌํŠธ๋กœ ๋…ธ์ถœ
LoadBalancer์™ธ๋ถ€ LB ์ž๋™ ์ƒ์„ฑ (AWS ELB ๋“ฑ)
ExternalNameDNS CNAME

Service Discovery (17์ฃผ์ฐจ ์ž๋™ ํ•ด๊ฒฐ):

  • http://ilic-service ์œผ๋กœ ์ ‘๊ทผ โ†’ K8s๊ฐ€ ์ž๋™ ๋ผ์šฐํŒ…
  • Eureka ๋“ฑ ๋ณ„๋„ ๋„๊ตฌ ๋ถˆํ•„์š”

ILIC ์‹œ๋‚˜๋ฆฌ์˜ค:

# Backend
Deployment: ilic-app (replicas: 3)
Service: ilic-service (ClusterIP)

# Frontend
Deployment: ilic-vue (replicas: 2)
Service: ilic-vue-service

# Ingress (์™ธ๋ถ€ ์ ‘๊ทผ)
Ingress:
  - api.ilic.com โ†’ ilic-service
  - ilic.com โ†’ ilic-vue-service

์ž๊ธฐ ์ ๊ฒ€

  • Pod์™€ Deployment ์ค‘ ๋ฌด์—‡์„ ์ง์ ‘ ๋งŒ๋“ค๊นŒ? (ํžŒํŠธ: Deployment โ€” Pod๋Š” ์ž๋™)
  • LoadBalancer Type์˜ ๋น„์šฉ์€? (ํžŒํŠธ: ํด๋ผ์šฐ๋“œ LB ๋น„์šฉ)

Unit 4.3 โ€” Ingress, ConfigMap, Secret

์„ ์ˆ˜ ์ง€์‹: Unit 4.2

Ingress โ€” HTTP ๋ผ์šฐํŒ…

๋ฌธ์ œ: LoadBalancer Service๋ฅผ ๋„๋ฉ”์ธ๋งˆ๋‹ค ๋งŒ๋“ค๋ฉด ๋น„์šฉ โ†‘

Ingress:

"HTTP/HTTPS L7 ๋ผ์šฐํŒ…"

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ilic-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt
spec:
  tls:
  - hosts:
    - api.ilic.com
    secretName: ilic-tls
  rules:
  - host: api.ilic.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: ilic-service
            port:
              number: 80
      - path: /admin
        pathType: Prefix
        backend:
          service:
            name: ilic-admin-service
            port:
              number: 80

์—ญํ• :

  • ๋„๋ฉ”์ธ/Path ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ…
  • TLS ์ข…๋ฃŒ
  • ์ธ์ฆ์„œ ์ž๋™ ๋ฐœ๊ธ‰ (cert-manager)

ConfigMap โ€” ํ™˜๊ฒฝ ์„ค์ •

apiVersion: v1
kind: ConfigMap
metadata:
  name: ilic-config
data:
  application.yml: |
    spring:
      profiles:
        active: prod
    server:
      port: 8080

์‚ฌ์šฉ:

spec:
  containers:
  - name: ilic-app
    volumeMounts:
    - name: config
      mountPath: /config
  volumes:
  - name: config
    configMap:
      name: ilic-config

Secret โ€” ๋ฏผ๊ฐ ์ •๋ณด

apiVersion: v1
kind: Secret
metadata:
  name: ilic-secret
type: Opaque
data:
  db-password: cGFzc3dvcmQ=    # Base64

์‚ฌ์šฉ:

env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: ilic-secret
      key: db-password

โš ๏ธ ์ฃผ์˜:

  • Secret์€ Base64 ์ธ์ฝ”๋”ฉ๋งŒ (์•”ํ˜ธํ™” X)
  • โ†’ Vault, Sealed Secrets ๋“ฑ ์ถ”๊ฐ€ ๋„๊ตฌ ๊ถŒ์žฅ
  • 18์ฃผ์ฐจ ๋ณด์•ˆ๊ณผ ์—ฐ๊ฒฐ

ILIC ์ ์šฉ:

  • ConfigMap: ํ™˜๊ฒฝ๋ณ„ ์„ค์ •
  • Secret: DB ๋น„๋ฐ€๋ฒˆํ˜ธ, JWT ํ‚ค
  • Ingress: api.ilic.com ๋ผ์šฐํŒ… + Let's Encrypt ์ž๋™ ๊ฐฑ์‹ 

์ž๊ธฐ ์ ๊ฒ€

  • Secret์ด Base64๋งŒ์ด๋ฉด ๋ณด์•ˆ์ธ๊ฐ€? (ํžŒํŠธ: NO โ€” ์™ธ๋ถ€ ๋„๊ตฌ ํ•„์š”)
  • Ingress vs Service LoadBalancer? (ํžŒํŠธ: Ingress 1๊ฐœ๋กœ ์—ฌ๋Ÿฌ ์„œ๋น„์Šค)

Unit 4.4 โ€” Health Check์™€ Auto-scaling

์„ ์ˆ˜ ์ง€์‹: Unit 4.2

Health Check (Probe) โญ

3๊ฐ€์ง€ Probe:

spec:
  containers:
  - name: ilic-app
    livenessProbe:                      โ† "์‚ด์•„์žˆ๋‚˜?"
      httpGet:
        path: /actuator/health
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 10
      failureThreshold: 3
    
    readinessProbe:                     โ† "ํŠธ๋ž˜ํ”ฝ ๋ฐ›์„ ์ค€๋น„?"
      httpGet:
        path: /actuator/health/readiness
        port: 8080
      periodSeconds: 5
    
    startupProbe:                       โ† "์‹œ์ž‘ ์ค‘?"
      httpGet:
        path: /actuator/health
        port: 8080
      failureThreshold: 30
      periodSeconds: 10

์ฐจ์ด์  โญ :

LivenessReadinessStartup
์‹คํŒจ ์‹œ์žฌ์‹œ์ž‘ํŠธ๋ž˜ํ”ฝ ์ฐจ๋‹จ๋‹ค๋ฅธ Probe ์‹œ์ž‘
์šฉ๋„Deadlock ๊ฐ์ง€์ผ์‹œ์  ๋ถ€ํ•˜๋А๋ฆฐ ์‹œ์ž‘

Spring Boot Actuator ํ™œ์šฉ:

management:
  endpoints:
    web:
      exposure:
        include: health
  endpoint:
    health:
      probes:
        enabled: true

โ†’ /actuator/health/liveness, /actuator/health/readiness ์ž๋™ ์ œ๊ณต


HPA (Horizontal Pod Autoscaler) โญ

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: ilic-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: ilic-deployment
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

ํšจ๊ณผ:

  • CPU 70% ์ดˆ๊ณผ โ†’ Pod ์ถ”๊ฐ€
  • CPU ๋‚ฎ์œผ๋ฉด Pod ์ œ๊ฑฐ
  • min ~ max ๋ฒ”์œ„ ๋‚ด

ILIC ์‹œ๋‚˜๋ฆฌ์˜ค:

  • ํ‰์†Œ: 3 Pod
  • ํŠธ๋ž˜ํ”ฝ ํญ์ฆ: ์ž๋™์œผ๋กœ 10 Pod๊นŒ์ง€
  • ์ƒˆ๋ฒฝ: ๋‹ค์‹œ 3 Pod๋กœ ์ถ•์†Œ โ†’ ๋น„์šฉ ์ ˆ๊ฐ

VPA (Vertical) vs HPA (Horizontal) โญ :

  • VPA: Pod ์ž์ฒด ๋ฆฌ์†Œ์Šค ๋Š˜๋ฆผ (Scale-Up ์œ ์‚ฌ)
  • HPA: Pod ๊ฐœ์ˆ˜ ๋Š˜๋ฆผ (Scale-Out ์œ ์‚ฌ)
  • โ†’ HPA๊ฐ€ ์ผ๋ฐ˜์ 

์ž๊ธฐ ์ ๊ฒ€

  • Liveness์™€ Readiness๊ฐ€ ๊ฐ™์œผ๋ฉด ์•ˆ ๋˜๋Š” ์ด์œ ๋Š”? (ํžŒํŠธ: Readiness๋Š” ์ผ์‹œ์  OK, Liveness๋Š” ์žฌ์‹œ์ž‘)
  • HPA๊ฐ€ ์ฆ‰์‹œ ๋ฐ˜์‘ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š”? (ํžŒํŠธ: ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘ ์ฃผ๊ธฐ, ์•ˆ์ •์„ฑ)

๐Ÿš€ Part C โ€” CI/CD์™€ ์šด์˜ (Day 5-6)

๐Ÿ“š Phase 5 โ€” CI/CD ํŒŒ์ดํ”„๋ผ์ธ

๋ชฉํ‘œ: ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ž๋™์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๋‹ค๋ฆฌ๋ฅผ ์ดํ•ดํ•œ๋‹ค.

Unit 5.1 โ€” CI/CD์˜ ๋ณธ์งˆ๊ณผ ๋‹จ๊ณ„

์„ ์ˆ˜ ์ง€์‹: Phase 4, 19์ฃผ์ฐจ (ํ…Œ์ŠคํŠธ)

CI (Continuous Integration):

"์ž์ฃผ ํ†ตํ•ฉ โ€” ๋นŒ๋“œ + ํ…Œ์ŠคํŠธ ์ž๋™ํ™”"

CD (Continuous Delivery / Deployment):

  • Delivery: ์ž๋™์œผ๋กœ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๊นŒ์ง€
  • Deployment: ์ž๋™์œผ๋กœ ์šด์˜ ํ™˜๊ฒฝ๊นŒ์ง€ ๋ฐฐํฌ

์ „ํ˜•์  ํŒŒ์ดํ”„๋ผ์ธ โญ :

[Code Push]
    โ†“
[Build]              โ† Gradle build
    โ†“
[Static Analysis]    โ† SonarQube, Checkstyle
    โ†“
[Unit Test]          โ† JUnit (19์ฃผ์ฐจ)
    โ†“
[Integration Test]   โ† Testcontainers (19์ฃผ์ฐจ)
    โ†“
[Build Image]        โ† Docker
    โ†“
[Push to Registry]   โ† ECR, GCR
    โ†“
[Deploy to Dev]      โ† ์ž๋™
    โ†“
[E2E Test]           โ† ์ž๋™
    โ†“
[Deploy to Staging]  โ† ์ž๋™
    โ†“
[Manual Approval]    โ† ์šด์˜ ๋ฐฐํฌ ์ „
    โ†“
[Deploy to Prod]
    โ†“
[Smoke Test]

๊ฐ ๋‹จ๊ณ„์˜ ์˜๋ฏธ โญ :

๋‹จ๊ณ„๋ชฉ์ 
Build์ฝ”๋“œ โ†’ ์‹คํ–‰ ๊ฐ€๋Šฅ ํ˜•ํƒœ
Static Analysis์ปดํŒŒ์ผ ์ „์— ์žก๊ธฐ (์ฝ”๋“œ ์Šค๋ฉœ, ๋ณด์•ˆ)
Unit Test๋น ๋ฅธ ํšŒ๊ท€ ๊ฒ€์ฆ
Integration Testํ†ตํ•ฉ ๊ฒ€์ฆ
Build Image๋ฐฐํฌ ๋‹จ์œ„
Deploy to Dev๊ฐœ๋ฐœ์ž ๊ฒ€์ฆ
E2E Test์ „์ฒด ์‹œ๋‚˜๋ฆฌ์˜ค
Deploy to Staging์šด์˜๊ณผ ๋™์ผ ํ™˜๊ฒฝ
Manual Approval์œ„ํ—˜ ํ†ต์ œ
Deploy to Prod์‚ฌ์šฉ์ž ๋…ธ์ถœ

์ž๊ธฐ ์ ๊ฒ€

  • "์™œ ๋งค๋ฒˆ Manual Approval?" ์ž๋™ํ™”์˜ ํ•œ๊ณ„๋Š”? (ํžŒํŠธ: ๋น„์ฆˆ๋‹ˆ์Šค ๊ฒฐ์ •, ํฐ ๋ณ€๊ฒฝ)
  • ILIC๊ฐ€ ์–ด๋””๊นŒ์ง€ ์ž๋™ํ™”๋˜์–ด ์žˆ๋Š”๊ฐ€?

Unit 5.2 โ€” GitHub Actions ์‹ค์ „

์„ ์ˆ˜ ์ง€์‹: Unit 5.1

GitHub Actions (๊ฐ€์žฅ ๋ณดํŽธ):

.github/workflows/ci-cd.yml:

name: CI/CD
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: test
          MYSQL_DATABASE: test
        ports:
          - 3306:3306
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Setup JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'
    
    - name: Cache Gradle
      uses: actions/cache@v3
      with:
        path: |
          ~/.gradle/caches
          ~/.gradle/wrapper
        key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
    
    - name: Run Tests
      run: ./gradlew test
    
    - name: Generate Coverage Report
      run: ./gradlew jacocoTestReport
    
    - name: Upload Coverage to Codecov
      uses: codecov/codecov-action@v3

  build-and-push:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    - name: Build with Gradle
      run: ./gradlew build -x test
    
    - name: Build Docker Image
      run: docker build -t ilic:${{ github.sha }} .
    
    - name: Login to ECR
      uses: aws-actions/amazon-ecr-login@v2
    
    - name: Push Image
      run: docker push ${{ env.ECR_REGISTRY }}/ilic:${{ github.sha }}

  deploy:
    needs: build-and-push
    runs-on: ubuntu-latest
    steps:
    - name: Deploy to K8s
      run: kubectl set image deployment/ilic ilic=ilic:${{ github.sha }}

ํ•ต์‹ฌ ๊ฐœ๋…:

Workflow

  • ์ž๋™ํ™” ํ๋ฆ„

Job

  • ๋ณ‘๋ ฌ/์ˆœ์ฐจ ์‹คํ–‰ ๋‹จ์œ„
  • needs๋กœ ์˜์กด์„ฑ

Step

  • Job ์•ˆ์˜ ๋ช…๋ น

Action

  • ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋นŒ๋”ฉ ๋ธ”๋ก
  • ๋งˆ์ผ“ํ”Œ๋ ˆ์ด์Šค์—์„œ ๊ฐ€์ ธ์˜ด

์บ์‹ฑ โญ โ€” ์†๋„ ํ–ฅ์ƒ:

  • Gradle ์˜์กด์„ฑ ์บ์‹œ
  • Docker ๋ ˆ์ด์–ด ์บ์‹œ
  • ๋นŒ๋“œ ์‹œ๊ฐ„ 50% ์ ˆ๊ฐ ๊ฐ€๋Šฅ

์ž๊ธฐ ์ ๊ฒ€

  • main ๋ธŒ๋žœ์น˜์—๋งŒ ๋ฐฐํฌํ•˜๋Š” ์ด์œ ๋Š”? (ํžŒํŠธ: ์•ˆ์ •์„ฑ)
  • Secret์„ GitHub Actions์— ์–ด๋–ป๊ฒŒ ์•ˆ์ „ํ•˜๊ฒŒ? (ํžŒํŠธ: Repository Secrets)

Unit 5.3 โ€” ๋ฐฐํฌ ์ „๋žต (Blue-Green, Canary, Rolling) โญ

์„ ์ˆ˜ ์ง€์‹: Phase 4, Unit 5.2

3๊ฐ€์ง€ ๋ฐฐํฌ ์ „๋žต โญ :

1. Rolling Update (K8s ๊ธฐ๋ณธ)

v1: [Pod] [Pod] [Pod]
       โ†“ 1๊ฐœ์”ฉ ๊ต์ฒด
v2: [Pod(v2)] [Pod(v1)] [Pod(v1)]
       โ†“
v2: [Pod(v2)] [Pod(v2)] [Pod(v1)]
       โ†“
v2: [Pod(v2)] [Pod(v2)] [Pod(v2)]

์žฅ์ : ๋‹จ์ˆœ, ์ž์› ํšจ์œจ
๋‹จ์ : ๋กค๋ฐฑ ๋А๋ฆผ, ๋‘ ๋ฒ„์ „ ๊ณต์กด


2. Blue-Green

Blue (์šด์˜): [Pod(v1)] [Pod(v1)] [Pod(v1)]  โ† ํŠธ๋ž˜ํ”ฝ
Green (๋Œ€๊ธฐ): [Pod(v2)] [Pod(v2)] [Pod(v2)]
       โ†“ ํŠธ๋ž˜ํ”ฝ ์ „ํ™˜
Blue (๋Œ€๊ธฐ):  [Pod(v1)] [Pod(v1)] [Pod(v1)]
Green (์šด์˜): [Pod(v2)] [Pod(v2)] [Pod(v2)]  โ† ํŠธ๋ž˜ํ”ฝ

์žฅ์ : ์ฆ‰์‹œ ๋กค๋ฐฑ ๊ฐ€๋Šฅ, ๋‘ ๋ฒ„์ „ ๊ณต์กด X
๋‹จ์ : ์ž์› 2๋ฐฐ


3. Canary

v1: [Pod] [Pod] [Pod] [Pod] [Pod]    โ† 95% ํŠธ๋ž˜ํ”ฝ
v2:                          [Pod]    โ† 5% ํŠธ๋ž˜ํ”ฝ
       โ†“ ์ ์ง„์  ํ™•๋Œ€
v1: [Pod] [Pod] [Pod]
v2:               [Pod] [Pod]         โ† 50% ํŠธ๋ž˜ํ”ฝ
       โ†“
v1:
v2: [Pod] [Pod] [Pod] [Pod] [Pod]    โ† 100% ํŠธ๋ž˜ํ”ฝ

์žฅ์ : ์ ์ง„์  ๊ฒ€์ฆ, ์‹คํŒจ ์‹œ ์ ์€ ์˜ํ–ฅ
๋‹จ์ : ๋ณต์žก

Argo Rollouts, Flagger ๋“ฑ ๋„๊ตฌ ํ™œ์šฉ.


์„ ํƒ ๊ฐ€์ด๋“œ โญ :

์ƒํ™ฉ์ถ”์ฒœ
์ผ๋ฐ˜ ๋ฐฐํฌRolling
๋น ๋ฅธ ๋กค๋ฐฑ ํ•„์š”Blue-Green
์œ„ํ—˜ํ•œ ๋ณ€๊ฒฝ, ์ ์ง„ ๊ฒ€์ฆCanary
์ž์› ์—ฌ์œ  ์ ์ŒRolling
์™„์ „ ๊ฒฉ๋ฆฌ ํ•„์š”Blue-Green

ILIC ์‹œ๋‚˜๋ฆฌ์˜ค:

  • ์ผ๋ฐ˜ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ โ†’ Rolling
  • ๊ฒฐ์ œ ์‹œ์Šคํ…œ ๋ณ€๊ฒฝ โ†’ Canary (5% โ†’ 50% โ†’ 100%)
  • ๋ฉ”์ด์ € ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ โ†’ Blue-Green

์ž๊ธฐ ์ ๊ฒ€

  • "๋กค๋ฐฑ์ด 5๋ถ„ ์ด๋‚ด์—ฌ์•ผ ํ•œ๋‹ค" ์‹œ ์–ด๋–ค ์ „๋žต? (ํžŒํŠธ: Blue-Green)
  • ILIC์˜ ์šด์˜ ๋ฐฐํฌ ๋นˆ๋„๋Š”? Canary ๋„์ž… ๊ฐ€์น˜ ์žˆ๋Š”๊ฐ€?

๐Ÿ“š Phase 6 โ€” 12-Factor App๊ณผ ์šด์˜ ์›์น™

๋ชฉํ‘œ: ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ์˜ ํ‘œ์ค€ ์›์น™์„ ์ •๋ฆฌํ•œ๋‹ค.

Unit 6.1 โ€” 12-Factor App โญ (๊ฐ„๋‹จ ์ •๋ฆฌ)

์„ ์ˆ˜ ์ง€์‹: Phase 5

12-Factor:

"ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์˜ 12๊ฐ€์ง€ ์›์น™" (Heroku ๋ฐœํ‘œ)


12๊ฐ€์ง€ ์›์น™ ์š”์•ฝ โญ :

#์›์น™์˜๋ฏธ
1Codebaseํ•œ ์•ฑ = ํ•œ ์ €์žฅ์†Œ
2Dependencies๋ช…์‹œ์  ์„ ์–ธ (build.gradle)
3Configํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ๋ถ„๋ฆฌ
4Backing ServicesDB/Redis ๋“ฑ = ์™ธ๋ถ€ ์ž์›
5Build/Release/Run๋‹จ๊ณ„ ๋ถ„๋ฆฌ
6ProcessesStateless
7Port Binding์ž์ฒด ํฌํŠธ ๋…ธ์ถœ
8Concurrencyํ”„๋กœ์„ธ์Šค ๋‹จ์œ„ ํ™•์žฅ
9Disposability๋น ๋ฅธ ์‹œ์ž‘/์ข…๋ฃŒ (Graceful Shutdown)
10Dev/Prod Parityํ™˜๊ฒฝ ๋™์ผ์„ฑ
11Logsstdout์œผ๋กœ ์ถœ๋ ฅ (Phase 7)
12Admin Processes์ผํšŒ์„ฑ ์ž‘์—… ๋ถ„๋ฆฌ

ํ•ต์‹ฌ ๊ฐ•์กฐ โญ :

Config (3) โ€” ๊ฐ€์žฅ ์ž์ฃผ ์œ„๋ฐ˜

  • ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•˜๋“œ์ฝ”๋”ฉ X
  • ConfigMap/Secret ํ™œ์šฉ (Phase 4)
  • ํ™˜๊ฒฝ๋ณ„ ๋‹ค๋ฅธ yml

Stateless (6) โ€” MSA์˜ ํ•ต์‹ฌ

  • Pod ์žฌ์‹œ์ž‘ํ•ด๋„ OK
  • Session์€ ์™ธ๋ถ€ (Redis)
  • 18์ฃผ์ฐจ JWT์™€ ์—ฐ๊ฒฐ

Logs (11) โ€” ์šด์˜์˜ ์‹œ์ž‘

  • ํŒŒ์ผ X, stdout ์œผ๋กœ
  • K8s/Docker๊ฐ€ ์ˆ˜์ง‘
  • Phase 7์—์„œ ์ž์„ธํžˆ

Disposability (9) โ€” Graceful Shutdown

// Spring Boot
server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s

โ†’ SIGTERM ๋ฐ›์œผ๋ฉด ์ƒˆ ์š”์ฒญ ์•ˆ ๋ฐ›๊ณ , ์ง„ํ–‰ ์ค‘์ธ ์š”์ฒญ ์™„๋ฃŒ ํ›„ ์ข…๋ฃŒ.


ILIC ์ ๊ฒ€:

  • ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ฝ”๋“œ์— ์žˆ๋Š”๊ฐ€?
  • Session์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๋Š”๊ฐ€?
  • ๋กœ๊ทธ๋ฅผ ํŒŒ์ผ์— ์“ฐ๋Š”๊ฐ€?
  • Graceful Shutdown์ด ๋˜๋Š”๊ฐ€?

์ž๊ธฐ ์ ๊ฒ€

  • 12-Factor ์ค‘ ILIC๊ฐ€ ๊ฐ€์žฅ ์•ฝํ•œ ๋ถ€๋ถ„์€?
  • "Stateless๊ฐ€ ์™œ ์–ด๋ ค์šด๊ฐ€?" (ํžŒํŠธ: ์บ์‹œ, Session, ํŒŒ์ผ ์—…๋กœ๋“œ)

๐Ÿ‘๏ธ Part D โ€” Observability (Day 7) โ€” โ˜… ์ •์  3

๐Ÿ“š Phase 7 โ€” 3 Pillars of Observability

๋ชฉํ‘œ: ์šด์˜ ์ค‘ ์ผ์–ด๋‚˜๋Š” ์ผ์„ ๋ณด๋Š” ์„ธ ๊ฐ€์ง€ ๋ˆˆ์„ ์ •๋ณตํ•œ๋‹ค.

Unit 7.1 โ€” Observability vs Monitoring

์„ ์ˆ˜ ์ง€์‹: Phase 5-6

Monitoring (์ „ํ†ต):

  • ๋ฏธ๋ฆฌ ์ •์˜ํ•œ ์ง€ํ‘œ ์ถ”์ 
  • "CPU 80% ๋„˜์œผ๋ฉด ์•Œ๋ฆผ"
  • ์•Œ๋ ค์ง„ ๋ฌธ์ œ ํƒ์ง€

Observability (ํ˜„๋Œ€):

  • ์‹œ์Šคํ…œ ๋‚ด๋ถ€๋ฅผ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•œ ์ƒํƒœ๋กœ
  • "์™œ ์ด๋ ‡๊ฒŒ ๋А๋ฆฐ๊ฐ€?" ๋ฅผ ์ถ”์  ๊ฐ€๋Šฅ
  • ์•Œ๋ ค์ง€์ง€ ์•Š์€ ๋ฌธ์ œ ํƒ์ง€

๊ด€๊ณ„:

"Monitoring์€ Observability์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ"


3 Pillars โญโญโญ :

Pillar๋‹ตํ•˜๋Š” ์งˆ๋ฌธ๋„๊ตฌ
Logs๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”๊ฐ€?ELK, Loki
Metrics์–ผ๋งˆ๋‚˜ ์ผ์–ด๋‚ฌ๋Š”๊ฐ€?Prometheus, Grafana
Traces์–ด๋–ป๊ฒŒ ํ˜๋ €๋Š”๊ฐ€?Zipkin, Jaeger

โ†’ 17์ฃผ์ฐจ Distributed Tracing์ด Traces.

์ž๊ธฐ ์ ๊ฒ€

  • Monitoring๊ณผ Observability์˜ ๊ฒฐ์ •์  ์ฐจ์ด๋Š”?
  • ILIC๊ฐ€ ํ˜„์žฌ ์–ด๋А Pillar๊ฐ€ ์•ฝํ•œ๊ฐ€?

Unit 7.2 โ€” Logs (๊ตฌ์กฐํ™”๋œ ๋กœ๊น…)

์„ ์ˆ˜ ์ง€์‹: Unit 7.1

๋‚˜์œ ๋กœ๊ทธ:

2024-05-04 10:00:00 - ์šด์ž„ ์ฒ˜๋ฆฌ ์‹œ์ž‘
2024-05-04 10:00:05 - ์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜ ๋ฐœ์ƒ

๋ฌธ์ œ:

  • ๊ฒ€์ƒ‰ ์–ด๋ ค์›€
  • ์ปจํ…์ŠคํŠธ ์—†์Œ
  • ์•Œ๋ฆผ ์ž๋™ํ™” X

๊ตฌ์กฐํ™” ๋กœ๊น… (JSON) โญ :

{
  "timestamp": "2024-05-04T10:00:00Z",
  "level": "ERROR",
  "service": "ilic-fare-service",
  "trace_id": "abc123",
  "user_id": "42",
  "fare_id": "100",
  "error": "PaymentTimeout",
  "duration_ms": 5000,
  "message": "๊ฒฐ์ œ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„ ์ดˆ๊ณผ"
}

ํšจ๊ณผ:

  • ํ•„๋“œ ๋‹จ์œ„ ๊ฒ€์ƒ‰ (Elasticsearch)
  • ์ž๋™ ์•Œ๋ฆผ (ํŠน์ • error ๋ฐœ์ƒ ์‹œ)
  • ํ†ต๊ณ„ ๋ถ„์„

Spring Boot ๊ตฌ์กฐํ™” ๋กœ๊น…:

# logback-spring.xml
<configuration>
  <appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
      <providers>
        <timestamp/>
        <logLevel/>
        <loggerName/>
        <mdc/>
        <message/>
      </providers>
    </encoder>
  </appender>
  
  <root level="INFO">
    <appender-ref ref="JSON"/>
  </root>
</configuration>

MDC (Mapped Diagnostic Context) โญ โ€” ์ปจํ…์ŠคํŠธ ์ „ํŒŒ:

@Component
public class TraceIdFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(...) {
        String traceId = request.getHeader("X-Trace-Id");
        if (traceId == null) traceId = UUID.randomUUID().toString();
        
        MDC.put("trace_id", traceId);
        try {
            filterChain.doFilter(request, response);
        } finally {
            MDC.clear();
        }
    }
}

โ†’ ๋ชจ๋“  ๋กœ๊ทธ์— trace_id ์ž๋™ ํฌํ•จ


ELK Stack (์ „ํ†ต):

  • Elasticsearch โ€” ์ €์žฅ + ๊ฒ€์ƒ‰
  • Logstash โ€” ์ˆ˜์ง‘ + ๋ณ€ํ™˜
  • Kibana โ€” ์‹œ๊ฐํ™”

Grafana Loki (ํ˜„๋Œ€):

  • ๊ฐ€๋ฒผ์›€ (๋ฉ”ํŠธ๋ฆญ๊ณผ ํ†ตํ•ฉ)
  • ๋น„์šฉ ํšจ์œจ์ 

ILIC ์ ์šฉ:

  • JSON ๋กœ๊ทธ โ†’ stdout
  • K8s๊ฐ€ ์ž๋™ ์ˆ˜์ง‘
  • ELK ๋˜๋Š” Loki๋กœ ์ง‘๊ณ„

์ž๊ธฐ ์ ๊ฒ€

  • ํ‰๋ฌธ vs JSON ๋กœ๊ทธ์˜ ๊ฒฐ์ •์  ์ฐจ์ด๋Š”?
  • ILIC๊ฐ€ 100๊ฐœ ์„œ๋ฒ„๋ผ๋ฉด ๋กœ๊ทธ ๊ฒ€์ƒ‰์„ ์–ด๋–ป๊ฒŒ?

Unit 7.3 โ€” Metrics (Prometheus + Grafana) โญ

์„ ์ˆ˜ ์ง€์‹: Unit 7.2

Metrics:

"์‹œ๊ณ„์—ด ์ˆซ์ž ๋ฐ์ดํ„ฐ โ€” ์–ผ๋งˆ๋‚˜ ์ผ์–ด๋‚ฌ๋Š”๊ฐ€"

์˜ˆ:

  • ์ดˆ๋‹น ์š”์ฒญ ์ˆ˜ (RPS)
  • ์‘๋‹ต ์‹œ๊ฐ„ P50/P95/P99
  • ์—๋Ÿฌ์œจ
  • CPU/๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋ฅ 

Prometheus โ€” ์‚ฌ์‹ค์ƒ ํ‘œ์ค€:

Pull ๋ชจ๋ธ:

  • Prometheus๊ฐ€ ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘
  • ์•ฑ์€ /actuator/prometheus ๋…ธ์ถœ
  • ๋ณ„๋„ ์ „์†ก X
# Spring Boot
management:
  endpoints:
    web:
      exposure:
        include: prometheus

โ†’ /actuator/prometheus ์ž๋™ ์ œ๊ณต:

# HELP http_server_requests_seconds 
# TYPE http_server_requests_seconds histogram
http_server_requests_seconds_count{method="GET",uri="/api/fares"} 1234
http_server_requests_seconds_sum{method="GET",uri="/api/fares"} 45.6

4๊ฐ€์ง€ ๋ฉ”ํŠธ๋ฆญ ํƒ€์ž… โญ :

ํƒ€์ž…์˜๋ฏธ์˜ˆ
Counter๋ˆ„์  ์นด์šดํŠธ (๊ฐ์†Œ X)์ด ์š”์ฒญ ์ˆ˜
Gaugeํ˜„์žฌ ๊ฐ’ํ˜„์žฌ ๋ฉ”๋ชจ๋ฆฌ
Histogram๋ถ„ํฌ (๋ฒ„ํ‚ท)์‘๋‹ต ์‹œ๊ฐ„ ๋ถ„ํฌ
SummaryPercentileP95 ์‘๋‹ต ์‹œ๊ฐ„

Spring Boot Actuator + Micrometer โญ :

implementation 'io.micrometer:micrometer-registry-prometheus'

์ž๋™ ๋ฉ”ํŠธ๋ฆญ :

  • HTTP ์š”์ฒญ
  • JVM (heap, GC)
  • DB Connection Pool
  • Tomcat
  • ์บ์‹œ

์ปค์Šคํ…€ ๋ฉ”ํŠธ๋ฆญ:

@Service
public class FareService {
    private final MeterRegistry meterRegistry;
    private final Counter fareCounter;
    private final Timer fareTimer;
    
    public FareService(MeterRegistry registry) {
        this.fareCounter = registry.counter("fare.created.total");
        this.fareTimer = registry.timer("fare.processing");
    }
    
    public Fare create(FareRequest request) {
        return fareTimer.record(() -> {
            Fare fare = ...;
            fareCounter.increment();
            return fare;
        });
    }
}

Grafana โ€” ์‹œ๊ฐํ™”:

  • Prometheus ๋ฉ”ํŠธ๋ฆญ์„ ๋Œ€์‹œ๋ณด๋“œ๋กœ
  • ์•Œ๋ฆผ ๊ทœ์น™ ์„ค์ •
  • ILIC ๋Œ€์‹œ๋ณด๋“œ ์˜ˆ:
    • RPS, ์—๋Ÿฌ์œจ, P95 ์‘๋‹ต์‹œ๊ฐ„
    • JVM heap, GC ์‹œ๊ฐ„
    • DB Connection Pool ์‚ฌ์šฉ๋ฅ 
    • ๋น„์ฆˆ๋‹ˆ์Šค ๋ฉ”ํŠธ๋ฆญ (์šด์ž„ ๋“ฑ๋ก ์ˆ˜ ๋“ฑ)

SLI/SLO/SLA โญ โ€” ๋ฉด์ ‘ ๋‹จ๊ณจ:

์˜๋ฏธ์˜ˆ
SLI (Indicator)์ธก์ • ์ง€ํ‘œ"์—๋Ÿฌ์œจ"
SLO (Objective)๋ชฉํ‘œ"์—๋Ÿฌ์œจ < 0.1%"
SLA (Agreement)๊ณ„์•ฝ"99.9% ๊ฐ€์šฉ์„ฑ, ๋ชป ์ง€ํ‚ค๋ฉด ํ™˜๋ถˆ"

ILIC ๊ถŒ์žฅ:

  • SLI: API ๊ฐ€์šฉ์„ฑ, ์‘๋‹ต ์‹œ๊ฐ„
  • SLO: 99.5% ๊ฐ€์šฉ์„ฑ, P95 < 500ms
  • SLA: ๊ณ ๊ฐ์‚ฌ์™€ ๊ณ„์•ฝ ์‹œ ์ •์˜

์ž๊ธฐ ์ ๊ฒ€

  • ILIC์˜ ํ•ต์‹ฌ SLI 3๊ฐ€์ง€๋ฅผ ์„ ์–ธํ•˜๋ผ
  • Counter์™€ Gauge ์ค‘ "ํ˜„์žฌ ํ™œ์„ฑ ์‚ฌ์šฉ์ž ์ˆ˜"๋Š”? (ํžŒํŠธ: Gauge)

Unit 7.4 โ€” Traces (OpenTelemetry) โญ

์„ ์ˆ˜ ์ง€์‹: Unit 7.3, 17์ฃผ์ฐจ Phase 9.4

๋ณต์Šต (17์ฃผ์ฐจ):

  • Trace ID โ€” ํ•œ ์š”์ฒญ์˜ ์ „์ฒด ํ๋ฆ„
  • Span โ€” ํ•œ ์ž‘์—…
  • Trace ID ์ „ํŒŒ (HTTP ํ—ค๋”)

OpenTelemetry (OTel) โญ :

"๊ด€์ธก ๊ฐ€๋Šฅ์„ฑ์˜ ํ‘œ์ค€ โ€” Logs/Metrics/Traces ํ†ตํ•ฉ"

์ฑ„ํƒ ํ˜„ํ™ฉ:

  • CNCF ํ‘œ์ค€
  • Zipkin, Jaeger ๋Œ€์ฒด ๊ฐ€๋Šฅ
  • ์‚ฌ์‹ค์ƒ ์ฐจ์„ธ๋Œ€ ํ‘œ์ค€

Spring Boot ํ†ตํ•ฉ (Micrometer Tracing):

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-tracing-bridge-otel'
implementation 'io.opentelemetry:opentelemetry-exporter-otlp'
management:
  tracing:
    sampling:
      probability: 0.1   # 10% ์ƒ˜ํ”Œ๋ง
  otlp:
    tracing:
      endpoint: http://otel-collector:4317

โ†’ ์ž๋™์œผ๋กœ ๋ชจ๋“  HTTP ์š”์ฒญ, DB ์ฟผ๋ฆฌ, Redis ํ˜ธ์ถœ ๋“ฑ ์ถ”์ 


3 Pillars ํ†ตํ•ฉ โญ โ€” ๊ฐ€์žฅ ๊ฐ•๋ ฅ:

// Log
{
  "timestamp": "...",
  "level": "ERROR",
  "trace_id": "abc123",      โ† Trace์™€ ์—ฐ๊ฒฐ
  "span_id": "span456",
  "message": "๊ฒฐ์ œ ์‹คํŒจ"
}

ํšจ๊ณผ:

  • Log์—์„œ trace_id ๋ฐœ๊ฒฌ โ†’ Trace ํ™”๋ฉด์œผ๋กœ ์ ํ”„
  • Trace์—์„œ ๋А๋ฆฐ Span ๋ฐœ๊ฒฌ โ†’ ํ•ด๋‹น ์‹œ์ ์˜ Metric ํ™•์ธ
  • Metric ์•Œ๋ฆผ โ†’ Trace๋กœ ์›์ธ ๋ถ„์„

ILIC ์ ์šฉ:

  • ๋ชจ๋“  ์š”์ฒญ์— Trace ID
  • Log + Metric + Trace ํ†ตํ•ฉ ๋Œ€์‹œ๋ณด๋“œ
  • ์žฅ์•  ๋ฐœ์ƒ ์‹œ 5๋ถ„ ๋‚ด ์›์ธ ํŒŒ์•… ๊ฐ€๋Šฅ

์ž๊ธฐ ์ ๊ฒ€

  • Trace ์ƒ˜ํ”Œ๋ง์ด 100%๋ฉด ์–ด๋–ค ๋น„์šฉ? (ํžŒํŠธ: ์ €์žฅ์†Œ, ์„ฑ๋Šฅ)
  • ILIC์—์„œ Trace๋กœ ๊ฐ€์žฅ ๋„์›€ ๋ฐ›์„ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š”?

๐Ÿ“š Phase 8 โ€” ์žฅ์•  ๋Œ€์‘๊ณผ ์‚ฌ๊ณ  ๋ถ„์„

๋ชฉํ‘œ: ์‹œ๋‹ˆ์–ด๊ฐ€ ์•„๋‹Œ 4๋…„์ฐจ์˜ ๊ฒฐ์ •์  ์ฐจ์ด ์˜์—ญ.

Unit 8.1 โ€” On-Call๊ณผ ์žฅ์•  ๋Œ€์‘

์„ ์ˆ˜ ์ง€์‹: Phase 7

On-Call ๋ฌธํ™”:

  • ์‹œ์Šคํ…œ ์žฅ์•  ์‹œ ์‘๋‹ต ์ฑ…์ž„์ž
  • ์‹œ๋‹ˆ์–ด๋กœ ๊ฐˆ์ˆ˜๋ก ๋” ๋งŽ์€ ์ฑ…์ž„

์ข‹์€ ์•Œ๋ฆผ ์‹œ์Šคํ…œ โญ :

๋‹จ๊ณ„์˜๋ฏธ
Info์ฐธ๊ณ ์šฉ (์ด๋ฉ”์ผ)
Warning์ฃผ์‹œ (Slack)
Critical์ฆ‰์‹œ ๋Œ€์‘ (์ „ํ™”/SMS)

์•Œ๋ฆผ ํ”ผ๋กœ(Alert Fatigue) โš ๏ธ :

  • ๋„ˆ๋ฌด ๋งŽ์€ ์•Œ๋ฆผ โ†’ ๋ฌด์‹œํ•˜๊ฒŒ ๋จ
  • "์–‘์น˜๊ธฐ ์†Œ๋…„ ํšจ๊ณผ"
  • ํ•ด๊ฒฐ: ์ •๋ง ์ค‘์š”ํ•œ ๊ฒƒ๋งŒ Critical

์žฅ์•  ๋Œ€์‘ ํ๋ฆ„ โญ :

1. ๊ฐ์ง€ (Detection)
   - ์ž๋™ ์•Œ๋ฆผ
   - ์‚ฌ์šฉ์ž ์‹ ๊ณ 
   โ†“
2. ๋ถ„๋ฅ˜ (Triage)
   - ์‹ฌ๊ฐ๋„ ํŒ๋‹จ
   - ์˜ํ–ฅ ๋ฒ”์œ„
   โ†“
3. ์™„ํ™” (Mitigation) โ€” ์šฐ์„ !
   - ๋น ๋ฅธ ํ•ด๊ฒฐ (๋กค๋ฐฑ, ํŠธ๋ž˜ํ”ฝ ์ฐจ๋‹จ)
   - "์ˆ˜์ •" ๋ณด๋‹ค "์ค‘๋‹จ" ์ด ์šฐ์„ 
   โ†“
4. ๋ณต๊ตฌ (Recovery)
   - ์ •์ƒ ์ƒํƒœ๋กœ
   โ†“
5. ๋ถ„์„ (Post-mortem) โญ
   - ์‚ฌํ›„ ๋ถ„์„
   - ๋น„๋‚œ X, ํ•™์Šต โ—‹

ํ•ต์‹ฌ ์›์น™ โญ :

"๊ทผ๋ณธ ์›์ธ ์ˆ˜์ • ์ „์— ์˜ํ–ฅ ์™„ํ™” ์šฐ์„ "

์˜ˆ: ๊ฒฐ์ œ ์‹œ์Šคํ…œ ๋‹ค์šด โ†’ ๋””๋ฒ„๊น… X โ†’ ์ฆ‰์‹œ ๋กค๋ฐฑ


์˜์‚ฌ๊ฒฐ์ • ํ”„๋ ˆ์ž„์›Œํฌ:

  • MTTR (Mean Time To Recovery) โ€” ๋ณต๊ตฌ๊นŒ์ง€ ์‹œ๊ฐ„
  • MTTF (Mean Time To Failure) โ€” ์žฅ์•  ๋ฐœ์ƒ ์ฃผ๊ธฐ
  • MTBF (Mean Time Between Failures) โ€” ์žฅ์•  ์‚ฌ์ด ์‹œ๊ฐ„

์‹œ๋‹ˆ์–ด์˜ ์ฐจ๋ณ„ํ™”:

  • ์นจ์ฐฉํ•จ
  • ์šฐ์„ ์ˆœ์œ„ ๋น ๋ฅธ ํŒ๋‹จ
  • ์‚ฌํ›„ ํ•™์Šต

์ž๊ธฐ ์ ๊ฒ€

  • "๋””๋ฒ„๊น…์„ ๋จผ์ € ํ•ด์•ผ ํ•˜๋‚˜?" ๋‹ต์€? (ํžŒํŠธ: NO โ€” ์™„ํ™” ๋จผ์ €)
  • ILIC์—์„œ ๊ฐ€์žฅ ํฐ ์žฅ์•  ์‚ฌ๋ก€๋ฅผ ๋ณธ์ธ ๊ฒฝํ—˜์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š”๊ฐ€?

Unit 8.2 โ€” Postmortem (์‚ฌํ›„ ๋ถ„์„) โญ

์„ ์ˆ˜ ์ง€์‹: Unit 8.1

Postmortem:

"์žฅ์•  ํ›„ ๊ณต์‹์ ์ธ ๋ถ„์„ + ํ•™์Šต ๋ฌธ์„œ"

ํ•ต์‹ฌ ์›์น™ โญ :

"Blameless (๋น„๋‚œ ์—†๋Š”)"

  • ์‚ฌ๋žŒ์„ ๋น„๋‚œ X
  • ์‹œ์Šคํ…œ/ํ”„๋กœ์„ธ์Šค๋ฅผ ๋น„๋‚œ
  • ๋‘๋ ค์›€ ์—†๋Š” ์†”์งํ•จ

Postmortem ํ…œํ”Œ๋ฆฟ โญ :

# ์žฅ์•  ๋ณด๊ณ ์„œ โ€” ์šด์ž„ ์‹œ์Šคํ…œ ๋‹ค์šด (2024-05-04)

## ์š”์•ฝ
- ๋ฐœ์ƒ: 2024-05-04 14:00 KST
- ๋ณต๊ตฌ: 2024-05-04 15:30 KST
- ์˜ํ–ฅ ๋ฒ”์œ„: ์ „์ฒด ์šด์ž„ ์‹œ์Šคํ…œ
- ์˜ํ–ฅ๋ฐ›์€ ์‚ฌ์šฉ์ž: ์•ฝ 500๋ช…

## Timeline
- 14:00 โ€” DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹œ์ž‘
- 14:15 โ€” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์™„๋ฃŒ, but ์ธ๋ฑ์Šค ๋ˆ„๋ฝ
- 14:20 โ€” ์šด์ž„ ๊ฒ€์ƒ‰ API ์‘๋‹ต 30์ดˆ โ†’ Critical ์•Œ๋ฆผ
- 14:30 โ€” ์˜จ์ฝœ ์ธ์ง€
- 14:45 โ€” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋กค๋ฐฑ ๊ฒฐ์ •
- 15:00 โ€” ๋กค๋ฐฑ ์‹œ์ž‘
- 15:30 โ€” ์ •์ƒ ๋ณต๊ตฌ

## ๊ทผ๋ณธ ์›์ธ (Root Cause)
- ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์Šคํฌ๋ฆฝํŠธ์— ์ธ๋ฑ์Šค ์ƒ์„ฑ ๋ˆ„๋ฝ
- Staging์—์„œ ์ถฉ๋ถ„ํ•œ ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ ์—†์—ˆ์Œ
- โ†’ ๋‹จ์ผ ์›์ธ X, ์—ฌ๋Ÿฌ ์š”์ธ์˜ ๊ฒฐํ•ฉ

## ๋ฌด์—‡์ด ์ž˜ ๋˜์—ˆ๋‚˜
- ๋น ๋ฅธ ์•Œ๋ฆผ ๊ฐ์ง€ (5๋ถ„)
- ์‹ ์†ํ•œ ๋กค๋ฐฑ ๊ฒฐ์ •

## ๋ฌด์—‡์ด ์ž˜๋ชป๋˜์—ˆ๋‚˜
- ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฒ€ํ†  ๋ถ€์žฌ
- Staging์˜ ๋ฐ์ดํ„ฐ ์–‘์ด ์šด์˜๊ณผ ๋‹ค๋ฆ„

## Action Items
1. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ PR ํ…œํ”Œ๋ฆฟ ๋„์ž… (Owner: A, Due: 5/15)
2. Staging ๋ฐ์ดํ„ฐ ์–‘์„ ์šด์˜์˜ 30%๋กœ (Owner: B, Due: 5/30)
3. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹œ ์ž๋™ ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ (Owner: C, Due: 6/15)

์ข‹์€ Postmortem์˜ ํŠน์ง•:
1. ์‚ฌ์‹ค ์œ„์ฃผ โ€” ์ถ”์ธก X
2. Blameless โ€” ์‚ฌ๋žŒ ๋น„๋‚œ X
3. Action Items ๋ช…ํ™• โ€” ๋ˆ„๊ฐ€, ์–ธ์ œ๊นŒ์ง€
4. ๊ณต์œ  โ€” ํŒ€ ์ „์ฒด ํ•™์Šต

ILIC ์ ์šฉ:

  • ๋ชจ๋“  P1/P2 ์žฅ์• ์— Postmortem
  • ์œ„ํ‚ค/๋ฌธ์„œ ์‹œ์Šคํ…œ์— ๋ณด๊ด€
  • ์ •๊ธฐ ๋ฆฌ๋ทฐ (๋ถ„๊ธฐ๋ณ„)

๋ฉด์ ‘ ์งˆ๋ฌธ ๋Œ€๋น„ โญ :

"์ง€๊ธˆ๊นŒ์ง€ ๊ฐ€์žฅ ์–ด๋ ค์› ๋˜ ์žฅ์•  ๊ฒฝํ—˜์€?"

์ข‹์€ ๋‹ต๋ณ€ ๊ตฌ์กฐ:
1. ์ƒํ™ฉ (๊ฐ„๋‹จ)
2. ๋ฌธ์ œ ๋ฐœ๊ฒฌ ๊ณผ์ •
3. ์™„ํ™” ์‹œ๋„
4. ๊ทผ๋ณธ ์›์ธ
5. ํ•™์Šต + ๊ฐœ์„ 

์ž๊ธฐ ์ ๊ฒ€

  • ILIC์—์„œ Postmortem ๋ฌธํ™”๊ฐ€ ์žˆ๋Š”๊ฐ€?
  • ๋ณธ์ธ ๊ฒฝํ—˜์˜ ์žฅ์•  ์‚ฌ๋ก€๋ฅผ ์œ„ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?

๐ŸŽ“ ์ข…ํ•ฉ ์ž๊ธฐ ์ ๊ฒ€ (20์ฃผ์ฐจ ์กธ์—… ์‹œํ—˜)

HTTP/๋„คํŠธ์›Œํฌ

  1. HTTP ๋ฉ”์„œ๋“œ 7๊ฐ€์ง€์˜ ๋ฉฑ๋“ฑ์„ฑ/์•ˆ์ „์„ฑ์„ ํ‘œ๋กœ ๊ทธ๋ ค๋ผ
  2. 401, 403, 422, 502, 504์˜ ์ฐจ์ด๋Š”?
  3. HTTP/1.1, 2, 3์˜ ๊ฒฐ์ •์  ์ฐจ์ด 3๊ฐ€์ง€๋Š”?
  4. TCP 3-way handshake๋ฅผ ์„ค๋ช…ํ•˜๋ผ
  5. TIME_WAIT๊ฐ€ ์™œ ๋ฐœ์ƒํ•˜๊ณ  ์–ด๋–ค ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š”๊ฐ€?
  6. TLS Handshake (1.2 vs 1.3) ์ฐจ์ด๋Š”?
  7. L4์™€ L7 Load Balancer์˜ ์ฐจ์ด๋Š”?

Docker/K8s

  1. Container์™€ VM์˜ ๊ฒฐ์ •์  ์ฐจ์ด๋Š”?
  2. Multi-stage Build์˜ ํšจ๊ณผ๋Š”?
  3. Pod, Deployment, Service์˜ ์—ญํ• ์€?
  4. Liveness, Readiness, Startup Probe์˜ ์ฐจ์ด๋Š”?
  5. HPA๊ฐ€ ๋™์ž‘ํ•˜๋Š” ์›๋ฆฌ๋Š”?

CI/CD

  1. CI์™€ CD์˜ ์ฐจ์ด๋Š”?
  2. Rolling, Blue-Green, Canary์˜ ์„ ํƒ ๊ธฐ์ค€์€?
  3. 12-Factor App์˜ ํ•ต์‹ฌ ์›์น™ 5๊ฐ€์ง€๋Š”?

Observability

  1. Monitoring๊ณผ Observability์˜ ์ฐจ์ด๋Š”?
  2. 3 Pillars (Logs, Metrics, Traces)์˜ ์—ญํ• ์€?
  3. ๊ตฌ์กฐํ™” ๋กœ๊น…์ด ์™œ ํ•„์š”ํ•œ๊ฐ€?
  4. SLI, SLO, SLA์˜ ์ฐจ์ด๋Š”?
  5. Counter์™€ Gauge ๋ฉ”ํŠธ๋ฆญ์˜ ์ฐจ์ด๋Š”?

์žฅ์•  ๋Œ€์‘

  1. ์žฅ์•  ๋Œ€์‘์˜ 5๋‹จ๊ณ„๋Š”?
  2. "๊ทผ๋ณธ ์›์ธ ์ˆ˜์ • vs ์˜ํ–ฅ ์™„ํ™”" ์šฐ์„ ์ˆœ์œ„๋Š”?
  3. Blameless Postmortem์ด ์™œ ์ค‘์š”ํ•œ๊ฐ€?

๋ฉด์ ‘ ๋ชจ์˜ ๋‹ต๋ณ€ (์‹ค์ „)

  1. "HTTP์™€ HTTPS์˜ ์ฐจ์ด๋ฅผ ๊นŠ์ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”" (3๋ถ„)
  2. "Kubernetes๋ฅผ ์จ๋ณด์…จ๋‚˜์š”?" (3๋ถ„)
  3. "์žฅ์•  ๋Œ€์‘ ๊ฒฝํ—˜์ด ์žˆ์œผ์‹ ๊ฐ€์š”?" (5๋ถ„)
  4. "ILIC์˜ ์šด์˜์„ ์–ด๋–ป๊ฒŒ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์‹œ๋‚˜์š”?" (3๋ถ„)
  5. "๋ฌด์ค‘๋‹จ ๋ฐฐํฌ๋Š” ์–ด๋–ป๊ฒŒ ํ•˜์‹œ๋‚˜์š”?" (3๋ถ„)

๐Ÿ“Œ ํ•™์Šต ์šด์˜ ํŒ

9-์„น์…˜ ๋งˆ์Šคํ„ฐ ํ”„๋กฌํ”„ํŠธ๋กœ ๊นŠ์ด ํŒŒ์•ผ ํ•  Unit

โ˜…โ˜…โ˜… ๋ฉด์ ‘ ๋‹จ๊ณจ (๋ฐ˜๋“œ์‹œ):

  • Unit 1.2 โ€” HTTP ์ƒํƒœ ์ฝ”๋“œ + ํ”ํ•œ ์˜คํ•ด
  • Unit 1.3 โ€” HTTP/2/3
  • Unit 2.2 โ€” TCP 3-way Handshake (โ˜… ์ •์ )
  • Unit 2.3 โ€” TLS Handshake
  • Unit 4.2 โ€” Pod, Deployment, Service (โ˜… ์ •์ )
  • Unit 5.3 โ€” ๋ฐฐํฌ ์ „๋žต
  • Unit 7.3 โ€” Metrics (โ˜… ์ •์ )

โ˜…โ˜… ๋งค์šฐ ๊ถŒ์žฅ:

  • Unit 1.1 โ€” HTTP ๋ณธ์งˆ
  • Unit 3.2 โ€” Dockerfile ์ตœ์ ํ™”
  • Unit 4.4 โ€” Health Check + HPA
  • Unit 7.2 โ€” ๊ตฌ์กฐํ™” ๋กœ๊น…
  • Unit 8.2 โ€” Postmortem

์„ธ ์ •์ 

Phase 2 (TCP/TLS) โ€” ๋ฐฑ์—”๋“œ์˜ ํ† ๋Œ€. "TCP 3-way handshake ์„ค๋ช…?" ๋ฉด์ ‘ 100%. ๋ฉด์ ‘๊ด€์ด ๊นŠ์ด ํŒŒ๊ณ ๋“œ๋Š” ์งˆ๋ฌธ ์˜์—ญ.

Phase 4 (Kubernetes) โ€” ํ˜„๋Œ€ ์šด์˜์˜ ํ‘œ์ค€. "K8s ์จ๋ณด์…จ๋‚˜์š”?" ์‹œ Pod/Deployment/Service์˜ ์ฐจ์ด๋ฅผ 1๋ถ„ ์•ˆ์— ๋‹ตํ•  ์ˆ˜ ์žˆ์–ด์•ผ ์ฐจ๋ณ„ํ™”.

Phase 7 (Observability) โ€” ์‹œ๋‹ˆ์–ด์˜ ๊ฒฐ์ •์  ์ฐจ๋ณ„ํ™”. "์žฅ์• ๋ฅผ ์–ด๋–ป๊ฒŒ ์ฐพ์œผ์„ธ์š”?" ๋‹ต๋ณ€์— 3 Pillars + SLI/SLO ๋“ค์–ด๊ฐ€๋ฉด ์‹œ๋‹ˆ์–ด ๋ ˆ๋ฒจ.

1~20์ฃผ์ฐจ ํ•™์Šต ์—ฌ์ • โ€” ์™„์„ฑ

์ด์ œ ์‹œ๋‹ˆ์–ด ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•Œ์•„์•ผ ํ•  ๊ฑฐ์˜ ๋ชจ๋“  ์˜์—ญ์„ ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค:

์˜์—ญ์ฃผ์ฐจ๊นŠ์ด
Java ์–ธ์–ด1-3โ˜…โ˜…โ˜…
๋™์‹œ์„ฑ4โ˜…โ˜…โ˜…
Spring Core5, 8-9โ˜…โ˜…โ˜…
ํŠธ๋žœ์žญ์…˜7, 10โ˜…โ˜…โ˜…
JPA11-12โ˜…โ˜…โ˜…
DB13-14โ˜…โ˜…โ˜…
Spring MVC15โ˜…โ˜…โ˜…
๋ถ„์‚ฐ ์‹œ์Šคํ…œ16-17โ˜…โ˜…โ˜…
Spring Security18โ˜…โ˜…โ˜…
ํ…Œ์ŠคํŠธ19โ˜…โ˜…โ˜…
HTTP/DevOps/Observability20โ˜…โ˜…โ˜…

โ†’ 20์ฃผ์— ๊ฑธ์ณ ์ž๋ฐ” ๋ฐฑ์—”๋“œ ์‹œ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž์˜ ๊ฑฐ์˜ ๋ชจ๋“  ์˜์—ญ์„ ์ •๋ณต


๐ŸŽฏ ๋‹ค์Œ์€ ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”๊ฐ€

1์ˆœ์œ„ โ€” ILIC ์‚ฌ๋ก€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ •๋ฆฌ โญ

๊ฐ€์žฅ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. 20์ฃผ์ฐจ ๋ถ„๋Ÿ‰์˜ ์ด๋ก  ์œ„์—:

  • ILIC 17๊ฐœ์›”์˜ ์˜์‚ฌ๊ฒฐ์ •์„ ๋ฉด์ ‘ ๋‹ต๋ณ€ ํ˜•ํƒœ๋กœ ์ •๋ฆฌ
  • ๊ฐ ๊ธฐ์ˆ  ์˜์—ญ๋งˆ๋‹ค "๋ฌธ์ œ โ†’ ๋ถ„์„ โ†’ ์‹œ๋„ โ†’ ๊ฒฐ๊ณผ โ†’ ํšŒ๊ณ "
  • 5๋ถ„ ๋‹ต๋ณ€ ๊ตฌ์กฐ ๋งŒ๋“ค๊ธฐ

์ด ์ž‘์—…์ด ์ด๋ก ์„ ๋ฉด์ ‘ ํ•ฉ๊ฒฉ์œผ๋กœ ๋ณ€ํ™˜ ํ•ฉ๋‹ˆ๋‹ค.

2์ˆœ์œ„ โ€” ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ์ค€๋น„

  • ํšŒ์‚ฌ์— ๋”ฐ๋ผ ๋ณ„๊ฐœ์˜ ์‚ฐ
  • ๋ฐฑ์ค€ ๊ณจ๋“œ ์ •๋„ + ์•Œ๊ณ ๋ฆฌ์ฆ˜ 4-8์ฃผ

3์ˆœ์œ„ โ€” ์‹œ์Šคํ…œ ๋””์ž์ธ ๋ฉด์ ‘

  • "Designing Data-Intensive Applications" ์ฑ…
  • ๋Œ€๊ทœ๋ชจ ์‹œ์Šคํ…œ ์„ค๊ณ„ ์—ฐ์Šต (URL Shortener, Twitter, Netflix ๋“ฑ)

4์ˆœ์œ„ โ€” ์ปฌ์ฒ˜ ํ• / ์Šคํ† ๋ฆฌ

  • ๋ณธ์ธ ๊ฐ€์น˜๊ด€ ์ •๋ฆฌ
  • ํ˜‘์—… ์‚ฌ๋ก€, ๊ฐˆ๋“ฑ ํ•ด๊ฒฐ, ๋ฆฌ๋”์‹ญ ๊ฒฝํ—˜

๐ŸŽค ๋งˆ์ง€๋ง‰ ์ข…ํ•ฉ ํ‰๊ฐ€ โ€” ์†”์งํ•˜๊ฒŒ

1~20์ฃผ์ฐจ๋ฅผ ์™„์ „ํžˆ ์ฒดํ™”ํ–ˆ๋‹ค๋ฉด:

  • ๊ธฐ์ˆ  ์ด๋ก  ๋ฉด์ ‘: ์‹œ๋‹ˆ์–ด 4-5๋…„์ฐจ ์ˆ˜์ค€ ์••๋„
  • ํ†ต๊ณผ์œจ: ์Šคํƒ€ํŠธ์—…/์ค‘๊ฒฌ 85%+, ๋Œ€๊ธฐ์—… 60%+
  • ๊ทธ๋Ÿฌ๋‚˜ ILIC ์‚ฌ๋ก€ + ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ๊ฐ€ ์ตœ์ข… ๋ณ€์ˆ˜

ํ˜„์žฌ์˜ ํ•™์Šต์œผ๋กœ ๋ถ€์กฑํ•œ ์˜์—ญ (์ž๊ธฐ ํ•™์Šต ๊ถŒ์žฅ):

  • ์•Œ๊ณ ๋ฆฌ์ฆ˜/์ž๋ฃŒ๊ตฌ์กฐ ์‹ฌํ™” (์ฝ”ํ…Œ์šฉ)
  • ์‹œ์Šคํ…œ ๋””์ž์ธ ๋ฉด์ ‘ (๋Œ€๊ธฐ์—…)
  • Frontend ๊นŠ์ด (ํ’€์Šคํƒ ๊ฐ•์กฐ ์‹œ)
  • ๋„๋ฉ”์ธ ์ „๋ฌธ์„ฑ (๋ฌผ๋ฅ˜๋ผ๋ฉด ์ด๋ฏธ ๊ฐ€์ง)

๋ณด์™„ ํ•„์š”:

  • ILIC ๊ฒฝํ—˜์„ ๋‹ต๋ณ€ ๊ฐ€๋Šฅํ•œ ์Šคํ† ๋ฆฌ๋กœ ์ •๋ฆฌ
  • ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ๋”ฐ๋กœ ์ค€๋น„
  • ๋ฉด์ ‘ ์ž์ฒด์— ๋Œ€ํ•œ ์—ฐ์Šต (๋ชจ์˜ ๋ฉด์ ‘)

profile
Software Developer

0๊ฐœ์˜ ๋Œ“๊ธ€