Kubernetes ์ปจํ…Œ์ด๋„ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€: ์ƒํƒœ ํ™•์ธ

Kubernetes ์ปจํ…Œ์ด๋„ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€: ์ƒํƒœ ํ™•์ธ

TL; DR

  • ์ปจํ…Œ์ด๋„ˆ์™€ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค์— ๋Œ€ํ•œ ๋†’์€ ๊ฐ€์‹œ์„ฑ์„ ๋‹ฌ์„ฑํ•˜๋ ค๋ฉด ๋กœ๊ทธ์™€ ๊ธฐ๋ณธ ์ง€ํ‘œ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋” ๋น ๋ฅธ ๋ณต๊ตฌ์™€ ํ–ฅ์ƒ๋œ ํƒ„๋ ฅ์„ฑ์„ ์œ„ํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ HOP(High Observability ์›์น™)๋ฅผ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€์—์„œ NOP์—๋Š” ์ ์ ˆํ•œ ๋กœ๊น…, ๊ธด๋ฐ€ํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง, ์˜จ์ „์„ฑ ๊ฒ€์‚ฌ ๋ฐ ์„ฑ๋Šฅ/์ „ํ™˜ ์ถ”์ ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • NOR์˜ ์š”์†Œ๋กœ ๊ฒ€์‚ฌ ์‚ฌ์šฉ ์ค€๋น„ ํ”„๋กœ๋ธŒ ะธ ํ™œ์„ฑ ํ”„๋กœ๋ธŒ ์ฟ  ๋ฒ„๋„ค ํ‹ฐ์Šค.

์ƒํƒœ ํ™•์ธ ํ…œํ”Œ๋ฆฟ์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋ฏธ์…˜ ํฌ๋ฆฌํ‹ฐ์ปฌํ•˜๊ณ  ๊ฐ€์šฉ์„ฑ์ด ๋†’์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค๊ณ„ํ•  ๋•Œ ๋‚ด๊ฒฐํ•จ์„ฑ๊ณผ ๊ฐ™์€ ์ธก๋ฉด์„ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์žฅ์• ๋กœ๋ถ€ํ„ฐ ์‹ ์†ํ•˜๊ฒŒ ๋ณต๊ตฌ๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋‚ด๊ฒฐํ•จ์„ฑ์ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ํด๋ผ์šฐ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋ณ„๋„์˜ ์ปจํ…Œ์ด๋„ˆ์— ๋ฐฐ์น˜๋˜๋Š” ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ k8s์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ€์šฉ์„ฑ์„ ๋†’์ด๋ ค๋ฉด ํŠน์ • ํŒจํ„ด์„ ๋”ฐ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ์ค‘์—๋Š” ์ƒํƒœ ํ™•์ธ ํ…œํ”Œ๋ฆฟ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ •์ƒ์ž„์„ k8s์™€ ํ†ต์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Pod๊ฐ€ ์‹คํ–‰ ์ค‘์ธ์ง€ ์—ฌ๋ถ€๋ฟ ์•„๋‹ˆ๋ผ ์š”์ฒญ์„ ์ˆ˜์‹ ํ•˜๊ณ  ์‘๋‹ตํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ •๋ณด์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. Kubernetes๊ฐ€ ํฌ๋“œ ์ƒํƒœ์— ๋Œ€ํ•ด ๋” ๋งŽ์ด ์•Œ์ˆ˜๋ก ํŠธ๋ž˜ํ”ฝ ๋ผ์šฐํŒ… ๋ฐ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ์— ๋Œ€ํ•ด ๋” ํ˜„๋ช…ํ•œ ๊ฒฐ์ •์„ ๋‚ด๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋†’์€ ๊ด€์ฐฐ ๊ฐ€๋Šฅ์„ฑ ์›์น™์„ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ ์‹œ์— ์š”์ฒญ์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋†’์€ ๊ด€์ฐฐ ๊ฐ€๋Šฅ์„ฑ ์›์น™(HOP)

