๐ŸณDocker #2

Neo-Renaissanceยท2025๋…„ 4์›” 13์ผ
post-thumbnail

์ด ๊ธ€์—์„œ๋Š” ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๊ฐ€์ƒํ™” ๊ธฐ์ˆ , ๊ทธ๋ฆฌ๊ณ  ๋„์ปค์˜ ๊ฐœ๋…๊นŒ์ง€ ๋‹ค๋ค„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ

์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์€ ํฌ๊ฒŒ ํ•˜๋“œ์›จ์–ด์™€ ์†Œํ”„ํŠธ์›จ์–ด๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ํ•˜๋“œ์›จ์–ด๋Š” CPU, ๋ฉ”๋ชจ๋ฆฌ, ์ €์žฅ์žฅ์น˜์™€ ๊ฐ™์€ ๋ฌผ๋ฆฌ์ ์ธ ์ „์‚ฐ ์ž์›์ด ์ง‘์ค‘๋œ ๋ถ€๋ถ„์ด๋ฉฐ, ์†Œํ”„ํŠธ์›จ์–ด๋Š” ์ด๋Ÿฌํ•œ ํ•˜๋“œ์›จ์–ด ์ž์›์„ ํ™œ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ๋“ค์ž…๋‹ˆ๋‹ค.

์†Œํ”„ํŠธ์›จ์–ด๋Š” ๋‹ค์‹œ ๋‘ ๊ฐ€์ง€๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค:

  • ์‹œ์Šคํ…œ ์†Œํ”„ํŠธ์›จ์–ด(์šด์˜์ฒด์ œ): ํ•˜๋“œ์›จ์–ด๋ฅผ ์ง์ ‘ ์ œ์–ดํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด
  • ์‘์šฉ ์†Œํ”„ํŠธ์›จ์–ด(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜): ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด

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

์ปดํ“จํ„ฐ์˜ ์ •์ฒด์„ฑ์€ ๋Œ€๋ถ€๋ถ„ ์–ด๋–ค ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์‹คํ–‰ํ•˜๋А๋ƒ์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ํ•˜๋“œ์›จ์–ด๋ผ๋„ ์—‘์…€์„ ์‹คํ–‰ํ•˜๋ฉด ์‚ฌ๋ฌด์šฉ ๊ธฐ๊ธฐ, ๊ฒŒ์ž„์„ ์‹คํ–‰ํ•˜๋ฉด ๊ฒŒ์ž„๊ธฐ, ์˜ํ™”๋ฅผ ๋ณด๋ฉด ์—”ํ„ฐํ…Œ์ธ๋จผํŠธ ๊ธฐ๊ธฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ๋‹ค์–‘ํ•œ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์„ค์น˜ํ•˜๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ปดํ“จํ„ฐ๋Š” '๋ฒ”์šฉ ์ปดํ“จํ„ฐ'๋ผ๊ณ  ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค.

๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ(Virtual Memory) ๊ฐœ๋…

๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ „๊ณต์ž์™€ ๋น„์ „๊ณต์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ์ค‘์š”ํ•œ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ผ๊ณ  ํ•˜๋ฉด RAM์„ ์˜๋ฏธํ•˜์ง€๋งŒ, ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ๋Š” RAM๊ณผ ํ•˜๋“œ๋””์Šคํฌ ๊ฐ™์€ 2์ฐจ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ฉ์ณ์„œ ํ•˜๋‚˜์˜ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์ถ”์ƒํ™”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

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

์ „ํ†ต์ ์ธ ๊ฐ€์ƒํ™”: VMware ์ดํ•ดํ•˜๊ธฐ

๊ฐ€์ƒํ™”๋Š” ํ•˜๋‚˜์˜ ๋ฌผ๋ฆฌ์  ์ปดํ“จํ„ฐ์—์„œ ์™„์ „ํžˆ ๊ฒฉ๋ฆฌ๋œ ์—ฌ๋Ÿฌ ๊ฐ€์ƒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. VMware์™€ ๊ฐ™์€ ๊ฐ€์ƒํ™” ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ ๋ฌผ๋ฆฌ์  ์ปดํ“จํ„ฐ์—์„œ ์—ฌ๋Ÿฌ ์šด์˜์ฒด์ œ๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜ธ์ŠคํŠธ OS(์˜ˆ: Windows)์— VMware๋ฅผ ์„ค์น˜ํ•˜๊ณ  ๊ทธ ์œ„์— ๊ฒŒ์ŠคํŠธ OS(์˜ˆ: Linux)๋ฅผ ์„ค์น˜ํ•˜๋ฉด, ๊ฒŒ์ŠคํŠธ OS๋„ ํ˜ธ์ŠคํŠธ OS์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์œ ์ € ๋ชจ๋“œ, ์ปค๋„ ๋ชจ๋“œ, ํ•˜๋“œ์›จ์–ด ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ์€ ๊ฒŒ์ŠคํŠธ OS์˜ ํ•˜๋“œ์›จ์–ด๋Š” ์‹ค์ œ ํ•˜๋“œ์›จ์–ด๊ฐ€ ์•„๋‹Œ ์†Œํ”„ํŠธ์›จ์–ด๋กœ ๊ตฌํ˜„๋œ ๊ฐ€์ƒ ํ•˜๋“œ์›จ์–ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ€์ƒํ™” ํ™˜๊ฒฝ์—์„œ ๊ฐ€์ƒ ๋จธ์‹ (VM)์€ ์™„์ „ํ•œ ์šด์˜์ฒด์ œ๋ถ€ํ„ฐ ํ•˜๋“œ์›จ์–ด๊นŒ์ง€ ๋ชจ๋“  ๊ณ„์ธต์„ ๊ฐ€์ƒํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ VM์€ ์ž์ฒด ์šด์˜์ฒด์ œ๋ฅผ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์— ์ž์› ์†Œ๋ชจ๊ฐ€ ํฌ๊ณ , ๋ถ€ํŒ… ์‹œ๊ฐ„์ด ๊ธธ๋ฉฐ, ์—ฌ๋Ÿฌ VM์„ ์‹คํ–‰ํ•  ๊ฒฝ์šฐ ๋งŽ์€ ์ €์žฅ ๊ณต๊ฐ„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์ƒ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ๋ฐฉ์‹

VMware๋‚˜ VirtualBox๋ฅผ ์„ค์น˜ํ•˜๋ฉด ๋ฒ„์ถ”์–ผ ๋‹‰ ๋“œ๋ผ์ด๋ฒ„(Virtual NIC Driver)๋ผ๋Š” ๊ฒƒ์ด ์„ค์น˜๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์‹ค์ œ ๋„คํŠธ์›Œํฌ ์นด๋“œ๊ฐ€ ์•„๋‹Œ ์†Œํ”„ํŠธ์›จ์–ด๋กœ ๊ตฌํ˜„๋œ ๋„คํŠธ์›Œํฌ ๋“œ๋ผ์ด๋ฒ„์ž…๋‹ˆ๋‹ค.

๊ฒŒ์ŠคํŠธ OS์˜ ์†Œํ”„ํŠธ์›จ์–ด ๋„คํŠธ์›Œํฌ ์นด๋“œ๋Š” ํ˜ธ์ŠคํŠธ OS์˜ ๊ฐ€์ƒ ๋„คํŠธ์›Œํฌ ์นด๋“œ๋ฅผ ๋งˆ์น˜ ๋ฌผ๋ฆฌ์  ์นด๋“œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๊ฐ€์ƒ ๋„คํŠธ์›Œํฌ ์นด๋“œ๋Š” L2 ์Šค์œ„์น˜์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฆฌ๋ˆ…์Šค ๊ฒŒ์ŠคํŠธ OS์—์„œ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, ์š”์ฒญ์ด ๊ฐ€์ƒ ๋„คํŠธ์›Œํฌ ์นด๋“œ๋ฅผ ํ†ตํ•ด ํ˜ธ์ŠคํŠธ OS๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ํ˜ธ์ŠคํŠธ OS๋Š” ์ฃผ๋กœ NAT(Network Address Translation) ๋ฐฉ์‹์„ ์ง€์›ํ•˜์—ฌ ๊ณต์œ ๊ธฐ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์š”์ฒญ์ด ํ˜ธ์ŠคํŠธ์˜ ๋ฌผ๋ฆฌ์  ๋„คํŠธ์›Œํฌ ์นด๋“œ๋ฅผ ํ†ตํ•ด ์ธํ„ฐ๋„ท์œผ๋กœ ๋‚˜๊ฐ€๊ณ , ์‘๋‹ต๋„ ๊ฐ™์€ ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ต๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ๊ฐ€์ƒํ™” ๊ธฐ์ˆ ์„ ํ™œ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ ์ปดํ“จํ„ฐ๋กœ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ปดํ“จํ„ฐ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„์ปค์˜ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ

๊ฐ€์ƒํ™” ํ™˜๊ฒฝ์—์„œ๋Š” ํ•˜๋‚˜์˜ ๋ฌผ๋ฆฌ์  ์ปดํ“จํ„ฐ์—์„œ ํ˜ธ์ŠคํŠธ OS์™€ ์—ฌ๋Ÿฌ ๊ฒŒ์ŠคํŠธ OS๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋งŽ์€ ์ค‘๋ณต๋œ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. "์ด ๊ฒŒ์ŠคํŠธ OS๋“ค์ด ๊ผญ ํ•„์š”ํ•œ๊ฐ€? ์—†์–ด๋„ ๋˜์ง€ ์•Š์„๊นŒ?"๋ผ๋Š” ์˜๋ฌธ์—์„œ ๋„์ปค(Docker)๋ผ๋Š” ๊ฐœ๋…์ด ํƒ„์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

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

๋„์ปค(Docker)์˜ ๊ฐœ๋…๊ณผ ์ž‘๋™ ๋ฐฉ์‹

๋„์ปค๋Š” ์ปจํ…Œ์ด๋„ˆํ™”๋ผ๋Š” ๊ฐ€์ƒํ™” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆํ™”๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๊ทธ ์˜์กด์„ฑ์„ ํ‘œ์ค€ํ™”๋œ ๋‹จ์œ„(์ปจํ…Œ์ด๋„ˆ)๋กœ ๊ฒฉ๋ฆฌํ•˜๊ณ  ํŒจํ‚ค์ง•ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋„์ปค๋Š” ์ด๋Ÿฌํ•œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ตฌ์ถ•, ๋ฐฐํฌ, ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ”Œ๋žซํผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋„์ปค ์ปจํ…Œ์ด๋„ˆ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ(์ฝ”๋“œ, ๋Ÿฐํƒ€์ž„, ์‹œ์Šคํ…œ ๋„๊ตฌ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ์„ค์ •)์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ๋Š” ๋งˆ์น˜ ๊นกํ†ต์ฒ˜๋Ÿผ ๋ชจ๋“  ๊ฒƒ์„ ๋‹ด๊ณ  ์žˆ์–ด์„œ ์ด๋ฆ„์ด ๋ถ™์—ฌ์กŒ์Šต๋‹ˆ๋‹ค.

๋„์ปค ์—”์ง„(Docker Engine)์€ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ์‹œ์Šคํ…œ ํ˜ธ์ถœ์„ ๋Œ€์‹  ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค. ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ•˜๋“œ์›จ์–ด ์ž์›์„ ์š”์ฒญํ•˜๋ฉด, ๋„์ปค ์—”์ง„์ด ํ˜ธ์ŠคํŠธ OS์— ์š”์ฒญํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์ปจํ…Œ์ด๋„ˆ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

์ „ํ†ต์ ์ธ ๊ฐ€์ƒํ™”์™€ ๋‹ฌ๋ฆฌ, ๋„์ปค๋Š” ํ˜ธ์ŠคํŠธ OS ์ปค๋„์„ ๊ณต์œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž์› ์‚ฌ์šฉ์ด ๋” ํšจ์œจ์ ์ด๊ณ  ์‹œ์ž‘ ์‹œ๊ฐ„์ด ๋น ๋ฆ…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 1GB ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์„ ๋•Œ VM์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ VM๋งˆ๋‹ค 1GB๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ, ๋„์ปค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ ๊ฐ„์— ๊ทธ 1GB๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„์ปค ์ปจํ…Œ์ด๋„ˆ์˜ ๊ตฌ์กฐ

๋„์ปค๊ฐ€ ์ž‘๋™ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ˜ธ์ŠคํŠธ OS์˜ ์ปค๋„์ด ๋ฆฌ๋ˆ…์Šค์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ๋ˆ…์Šค ์ปค๋„์„ ๊ณต์œ ํ•˜์—ฌ ๋‹ค๋ฅธ ๋ฆฌ๋ˆ…์Šค ๋ฐฐํฌํŒ์„ ์ปจํ…Œ์ด๋„ˆ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋„์ปค ์ปจํ…Œ์ด๋„ˆ๋Š” ํ˜ธ์ŠคํŠธ OS์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ ์ปจํŠธ๋กค ๊ทธ๋ฃน๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ฒฉ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋Š” ๋…๋ฆฝ๋œ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๋ฉด์„œ๋„ ํ˜ธ์ŠคํŠธ OS์˜ ์ปค๋„์„ ๊ณต์œ ํ•˜์—ฌ ํšจ์œจ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„์ปค์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์€ AuFS(Advanced Multi-Layered Unification Filesystem)๋ผ๋Š” ๊ณ„์ธตํ™”๋œ ํŒŒ์ผ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์‹œ์Šคํ…œ์€ ์ฝ๊ธฐ ์ „์šฉ ๋ถ€๋ถ„๊ณผ ์“ฐ๊ธฐ ๋ถ€๋ถ„์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•จ์œผ๋กœ์จ ๊ณตํ†ต ๋ถ€๋ถ„์„ ๊ณต์œ ํ•˜๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋งŒ ๊ฐœ๋ณ„์ ์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค(Kubernetes)์™€ ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ

๋„์ปค ์ปจํ…Œ์ด๋„ˆ๋Š” ๊ฐ€๋” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ๊ฐ€ "๋ง›์ด ๊ฐ€๊ฑฐ๋‚˜" ์ฃฝ์„ ์ˆ˜๋„ ์žˆ๊ณ , ๋” ๋งŽ์€ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค(Kubernetes)๊ฐ€ ํƒ„์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ๋ฅผ ์ž๋™ํ™”ํ•ด์ฃผ๋Š” ํ”Œ๋žซํผ์œผ๋กœ, ์„œ๋น„์Šค ๋””์Šค์ปค๋ฒ„๋ฆฌ, ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ, ์Šคํ† ๋ฆฌ์ง€ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด, ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ฐ˜์˜ ๋ฐฐํฌ๊ฐ€ ๋”์šฑ ์•ˆ์ •์ ์ด๊ณ  ํ™•์žฅ์„ฑ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ํŠนํžˆ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜์™€ ๊ฐ™์ด ๋งŽ์€ ์ˆ˜์˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ํ™˜๊ฒฝ์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ˜„๋Œ€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์—์„œ ์ ์  ๋” ์ค‘์š”ํ•ด์ง€๊ณ  ์žˆ๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

๋„์ปค ์ด๋ฏธ์ง€์™€ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ

๋„์ปค ์ด๋ฏธ์ง€๋Š” ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ฝ๊ธฐ ์ „์šฉ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. ๋„์ปค ์ด๋ฏธ์ง€๋Š” Dockerfile์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋˜๋ฉฐ, ์ด๋ฏธ์ง€ ๋‚ด์šฉ๊ณผ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์ธก๋ฉด์—์„œ ๋„์ปค์˜ ์žฅ์ ์€ ํ‘œ์ค€ํ™”๋œ ํ™˜๊ฒฝ์„ ์‰ฝ๊ฒŒ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํŒŒ์ด์ฌ์ด๋‚˜ Node.js๋กœ ๊ฐœ๋ฐœํ•˜๋ ค๋ฉด ์—ฌ๋Ÿฌ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Ÿฐ ์„ค์ •์„ ๋ชจ๋‘ ๋‹ด์€ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋ฏธ๋ฆฌ ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์ด ์„ค์น˜๋œ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์–ด ๋†“์œผ๋ฉด, ๊ฐœ๋ฐœ์ž๋“ค์€ ์ด๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ์›น ๊ฐœ๋ฐœ ๊ต์œก ํ”Œ๋žซํผ์ธ ์—˜๋ฆฌ์Šค, ๊ตฌ๋ฆ„ ๋“ฑ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ•™์Šต์ž๋“ค์—๊ฒŒ ํ‘œ์ค€ํ™”๋œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ด๋Š” "๋‚ด ์ปดํ“จํ„ฐ์—์„œ๋Š” ์ž‘๋™ํ–ˆ๋Š”๋ฐ" ๋ผ๋Š” ํ”ํ•œ ๊ฐœ๋ฐœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ํฌ๊ฒŒ ๊ธฐ์—ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ž‘๋™ํ•˜๋Š” ํ™˜๊ฒฝ์„ ๊ทธ๋Œ€๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ™˜๊ฒฝ ์ฐจ์ด๋กœ ์ธํ•œ ๋ฌธ์ œ๋ฅผ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์ƒํ™”์™€ ๋„์ปค์˜ ์ฐจ์ด์  ์š”์•ฝ

