๐ŸŽฏ Kubernetes์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“— Today I Learned

๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜(MSA; Microservice Architecture)

์ถœ์ฒ˜: gabia

ํ•˜๋‚˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ ์„œ๋น„์Šค๋กœ ๋‚˜๋ˆ„์–ด ๊ฐœ๋ฐœ ๋ฐ ์šด์˜ํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜ ์Šคํƒ€์ผ์ž…๋‹ˆ๋‹ค.

  • ๊ฐ ์„œ๋น„์Šค๋Š” ์ž์ฒด์ ์œผ๋กœ ๋ฐฐํฌ ๋ฐ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹ ์€ ๋ณดํ†ต API๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

  • ํ•˜๋‚˜์˜ ์„œ๋น„์Šค์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„, ๋‹ค๋ฅธ ์„œ๋น„์Šค๋Š” ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ  ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐœ๋ฐœ๊ณผ ์œ ์ง€๋ณด์ˆ˜, ๋ฐฐํฌ๊ฐ€ ์œ ์—ฐํ•˜๊ณ  ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.


๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜๋Š” ๊ฐ๊ฐ์˜ ์„œ๋น„์Šค๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ, ์ปจํ…Œ์ด๋„ˆ ๋ชจ๋ธ๊ณผ ๋งค์šฐ ์ž˜ ์–ด์šธ๋ฆฝ๋‹ˆ๋‹ค.

  • ์ปจํ…Œ์ด๋„ˆ๋Š” ์„œ๋น„์Šค๋ฅผ ๊ฒฉ๋ฆฌ๋œ ๋‹จ์œ„๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

  • ์–ด๋””์„œ๋‚˜ ๋™์ผํ•œ ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ผ๊ด€์„ฑ๊ณผ ์ด์‹์„ฑ์ด ๋›ฐ์–ด๋‚ฉ๋‹ˆ๋‹ค.

  • ๋”ฐ๋ผ์„œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ฐ˜์˜ ์šด์˜ ํ™˜๊ฒฝ์ด ๋งค์šฐ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.


Monolithic vs MSA

  • ๋ชจ๋†€๋ฆฌ์‹ ์•„ํ‚คํ…์ฒ˜ (Monolithic Architecture)

    • ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ํ•˜๋‚˜์˜ ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•ˆ์— ํ†ตํ•ฉ๋˜์–ด ์žˆ์œผ๋ฉฐ, ํ•˜๋‚˜์˜ ๋ฉ์–ด๋ฆฌ๋กœ์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

    • ๋ฐฐํฌ๋‚˜ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๊ณ , ํ•˜๋‚˜์˜ ๋ฌธ์ œ๊ฐ€ ์ „์ฒด ์‹œ์Šคํ…œ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜ (MSA)

    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ธฐ๋Šฅ ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ๊ฐ์˜ ์„œ๋น„์Šค๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • ๊ฐ ์„œ๋น„์Šค๋Š” ํŠน์ •ํ•œ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๋ฉฐ, ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ” ๋ฐฐํฌ ๊ตฌ์กฐ์˜ ๋ณ€ํ™” ์š”์•ฝ
์ถœ์ฒ˜: https://fullstackdeeplearning.com/

1. Traditional Deployment

  • ํ•˜๋‚˜์˜ ์„œ๋ฒ„์— ๋ชจ๋“  ๊ฑธ ์˜ฌ๋ฆฌ๋Š” ๊ตฌ์กฐ
  • ๋ชจ๋†€๋ฆฌ์‹ ์•„ํ‚คํ…์ฒ˜์— ํ•ด๋‹นํ•˜๋ฉฐ, ํ™•์žฅ์„ฑ๊ณผ ์œ ์—ฐ์„ฑ์ด ๋ถ€์กฑํ•จ

2. Virtualized Deployment

  • ๊ฐ€์ƒ ๋จธ์‹ ์„ ์ด์šฉํ•ด ๊ฒฉ๋ฆฌ์„ฑ์„ ํ™•๋ณด
  • ํ•˜์ง€๋งŒ ๊ฐ VM์ด ๋ฌด๊ฑฐ์›Œ ์ž์› ๋‚ญ๋น„๊ฐ€ ํผ

3. Container Deployment

  • ์ปจํ…Œ์ด๋„ˆ ๊ธฐ์ˆ ๋กœ ๊ฐ€๋ณ๊ณ  ๋น ๋ฅธ ์‹คํ–‰ ๊ฐ€๋Šฅ
  • ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋ฅผ ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์ ํ•ฉ

4. Kubernetes Deployment

  • ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋งŽ์•„์ง€๋ฉด์„œ ์—ฌ๋Ÿฌ ๋Œ€์˜ ์„œ๋ฒ„์— ๋ถ„์‚ฐ๋˜์–ด ์‹คํ–‰, ์ด๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์กฐ์œจํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•ด์ง
  • Kubernetes๋Š” ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ํ™˜๊ฒฝ์—์„œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๋ฐฐ์น˜, ์‹คํ–‰, ๋ณต๊ตฌ, ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์คŒ
  • โœจ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ ์„œ๋ฒ„(๋…ธ๋“œ)๋งˆ๋‹ค Docker์™€ ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ ๋Ÿฐํƒ€์ž„์ด ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, Kubernetes๋Š” ์ด๋Ÿฌํ•œ Docker ํ™˜๊ฒฝ๋“ค์„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์›Œ์ปค ๋…ธ๋“œ(์‹ค์ œ๋กœ ์‹คํ–‰ํ•˜๋Š” ์„œ๋ฒ„)๋กœ ๋ฌถ์–ด ํ•˜๋‚˜์˜ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๊ตฌ์„ฑ๋จ

๐Ÿ‘‰ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋Š” ๊ฐœ๋ณ„์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋งŽ์•„์ง€๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ํ†ตํ•ฉ์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” '์ปจํ…Œ์ด๋„ˆ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๋„๊ตฌ'๊ฐ€ ๊ผญ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ค‘ ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ๋„๊ตฌ๊ฐ€ ๋ฐ”๋กœ Kubernetes์ž…๋‹ˆ๋‹ค.




Kubernetes

์ถœ์ฒ˜: wikimedia

Kubernetes (์ค„์—ฌ์„œ k8s)๋Š” ์ปจํ…Œ์ด๋„ˆ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์†”๋ฃจ์…˜, ์ฆ‰ ์ปจํ…Œ์ด๋„ˆ๋“ค์„ ์ง€ํœ˜ํ•˜๊ณ  ์กฐ์œจํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

  • ์ˆ˜๋งŽ์€ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ž๋™์œผ๋กœ ๋ฐฐํฌํ•˜๊ณ , ์‹คํ–‰ ์ค‘์ธ ์ปจํ…Œ์ด๋„ˆ์˜ ์ƒํƒœ๋ฅผ ์ง€์†์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ, ํŠธ๋ž˜ํ”ฝ์ด๋‚˜ ๋ถ€ํ•˜ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ปจํ…Œ์ด๋„ˆ ์ˆ˜๋ฅผ ์ž๋™์œผ๋กœ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ์ถ•์†Œํ•˜๋Š” ๋“ฑ์˜ ๋ณต์žกํ•œ ์ž‘์—…์„ ์ž๋™ํ™”ํ•ด์ค๋‹ˆ๋‹ค.