๋†’์€ ๊ด€์ฐฐ ๊ฐ€๋Šฅ์„ฑ์˜ ์›์น™์€ ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆํ™”๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค๊ณ„ ์›์น™. ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜์—์„œ ์„œ๋น„์Šค๋Š” ์š”์ฒญ์ด ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š”์ง€(๊ทธ๋ฆฌ๊ณ  ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š”์ง€) ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์ง€๋งŒ, ์ค‘์š”ํ•œ ๊ฒƒ์€ ์ˆ˜์‹  ์„œ๋น„์Šค๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์„ ๋ฐ›๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๋ฅผ ์ธ์ฆํ•˜๊ธฐ ์œ„ํ•ด ํ•œ ์ปจํ…Œ์ด๋„ˆ๋Š” ํŠน์ • ํ˜•์‹์˜ ์‘๋‹ต์„ ๊ธฐ๋Œ€ํ•˜๋ฉด์„œ ๋‹ค๋ฅธ ์ปจํ…Œ์ด๋„ˆ์— HTTP ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ์ „๋ถ€์ž…๋‹ˆ๋‹ค. PythonJS๋„ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ณ  Python Flask๊ฐ€ ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ๋Š” ์„œ๋กœ ์ˆจ๊ฒจ์ง„ ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ธ”๋ž™๋ฐ•์Šค์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ NOP ์›์น™์— ๋”ฐ๋ฅด๋ฉด ๊ฐ ์„œ๋น„์Šค๋Š” ์ƒํƒœ์™€ ์ค€๋น„ ์ƒํƒœ, ๋‚ด๊ฒฐํ•จ์„ฑ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์—ฌ๋Ÿฌ API ์—”๋“œํฌ์ธํŠธ๋ฅผ ๋…ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Kubernetes๋Š” ๋ผ์šฐํŒ… ๋ฐ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ์„ ์œ„ํ•œ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๊ณ ๋ คํ•˜๊ธฐ ์œ„ํ•ด ์ด๋Ÿฌํ•œ ์ง€ํ‘œ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

์ž˜ ์„ค๊ณ„๋œ ํด๋ผ์šฐ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํ‘œ์ค€ I/O ์ŠคํŠธ๋ฆผ STDERR ๋ฐ STDOUT์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์š” ์ด๋ฒคํŠธ๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์ค‘์•™ ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ(์˜ˆ: Prometheus) ๋ฐ ๋กœ๊ทธ ์ˆ˜์ง‘ ์‹œ์Šคํ…œ(ELK ์†Œํ”„ํŠธ์›จ์–ด ์ œํ’ˆ๊ตฐ)์— ๋กœ๊ทธ๋ฅผ ์ „๋‹ฌํ•˜๋Š” filebeat, logstash ๋˜๋Š” fluentd์™€ ๊ฐ™์€ ๋ณด์กฐ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ์ƒํƒœ ํ…Œ์ŠคํŠธ ํŒจํ„ด ๋ฐ ๋†’์€ ๊ด€์ฐฐ ๊ฐ€๋Šฅ์„ฑ ์›์น™์— ๋”ฐ๋ผ ํด๋ผ์šฐ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Kubernetes ์ปจํ…Œ์ด๋„ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€: ์ƒํƒœ ํ™•์ธ

Kubernetes์—์„œ ์ƒํƒœ ํ™•์ธ ํŒจํ„ด์„ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋‚˜์š”?