์•„๋ž˜ ํ‘œ๋Š” ์ „ํ†ต์ ์ธ ๊ฐ€์ƒํ™” ๊ธฐ์ˆ ๊ณผ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ์˜ ์ฃผ์š” ์ฐจ์ด์ ์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

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

์ „ํ†ต์ ์ธ ๊ฐ€์ƒํ™”(VMware ๋“ฑ)๋Š” ํ˜ธ์ŠคํŠธ OS ์œ„์— ์™„์ „ํ•œ ๊ฒŒ์ŠคํŠธ OS๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ, ํ•˜๋“œ์›จ์–ด๋ถ€ํ„ฐ OS๊นŒ์ง€ ๋ชจ๋“  ๊ณ„์ธต์„ ๊ฐ€์ƒํ™”ํ•˜๋ฏ€๋กœ ์ž์› ์†Œ๋ชจ๊ฐ€ ํฝ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด ๋„์ปค๋Š” ํ˜ธ์ŠคํŠธ OS์˜ ์ปค๋„์„ ๊ณต์œ ํ•˜๋ฉด์„œ ์ค‘๋ณต๋˜๋Š” OS ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐ€์ƒํ™”์˜ ์žฅ์ (๋ถ„๋ฆฌ)์€ ์œ ์ง€ํ•˜๋ฉด์„œ ํšจ์œจ์„ฑ์€ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

๋„์ปค ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด ๊ตฌ์กฐ

๋‹ค์Œ์œผ๋กœ ๋„์ปค์˜ ํ•ต์‹ฌ์ธ ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด ๊ตฌ์กฐ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๋‚ด์šฉ์—์„œ๋Š” ๋„์ปค ์ด๋ฏธ์ง€์˜ ๋ ˆ์ด์–ด ๊ตฌ์กฐ, ์ž‘๋™ ์›๋ฆฌ, ๊ทธ๋ฆฌ๊ณ  ๊ด€๋ จ ๊ธฐ์ˆ ์  ๊ฐœ๋…๋“ค์„ ๊นŠ์ด ์žˆ๊ฒŒ ๋‹ค๋ฃจ์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€์˜ ๊ธฐ๋ณธ ๊ฐœ๋…

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

์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํŠน์ง•์€ ๋ถˆ๋ณ€์„ฑ(Immutability)์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€๊ฐ€ ํ•œ ๋ฒˆ ์ƒ์„ฑ๋˜๋ฉด ๊ทธ ๋‚ด์šฉ์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฉฐ, ์ด๋Ÿฌํ•œ ํŠน์„ฑ์€ ์ผ๊ด€๋œ ํ™˜๊ฒฝ์„ ๋ณด์žฅํ•˜๊ณ , ๊ฐœ๋ฐœ์—์„œ ํ…Œ์ŠคํŠธ, ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ์ด๋ฅด๊ธฐ๊นŒ์ง€ ๋™์ผํ•œ ํ™˜๊ฒฝ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

๋„์ปค ์ด๋ฏธ์ง€๋Š” ์ฃผ๋กœ Dockerfile์„ ํ†ตํ•ด ์ •์˜๋ฉ๋‹ˆ๋‹ค. Dockerfile์˜ ๊ฐ ๋ช…๋ น์–ด(FROM, RUN, COPY ๋“ฑ)๋Š” ์ด๋ฏธ์ง€์— ์ƒˆ๋กœ์šด ๋ ˆ์ด์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉฐ, ์ด๋Ÿฌํ•œ ๋ ˆ์ด์–ด ๊ตฌ์กฐ๊ฐ€ ๋„์ปค์˜ ํšจ์œจ์„ฑ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋„์ปค ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด ๊ตฌ์กฐ ์ดํ•ดํ•˜๊ธฐ

๋„์ปค ์ด๋ฏธ์ง€๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ฝ๊ธฐ ์ „์šฉ ๋ ˆ์ด์–ด๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๋ ˆ์ด์–ด๋Š” ์ด์ „ ๋ ˆ์ด์–ด์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์‚ฌํ•ญ๋งŒ์„ ํฌํ•จํ•˜๋Š” ์ฆ๋ถ„(incremental) ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

FROM alpine:latest
RUN apk update && apk add nodejs
RUN echo "console.log('Hello World')" > main.js

์œ„ Dockerfile์„ ์˜ˆ๋กœ ๋“ค๋ฉด:
1. ์ฒซ ๋ฒˆ์งธ ๋ ˆ์ด์–ด๋Š” alpine:latest ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€์ž…๋‹ˆ๋‹ค.
2. ๋‘ ๋ฒˆ์งธ ๋ ˆ์ด์–ด๋Š” Node.js๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋ช…๋ น์˜ ๊ฒฐ๊ณผ๋ฌผ์ž…๋‹ˆ๋‹ค.
3. ์„ธ ๋ฒˆ์งธ ๋ ˆ์ด์–ด๋Š” main.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ๋ช…๋ น์˜ ๊ฒฐ๊ณผ๋ฌผ์ž…๋‹ˆ๋‹ค.

์ค‘์š”ํ•œ ์ ์€ ๊ฐ ๋ ˆ์ด์–ด๊ฐ€ ์ด์ „ ๋ ˆ์ด์–ด์˜ ์ „์ฒด ๋ณต์‚ฌ๋ณธ์ด ์•„๋‹ˆ๋ผ, ์˜ค์ง ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ํฌํ•จํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์„ค๊ณ„๋Š” ์ด๋ฏธ์ง€ ๋นŒ๋“œ ์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œํ‚ค๊ณ  ์Šคํ† ๋ฆฌ์ง€ ํšจ์œจ์„ฑ์„ ๋†’์—ฌ์ค๋‹ˆ๋‹ค.

๋ ˆ์ด์–ด ๊ตฌ์กฐ์˜ ์ด์ 

๋„์ปค์˜ ๋ ˆ์ด์–ด๋ง ์‹œ์Šคํ…œ์€ ์ด๋ฏธ์ง€ ์ž‘์—…์„ ๋”์šฑ ํšจ์œจ์ ์ด๊ณ  ์„ฑ๋Šฅ์ด ์ข‹๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๊ทธ์— ๋”ฐ๋ฅธ ์ด์ ๋“ค ์ž…๋‹ˆ๋‹ค.

  1. ํšจ์œจ์ ์ธ ์žฌ์‚ฌ์šฉ: ์ด๋ฏธ์ง€ ๊ฐ„ ๊ณต์œ ๋˜๋Š” ๋ ˆ์ด์–ด๋Š” ์บ์‹œ๋˜์–ด ์ค‘๋ณต ์ €์žฅ๋˜์ง€ ์•Š์•„ ์Šคํ† ๋ฆฌ์ง€ ์š”๊ตฌ ์‚ฌํ•ญ์ด ๊ฐ์†Œํ•ฉ๋‹ˆ๋‹ค.
  2. ๋น ๋ฅธ ๋ฐฐํฌ: ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๋ ˆ์ด์–ด๋Š” ์žฌ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ๋นŒ๋“œ ์†๋„๊ฐ€ ํ–ฅ์ƒ๋˜๊ณ  ํ‘ธ์‹œ/ํ’€ ์‹œ๊ฐ„์ด ๋‹จ์ถ•๋ฉ๋‹ˆ๋‹ค.
  3. ์ ์ง„์  ์—…๋ฐ์ดํŠธ: ์ˆ˜์ •๋œ ๋ ˆ์ด์–ด๋งŒ ์ „์†ก๋˜๋ฏ€๋กœ ๋Œ€์—ญํญ ์‚ฌ์šฉ์ด ์ตœ์†Œํ™”๋ฉ๋‹ˆ๋‹ค.
  4. ๋นŒ๋“œ ์ผ๊ด€์„ฑ: ๊ฐ ๋ ˆ์ด์–ด๋Š” ํŠน์ • Dockerfile ๋ช…๋ น์— ๋งคํ•‘๋˜์–ด ๋นŒ๋“œ๋ฅผ ์žฌํ˜„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  5. ๋ฌธ์ œ ํ•ด๊ฒฐ ๋‹จ์ˆœํ™”: ๊ณ„์ธตํ™”๋œ ๊ตฌ์กฐ๋Š” ์–ด๋–ค ๋‹จ๊ณ„์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.
  6. ๋ชจ๋“ˆ์„ฑ๊ณผ ์ด์‹์„ฑ: ๋ ˆ์ด์–ด๋Š” ๋ชจ๋“ˆ์‹์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์–ด ํ™˜๊ฒฝ ๊ฐ„์— ์ด๋ฏธ์ง€๋ฅผ ์‰ฝ๊ฒŒ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์ฝ๊ธฐ ์ „์šฉ ๋ ˆ์ด์–ด์™€ ์“ฐ๊ธฐ ๊ฐ€๋Šฅ ๋ ˆ์ด์–ด