ํŠน์ง•

  • Docker ์ปจํ…Œ์ด๋„ˆ๋“ค๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

  • ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ๋„ ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ž…๋‹ˆ๋‹ค.

  • ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋Š” Pod๋ผ๋Š” k8s ์˜ค๋ธŒ์ ํŠธ ๋‹จ์œ„๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.




Kubernetes Cluster

ํด๋Ÿฌ์Šคํ„ฐ(Cluster)๋Š” ์—ฌ๋Ÿฌ ๋Œ€์˜ ์ปดํ“จํ„ฐ(์„œ๋ฒ„)๋ฅผ ํ•˜๋‚˜์ฒ˜๋Ÿผ ๋ฌถ์–ด์„œ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“  ์‹œ์Šคํ…œ ๋‹จ์œ„๋กœ Kubernetes์—์„œ๋Š” ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์„œ๋ฒ„๋“ค์˜ ์ง‘ํ•ฉ์„ ํด๋Ÿฌ์Šคํ„ฐ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
์ถœ์ฒ˜: Kubernetes

๊ตฌ์„ฑ ์š”์†Œ

Kubernetes ํด๋Ÿฌ์Šคํ„ฐ๋Š” ํฌ๊ฒŒ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

1๏ธโƒฃ ๋งˆ์Šคํ„ฐ ๋…ธ๋“œ (์ปจํŠธ๋กค ํ”Œ๋ ˆ์ธ)

  • API Server (api)

    • kubectl ๋“ฑ ์™ธ๋ถ€์—์„œ ์˜ค๋Š” ์š”์ฒญ์„ ๋ฐ›์•„๋“ค์ด๋Š” ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ž…๊ตฌ์ž…๋‹ˆ๋‹ค.

    • ๋ชจ๋“  ๋ช…๋ น์€ ์ด๊ณณ์„ ํ†ตํ•ด ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

      ๐Ÿค” kubectl๋Š” ๋ฌด์—‡์ผ๊นŒ?

      ์‚ฌ์šฉ์ž๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” CLI ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

  • etcd

    • ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” Key-Value ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค.

    • ์–ด๋–ค Pod๊ฐ€ ์–ด๋””์— ์žˆ๋Š”์ง€, ๋…ธ๋“œ ์ƒํƒœ ๋“ฑ ๋ชจ๋“  ์ •๋ณด๊ฐ€ ์—ฌ๊ธฐ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค.

      ๐Ÿค” Pod๋Š” ๋ฌด์—‡์ผ๊นŒ?

      Pod๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ๋…ผ๋ฆฌ์ ์ธ ๋‹จ์œ„๋กœ, ๊ฐ™์€ ๋„คํŠธ์›Œํฌ ๊ณต๊ฐ„(IP)๊ณผ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

      Pod๋Š” ์›Œ์ปค ๋…ธ๋“œ(Node) ์•ˆ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. kubelet์ด Pod๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ์ด๊ธฐ ๋•Œ๋ฌธ์—, Pod๋Š” kubelet ๋ฐ‘์—์„œ ์‹ค์ œ๋กœ ๋Œ์•„๊ฐ€๊ณ  ์žˆ๋Š” ์‹คํ–‰ ์œ ๋‹›์ž…๋‹ˆ๋‹ค.


      ๐Ÿงช ์™œ ๊ทธ๋ƒฅ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•„๋‹ˆ๋ผ Pod์ผ๊นŒ?

      Kubernetes๋Š” Docker ์ปจํ…Œ์ด๋„ˆ๋งŒ ์ง์ ‘ ๋‹ค๋ฃจ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ•˜๋‚˜์˜ ๋…ผ๋ฆฌ์  ๋‹จ์œ„์ธ Pod์œผ๋กœ ๋ฌถ์–ด ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด์—์„œ ํšจ์œจ์ ์œผ๋กœ ๋ฐฐํฌํ•˜๊ณ  ์šด์˜ํ•ฉ๋‹ˆ๋‹ค.

  • Controller Manager (c-m)

    • ํด๋Ÿฌ์Šคํ„ฐ์˜ ์‹ค์ œ ์ƒํƒœ๊ฐ€ ์„ ์–ธํ•œ ์ƒํƒœ์™€ ๋‹ค๋ฅด๋ฉด, ์ด๋ฅผ ์ž๋™์œผ๋กœ ์กฐ์ •ํ•ด์ค๋‹ˆ๋‹ค.
  • Cloud Controller Manager (c-c-m)

    • AWS, GCP ๋“ฑ ํด๋ผ์šฐ๋“œ ์ธํ”„๋ผ์™€ ํ†ต์‹ ํ•˜๋Š” ์—ญํ• ์ž…๋‹ˆ๋‹ค.
  • Scheduler (sched)

    • ์ƒˆ๋กœ ์ƒ์„ฑ๋  Pod๊ฐ€ ์–ด๋А ๋…ธ๋“œ์— ๋ฐฐ์น˜๋ ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.

2๏ธโƒฃ (์›Œ์ปค) ๋…ธ๋“œ

  • ์ปจํ…Œ์ด๋„ˆ ๋Ÿฐํƒ€์ž„(CRI; Container Runtime Interface)

    • Pod ๋‚ด๋ถ€์˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹ค์ œ๋กœ ์‹คํ–‰์‹œํ‚ค๋Š” ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.
  • kubelet

    • Pod์˜ ๊ตฌ์„ฑ ๋‚ด์šฉ์„ ๋ฐ›์•„ CRI์— ์ „๋‹ฌํ•˜๊ณ  ์ปจํ…Œ์ด๋„ˆ๋“ค์˜ ๋™์ž‘ ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
  • kube-proxy (k-proxy)

    • ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹ ์„ ์œ„ํ•ด ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ์˜ฌ๋ฐ”๋ฅธ Pod๋กœ ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค.