๊ธฐ๋ณธ์ ์œผ๋กœ k8s๋Š” ์ปจํŠธ๋กค๋Ÿฌ(๋ฐฐํฌ, ๋ ˆํ”Œ๋ฆฌ์นด์„ธํŠธ, ๋ฐ๋ชฌ์„ธํŠธ, StatefulSet ๋“ฑ). ์–ด๋–ค ์ด์œ ๋กœ ํฌ๋“œ๊ฐ€ ๋–จ์–ด์ง„ ๊ฒƒ์„ ๋ฐœ๊ฒฌํ•œ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ํฌ๋“œ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ์ด๋™ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํฌ๋“œ๋Š” ์‹คํ–‰ ์ค‘์ด๋ผ๊ณ  ๋ณด๊ณ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ž์ฒด์ ์œผ๋กœ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด Apache๋ฅผ ์›น ์„œ๋ฒ„๋กœ ์‚ฌ์šฉํ•˜๊ณ  ํด๋Ÿฌ์Šคํ„ฐ์˜ ์—ฌ๋Ÿฌ Pod์— ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์„ค์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ž˜๋ชป ๊ตฌ์„ฑ๋˜์—ˆ์œผ๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ๋ชจ๋“  ์š”์ฒญ์€ ์ฝ”๋“œ 500(๋‚ด๋ถ€ ์„œ๋ฒ„ ์˜ค๋ฅ˜)์œผ๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ์†ก ํ™•์ธ ์‹œ ํŒŸ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๋ฉด ์„ฑ๊ณต์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๊ณ ๊ฐ์˜ ์ƒ๊ฐ์€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด ๋ฐ”๋žŒ์งํ•˜์ง€ ์•Š์€ ์ƒํ™ฉ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Kubernetes ์ปจํ…Œ์ด๋„ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€: ์ƒํƒœ ํ™•์ธ

์ด ์˜ˆ์—์„œ๋Š” k8s๊ฐ€ ๊ธฐ๋Šฅ ์ ๊ฒ€. ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ํ™•์ธ์—์„œ kubelet์€ ์ปจํ…Œ์ด๋„ˆ์˜ ํ”„๋กœ์„ธ์Šค ์ƒํƒœ๋ฅผ ์ง€์†์ ์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ค‘์ง€๋˜์—ˆ์Œ์„ ์ดํ•ดํ•˜๋ฉด ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ณ  ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋˜๋„๋ก ์„ค๊ณ„๋œ ๊ฒฝ์šฐ NOP ๋ฐ ์ƒํƒœ ํ…Œ์ŠคํŠธ ํŒจํ„ด์„ ๋”ฐ๋ฅด๋ ค๋ฉด ํ”„๋กœ์„ธ์Šค ์ƒํƒœ ํ™•์ธ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์œ ์ผํ•œ ์œ ๊ฐ์Šค๋Ÿฌ์šด ์ ์€ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด๋„ ๋ชจ๋“  ์˜ค๋ฅ˜๊ฐ€ ์ œ๊ฑฐ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ k8s๋Š” ํฌ๋“œ ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ•˜๋Š” 2๊ฐ€์ง€ ๋” ๊นŠ์€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํ™œ์„ฑ ํ”„๋กœ๋ธŒ ะธ ์ค€๋น„ ํ”„๋กœ๋ธŒ.

ํ™œ์„ฑ ํ”„๋กœ๋ธŒ

๋™์•ˆ ํ™œ์„ฑ ํ”„๋กœ๋ธŒ kubelet์€ 3๊ฐ€์ง€ ์œ ํ˜•์˜ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํฌ๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘์ธ์ง€ ์—ฌ๋ถ€๋ฟ ์•„๋‹ˆ๋ผ ์š”์ฒญ์„ ์ˆ˜์‹ ํ•˜๊ณ  ์ ์ ˆํ•˜๊ฒŒ ์‘๋‹ตํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€๋„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  • Pod์— ๋Œ€ํ•œ HTTP ์š”์ฒญ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์‘๋‹ต์—๋Š” 200~399 ๋ฒ”์œ„์˜ HTTP ์‘๋‹ต ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝ”๋“œ 5xx ๋ฐ 4xx๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰ ์ค‘์ž„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ํฌ๋“œ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • HTTP๊ฐ€ ์•„๋‹Œ ์„œ๋น„์Šค(์˜ˆ: Postfix ๋ฉ”์ผ ์„œ๋ฒ„)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํฌ๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด TCP ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Pod์— ๋Œ€ํ•œ ์ž„์˜์˜ ๋ช…๋ น์„ (๋‚ด๋ถ€์ ์œผ๋กœ) ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ช…๋ น ์™„๋ฃŒ ์ฝ”๋“œ๊ฐ€ 0์ด๋ฉด ํ™•์ธ์ด ์„ฑ๊ณตํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์˜ˆ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ Pod ์ •์˜์—๋Š” HTTP ์š”์ฒญ ์‹œ 500 ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” NodeJS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์‹ ํ•  ๋•Œ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋‹ค์‹œ ์‹œ์ž‘๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด livenessProbe ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