๋„์ปค ์ด๋ฏธ์ง€์˜ ๋ชจ๋“  ๋ ˆ์ด์–ด๋Š” ๋ถˆ๋ณ€(immutable)์ž…๋‹ˆ๋‹ค. ์ฆ‰, ํ•œ๋ฒˆ ์ƒ์„ฑ๋˜๋ฉด ์ฝ๊ธฐ ์ „์šฉ์ด ๋˜๋ฉฐ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ถˆ๋ณ€์„ฑ์ด ๋„์ปค์˜ ํšจ์œจ์„ฑ๊ณผ ์•ˆ์ •์„ฑ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ปจํ…Œ์ด๋„ˆ์—์„œ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹œ์ž‘๋  ๋•Œ, ๋„์ปค๋Š” ์ด๋ฏธ์ง€์˜ ๋ชจ๋“  ๋ ˆ์ด์–ด ์œ„์— ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด(writable layer)๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ ˆ์ด์–ด๋Š” '์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ด์–ด' ๋ผ๊ณ ๋„ ๋ถˆ๋ฆฌ๋ฉฐ, ์ปจํ…Œ์ด๋„ˆ์˜ ๋ชจ๋“  ๋ณ€๊ฒฝ์‚ฌํ•ญ(ํŒŒ์ผ ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œ)์ด ์ด ๋ ˆ์ด์–ด์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค.

์ˆ˜์ • ์ค‘์ผ ๋•Œ ์ง„ํ–‰๋˜๋Š” ๋ชจ๋“  ๋ณ€๊ฒฝ์‚ฌํ•ญ์€ ์ด ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ , ์›๋ณธ ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋™์ผํ•œ ์ด๋ฏธ์ง€์—์„œ ์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

Copy-on-Write(CoW) ๋ฉ”์ปค๋‹ˆ์ฆ˜

๋„์ปค๋Š” ๋ ˆ์ด์–ด๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด "Copy-on-Write(์“ฐ๊ธฐ ์‹œ ๋ณต์‚ฌ)" ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ์ˆ ์€ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ด๋ฏธ์ง€์˜ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๋ ค๊ณ  ํ•  ๋•Œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

CoW์˜ ์ž‘๋™ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํŒŒ์ผ์„ ์ฝ๊ธฐ๋งŒ ํ•  ๋•Œ๋Š” ์ฝ๊ธฐ ์ „์šฉ ๋ ˆ์ด์–ด์—์„œ ์ง์ ‘ ํŒŒ์ผ์„ ์ฝ์Šต๋‹ˆ๋‹ค.
  2. ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ํ•ด๋‹น ํŒŒ์ผ์€ ์ฝ๊ธฐ ์ „์šฉ ๋ ˆ์ด์–ด์—์„œ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด๋กœ ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค.
  3. ์ˆ˜์ •๋œ ํŒŒ์ผ์€ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด์— ์ €์žฅ๋˜๊ณ , ์›๋ณธ ํŒŒ์ผ์€ ์ฝ๊ธฐ ์ „์šฉ ๋ ˆ์ด์–ด์— ๊ทธ๋Œ€๋กœ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค.
  4. ์ปจํ…Œ์ด๋„ˆ์—์„œ ํŒŒ์ผ์„ ์‚ญ์ œํ•  ๊ฒฝ์šฐ, ์‹ค์ œ๋กœ ์ฝ๊ธฐ ์ „์šฉ ๋ ˆ์ด์–ด์˜ ํŒŒ์ผ์ด ์‚ญ์ œ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด์— '์‚ญ์ œ๋จ' ํ‘œ์‹œ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ์ฃผ์š” ์ด์ ์œผ๋กœ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ด์ ๋“ค์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

  1. ๋””์Šคํฌ ๊ณต๊ฐ„ ์ ˆ์•ฝ: ์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋™์ผํ•œ ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ๋น ๋ฅธ ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ: ์ƒˆ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ธฐ์กด ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด๋ฅผ ๋ณต์‚ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  3. ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๊ฒฉ๋ฆฌ: ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋Š” ์ž์ฒด ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด๋ฅผ ๊ฐ€์ง€๋ฏ€๋กœ, ์ปจํ…Œ์ด๋„ˆ ๊ฐ„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์„œ๋กœ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์œ ๋‹ˆ์˜จ ํŒŒ์ผ ์‹œ์Šคํ…œ(Union File System)

๋„์ปค ๋ ˆ์ด์–ด์˜ ๋ชจ๋“  ๋งˆ๋ฒ•์€ ์œ ๋‹ˆ์˜จ ํŒŒ์ผ ์‹œ์Šคํ…œ ๋•๋ถ„์— ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์œ ๋‹ˆ์˜จ ํŒŒ์ผ ์‹œ์Šคํ…œ์€ ์—ฌ๋Ÿฌ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ํ•˜๋‚˜์˜ ํ†ตํ•ฉ๋œ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํŠน๋ณ„ํ•œ ํŒŒ์ผ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค.

์œ ๋‹ˆ์˜จ ๋งˆ์šดํŠธ(Union Mount)๋ผ๊ณ ๋„ ๋ถˆ๋ฆฌ๋Š” ์ด ๊ธฐ๋Šฅ์€ ๋ณต์ˆ˜์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์œผ๋กœ ๋งˆ์šดํŠธํ•˜๋Š” ๊ธฐ๋Šฅ์œผ๋กœ, ๋‘ ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ ๋™์ผํ•œ ํŒŒ์ผ์ด ์žˆ์„ ๊ฒฝ์šฐ ๋‚˜์ค‘์— ๋งˆ์šดํŠธ๋œ ํŒŒ์ผ ์‹œ์Šคํ…œ์˜ ํŒŒ์ผ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋„์ปค์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ฃผ์š” ์œ ๋‹ˆ์˜จ ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ตฌํ˜„์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. UnionFS: ์ดˆ๊ธฐ์— ๊ตฌํ˜„๋œ ์œ ๋‹ˆ์˜จ ํŒŒ์ผ ์‹œ์Šคํ…œ
  2. AUFS(Advanced Union File System): UnionFS๋ฅผ ๊ฐœ์„ ํ•œ ๋ฒ„์ „
  3. OverlayFS(overlay, overlay2): ํ˜„์žฌ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๊ตฌํ˜„์ฒด, ๋ฆฌ๋ˆ…์Šค ์ปค๋„์— ํ†ตํ•ฉ๋จ
  4. Btrfs, ZFS: ๋‹ค๋ฅธ ๊ณ ๊ธ‰ ํŒŒ์ผ ์‹œ์Šคํ…œ ์˜ต์…˜

ํ˜„์žฌ ์–ด๋–ค ์Šคํ† ๋ฆฌ์ง€ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€๋Š” docker info ๋ช…๋ น์–ด๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ์ข…๋ฃŒ ์‹œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