k8s๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ

  • ์ปจํ…Œ์ด๋„ˆ ๋ฐธ๋Ÿฐ์‹ฑ

    • Pod์˜ ๋ถ€ํ•˜ ๊ท ๋“ฑํ™”๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ช‡ ๊ฐœ์˜ ์‘์šฉ์„ ๋ณต์ œํ• ์ง€ ์„ค์ •๋งŒ ํ•˜๋ฉด, Kubernetes๊ฐ€ ์•Œ์•„์„œ ์ ์ ˆํ•˜๊ฒŒ ๋ถ„์‚ฐ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.
  • ํŠธ๋ž˜ํ”ฝ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ

    • ๋™์ผํ•œ ์‘์šฉ์˜ ๋ณต์ œ๋ณธ(Pod)์ด ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๊ฒฝ์šฐ, ์™ธ๋ถ€ ๋˜๋Š” ๋‚ด๋ถ€์—์„œ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์„ ์ž๋™์œผ๋กœ ๋ถ„์‚ฐ์‹œ์ผœ ์„œ๋น„์Šค์˜ ์•ˆ์ •์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ๋™์  ์ˆ˜ํ‰ ์Šค์ผ€์ผ๋ง

    • ํŠธ๋ž˜ํ”ฝ์ด๋‚˜ ์ž์› ์‚ฌ์šฉ๋Ÿ‰์— ๋”ฐ๋ผ Pod ์ˆ˜๋ฅผ ์ž๋™์œผ๋กœ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ์ถ•์†Œํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‹œ์Šคํ…œ ์ž์›์„ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ค๋ฅ˜ ๋ณต๊ตฌ

    • Pod๋‚˜ ๋…ธ๋“œ์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ, Kubernetes๋Š” ์ด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ž๋™์œผ๋กœ ์ƒˆ๋กœ์šด Pod ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ณต๊ตฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋กค๋ง ์—…๋ฐ์ดํŠธ

    • ์„œ๋น„์Šค๋ฅผ ์ค‘๋‹จํ•˜์ง€ ์•Š๊ณ  ์ ์ง„์ ์œผ๋กœ ์ƒˆ ๋ฒ„์ „์„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด ๋น ๋ฅด๊ฒŒ ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๋Š” ๋กค๋ฐฑ ๊ธฐ๋Šฅ๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์Šคํ† ๋ฆฌ์ง€ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜

    • ๋‹ค์–‘ํ•œ ์Šคํ† ๋ฆฌ์ง€ ์‹œ์Šคํ…œ๊ณผ ์—ฐ๋™ํ•˜์—ฌ Pod์— ํ•„์š”ํ•œ ๋ณผ๋ฅจ์„ ์ž๋™์œผ๋กœ ์—ฐ๊ฒฐํ•ด์ค๋‹ˆ๋‹ค.
  • ์„œ๋น„์Šค ๋””์Šค์ปค๋ฒ„๋ฆฌ

    • Pod์˜ IP๋Š” ๋™์ ์œผ๋กœ ๋ฐ”๋€Œ๊ธฐ ๋•Œ๋ฌธ์—, ์ž์ฒด DNS๋ฅผ ์ด์šฉํ•ด ์•ˆ์ •์ ์ธ ์ ‘์† ์ฃผ์†Œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.



Pod์˜ ์ƒ๋ช… ์ฃผ๊ธฐ

  1. ์‚ฌ์šฉ์ž๊ฐ€ kubectl์„ ํ†ตํ•ด API ์„œ๋ฒ„์— Pod ์ƒ์„ฑ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

  2. API ์„œ๋ฒ„๋Š” ์š”์ฒญ์„ ๋ฐ›์•„ etcd์— ์ƒํƒœ๋ฅผ ๊ธฐ๋กํ•˜๊ณ , ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ๋ฅผ ์ตœ์‹ ์œผ๋กœ ์œ ์ง€ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

  3. ์ปจํŠธ๋กค๋Ÿฌ ๋งค๋‹ˆ์ €๊ฐ€ Pod๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ทธ ์ •๋ณด๋ฅผ API ์„œ๋ฒ„์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. (์•„์ง ์–ด๋–ค ๋…ธ๋“œ์— ์‹คํ–‰๋ ์ง€๋Š” ์ •ํ•ด์ง€์ง€ ์•Š์Œ)

  4. ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ Pod๋ฅผ ์‹คํ–‰ํ•  ์ ์ ˆํ•œ ์›Œ์ปค ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  5. ํ•ด๋‹น ๋…ธ๋“œ์˜ kubelet์ด ์ปจํ…Œ์ด๋„ˆ ๋Ÿฐํƒ€์ž„(CRI)์— ์š”์ฒญํ•˜์—ฌ Pod๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’ก Kubernetes๋Š” ์ ˆ์ฐจํ˜•์ด ์•„๋‹ˆ๋ผ ์„ ์–ธํ˜• ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ์ƒํƒœ๋ฅผ ์„ ์–ธํ•˜๋ฉด, ํ˜„์žฌ ์ƒํƒœ์™€ ๋น„๊ตํ•˜์—ฌ ์ด๋ฅผ ์ง€์†์ ์œผ๋กœ ๋งž์ถ”๊ธฐ ์œ„ํ•ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.


โš™๏ธ ๊ด€๊ณ„ ๊ตฌ์กฐ

Node
 โ”œโ”€โ”€ Pod A
 โ”‚    โ”œโ”€โ”€ Container 1
 โ”‚    โ””โ”€โ”€ Container 2
 โ”œโ”€โ”€ Pod B
 โ”‚    โ””โ”€โ”€ Container 3
 โ””โ”€โ”€ Pod C
      โ””โ”€โ”€ Container 4



k8s ๋ฆฌ์†Œ์Šค ํ๋ฆ„๋„