apiVersion: v1
kind: Pod
metadata:
 name: node500
spec:
 containers:
   - image: magalix/node500
     name: node500
     ports:
       - containerPort: 3000
         protocol: TCP
     livenessProbe:
       httpGet:
         path: /
         port: 3000
       initialDelaySeconds: 5

์ด๋Š” ๋‹ค๋ฅธ ํฌ๋“œ ์ •์˜์™€ ๋‹ค๋ฅด์ง€ ์•Š์ง€๋งŒ ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. .spec.containers.livenessProbe. ๋ชจ์ˆ˜ httpGet HTTP GET ์š”์ฒญ์ด ์ „์†ก๋˜๋Š” ๊ฒฝ๋กœ๋ฅผ ์ˆ˜๋ฝํ•ฉ๋‹ˆ๋‹ค(์ด ์˜ˆ์—์„œ๋Š” /, ๊ทธ๋Ÿฌ๋‚˜ ์ „ํˆฌ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. /api/v1/status). ๋˜ ๋‹ค๋ฅธ livenessProbe๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. initialDelaySeconds, ์ด๋Š” ์ง€์ •๋œ ์‹œ๊ฐ„(์ดˆ) ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฌ๋„๋ก ํ™•์ธ ์ž‘์—…์— ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ํ•„์š”ํ•˜๊ณ  ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ฉด ํ•œ๋™์•ˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ง€์—ฐ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด ์„ค์ •์„ ํด๋Ÿฌ์Šคํ„ฐ์— ์ ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

kubectl apply -f pod.yaml

๋ช‡ ์ดˆ ํ›„์— ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ Pod์˜ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

kubectl describe pods node500

์ถœ๋ ฅ์ด ๋๋‚˜๋ฉด ๋‹ค์Œ์„ ์ฐพ์œผ์‹ญ์‹œ์˜ค. ๊ทธ๊ฒŒ ๋ญ์•ผ?.

๋ณด์‹œ๋‹ค์‹œํ”ผ livenessProbe๋Š” HTTP GET ์š”์ฒญ์„ ์‹œ์ž‘ํ–ˆ๊ณ , ์ปจํ…Œ์ด๋„ˆ๋Š” ์˜ค๋ฅ˜ 500์„ ์ƒ์„ฑํ–ˆ์œผ๋ฉฐ(์ด๊ฒƒ์ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋œ ๋‚ด์šฉ์ž„) kubelet์ด ์ด๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

NideJS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์–ด๋–ป๊ฒŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋˜์—ˆ๋Š”์ง€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์‚ฌ์šฉ๋œ app.js ๋ฐ Dockerfile์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•ฑ.js

var http = require('http');

var server = http.createServer(function(req, res) {
    res.writeHead(500, { "Content-type": "text/plain" });
    res.end("We have run into an errorn");
});

server.listen(3000, function() {
    console.log('Server is running at 3000')
})

๋„์ปค ํŒŒ์ผ

FROM node
COPY app.js /
EXPOSE 3000
ENTRYPOINT [ "node","/app.js" ]

๋‹ค์Œ ์‚ฌํ•ญ์— ์œ ์˜ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. livenessProbe๋Š” ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ์ž‘ํ•ด๋„ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰์„ ๋ฐฉํ•ดํ•˜๋Š” ์˜ค๋ฅ˜๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์œผ๋ฉด kubelet์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์กฐ์น˜๋ฅผ ์ทจํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ค€๋น„ ํ”„๋กœ๋ธŒ