์ปจํ…Œ์ด๋„ˆ์˜ ์ค‘์š”ํ•œ ํŠน์„ฑ ์ค‘ ํ•˜๋‚˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํœ˜๋ฐœ์„ฑ(ephemeral)์ด๋ผ๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ค‘์ง€(docker stop)ํ–ˆ์„ ๋•Œ

  • ์ปจํ…Œ์ด๋„ˆ์˜ ์‹คํ–‰ ํ™˜๊ฒฝ(๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ cgroup)์€ ์†Œ๋ฉธํ•ฉ๋‹ˆ๋‹ค.
  • ํ•˜์ง€๋งŒ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด(ํŒŒ์ผ ์‹œ์Šคํ…œ ๋ณ€๊ฒฝ์‚ฌํ•ญ)๋Š” ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
  • ์ปจํ…Œ์ด๋„ˆ๋Š” docker start ๋ช…๋ น์œผ๋กœ ์ด์ „ ์ƒํƒœ์—์„œ ์žฌ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ œ๊ฑฐ(docker rm)ํ–ˆ์„ ๋•Œ

  • ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ ๋ฐ์ดํ„ฐ๊ฐ€ ์˜๊ตฌ์ ์œผ๋กœ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.
  • ์ปจํ…Œ์ด๋„ˆ์˜ ์ƒํƒœ๋ฅผ ๋ณต๊ตฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ปจํ…Œ์ด๋„ˆ์˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๋„˜์–ด ์ง€์†ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  1. ๋ณผ๋ฅจ(Volumes): ๋„์ปค๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ํ˜ธ์ŠคํŠธ ํŒŒ์ผ ์‹œ์Šคํ…œ์˜ ์ผ๋ถ€. ์ปจํ…Œ์ด๋„ˆ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์กด์žฌํ•˜๋ฉฐ ์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ ๊ฐ„ ๊ณต์œ  ๊ฐ€๋Šฅ.

    docker volume create data-volume
    docker run -v data-volume:/app/data my-image
  2. ๋ฐ”์ธ๋“œ ๋งˆ์šดํŠธ(Bind Mounts): ํ˜ธ์ŠคํŠธ ํŒŒ์ผ ์‹œ์Šคํ…œ์˜ ํŠน์ • ๊ฒฝ๋กœ๋ฅผ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€๋กœ ๋งˆ์šดํŠธ.

    docker run -v /host/path:/container/path my-image
  3. Docker Commit: ์ปจํ…Œ์ด๋„ˆ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ƒˆ ์ด๋ฏธ์ง€๋กœ ์ €์žฅ.

    docker commit my-container my-new-image

๋„์ปค ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด ์ตœ์ ํ™” ์ „๋žต

๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ „๋žต:

  1. ๋ ˆ์ด์–ด ์ˆ˜ ์ตœ์†Œํ™”: Dockerfile ๋ช…๋ น์–ด๋ฅผ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•˜์—ฌ AND(&&)๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

    # ๋น„ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•
    RUN apt-get update
    RUN apt-get install -y package1
    
    # ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•
    RUN apt-get update && apt-get install -y package1
  2. ๋‹ค๋‹จ๊ณ„ ๋นŒ๋“œ(Multi-stage builds) ์‚ฌ์šฉ: ๋นŒ๋“œ ํ™˜๊ฒฝ๊ณผ ์‹คํ–‰ ํ™˜๊ฒฝ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ตœ์ข… ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค.

  3. .dockerignore ํŒŒ์ผ ์‚ฌ์šฉ: ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ์ด ์ด๋ฏธ์ง€์— ํฌํ•จ๋˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

  4. ๊ธฐ๋ณธ ์ด๋ฏธ์ง€ ์„ ํƒ์— ์ฃผ์˜: ๊ฐ€๋Šฅํ•œ ์ž‘์€ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€(alpine ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  5. ์บ์‹œ ํ™œ์šฉ: ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” ๋ ˆ์ด์–ด๋Š” Dockerfile์˜ ํ›„๋ฐ˜๋ถ€์— ๋ฐฐ์น˜ํ•˜์—ฌ ๋นŒ๋“œ ์บ์‹œ๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋„์ปคํŒŒ์ผ๊ณผ ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด์˜ ๊ด€๊ณ„

๋„์ปค ์ด๋ฏธ์ง€ ๋นŒ๋“œ์˜ ํ•ต์‹ฌ์ธ Dockerfile๊ณผ ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์ดํ•ดํ•˜๋ฉด ํšจ์œจ์ ์ธ ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Dockerfile ๋ช…๋ น์–ด์™€ ๋ ˆ์ด์–ด ์ƒ์„ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜

1. ๊ธฐ๋ณธ ๋ ˆ์ด์–ด ์ƒ์„ฑ ๊ทœ์น™

  • FROM: ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€์˜ ๋ชจ๋“  ๋ ˆ์ด์–ด๋ฅผ ์ƒ์†๋ฐ›์Œ
    FROM alpine:3.18  # alpine์˜ ์ „์ฒด ๋ ˆ์ด์–ด ์ฒด์ธ์„ ๊ฐ€์ ธ์˜ด
  • RUN/COPY/ADD: ํŒŒ์ผ ์‹œ์Šคํ…œ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋Š” ๋ช…๋ น์–ด โ†’ ์ƒˆ ๋ ˆ์ด์–ด ์ƒ์„ฑ
    RUN apk add --no-cache nodejs  # 5MB ํฌ๊ธฐ์˜ ์ƒˆ ๋ ˆ์ด์–ด ์ถ”๊ฐ€
    COPY app.js /app/              # ํŒŒ์ผ ๋ณต์‚ฌ ๋ ˆ์ด์–ด ์ƒ์„ฑ
  • ENV/LABEL/EXPOSE: ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ โ†’ Empty Layer ์ƒ์„ฑ (ํฌ๊ธฐ 0B)
    ENV NODE_ENV=production  # ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ • (๋ ˆ์ด์–ด ํฌ๊ธฐ 0B)

๊ฒ€์‚ฌ ๋„๊ตฌ ๋น„๊ต

ํŠน์„ฑdocker historydocker inspect
ํ‘œ์‹œ ๋‚ด์šฉ๋ชจ๋“  ๋นŒ๋“œ ๋ช…๋ น์–ด ๊ธฐ๋ก์‹ค์ œ ํŒŒ์ผ ์‹œ์Šคํ…œ ๋ ˆ์ด์–ด
Empty Layer ํ‘œ์‹œโœ… (ํฌ๊ธฐ 0B๋กœ ํ‘œ์‹œ)โŒ
์‹คํ–‰ ์˜ˆ์‹œdocker history my-imagedocker inspect my-image
์ถœ๋ ฅ ํ˜•์‹ํ…Œ์ด๋ธ”JSON
# docker history ์ถœ๋ ฅ ์˜ˆ์‹œ
IMAGE          CREATED         COMMAND                  SIZE
d9eaf6fd6d0a   2 minutes ago   /bin/sh -c #(nop)  ENV   0B
a1b2c3d4e5f6   3 minutes ago   COPY app.js /app/       1.2kB

์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด ์ฒด์ธ์˜ ํ•ต์‹ฌ ์›๋ฆฌ

1. ๋ ˆ์ด์–ด ์ €์žฅ ๊ตฌ์กฐ

  • ๋ฐฉํ–ฅ์„ฑ ๋น„์ˆœํ™˜ ๊ทธ๋ž˜ํ”„(DAG): ๊ฐ ๋ ˆ์ด์–ด๊ฐ€ ๊ณ ์œ ํ•œ ๋ถ€๋ชจ ์ฐธ์กฐ
  • ์ปจํ…์ธ  ์ฃผ์†Œํ™” ์‹œ์Šคํ…œ: SHA256 ํ•ด์‹œ๋กœ ๋ ˆ์ด์–ด ์‹๋ณ„
    # ๋ ˆ์ด์–ด ์‹๋ณ„์ž ์˜ˆ์‹œ
    sha256:38a8310d387e375e0ec6fabe047a9149e8eb214073db9f461fee6251fd936a75

2. ๋ ˆ์ด์–ด ๊ณต์œ  ๋ฉ”์ปค๋‹ˆ์ฆ˜

  • ๋นŒ๋“œ ์บ์‹œ ํ™œ์šฉ: ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๋ ˆ์ด์–ด ์žฌ์‚ฌ์šฉ์œผ๋กœ ๋นŒ๋“œ ์‹œ๊ฐ„ 70% ๋‹จ์ถ•

๋ ˆ์ด์–ด ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ 5๊ฐ€์ง€ ์ „๋žต

1. ๋ช…๋ น์–ด ํ†ตํ•ฉ (Layer Minimization)

# ๋น„ํšจ์œจ์  ์˜ˆ์‹œ (๋ ˆ์ด์–ด 3๊ฐœ)
RUN apt-get update
RUN apt-get install -y python3
RUN rm -rf /var/lib/apt/lists/*

# ์ตœ์ ํ™” ์˜ˆ์‹œ (๋ ˆ์ด์–ด 1๊ฐœ)
RUN apt-get update && \
    apt-get install -y python3 && \
    rm -rf /var/lib/apt/lists/*

2. ๋‹ค๋‹จ๊ณ„ ๋นŒ๋“œ (Multi-stage)

# ๋นŒ๋“œ ์Šคํ…Œ์ด์ง€
FROM node:18 as builder
COPY . .
RUN npm install && npm run build  # 1.2GB

# ์ตœ์ข… ์Šคํ…Œ์ด์ง€
FROM node:18-alpine
COPY --from=builder /app/dist ./  # 150MB

โ†’ ๊ฒฐ๊ณผ: ์ด๋ฏธ์ง€ ํฌ๊ธฐ 87% ๊ฐ์†Œ

3. .dockerignore ํ™œ์šฉ

node_modules/
.git/
*.log

โ†’ ๋ถˆํ•„์š” ํŒŒ์ผ ์ œ์™ธ๋กœ ๋ ˆ์ด์–ด ํฌ๊ธฐ ๊ฐ์†Œ

4. ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€ ์„ ํƒ

  • Alpine Linux: 5MB (๊ธฐ๋ณธ Ubuntu๋ณด๋‹ค 97% ๊ฒฝ๋Ÿ‰ํ™”)
  • Distroless: ๋Ÿฐํƒ€์ž„ ์ตœ์†Œํ™” (Shell ์—†๋Š” ํ™˜๊ฒฝ)

5. ๋ ˆ์ด์–ด ์บ์‹œ ์ „๋žต

# ์บ์‹œ ์นœํ™”์  ๊ตฌ์กฐ
COPY package.json .
RUN npm install          # ํŒจํ‚ค์ง€ ๋ณ€๊ฒฝ์‹œ๋งŒ ์žฌ์‹คํ–‰
COPY . .

โ†’ ์†Œ์Šค ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ package.json ๋ ˆ์ด์–ด ์บ์‹œ ์œ ์ง€

๊ณ ๊ธ‰ ๋ถ„์„: Empty Layer์˜ ์ž‘๋™ ์›๋ฆฌ

1. Empty Layer ํŠน์ง•

  • ํฌ๊ธฐ: 0B (๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒ ์ €์žฅ)
  • ์ƒ์„ฑ ๋ช…๋ น์–ด: ENV, LABEL, MAINTAINER ๋“ฑ
  • ์ €์žฅ ์œ„์น˜: ์ด๋ฏธ์ง€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— ํฌํ•จ

2. ์‹ค์ œ ์‚ฌ๋ก€ ๋ถ„์„

FROM alpine
LABEL maintainer="dev@example.com"  # Empty Layer 1
ENV APP_ENV=production              # Empty Layer 2
COPY app.js /app/                   # 120kB ๋ ˆ์ด์–ด
CMD ["node", "/app/app.js"]         # Empty Layer 3

โ†’ docker history ์ถœ๋ ฅ์‹œ 4๊ฐœ ๋ ˆ์ด์–ด (3 Empty + 1 Real)

๋ฌธ์ œ ํ•ด๊ฒฐ: ๋ ˆ์ด์–ด ๊ด€๋ จ ์ด์Šˆ ๋Œ€์ฒ˜๋ฒ•

1. ์บ์‹œ ๋ฌดํšจํ™” ํ˜„์ƒ

  • ์ฆ์ƒ: ์‚ฌ์†Œํ•œ ๋ณ€๊ฒฝ ํ›„ ๋ถˆํ•„์š”ํ•œ ์žฌ๋นŒ๋“œ
  • ํ•ด๊ฒฐ: ๋ณ€๊ฒฝ ๋นˆ๋„ ๋‚ฎ์€ ๋ช…๋ น์–ด๋ฅผ Dockerfile ์ƒ๋‹จ์— ๋ฐฐ์น˜

2. ๋ ˆ์ด์–ด ๋ธ”๋กœํŠธ (Layer Bloat)

  • ์ฆ์ƒ: ๋ถˆํ•„์š”ํ•œ ๋Œ€์šฉ๋Ÿ‰ ๋ ˆ์ด์–ด ๋ˆ„์ 
  • ํ•ด๊ฒฐ: docker image prune -a๋กœ ๋ฏธ์‚ฌ์šฉ ๋ ˆ์ด์–ด ์ •๋ฆฌ

3. ๋ณด์•ˆ ์ทจ์•ฝ์  ์ „ํŒŒ

  • ๋ฌธ์ œ: ์ทจ์•ฝํ•œ ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด ๊ณต์œ 
  • ๋Œ€์‘: dive ๋„๊ตฌ๋กœ ๋ ˆ์ด์–ด๋ณ„ ์ทจ์•ฝ์  ์Šค์บ”

๊ฒฐ๋ก : ํšจ์œจ์ ์ธ Dockerfile ์ž‘์„ฑ์˜ ํ•ต์‹ฌ

๋„์ปค ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด ๊ตฌ์กฐ๋ฅผ ๋งˆ์Šคํ„ฐํ•˜๋ ค๋ฉด ๋‹ค์Œ ์›์น™์„ ์ค€์ˆ˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
1. ๋ ˆ์ด์–ด ์ˆ˜ ์ตœ์†Œํ™”: ๊ด€๋ จ ๋ช…๋ น์–ด ํ†ตํ•ฉ
2. ์บ์‹œ ํ™œ์šฉ ๊ทน๋Œ€ํ™”: ๋ณ€๊ฒฝ ๋นˆ๋„์— ๋”ฐ๋ฅธ ๋ช…๋ น์–ด ๋ฐฐ์น˜
3. ๋ณด์•ˆ ๊ณ ๋ ค: ์ตœ์†Œ ๊ถŒํ•œ ์›์น™ ์ ์šฉ
4. ์ง€์†์  ๋ชจ๋‹ˆํ„ฐ๋ง: dive, docker-slim ๋“ฑ ๋„๊ตฌ ํ™œ์šฉ

๋„์ปค ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ

์ด ๊ธ€์—์„œ๋Š” ๋„์ปค์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์ธ ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€(Multi-stage) ๋นŒ๋“œ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ณ , ์–ด๋–ป๊ฒŒ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋ž€?

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋Š” ํ•˜๋‚˜์˜ Dockerfile ๋‚ด์—์„œ ์—ฌ๋Ÿฌ FROM ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„(stage)๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๊ฐ ๋‹จ๊ณ„๋Š” ๋…๋ฆฝ์ ์ธ ๋นŒ๋“œ ํ™˜๊ฒฝ์œผ๋กœ, ์ด์ „ ๋‹จ๊ณ„์˜ ๊ฒฐ๊ณผ๋ฌผ์„ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋ณต์‚ฌํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„์ปค์˜ ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๊ธฐ๋Šฅ์€ ๋„์ปค 17.05 ๋ฒ„์ „๋ถ€ํ„ฐ ๋„์ž…๋˜์—ˆ์œผ๋ฉฐ, ์ด ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜๊ธฐ ์ „์—๋Š” ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ์‰˜ ์Šคํฌ๋ฆฝํŠธ๋‚˜ ์—ฌ๋Ÿฌ Dockerfile์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€์˜ ๊ธฐ๋ณธ ์›๋ฆฌ

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ์˜ ํ•ต์‹ฌ์€ ๋นŒ๋“œ ๋‹จ๊ณ„์˜ ๊ฒฐ๊ณผ๋ฌผ๋งŒ ์ตœ์ข… ์ด๋ฏธ์ง€์— ํฌํ•จ์‹œํ‚ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Go ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•  ๋•Œ, ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” Go ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๋ชจ๋“  ๊ฐœ๋ฐœ ๋„๊ตฌ๋ฅผ ํฌํ•จํ•œ ํฐ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” ๋งค์šฐ ์ž‘์€ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€์— ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ ์ปดํŒŒ์ผ๋œ ์‹คํ–‰ ํŒŒ์ผ๋งŒ ๋ณต์‚ฌํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๊ธฐ๋ณธ์ ์ธ ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ Dockerfile์˜ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค:

# ์ฒซ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€: ๋นŒ๋“œ ํ™˜๊ฒฝ
FROM golang:1.23 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .

# ๋‘ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€: ์ตœ์ข… ์ด๋ฏธ์ง€
FROM alpine:latest
COPY --from=builder /app/main /app/
CMD ["/app/main"]

์œ„ ์˜ˆ์‹œ์—์„œ๋Š” ์ฒซ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€์—์„œ Go ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•œ ํ›„, ๋‘ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€์—์„œ๋Š” Alpine Linux๋ผ๋Š” ๋งค์šฐ ์ž‘์€ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œ๋œ ์‹คํ–‰ ํŒŒ์ผ๋งŒ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์„ ํ†ตํ•ด ์ตœ์ข… ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ์˜ ์ฃผ์š” ์ด์ 

1. ์ด๋ฏธ์ง€ ํฌ๊ธฐ ๋Œ€ํญ ๊ฐ์†Œ

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ์ตœ์ข… ์ด๋ฏธ์ง€ ํฌ๊ธฐ์˜ ํš๊ธฐ์ ์ธ ๊ฐ์†Œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Go ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฝ์šฐ ๋‹จ์ผ ์Šคํ…Œ์ด์ง€ ์ด๋ฏธ์ง€๋Š” ์•ฝ 840MB์— ๋‹ฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด 12MB ์ •๋„๋กœ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ปจํ…Œ์ด๋„ˆ ๋‹ค์šด๋กœ๋“œ ์‹œ๊ฐ„, ์ €์žฅ ๊ณต๊ฐ„, ์‹œ์ž‘ ์‹œ๊ฐ„ ๋ชจ๋‘์— ๊ธ์ •์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

2. ๋ณด์•ˆ ๊ฐ•ํ™”

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

3. ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค ํ†ตํ•ฉ

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ ์ด์ „์—๋Š” ๊ฐœ๋ฐœ์ž๋“ค์ด ๋นŒ๋“œ์šฉ๊ณผ ๋ฐฐํฌ์šฉ์œผ๋กœ ๋‘ ๊ฐœ์˜ Dockerfile์„ ๊ด€๋ฆฌํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ Dockerfile์— ๋ชจ๋“  ๋นŒ๋“œ ๋‹จ๊ณ„๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์–ด ๊ด€๋ฆฌ๊ฐ€ ๋‹จ์ˆœํ•ด์ง€๊ณ  ์ผ๊ด€์„ฑ์ด ๋†’์•„์ง‘๋‹ˆ๋‹ค.

4. ๋นŒ๋“œ ์„ฑ๋Šฅ ํ–ฅ์ƒ

Docker BuildKit์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜์กด์„ฑ์ด ์—†๋Š” ์Šคํ…Œ์ด์ง€๋ฅผ ๋ณ‘๋ ฌ๋กœ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ „์ฒด ๋นŒ๋“œ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํšจ์œจ์ ์ธ ์บ์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ๋ฐ˜๋ณต์ ์ธ ๋นŒ๋“œ ์‹œ๊ฐ„๋„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ๋ณ‘๋ ฌ ๋นŒ๋“œ ์˜ˆ์‹œ
FROM docker-image as deps
RUN commands-that-builds-dependencies

FROM deps as server
RUN command-that-builds-app-server

FROM deps as client
RUN command-that-builds-app-client

์œ„ ์˜ˆ์‹œ์—์„œ server์™€ client ์Šคํ…Œ์ด์ง€๋Š” deps ์Šคํ…Œ์ด์ง€๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ๋ณ‘๋ ฌ๋กœ ๋นŒ๋“œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ์˜ ํ™œ์šฉ ์‚ฌ๋ก€

1. ์ปดํŒŒ์ผ ์–ธ์–ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋Š” ํŠนํžˆ ์ปดํŒŒ์ผ ์–ธ์–ด๋กœ ์ž‘์„ฑ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. Go, Java, C/C++ ๋“ฑ์˜ ์–ธ์–ด๋Š” ์ปดํŒŒ์ผ ๊ณผ์ •์—์„œ ๋‹ค์–‘ํ•œ ๋„๊ตฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ, ์‹คํ–‰ ์‹œ์—๋Š” ์ปดํŒŒ์ผ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋งŒ ์žˆ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Go ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ˆ์‹œ

Go ์–ธ์–ด๋Š” ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ์˜ ์ด์ ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Go๋Š” ์ •์  ๋งํฌ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์–ด, ์‹คํ–‰ ํ™˜๊ฒฝ์— ์ถ”๊ฐ€ ์ข…์†์„ฑ์ด ๊ฑฐ์˜ ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

# ๋นŒ๋“œ ์Šคํ…Œ์ด์ง€
FROM golang:1.23 AS build

WORKDIR /app

COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

# ์ตœ์ข… ์Šคํ…Œ์ด์ง€
FROM scratch

COPY --from=build /app/app /

ENTRYPOINT ["/app"]

์ด ์˜ˆ์‹œ์—์„œ๋Š” ์ฒซ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€์—์„œ Go ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ปดํŒŒ์ผํ•˜๊ณ , ๋‘ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€์—์„œ๋Š” 'scratch'๋ผ๋Š” ์™„์ „ํžˆ ๋นˆ ์ด๋ฏธ์ง€์— ์ปดํŒŒ์ผ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋งŒ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ตœ์ข… ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” ๋ช‡ MB์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

Java ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ˆ์‹œ

Java ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฝ์šฐ์—๋„ ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๊ฐ€ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. Maven์ด๋‚˜ Gradle๋กœ ๋นŒ๋“œํ•œ ํ›„, JRE๋งŒ ํฌํ•จ๋œ ์ด๋ฏธ์ง€๋กœ JAR ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜์—ฌ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ๋นŒ๋“œ ์Šคํ…Œ์ด์ง€
FROM eclipse-temurin:21-jdk-jammy AS build
WORKDIR /build
COPY --chmod=0755 mvnw mvnw
COPY .mvn/ .mvn/
COPY ./src src/
COPY pom.xml .
RUN ./mvnw package -DskipTests

# ๋Ÿฐํƒ€์ž„ ์Šคํ…Œ์ด์ง€
FROM eclipse-temurin:21-jre-jammy
WORKDIR /app
COPY --from=build /build/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

์ด ์˜ˆ์‹œ์—์„œ๋Š” ์ฒซ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€์—์„œ JDK๋ฅผ ์‚ฌ์šฉํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๊ณ , ๋‘ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€์—์„œ๋Š” JRE๋งŒ ํฌํ•จ๋œ ๋” ์ž‘์€ ์ด๋ฏธ์ง€์— ๋นŒ๋“œ๋œ JAR ํŒŒ์ผ๋งŒ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.

2. ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์—์„œ๋„ ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๊ฐ€ ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค. Node.js ํ™˜๊ฒฝ์—์„œ React๋‚˜ Vue.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•œ ํ›„, ์ •์  ํŒŒ์ผ๋งŒ Nginx ์ด๋ฏธ์ง€๋กœ ๋ณต์‚ฌํ•˜์—ฌ ๊ฐ€๋ฒผ์šด ์›น ์„œ๋ฒ„๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ๋นŒ๋“œ ์Šคํ…Œ์ด์ง€
FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# ๋Ÿฐํƒ€์ž„ ์Šคํ…Œ์ด์ง€
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
ENTRYPOINT ["nginx", "-g", "daemon off;"]

์ด ์˜ˆ์‹œ์—์„œ๋Š” ์ฒซ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€์—์„œ Node.js ํ™˜๊ฒฝ์œผ๋กœ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๊ณ , ๋‘ ๋ฒˆ์งธ ์Šคํ…Œ์ด์ง€์—์„œ๋Š” Nginx ์ด๋ฏธ์ง€์— ๋นŒ๋“œ๋œ ์ •์  ํŒŒ์ผ๋งŒ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ Node.js ๋Ÿฐํƒ€์ž„์ด๋‚˜ npm ํŒจํ‚ค์ง€๊ฐ€ ์—†๋Š” ์ž‘์€ ์ด๋ฏธ์ง€๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•

1. ์Šคํฌ๋ž˜์น˜ ์ด๋ฏธ์ง€ ํ™œ์šฉ

์Šคํฌ๋ž˜์น˜(scratch)๋Š” ๋นˆ ์ด๋ฏธ์ง€๋กœ, ์–ด๋–ค ํŒŒ์ผ ์‹œ์Šคํ…œ์ด๋‚˜ ์‰˜๋„ ํฌํ•จํ•˜์ง€ ์•Š์•„ ๊ฐ€์žฅ ์ž‘์€ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Go๋‚˜ Rust์™€ ๊ฐ™์ด ์ •์  ๋งํฌ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด์— ํŠนํžˆ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

FROM golang:1.23 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

FROM scratch
COPY --from=builder /app/main /
CMD ["/main"]

๋‹จ, ์Šคํฌ๋ž˜์น˜ ์ด๋ฏธ์ง€๋Š” ์‰˜์ด๋‚˜ ๋””๋ฒ„๊น… ๋„๊ตฌ๊ฐ€ ์—†์–ด ๋ฌธ์ œ ํ•ด๊ฒฐ์ด ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

2. ํŠน์ • ์Šคํ…Œ์ด์ง€ ํƒ€๊ฒŸํŒ…

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋Š” ํŠน์ • ์Šคํ…Œ์ด์ง€๋ถ€ํ„ฐ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. docker build --target ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ์Šคํ…Œ์ด์ง€๊นŒ์ง€๋งŒ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์–ด, ๋””๋ฒ„๊น…์ด๋‚˜ ํ…Œ์ŠคํŠธ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

# ๊ฐœ๋ฐœ ๋‹จ๊ณ„๋งŒ ๋นŒ๋“œ
docker build --target development -t myapp:dev .

์ด ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ Dockerfile๋กœ ๊ฐœ๋ฐœ, ํ…Œ์ŠคํŠธ, ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ๋งž๋Š” ๋‹ค์–‘ํ•œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ์บ์‹œ ์ตœ์ ํ™” ๋ฐ ์˜์กด์„ฑ ๋ ˆ์ด์–ด ๋ถ„๋ฆฌ

ํšจ์œจ์ ์ธ ๋นŒ๋“œ๋ฅผ ์œ„ํ•ด ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” ๋ ˆ์ด์–ด์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ๋ ˆ์ด์–ด๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์˜์กด์„ฑ ํŒŒ์ผ(package.json, requirements.txt ๋“ฑ)์„ ๋จผ์ € ๋ณต์‚ฌํ•˜๊ณ  ์˜์กด์„ฑ์„ ์„ค์น˜ํ•œ ํ›„, ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•˜๋ฉด ์บ์‹œ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ์˜์กด์„ฑ ๋ ˆ์ด์–ด ๋ถ„๋ฆฌ ์˜ˆ์‹œ
FROM node:22-slim AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

# ๋นŒ๋“œ ์Šคํ…Œ์ด์ง€
FROM deps AS build
WORKDIR /app
COPY . .
RUN npm run build

์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์˜์กด์„ฑ ๋ ˆ์ด์–ด๋Š” ์บ์‹œ์—์„œ ์žฌ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ๋นŒ๋“œ ์‹œ๊ฐ„์ด ๋‹จ์ถ•๋ฉ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ ์‹ค์ œ ์‚ฌ๋ก€

Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ตœ์ ํ™”

์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์„ ์ง€์›ํ•˜๋Š” Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฝ์šฐ, ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ ์ข…์†์„ฑ์„ ์ œ์™ธํ•˜๊ณ  ํ”„๋กœ๋•์…˜์— ํ•„์š”ํ•œ ํŒŒ์ผ๋งŒ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ์˜์กด์„ฑ ์Šคํ…Œ์ด์ง€
FROM node:22-slim AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

# ํ…Œ์ŠคํŠธ ์Šคํ…Œ์ด์ง€
FROM deps AS test
WORKDIR /app
RUN npm run test

# ๋นŒ๋“œ ์Šคํ…Œ์ด์ง€
FROM deps AS build
WORKDIR /app
COPY . .
RUN npm run build

# ๋Ÿฐํƒ€์ž„ ์Šคํ…Œ์ด์ง€
FROM node:22-slim AS runtime
WORKDIR /app
COPY --from=build /app/public ./public
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static
ENV NODE_ENV=production
EXPOSE 3000
USER node
CMD ["node", "server.js"]

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

Java Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

Java Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ Maven์ด๋‚˜ Gradle์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œ๋˜๋ฉฐ, ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋ฅผ ํ†ตํ•ด JDK ๋Œ€์‹  JRE๋งŒ ํฌํ•จ๋œ ๋” ์ž‘์€ ๋Ÿฐํƒ€์ž„ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ๋นŒ๋“œ ์Šคํ…Œ์ด์ง€
FROM eclipse-temurin:21-jdk-jammy AS build
WORKDIR /build
COPY . .
RUN ./mvnw package -DskipTests && \
    mv target/*.jar target/app.jar

# ์ถ”์ถœ ์Šคํ…Œ์ด์ง€
FROM build AS extract
WORKDIR /build
RUN java -Djarmode=layertools -jar target/app.jar extract --destination target/extracted

# ๋Ÿฐํƒ€์ž„ ์Šคํ…Œ์ด์ง€
FROM eclipse-temurin:21-jre-jammy AS runtime
WORKDIR /app
COPY --from=extract /build/target/extracted/dependencies/ ./
COPY --from=extract /build/target/extracted/spring-boot-loader/ ./
COPY --from=extract /build/target/extracted/snapshot-dependencies/ ./
COPY --from=extract /build/target/extracted/application/ ./
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]

์ด ์˜ˆ์‹œ์—์„œ๋Š” Spring Boot์˜ ๋ ˆ์ด์–ด ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ JAR ํŒŒ์ผ์„ ์—ฌ๋Ÿฌ ๋ ˆ์ด์–ด๋กœ ์ถ”์ถœํ•˜๊ณ , ๋Ÿฐํƒ€์ž„ ์ด๋ฏธ์ง€์— ํ•„์š”ํ•œ ๋ ˆ์ด์–ด๋งŒ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ  ๋ ˆ์ด์–ด ์บ์‹ฑ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ์˜ ๊ณ ๋ ค์‚ฌํ•ญ

์–ธ์ œ ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ?

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค:

  1. ์ปดํŒŒ์ผ ์–ธ์–ด(Go, Java, C/C++ ๋“ฑ)๋กœ ์ž‘์„ฑ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
  2. ๋นŒ๋“œ ์‹œ ๋งŽ์€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ ์‹คํ–‰ ์‹œ์—๋Š” ๊ฒฐ๊ณผ๋ฌผ๋งŒ ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  3. ์ด๋ฏธ์ง€ ํฌ๊ธฐ๊ฐ€ ์ค‘์š”ํ•œ ํ™˜๊ฒฝ(ํด๋ผ์šฐ๋“œ, ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค, IoT ๋“ฑ)
  4. ๋ณด์•ˆ์ด ์ค‘์š”ํ•œ ํ™˜๊ฒฝ์—์„œ ๊ณต๊ฒฉ ํ‘œ๋ฉด์„ ์ค„์ด๊ณ ์ž ํ•  ๋•Œ
  5. CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ฐ„์†Œํ™”ํ•˜๊ณ ์ž ํ•  ๋•Œ

๋ฐ˜๋ฉด, ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์–ธ์–ด(Python, Ruby, PHP ๋“ฑ)๋กœ ์ž‘์„ฑ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ์˜ ์ด์ ์ด ์ƒ๋Œ€์ ์œผ๋กœ ์ ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์–ธ์–ด๋Š” ์‹คํ–‰ ์‹œ ์†Œ์Šค ์ฝ”๋“œ์™€ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ๋ชจ๋‘ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๊ฐœ๋ฐœ ์ข…์†์„ฑ๊ณผ ํ”„๋กœ๋•์…˜ ์ข…์†์„ฑ์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐ ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

profile
if (์‹คํŒจ) { ๋‹ค์‹œ ๋„์ „; } else { ์„ฑ๊ณต; }

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