์ถœ์ฒ˜: ๊ฐœ์ธ๋ธ”๋กœ๊ทธ https://blog.taehun.dev/from-zero-to-hero-mlops-tools-3-1


  • Namespace

    • k8s ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๊ทธ๋ฃน๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋…ผ๋ฆฌ์  ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

  • Deployment

    • Pod์˜ ์„ ์–ธ, ๋ฐฐํฌ, ์—…๋ฐ์ดํŠธ, ๋ณต์ œ ๋“ฑ์„ ์ž๋™ํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์ปจํŠธ๋กค๋Ÿฌ์ž…๋‹ˆ๋‹ค.

    • ๋‚ด๋ถ€์ ์œผ๋กœ ReplicaSet์„ ์ด์šฉํ•ด Pod ์ˆ˜๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ๋ฒ„์ „ ๋ณ€๊ฒฝ ์‹œ ๋กค๋ง ์—…๋ฐ์ดํŠธ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.


  • ReplicaSet

    • ํŠน์ • ์ˆ˜์˜ Pod๋ฅผ ํ•ญ์ƒ ์œ ์ง€ํ•ด์ฃผ๋Š” ์ปจํŠธ๋กค๋Ÿฌ์ž…๋‹ˆ๋‹ค.

    • ์˜ˆ๋ฅผ ๋“ค์–ด 3๊ฐœ์˜ Pod๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์„ ๋•Œ, ํ•˜๋‚˜๊ฐ€ ์ฃฝ์œผ๋ฉด ์ž๋™์œผ๋กœ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.


  • Pod
    • ํ•˜๋‚˜ ์ด์ƒ์˜ ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ตฌ์„ฑ๋œ ๊ฐ€์žฅ ์ž‘์€ ์‹คํ–‰ ๋‹จ์œ„์ž…๋‹ˆ๋‹ค. ๊ณ ์œ ํ•œ IP๋ฅผ ๊ฐ–๊ณ  ์žˆ์œผ๋ฉฐ, ์–ธ์ œ๋“ ์ง€ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋Š” ์„ฑ์งˆ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

  • Volume

    • Pod๊ฐ€ ์ƒ์„ฑ๋  ๋–„ Pod์— ๋งˆ์šดํŠธ๋˜๋Š” ์ €์žฅ ๊ณต๊ฐ„์œผ๋กœ, ์ปจํ…Œ์ด๋„ˆ ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ณต์œ  ๋“ฑ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • Service

    • ์—ฌ๋Ÿฌ Pod ์•ž์— ์žˆ๋Š” ๋„คํŠธ์›Œํฌ ์ ‘๊ทผ ์ง€์ ์ž…๋‹ˆ๋‹ค.

    • Pod๋Š” IP๊ฐ€ ๋ฐ”๋€” ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์•ˆ์ •์ ์ธ ์ ‘๊ทผ์„ ์œ„ํ•ด ๊ณ ์ •๋œ ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    • ์„œ๋น„์Šค์˜ ๋‹ค๋ฅธ ํ˜•ํƒœ๋“ค

      • ClusterIP
        • ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ธฐ๋ณธ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์™ธ๋ถ€์—์„œ๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ณ , ๋‚ด๋ถ€ ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹ ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
      • NodePort
        • ๊ฐ ๋…ธ๋“œ์˜ ํฌํŠธ๋ฅผ ์—ด์–ด ์™ธ๋ถ€์—์„œ๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
      • LoadBalancer
        • ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์—์„œ ์™ธ๋ถ€์— ๊ณต์ธ IP๋ฅผ ๋…ธ์ถœํ•ด์ฃผ๋Š” ํƒ€์ž…์ž…๋‹ˆ๋‹ค.
          ์ถœ์ฒ˜: ๊ฐœ์ธ๋ธ”๋กœ๊ทธ
      • ExternalName

        • ์™ธ๋ถ€ DNS ์ด๋ฆ„์„ ๋‚ด๋ถ€ ์„œ๋น„์Šค ์ด๋ฆ„์œผ๋กœ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค.

  • Ingress

    • ์™ธ๋ถ€ ์‚ฌ์šฉ์ž์˜ HTTP/HTTPS ์š”์ฒญ์„ Service๋กœ ๋ผ์šฐํŒ…ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

    • ์™ธ๋ถ€์—์„œ ํ•˜๋‚˜์˜ IP๋กœ ์—ฌ๋Ÿฌ ์„œ๋น„์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ์œ„ํ•œ ์ง„์ž… ์ง€์ ์ž…๋‹ˆ๋‹ค.
      ์ถœ์ฒ˜: geeksforgeeks




k8s ์ธํ”„๋ผ ๊ตฌ์ถ•

  • ๋กœ์ปฌ ํ™˜๊ฒฝ ๊ตฌ์ถ•

    • kubeadm, Docker Desktop ๋“ฑ์„ ํ†ตํ•ด ๊ฐ„๋‹จํžˆ ํ…Œ์ŠคํŠธ์šฉ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํผ๋ธ”๋ฆญ ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค

    • Amazon AWS EKS (Elastic Kubernetes Services)

    • GCP GKE (Google Kubernetes Engine)

    • Microsoft AKS (Azuer Kubernetes Service)

  • ์˜จํ”„๋ ˆ๋ฏธ์Šค ์„ค์น˜ํ˜• ์†”๋ฃจ์…˜

    • SUSE Rancher

    • RedHat OpenShift




์‹ค์Šต

์‹ค์Šต ์ค€๋น„

  • โš™๏ธ Docker Desktop > Settings > Kubernetes > Enable Kubernetes โœ… ํ† ๊ธ€์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • kubectl get nodes ๋ช…๋ น์–ด ์‹คํ–‰ โ†’ ๋…ธ๋“œ๊ฐ€ ์ž˜ ๋“ฑ๋ก๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

Pod โ†’ Deployment โ†’ Service ์ ˆ์ฐจํ˜• ๊ตฌ์กฐ ์‹ค์Šต

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ Pod๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•ด๋ณด๊ณ , Deployment๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌํ•˜๋ฉฐ, Service๋กœ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜๋Š” ์ „์ฒด ํ๋ฆ„์„ ์‹ค์Šตํ•ฉ๋‹ˆ๋‹ค.


1๏ธโƒฃ ์ „์ฒด ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ Pod ์กฐํšŒ

kubectl get pods --all-namespaces
  • ๋ชจ๋“  ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ๋Š” Pod ๋ชฉ๋ก์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

2๏ธโƒฃ ๊ฐœ๋ณ„ Pod ์ƒ์„ฑ

kubectl run nginx-pod --image=nginx
  • nginx ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•ด์„œ nginx-pod๋ผ๋Š” ๋‹จ์ผ Pod๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’ก ์ด ๋ช…๋ น์–ด๋Š” Deployment ์—†์ด ๋‹จ์ผ Pod๋งŒ ์ง์ ‘ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์‹ค๋ฌด๋ณด๋‹ค๋Š” ์‹ค์Šต์ด๋‚˜ ํ…Œ์ŠคํŠธ์šฉ์œผ๋กœ ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.


3๏ธโƒฃ Deployment ์ƒ์„ฑ

kubectl create deployment dpy-nginx --image=nginx
kubectl get deployment -o wide
  • nginx ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ dpy-nginx๋ผ๋Š” Deployment๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  • -o wide ์˜ต์…˜์€ IP, ๋…ธ๋“œ ๋“ฑ ์ถ”๊ฐ€ ์ •๋ณด๊นŒ์ง€ ๊ฐ™์ด ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

4๏ธโƒฃ Replica ๊ฐœ์ˆ˜ ์กฐ์ ˆ

kubectl scale deployment dpy-nginx --replicas=3
kubectl get pods -o wide
  • dpy-nginx Deployment๋ฅผ Pod 3๊ฐœ๋กœ ํ™•์žฅํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • get pods๋กœ ํ™•์ธํ•˜๋ฉด 3๊ฐœ์˜ ๋™์ผํ•œ Pod๊ฐ€ ์ƒ๊ธด ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


5๏ธโƒฃ ๋‹จ์ผ Pod์— Service ๋…ธ์ถœ

kubectl expose pod nginx-pod --type=NodePort --name=pod-svc --port=80
kubectl get svc
  • type=NodePort : ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ณ ์ • ํฌํŠธ๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

  • kubectl get svc๋กœ ์„œ๋น„์Šค IP ๋ฐ ํฌํŠธ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.


6๏ธโƒฃ ์™ธ๋ถ€์—์„œ ์ ‘์† (curl)

curl localhost:30425
  • ์ƒ์„ฑ๋œ NodePort๋กœ ์ ‘์†์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

7๏ธโƒฃ Deployment์—๋„ Service ๋…ธ์ถœ

kubectl expose deployment dpy-nginx --type=NodePort --name=dpy-svc --port=80
kubectl get services

  • Deployment ์ „์ฒด๋ฅผ ์™ธ๋ถ€์— ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  • ์—ฌ๋Ÿฌ Pod ์ค‘ ํ•˜๋‚˜์—๊ฒŒ ๋ผ์šฐํŒ…ํ•ด์ฃผ๋Š” ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.