readinessProbe๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ ์ž‘์—…์„ ์ œ์™ธํ•˜๊ณ  livenessProbes(GET ์š”์ฒญ, TCP ํ†ต์‹  ๋ฐ ๋ช…๋ น ์‹คํ–‰)์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ๊ฐ์ง€๋œ ์ปจํ…Œ์ด๋„ˆ๋Š” ๋‹ค์‹œ ์‹œ์ž‘๋˜์ง€ ์•Š์ง€๋งŒ ๋“ค์–ด์˜ค๋Š” ํŠธ๋ž˜ํ”ฝ์—์„œ ๊ฒฉ๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋งŽ์€ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ๋ถ€ํ•˜๊ฐ€ ๋†’์•„ ์‘๋‹ต ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง„๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์„ธ์š”. livenessProbe์˜ ๊ฒฝ์šฐ ์‘๋‹ต ๊ฐ€์šฉ์„ฑ ํ™•์ธ์ด ํŠธ๋ฆฌ๊ฑฐ๋˜๊ณ (timeoutSeconds ํ™•์ธ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด) ๊ทธ ํ›„ kubelet์ด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์‹œ์ž‘๋˜๋ฉด ์ปจํ…Œ์ด๋„ˆ๋Š” ๋ฆฌ์†Œ์Šค ์ง‘์•ฝ์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๊ณ  ๋‹ค์‹œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์‘๋‹ต ์†๋„๊ฐ€ ํ•„์š”ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋งค์šฐ ์ค‘์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋„๋กœ์— ์žˆ๋Š” ์ž๋™์ฐจ๊ฐ€ ์„œ๋ฒ„์˜ ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š”๋ฐ ์‘๋‹ต์ด ์ง€์—ฐ๋˜์–ด ์ž๋™์ฐจ๊ฐ€ ์‚ฌ๊ณ ๋ฅผ ๋‹นํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

GET ์š”์ฒญ ์‘๋‹ต ์‹œ๊ฐ„์„ 5์ดˆ ์ดํ•˜๋กœ ์„ค์ •ํ•˜๋Š” redinessProbe ์ •์˜๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ XNUMX์ดˆ ํ›„์— GET ์š”์ฒญ์— ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. pod.yaml ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

apiVersion: v1
kind: Pod
metadata:
 name: nodedelayed
spec:
 containers:
   - image: afakharany/node_delayed
     name: nodedelayed
     ports:
       - containerPort: 3000
         protocol: TCP
     readinessProbe:
       httpGet:
         path: /
         port: 3000
       timeoutSeconds: 2

kubectl์„ ์‚ฌ์šฉํ•˜์—ฌ ํฌ๋“œ๋ฅผ ๋ฐฐํฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

kubectl apply -f pod.yaml

๋ช‡ ์ดˆ ์ •๋„ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ readinessProbe๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

kubectl describe pods nodedelayed

์ถœ๋ ฅ์ด ๋๋‚˜๋ฉด ์ผ๋ถ€ ์ด๋ฒคํŠธ๊ฐ€ ๋น„์Šทํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•˜๋‚˜.

๋ณด์‹œ๋‹ค์‹œํ”ผ kubectl์€ ํ™•์ธ ์‹œ๊ฐ„์ด 2์ดˆ๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด Pod๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ทธ๋Š” ์š”์ฒญ์„ ์ทจ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜์‹  ํ†ต์‹ ์€ ์ž‘๋™ ์ค‘์ธ ๋‹ค๋ฅธ ํฌ๋“œ๋กœ ๋ฆฌ๋””๋ ‰์…˜๋ฉ๋‹ˆ๋‹ค.

์ด์ œ ํฌ๋“œ๊ฐ€ ์˜คํ”„๋กœ๋“œ๋˜์—ˆ์œผ๋ฏ€๋กœ kubectl์€ ์š”์ฒญ์„ ๋‹ค์‹œ ํฌ๋“œ๋กœ ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค. GET ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์€ ๋” ์ด์ƒ ์ง€์—ฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋น„๊ต๋ฅผ ์œ„ํ•ด ์ˆ˜์ •๋œ app.js ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

var http = require('http');

var server = http.createServer(function(req, res) {
   const sleep = (milliseconds) => {
       return new Promise(resolve => setTimeout(resolve, milliseconds))
   }
   sleep(5000).then(() => {
       res.writeHead(200, { "Content-type": "text/plain" });
       res.end("Hellon");
   })
});

server.listen(3000, function() {
   console.log('Server is running at 3000')
})

TL; DR
ํด๋ผ์šฐ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋“ฑ์žฅํ•˜๊ธฐ ์ „์—๋Š” ๋กœ๊ทธ๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  ํ™•์ธํ•˜๋Š” ์ฃผ์š” ์ˆ˜๋‹จ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹œ์ • ์กฐ์น˜๋ฅผ ์ทจํ•  ๋ฐฉ๋ฒ•์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ๋Š” ์˜ค๋Š˜๋‚ ์—๋„ ์—ฌ์ „ํžˆ ์œ ์šฉํ•˜๋ฉฐ ๊ธด๊ธ‰ ์ƒํ™ฉ์„ ๋ถ„์„ํ•˜๊ณ  ์˜์‚ฌ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๊ธฐ ์œ„ํ•ด ๋กœ๊ทธ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ๋กœ๊ทธ ์ˆ˜์ง‘ ์‹œ์Šคํ…œ์œผ๋กœ ์ „์†กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. [์˜ˆ๋ฅผ ๋“ค์–ด monit์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์šฐ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์—†์ด ์ด ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ k8s๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ์‰ฌ์›Œ์กŒ์Šต๋‹ˆ๋‹ค. :) โ€“ ํŽธ์ง‘์ž ์ฃผ. ]

์˜ค๋Š˜๋‚ ์—๋Š” ๊ฑฐ์˜ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ˆ˜์ •์ด ์ด๋ฃจ์–ด์ ธ์•ผ ํ•˜๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋” ์ด์ƒ ๋ธ”๋ž™๋ฐ•์Šค์ผ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ์š”, ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์ด ํ”„๋กœ์„ธ์Šค ์ƒํƒœ์— ๋Œ€ํ•œ ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฟผ๋ฆฌํ•˜๊ณ  ์ˆ˜์ง‘ํ•˜์—ฌ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ฆ‰์‹œ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ‘œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ HOP(High Observability ์›์น™)๋ฅผ ๋”ฐ๋ฅด๋Š” ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๋””์ž์ธ ํŒจํ„ด์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

Kubernetes๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ readinessProbe์™€ livenessProbe๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ์ƒํƒœ ํ™•์ธ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ๋™์ผํ•œ ์œ ํ˜•์˜ ๊ฒ€์‚ฌ(HTTP GET ์š”์ฒญ, TCP ํ†ต์‹  ๋ฐ ๋ช…๋ น ์‹คํ–‰)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํฌ๋“œ์˜ ๋ฌธ์ œ์— ๋Œ€์‘ํ•˜์—ฌ ๋‚ด๋ฆฌ๋Š” ๊ฒฐ์ •์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. livenessProbe๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋‹ค์‹œ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ผ๋ฉฐ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๊ณ , readinessProbe๋Š” ๋ฌธ์ œ์˜ ์›์ธ์ด ํ•ด๊ฒฐ๋  ๋•Œ๊นŒ์ง€ ์ˆ˜์‹  ํŠธ๋ž˜ํ”ฝ์—์„œ ํฌ๋“œ๋ฅผ ๊ฒฉ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ ์ ˆํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค๊ณ„์—๋Š” ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ๊ฒ€์‚ฌ๊ฐ€ ๋ชจ๋‘ ํฌํ•จ๋˜์–ด์•ผ ํ•˜๋ฉฐ, ํŠนํžˆ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์ถฉ๋ถ„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ(Prometheus)์— ์ค‘์š”ํ•œ ์ƒํƒœ ์ง€ํ‘œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ API ์—”๋“œํฌ์ธํŠธ๋„ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€