8๏ธโƒฃ ์™ธ๋ถ€์—์„œ ์ ‘์† (curl)

curl localhost:30760
  • ์ƒ์„ฑ๋œ NodePort๋กœ ์ ‘์†์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’ก dpy-nginx Deployment์— ์—ฐ๊ฒฐ๋œ 3๊ฐœ์˜ Pod ์ค‘ ํ•˜๋‚˜๋กœ ์ž๋™์œผ๋กœ ์š”์ฒญ์„ ๋ถ„์‚ฐ(๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ) ํ•ฉ๋‹ˆ๋‹ค.


9๏ธโƒฃ ์„œ๋น„์Šค ์‚ญ์ œ

kubectl delete service pod-svc dpy-svc
  • ์•ž์„œ ๋งŒ๋“  pod-svc์™€ dpy-svc๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.




์ง€๊ธˆ๊นŒ์ง€๋Š” kubectl ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์ง์ ‘ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

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

๊ทธ๋ž˜์„œ Kubernetes์—์„œ๋Š” ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์„ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ ์„ ์–ธ์ (Declarative)์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.




๋งค๋‹ˆํŽ˜์ŠคํŠธ

์˜ค๋ธŒ์ ํŠธ(Pod, Deployment, Service ๋“ฑ)์— ๋Œ€ํ•œ ์„ค์ •์„ ํŒŒ์ผ๋กœ ๊ธฐ๋กํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • YAML (Yet Another Markup Language ๋˜๋Š” YAML Ain't Markup Language) ํ˜•์‹์œผ๋กœ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค.

  • ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์–ด๋–ค ์ƒํƒœ๋กœ ์กด์žฌํ•ด์•ผ ํ•˜๋Š”์ง€(=์˜๋„ํ•œ ์ƒํƒœ, desired state)๋ฅผ ๊ธฐ์ˆ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์„ค์ • ๋ถ€๋ถ„์„ ์˜ค๋ธŒ์ ํŠธ ์ŠคํŽ™(spec)์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

  • ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋™์ผํ•œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๋ฐ˜๋ณต ์ ์šฉํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์„ ํ†ตํ•ด ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • ๋ณต์žกํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ช…๋ น์–ด๋กœ ์ผ์ผ์ด ์ž…๋ ฅํ•˜๊ธฐ๋ณด๋‹ค, ํŒŒ์ผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ์ž๋™ํ™”์™€ ์œ ์ง€๋ณด์ˆ˜์— ํ›จ์”ฌ ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


๋งค๋‹ˆํŽ˜์ŠคํŠธ ์ ์šฉ ๋ช…๋ น์–ด

kubectl apply -f <๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ>

๐Ÿค” kubectl create -f๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ญ˜๊นŒ?

kubectl apply๋Š” ๋‹จ์ˆœํžˆ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ๊ทธ์น˜์ง€ ์•Š๊ณ , ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ๋งŒ ๋ฐ˜์˜ํ•˜๋Š” ๊ธฐ๋Šฅ๊นŒ์ง€ ํฌํ•จํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

kubectl create๋Š” ์˜ค๋ธŒ์ ํŠธ๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์ƒ์„ฑํ•˜๋Š” ๋ช…๋ น์–ด๋กœ, ์ด๋ฏธ ๋™์ผํ•œ ๋ฆฌ์†Œ์Šค๊ฐ€ ์กด์žฌํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.


๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ ์˜ˆ์‹œ

  • deployment.yaml
apiVersion: app/v1
kind: Deployment

metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector: 
    matchLabels:
      app: nginx
  template:
    metadata:
    labels:
      app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
  • service.yaml
apiVersion: v1
kind: Service

metadata:
  name: nginx-service
spec:
  type: NodePort
  selector: 
      app: nginx
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30000



๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ ์‹ค์Šต

Flask ์•ฑ์„ ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ตฌ์„ฑํ•˜๊ณ  Kubernetes์— ๋ฐฐํฌํ•œ ๋’ค, NodePort ์„œ๋น„์Šค๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ๋“œ์— ์ž๋™ ๋ถ„์‚ฐ(๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ)ํ•˜๋Š” ๊ณผ์ •์„ ์‹ค์Šตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ์ด๋ž€?

๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ์ด๋ž€ ๋งŽ์€ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ, ํ•œ ๊ณณ์— ๋ชฐ๋ฆฌ์ง€ ์•Š๋„๋ก ์—ฌ๋Ÿฌ ์„œ๋ฒ„(Pod)๋กœ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ๋‚˜๋ˆ ์ฃผ๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.
์ถœ์ฒ˜: medium


๐Ÿค” ์™œ ํ•„์š”ํ•œ ๊ฑธ๊นŒ?

1. ํŠธ๋ž˜ํ”ฝ ๋ถ„์‚ฐ
์‚ฌ์šฉ์ž๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ํ•œ ์„œ๋ฒ„๊ฐ€ ๊ฐ๋‹นํ•˜๊ธฐ ํž˜๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜๋ˆ„๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

2. ๊ณ ๊ฐ€์šฉ์„ฑ (High Availability)
ํ•˜๋‚˜์˜ ํŒŒ๋“œ๊ฐ€ ์ฃฝ๋”๋ผ๋„ ๋‚˜๋จธ์ง€๊ฐ€ ์‚ด์•„์„œ ์‘๋‹ต์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

3. ์Šค์ผ€์ผ๋ง ์œ ์—ฐ์„ฑ
ํŠน์ • ๊ธฐ๋Šฅ(์˜ˆ: ๊ฒฐ์ œ)๋งŒ ํŠธ๋ž˜ํ”ฝ ๋งŽ์œผ๋ฉด ๊ทธ ํŒŒ๋“œ๋งŒ ๋Š˜๋ฆฌ๋ฉด ๋˜๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.


1๏ธโƒฃ Flask ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์„ฑ

  • app.py
from flask import Flask
import socket

app = Flask(__name__)

hostname = socket.gethostname()
ipv4 = socket.gethostbyname(hostname)

message = f'<p>Hostname: {hostname}</p><p>IPv4 Address: {ipv4}</p>\n'

@app.route('/')
def root():
  return message

  • requirements.txt
Flask

2๏ธโƒฃ Nginx๋กœ ํ”„๋ก์‹œ ์„ค์ •

  • site.conf
server {
  listen 80;
  server_name localhost;
  access_log /var/log/nginx/access.log main;'
  location / {
    proxy_pass http://127.0.0.1:5000;
  }
}

  • start.sh
service nginx start
/flaskapp/venv/bin/flask --app app run --host 0.0.0.0

3๏ธโƒฃ Dockerfile ๊ตฌ์„ฑ

  • Dockerfile
FROM nginx:latest

RUN apt update
RUN apt install -y python3-full
RUN apt install -y procps

WORKDIR /flaskapp
RUN python3 -m venv /flaskapp/venv
COPY requirements.txt requirements.txt
RUN /flaskapp/venv/bin/pip install -r requirements.txt

COPY app.py app.py
COPY site.conf /etc/nginx/sites-available/flaskapp.conf
RUN ln -s /etc/nginx/sites-available/flaskapp.conf /etc/nginx/conf.d
RUN mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak

COPY start.sh start.sh
RUN chmod 777 start.sh

ENTRYPOINT ["/flaskapp/start.sh"]

  • deployment.yaml
apiVersion: apps/v1
kind: Deployment

metadata:
  name: dpy-hname
  labels:
    app: hostname
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hostname
  template:
    metadata:
      labels:
        app: hostname
    spec:
      containers:
        - name: hname
          image: ๊ณ„์ •์ด๋ฆ„/hostname:latest
          ports:
            - containerPort: 80

  • service.yaml
apiVersion: v1
kind: Service

metadata:
    name: svc-hname
spec:
    type: NodePort
    selector:
        app: hostname
    ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30000

๐Ÿค” ์™œ NodePort๋ฅผ ์‚ฌ์šฉํ• ๊นŒ?

Flask ์•ฑ์€ k8s Pod ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ curl์ด๋‚˜ ์™ธ๋ถ€ ๋ธŒ๋ผ์šฐ์ €์˜ ์š”์ฒญ์„ ๋ณด๋‚ด๋ ค๋ฉด ๋‚ด๋ถ€๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ฐ›์•„์ฃผ๋Š” NodePort ํƒ€์ž…์˜ Service๋ฅผ ์‚ฌ์šฉํ•ด ๋…ธ๋“œ์˜ ํŠน์ • ํฌํŠธ๋ฅผ ๊ฐœ๋ฐฉํ•˜๊ณ , ๊ทธ ํฌํŠธ๋กœ ๋“ค์–ด์˜จ ์š”์ฒญ์„ ๋‚ด๋ถ€ Pod๋กœ ๋ผ์šฐํŒ…ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.


4๏ธโƒฃ DockerHub ์—…๋กœ๋“œ

  • deployment.yaml ์—์„œ ์ž‘์„ฑํ•œ image๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ DockerHub์— ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
docker build -t hostname:latest .

docker tag hostname:latest ๊ณ„์ •์ด๋ฆ„/hostname:latest
docker push ๊ณ„์ •์ด๋ฆ„/hostname:latest


5๏ธโƒฃ Kubernetes์— ๋ฐฐํฌ

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl get pods -o wide


6๏ธโƒฃ curl๋กœ ํ…Œ์ŠคํŠธ

  • ์—ฌ๋Ÿฌ ๋ฒˆ ์š”์ฒญํ•˜๋ฉด ๋‹ค๋ฅธ ํŒŒ๋“œ์—์„œ ์‘๋‹ตํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
curl localhost:30000
curl localhost:30000
curl localhost:30000
curl localhost:30000
curl localhost:30000

ํ๋ฆ„ ์š”์•ฝ

[ ์‚ฌ์šฉ์ž (curl or ๋ธŒ๋ผ์šฐ์ €) ]
           โ†“
  http://localhost:30000
           โ†“
[ Kubernetes NodePort ์„œ๋น„์Šค (30000) ]
           โ†“
[ ์—ฌ๋Ÿฌ ํŒŒ๋“œ ์ค‘ ํ•˜๋‚˜ ์„ ํƒ (๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ) ]
           โ†“
[ Nginx (80) โ†’ Flask (5000) ]
           โ†“
[ HTML ์‘๋‹ต: Hostname & IP ์ถœ๋ ฅ ]



๋ฐฐํฌ๋œ ์†Œํ”„ํŠธ์›จ์–ด ์—…๋ฐ์ดํŠธ์™€ ๋ณต๊ตฌ ์‹ค์Šต

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ์ˆ˜๋™์œผ๋กœ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ , ํ•„์š”ํ•˜๋ฉด ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๊ฒŒ ์—ฐ์Šตํ•˜๋Š” ์‹ค์Šต์ž…๋‹ˆ๋‹ค.

- kubectl rollout undo deployment <๋””ํ”Œ๋กœ์ด๋จผํŠธ ์ด๋ฆ„> 

- kubectl rollout undo deployment <๋””ํ”Œ๋กœ์ด๋จผํŠธ ์ด๋ฆ„> --to-revision=<๋ฆฌ๋น„์ „ ๋ฒˆํ˜ธ> : ํŠน์ • ์‹œ์ ์œผ๋กœ ๋Œ๋ฆฌ๋Š” ๊ฑฐ
  • rollout.yaml
apiVersion: apps/v1
kind: Deployment

metadata:
  name: dpy-nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.0
        ports:
        - containerPort: 80
  • service.yaml
apiVersion: v1
kind: Service

metadata:
    name: svc-nginx
spec:
    type: NodePort
    selector:
      app: nginx
    ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30000

1๏ธโƒฃ ์ดˆ๊ธฐ ๋ฐฐํฌ (nginx:1.17.0)

kubectl apply -f rollout.yaml
  • rollout.yaml ํŒŒ์ผ์„ ์ ์šฉํ•ด์„œ Deployment ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
kubectl apply -f rollout.yaml --record
  • --record ์˜ต์…˜์„ ์ฃผ๋ฉด, ๋ช…๋ น ์‹คํ–‰ ์ด๋ ฅ์ด revision์— ๋‚จ๊ฒจ์ ธ ๋ฌด์—‡์„ ํ–ˆ๋Š”์ง€ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
kubectl rollout status deployment dpy-nginx
  • ๋ฐฐํฌ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ง„ํ–‰ ์ค‘์ธ์ง€, ๋กค์•„์›ƒ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
kubectl rollout history deployment dpy-nginx
  • ์ง€๊ธˆ๊นŒ์ง€์˜ ๋ฐฐํฌ ์ด๋ ฅ์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.


2๏ธโƒฃ nginx ๋ฒ„์ „ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ (1.16.0)

kubectl delete deployment dpy-nginx
  • ๋ฐฐํฌ๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
# rollout.yaml ํŒŒ์ผ์—์„œ nginx:1.16.0 ์œผ๋กœ ์ด๋ฏธ์ง€ ๋ฒ„์ „ ์ˆ˜์ •
kubectl apply -f rollout.yaml
  • nginx ๋ฒ„์ „ 1.16.0์œผ๋กœ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

3๏ธโƒฃ ์ˆ˜๋™ ์—…๋ฐ์ดํŠธ (๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ)

kubectl set image deployment dpy-nginx nginx=nginx:1.17.0
  • set image ๋ช…๋ น์œผ๋กœ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐฐํฌ ์ค‘์ธ Deployment์˜ ์ด๋ฏธ์ง€๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
kubectl annotate deployment dpy-nginx kubernetes.io/change-cause="์„ค๋ช…"
  • ๋ณ€๊ฒฝ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์„ค๋ช…์„ ์ฃผ์„(annotation)์œผ๋กœ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
kubectl rollout history deployment dpy-nginx
  • ๋‹ค์‹œ ๋ฐฐํฌ ์ด๋ ฅ์„ ํ™•์ธํ•˜๋ฉด, ๋ฐฉ๊ธˆ ๋ณ€๊ฒฝํ•œ ๋‚ด์šฉ์ด revision 2๋กœ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค.


4๏ธโƒฃ ๋˜๋Œ๋ฆฌ๊ธฐ

kubectl rollout undo deployment dpy-nginx
  • ๊ฐ€์žฅ ์ด์ „ revision์œผ๋กœ ๋˜๋Œ๋ฆฌ๋Š” ๊ธฐ๋ณธ rollback ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค.
kubectl rollout undo deployment dpy-nginx --to-revision=<๋ฒˆํ˜ธ>
  • ํŠน์ • revision ๋ฒˆํ˜ธ(kubectl rollout history)๋กœ ์ •ํ™•ํžˆ ์ง€์ •ํ•ด์„œ ๋˜๋Œ๋ฆด ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

5๏ธโƒฃ ๋ฒ„์ „ ํ™•์ธํ•˜๊ธฐ

curl -I --silent localhost:30000 | grep Server
  • -I : ํ—ค๋”๋งŒ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค. (HTTP ์‘๋‹ต ๋ณธ๋ฌธ์€ ์ œ์™ธ)

  • --silent : ์ง„ํ–‰ ์ƒํƒœ ์ถœ๋ ฅ ์ˆจ๊น๋‹ˆ๋‹ค.

  • grep Server : Server: ๊ฐ€ ํฌํ•จ๋œ ์ค„๋งŒ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.




์ž๋™ ์Šค์ผ€์ผ๋ง ์‹ค์Šต

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค Horizontal Pod Autoscaler (HPA)๋ฅผ ์‚ฌ์šฉํ•ด์„œ CPU ์‚ฌ์šฉ๋ฅ ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ Pod ์ˆ˜๋ฅผ ๋Š˜๋ ธ๋‹ค ์ค„์ด๋Š” ๋™์  ์Šค์ผ€์ผ๋ง์„ ์‹ค์Šตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” HPA(Horizontal Pod Autoscaler)๋ž€?

ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด ๋ถ€ํ•˜๋Ÿ‰์— ๋”ฐ๋ผ Deployment์˜ Pod ์ˆ˜๋ฅผ ์ž๋™์œผ๋กœ ์กฐ์ ˆํ•˜๋Š” Kubernetes์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ CPU ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ๊ธฐ์ค€์œผ๋กœ ํŒ๋‹จํ•˜๋ฉฐ, metrics-server๋กœ๋ถ€ํ„ฐ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰ ์ •๋ณด๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” Pod์˜ ์ˆ˜๋ฅผ ๋™์ ์œผ๋กœ ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค.


์‹ค์Šต ํŒŒ์ผ

  • metrics.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-view: "true"
  name: system:aggregated-metrics-reader
rules:
- apiGroups:
  - metrics.k8s.io
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
  name: system:metrics-server
rules:
- apiGroups:
  - ""
  resources:
  - nodes/metrics
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server-auth-reader
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server:system:auth-delegator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: system:metrics-server
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:metrics-server
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  strategy:
    rollingUpdate:
      maxUnavailable: 0
  template:
    metadata:
      labels:
        k8s-app: metrics-server
    spec:
      containers:
      - args:
        - --cert-dir=/tmp
        - --kubelet-insecure-tls
        - --secure-port=4443
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        image: registry.k8s.io/metrics-server/metrics-server:v0.6.4
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /livez
            port: https
            scheme: HTTPS
          periodSeconds: 10
        name: metrics-server
        ports:
        - containerPort: 4443
          name: https
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /readyz
            port: https
            scheme: HTTPS
          initialDelaySeconds: 20
          periodSeconds: 10
        resources:
          requests:
            cpu: 100m
            memory: 200Mi
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
        volumeMounts:
        - mountPath: /tmp
          name: tmp-dir
      nodeSelector:
        kubernetes.io/os: linux
      priorityClassName: system-cluster-critical
      serviceAccountName: metrics-server
      volumes:
      - emptyDir: {}
        name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  labels:
    k8s-app: metrics-server
  name: v1beta1.metrics.k8s.io
spec:
  group: metrics.k8s.io
  groupPriorityMinimum: 100
  insecureSkipTLSVerify: true
  service:
    name: metrics-server
    namespace: kube-system
  version: v1beta1
  versionPriority: 100
  • php-apache
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  selector:
    matchLabels:
      run: php-apache
  template:
    metadata:
      labels:
        run: php-apache
    spec:
      containers:
      - name: php-apache
        image: registry.k8s.io/hpa-example
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 500m
          requests:
            cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
  name: php-apache
  labels:
    run: php-apache
spec:
  ports:
  - port: 80
  selector:
    run: php-apache

1๏ธโƒฃ Metrics ์„œ๋ฒ„ ์„ค์น˜

 kubectl apply -f metrics.yaml
  • HPA๋Š” CPU ์‚ฌ์šฉ๋ฅ  ๋“ฑ์˜ ๋ฉ”ํŠธ๋ฆญ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์Šค์ผ€์ผ๋งํ•˜๋Š” ๊ธฐ๋Šฅ์ด๊ธฐ ๋•Œ๋ฌธ์— metrics-server๊ฐ€ ์—†์œผ๋ฉด HPA CPU ์‚ฌ์šฉ๋ฅ ์„ ์ฝ์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์„ค์น˜๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค.
kubectl get pods --all-namespaces
  • ๊ฐ„๋‹จํ•œ ์›น์„œ๋ฒ„ (php-apache)๋ฅผ 1๊ฐœ์˜ Pod๋กœ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ (php-apache)

kubectl apply -f php-apache.yaml
  • ๊ฐ„๋‹จํ•œ ์›น ์„œ๋ฒ„ ์‘์šฉ์„ ๋ฐฐํฌ(ํฌ๋“œ 1๊ฐœ)ํ•˜๊ณ  ClusterIP๋กœ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์—๋งŒ ๋…ธ์ถœ

3๏ธโƒฃ Horizontal Pod Autoscaler ์„ค์ •

kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
  • CPU ์‚ฌ์šฉ๋ฅ ์ด 50%๋ฅผ ๋„˜์œผ๋ฉด Pod๋ฅผ ์ž๋™์œผ๋กœ ๋Š˜๋ฆฌ๊ณ ,
    ๋‚ฎ์•„์ง€๋ฉด ์ค„์ด๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค.

  • Pod ์ˆ˜๋Š” ์ตœ์†Œ 1๊ฐœ, ์ตœ๋Œ€ 10๊ฐœ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.


4๏ธโƒฃ ๋ถ€ํ•˜ ์ƒ์„ฑ (load generator)

kubectl run -it load-gen --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
  • busybox ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•ด์„œ php-apache ์„œ๋น„์Šค์— ์ง€์†์ ์œผ๋กœ HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์—ญํ• ์ž…๋‹ˆ๋‹ค.

  • 0.01์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ๊ณ„์† ์š”์ฒญํ•ด์„œ CPU ์‚ฌ์šฉ๋Ÿ‰์„ ์ธ์œ„์ ์œผ๋กœ ์˜ฌ๋ฆฌ๋Š” ๋ชฉ์ ์ž…๋‹ˆ๋‹ค.


5๏ธโƒฃ HPA ์ƒํƒœ ํ™•์ธ

kubectl get hpa
  • ํ˜„์žฌ HPA๊ฐ€ ๊ฐ์ง€ํ•œ CPU ์‚ฌ์šฉ๋ฅ ๊ณผ Pod ๊ฐœ์ˆ˜ ์กฐ์ ˆ ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.




๋ณผ๋ฅจ ์‹ค์Šต

Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์—์„œ PersistentVolume(PV)์™€ PersistentVolumeClaim(PVC)์„ ์‚ฌ์šฉํ•ด
๋กœ์ปฌ ์ €์žฅ์†Œ๋ฅผ ๋งˆ์šดํŠธํ•˜๊ณ , nginx ์›น ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด HTML ํŒŒ์ผ์„ ์„œ๋น„์Šคํ•˜๋Š” ๊ณผ์ •์„ ์‹ค์Šตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” ๋ณผ๋ฅจ์ด ์ค‘์š”ํ•œ ์ด์œ ๋Š” ๋ญ˜๊นŒ?

์ปจํ…Œ์ด๋„ˆ๋Š” ์žฌ์‹œ์ž‘ํ•˜๋ฉด ๋‚ด๋ถ€์— ์žˆ๋˜ ํŒŒ์ผ์ด ๋‚ ์•„๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ๋ณผ๋ฅจ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์˜๊ตฌ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.


PV (PersistentVolume)

Pod๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฏธ๋ฆฌ ๋“ฑ๋ก๋œ ์ €์žฅ ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

  • Pod๋Š” ์ด ์ €์žฅ์†Œ์— ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ  PVC(PersistentVolumeClaim)๋ฅผ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  • ๋ณ€ํ™”ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ก, ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

PVC (PersistentVolumeClaim)

Pod์ด ์‚ฌ์šฉํ•  ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

  • pod : node = pvc : pv

  • ์›ํ•˜๋Š” ์ €์žฅ ์šฉ๋Ÿ‰๊ณผ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์‹ค์Šต ํŒŒ์ผ

  • pv-volume.yaml
apiVersion: v1
kind: PersistentVolume

metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/c/Users/MSI/Downloads/2-05 (1)/2-05/pv/data"

  • pv-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim

metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
  • deployment.yaml
apiVersion: apps/v1
kind: Deployment

metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      run: nginx
  template:
    metadata:
      labels:
        run: nginx
    spec:
      volumes:
        - name: task-pv-storage
          persistentVolumeClaim:
            claimName: task-pv-claim
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: "/run/desktop/mnt/host/c/Users/MSI/pv/data"
---
apiVersion: v1
kind: Service

metadata:
  name: nginx
  labels:
    run: nginx
spec:
  type: NodePort
  selector:
    run: nginx
  ports:
    - port: 80
      nodePort: 30000

1๏ธโƒฃ ๋กœ์ปฌ ๋””๋ ‰ํ† ๋ฆฌ ์ค€๋น„

mkdir data
cd data
cat > index.html
<p>Hello from k8s Storage!</p>
  • ๋กœ์ปฌ ๋””์Šคํฌ์— data ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ , nginx๊ฐ€ ์„œ๋น„์Šคํ•  HTML ํŒŒ์ผ(index.html)์„ ์ง์ ‘ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ PersistentVolume ์ƒ์„ฑ

kubectl apply -f pv-volume.yaml
kubectl get pv
  • pv-volume.yaml์„ ์ด์šฉํ•ด ๋กœ์ปฌ ๋””์Šคํฌ๋ฅผ Kubernetes์˜ PV ๋ฆฌ์†Œ์Šค๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

3๏ธโƒฃ PersistentVolumeClaim ์ƒ์„ฑ

kubectl apply -f pv-claim.yaml
kubectl get pvc
  • PVC๋Š” Pod๊ฐ€ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•  ๋•Œ ๋‚ด๋Š” ์š”์ฒญ์„œ์ž…๋‹ˆ๋‹ค.

  • get pvc๋กœ ๋ฐ”์ธ๋”ฉ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ด์„œ PVC๊ฐ€ PV์™€ ์ž˜ ์—ฐ๊ฒฐ๋˜์—ˆ๋Š”์ง€ ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค.

    • STATUS๊ฐ€ Bound์ด๋ฉด ์—ฐ๊ฒฐ์ด ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

4๏ธโƒฃ Deployment & Service ์ƒ์„ฑ

kubectl apply -f deployment.yaml
kubectl get svc
  • nginx Deployment๋ฅผ ๋งŒ๋“ค๊ณ , ๋ฐฉ๊ธˆ ๋งŒ๋“  PVC๋ฅผ nginx Pod์— ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. ๋™์‹œ์— NodePort ํƒ€์ž…์˜ Service๋„ ๋งŒ๋“ค์–ด์„œ ์™ธ๋ถ€(๋กœ์ปฌ)์—์„œ ์ ‘์† ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

5๏ธโƒฃ ์›น ์ ‘์† ํ…Œ์ŠคํŠธ

curl localhost:30000
  • curl๋กœ nginx ์„œ๋น„์Šค์— ์ ‘์†ํ•ฉ๋‹ˆ๋‹ค.

6๏ธโƒฃ Pod ๋‚ด๋ถ€ ์ ‘๊ทผ + ํŒŒ์ผ ์ƒ์„ฑ ์‹ค์Šต

kubectl get pods
kubectl exec -it <์ด๋ฆ„> -- /bin/bash
cd /usr/share/nginx/html
cat > tmp.txt
This file is being created inside a container.
exit
  • tmp.txt ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ, ์ •๋ง๋กœ ํ˜ธ์ŠคํŠธ ๋””๋ ‰ํ† ๋ฆฌ์™€ ๊ณต์œ ๋˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.

  • ๋‚˜์™€์„œ cat tmp.txt ๋กœ ํ™•์ธํ•˜๊ฑฐ๋‚˜ ๋กœ์ปฌ ํด๋”์— ํŒŒ์ผ์ด ๋ณด์ด๋ฉด ์„ฑ๊ณตํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.




โœ๏ธ ํšŒ๊ณ 

k8s ์•ˆ์—์„œ๋„ ๊ฐœ๋…์ด ๋งŽ์€ ๋งŒํผ, ์‹ค์ œ ์‹ค์Šต๊ณผ ํ•จ๊ป˜ ๋ณ‘ํ–‰ํ•ด์„œ ์ตํžˆ๋ฉด์„œ ์ดํ•ด๋ฅผ ํ•ด์•ผํ•˜๋Š”๋ฐ ์•„์ง์€ ์–ด๋ ค์šด ๊ฒƒ ๊ฐ™๋‹ค.

profile
๐ŸŒฑ๊ฐœ๋ฐœ ๊ธฐ๋ก์žฅ

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