์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿ”„ K8s Pod ์žฌ์‹œ์ž‘ ์ •์ฑ… ์™„์ „ ์ •๋ณต: restartPolicy๋ฅผ ๋‚ด ์†์•ˆ์—!
โ˜๏ธ ํด๋ผ์šฐ๋“œ / DevOps

๐Ÿ”„ K8s Pod ์žฌ์‹œ์ž‘ ์ •์ฑ… ์™„์ „ ์ •๋ณต: restartPolicy๋ฅผ ๋‚ด ์†์•ˆ์—!

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค Pod๊ฐ€ ์ฃฝ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ์žฌ์‹œ์ž‘ ์ •์ฑ…์˜ ๋ชจ๋“  ๊ฒƒ์„ ์นœ๊ตฌ์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ํŒŒํ—ค์ณ๋ณด์ž ๐Ÿš€

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค Pod ์žฌ์‹œ์ž‘ ์ •์ฑ… ํ•œ๋ˆˆ์— ๋ณด๊ธฐ Always ํ•ญ์ƒ ์žฌ์‹œ์ž‘ ๐Ÿ”„ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์ด์œ  ๋ถˆ๋ฌธํ•˜๊ณ  ๋ฌด์กฐ๊ฑด ์žฌ์‹œ์ž‘! ์›น์„œ๋ฒ„, ๋ฐ๋ชฌ ๋“ฑ ์žฅ๊ธฐ ์‹คํ–‰ ์„œ๋น„์Šค์— ์ ํ•ฉ OnFailure ์‹คํŒจ ์‹œ์—๋งŒ ์žฌ์‹œ์ž‘ โš ๏ธ ๋น„์ •์ƒ ์ข…๋ฃŒ(์—๋Ÿฌ)์ผ ๋•Œ๋งŒ ์žฌ์‹œ์ž‘, ์ •์ƒ ์ข…๋ฃŒ(0)๋ฉด ์žฌ์‹œ์ž‘ ์•ˆ ํ•จ ๋ฐฐ์น˜ ์ž‘์—…, ํฌ๋ก ์žก ๋“ฑ ์ผํšŒ์„ฑ ์ž‘์—…์— ์ ํ•ฉ Never ์ ˆ๋Œ€ ์žฌ์‹œ์ž‘ ์•ˆ ํ•จ ๐Ÿšซ ์–ด๋–ค ์ด์œ ๋กœ ์ข…๋ฃŒ๋˜๋“  ์ ˆ๋Œ€๋กœ ์žฌ์‹œ์ž‘ํ•˜์ง€ ์•Š์Œ ์ข…๋ฃŒ = ๋ ๋””๋ฒ„๊น…, ๋‹จ๋ฐœ์„ฑ ํ…Œ์ŠคํŠธ, ๋กœ๊ทธ ์ˆ˜์ง‘ ๋“ฑ์— ์ ํ•ฉ spec.restartPolicy ํ•„๋“œ๋กœ ์„ค์ • ยท ๊ธฐ๋ณธ๊ฐ’์€ Always
๐ŸŽฏ ๋“ค์–ด๊ฐ€๋ฉฐ: Pod๊ฐ€ ์ฃฝ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค(Kubernetes, ์ค„์—ฌ์„œ K8s)๋ฅผ ์ฒ˜์Œ ๋ฐฐ์šธ ๋•Œ ๋ˆ„๊ตฌ๋‚˜ ํ•œ ๋ฒˆ์ฏค ์ด๋Ÿฐ ์ƒํ™ฉ์„ ๊ฒช์–ด๋ดค์„ ๊ฑฐ์•ผ. ์—ด์‹ฌํžˆ ๋ฐฐํฌํ•œ Pod๊ฐ€ ๊ฐ‘์ž๊ธฐ CrashLoopBackOff ์ƒํƒœ๊ฐ€ ๋˜๊ฑฐ๋‚˜, ์•„๋‹ˆ๋ฉด ๋ฐฐ์น˜ ์ž‘์—…์„ ๋Œ๋ ธ๋Š”๋ฐ ์ž‘์—…์ด ๋๋‚ฌ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  Pod๊ฐ€ ๊ณ„์† ์žฌ์‹œ์ž‘์„ ๋ฐ˜๋ณตํ•˜๋Š” ํ™ฉ๋‹นํ•œ ๊ฒฝํ—˜ ๋ง์ด์•ผ. ๐Ÿ˜…

์ด๋Ÿฐ ์ƒํ™ฉ์ด ์™œ ์ƒ๊ธฐ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ป๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด Pod์˜ ์žฌ์‹œ์ž‘ ์ •์ฑ…(restartPolicy)์„ ์ œ๋Œ€๋กœ ์•Œ์•„์•ผ ํ•ด. ์˜ค๋Š˜์€ ์ด ์ฃผ์ œ๋ฅผ ์™„์ „ํžˆ ๋œฏ์–ด๋ณด๋ฉด์„œ, ์‹ค๋ฌด์—์„œ ๋ฐ”๋กœ ์จ๋จน์„ ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€๊นŒ์ง€ ๊ฐ™์ด ํŒŒํ—ค์ณ๋ณด์ž!

๐Ÿ’ก ์ด ๊ธ€์—์„œ ๋ฐฐ์šธ ๊ฒƒ๋“ค
restartPolicy 3๊ฐ€์ง€ Pod ์ƒ๋ช…์ฃผ๊ธฐ CrashLoopBackOff ํ•ด๊ฒฐ ์‹ค์ „ YAML ์˜ˆ์ œ Job/CronJob ์—ฐ๊ณ„ ๋ฐฑ์˜คํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ Pod๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ฌถ์–ด์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋ฐฐํฌ ๋‹จ์œ„์•ผ. ๊ทธ๋Ÿฐ๋ฐ ์ปจํ…Œ์ด๋„ˆ๋Š” ์–ธ์ œ๋“ ์ง€ ์ฃฝ์„ ์ˆ˜ ์žˆ์–ด. ์•ฑ ๋ฒ„๊ทธ๋กœ ์ธํ•œ ํฌ๋ž˜์‹œ, ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ(OOM Kill), ์™ธ๋ถ€ ์‹ ํ˜ธ(SIGTERM, SIGKILL), ํ˜น์€ ๊ทธ๋ƒฅ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์–ด์„œ ์ •์ƒ ์ข…๋ฃŒ๋˜๋Š” ๊ฒฝ์šฐ๊นŒ์ง€ ๋‹ค์–‘ํ•œ ์ด์œ ๋กœ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๊ฑฐ๋“ .

์ด๋•Œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๊ฐ€ "์ด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋‹ค์‹œ ์‚ด๋ฆด๊นŒ ๋ง๊นŒ?"๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ธฐ์ค€์ด ๋ฐ”๋กœ restartPolicy์•ผ. ์ด ์„ค์ • ํ•˜๋‚˜๊ฐ€ ์‹œ์Šคํ…œ์˜ ์•ˆ์ •์„ฑ๊ณผ ์šด์˜ ๋ฐฉ์‹์— ์—„์ฒญ๋‚œ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ธฐ ๋•Œ๋ฌธ์—, ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ณ  ์“ฐ๋Š” ๊ฒŒ ์ •๋ง ์ค‘์š”ํ•ด!


๐Ÿ“š restartPolicy๋ž€ ๋ฌด์—‡์ธ๊ฐ€?
๊ธฐ๋ณธ ๊ฐœ๋… ์žก๊ธฐ

restartPolicy๋Š” Pod ์ŠคํŽ™(spec)์— ์ •์˜ํ•˜๋Š” ํ•„๋“œ๋กœ, Pod ๋‚ด์˜ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ์„ ๋•Œ kubelet์ด ์–ด๋–ป๊ฒŒ ๋ฐ˜์‘ํ• ์ง€๋ฅผ ๊ฒฐ์ •ํ•ด. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด "์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ฃฝ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๋ž˜?"์— ๋Œ€ํ•œ ๋‹ต๋ณ€์ด์•ผ.

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
restartPolicy: Always   # โ† ๋ฐ”๋กœ ์ด ๋ถ€๋ถ„!
containers:
- name: my-container
image: nginx:latest

์œ„์น˜๋ฅผ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, restartPolicy๋Š” Pod ๋ ˆ๋ฒจ์—์„œ ์„ค์ •ํ•ด. ์ฆ‰, Pod ์•ˆ์— ์žˆ๋Š” ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ์— ๋™์ผํ•˜๊ฒŒ ์ ์šฉ๋ผ. ์ปจํ…Œ์ด๋„ˆ๋ณ„๋กœ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •ํ•˜๋Š” ๊ฑด ๋ถˆ๊ฐ€๋Šฅํ•ด. ์ด ์ ์€ ๊ผญ ๊ธฐ์–ตํ•ด๋‘์ž!

๐Ÿ” ์ค‘์š”ํ•œ ํฌ์ธํŠธ! restartPolicy๋Š” Pod ์ „์ฒด์— ์ ์šฉ๋˜๋Š” ์„ค์ •์ด์•ผ. Pod ์•ˆ์— ์ปจํ…Œ์ด๋„ˆ๊ฐ€ 3๊ฐœ ์žˆ๋‹ค๋ฉด, 3๊ฐœ ๋ชจ๋‘ ๊ฐ™์€ ์žฌ์‹œ์ž‘ ์ •์ฑ…์„ ๋”ฐ๋ฅด๊ฒŒ ๋ผ. ์ปจํ…Œ์ด๋„ˆ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ •์ฑ…์„ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ๋ณ„๋„์˜ Pod๋กœ ๋ถ„๋ฆฌํ•ด์•ผ ํ•ด.
์„ธ ๊ฐ€์ง€ ์˜ต์…˜: Always, OnFailure, Never

restartPolicy์—๋Š” ๋”ฑ ์„ธ ๊ฐ€์ง€ ๊ฐ’๋งŒ ์˜ฌ ์ˆ˜ ์žˆ์–ด. ์ด ์„ธ ๊ฐ€์ง€๊ฐ€ ์ „๋ถ€์•ผ!

์ •์ฑ… ์žฌ์‹œ์ž‘ ์กฐ๊ฑด ๊ธฐ๋ณธ๊ฐ’ ์—ฌ๋ถ€ ์ฃผ์š” ์‚ฌ์šฉ ์‚ฌ๋ก€
Always ์ข…๋ฃŒ ์ด์œ  ๋ถˆ๋ฌธ, ํ•ญ์ƒ ์žฌ์‹œ์ž‘ โœ… ๊ธฐ๋ณธ๊ฐ’ ์›น์„œ๋ฒ„, API ์„œ๋ฒ„, ๋ฐ๋ชฌ ํ”„๋กœ์„ธ์Šค
OnFailure ๋น„์ •์ƒ ์ข…๋ฃŒ(exit code โ‰  0)์ผ ๋•Œ๋งŒ โŒ ๋ฐฐ์น˜ ์ž‘์—…, ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ
Never ์ ˆ๋Œ€ ์žฌ์‹œ์ž‘ ์•ˆ ํ•จ โŒ ๋””๋ฒ„๊น…, ๋‹จ๋ฐœ์„ฑ ์ž‘์—…, ๋กœ๊ทธ ์ˆ˜์ง‘

๊ธฐ๋ณธ๊ฐ’์ด Always๋ผ๋Š” ์ ์ด ์ค‘์š”ํ•ด. ์ฆ‰, restartPolicy๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ์ž๋™์œผ๋กœ Always๊ฐ€ ์ ์šฉ๋ผ. ์ด๊ฒŒ ์™œ ์ค‘์š”ํ•˜๋ƒ๋ฉด, ๋ฐฐ์น˜ ์ž‘์—…์„ ๋งŒ๋“ค ๋•Œ ์‹ค์ˆ˜๋กœ restartPolicy๋ฅผ ๋น ๋œจ๋ฆฌ๋ฉด ์ž‘์—…์ด ๋๋‚˜๋„ ๊ณ„์† ์žฌ์‹œ์ž‘ํ•˜๋Š” ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์งˆ ์ˆ˜ ์žˆ๊ฑฐ๋“ ! ๐Ÿ˜ฑ


๐Ÿ”„ Always: ๋ถˆ์‚ฌ์กฐ ์ •์ฑ…
Always๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ?

Always๋Š” ๋ง ๊ทธ๋Œ€๋กœ "ํ•ญ์ƒ ์žฌ์‹œ์ž‘"์ด์•ผ. ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์–ด๋–ค ์ด์œ ๋กœ ์ข…๋ฃŒ๋˜๋“  ์ƒ๊ด€์—†์ด kubelet์ด ๋ฌด์กฐ๊ฑด ๋‹ค์‹œ ์‚ด๋ ค์ค˜. ์ •์ƒ ์ข…๋ฃŒ(exit code 0)๋“ , ์—๋Ÿฌ ์ข…๋ฃŒ(exit code โ‰  0)๋“ , ์‹ฌ์ง€์–ด ์™ธ๋ถ€์—์„œ ๊ฐ•์ œ๋กœ ์ฃฝ์˜€๋“  ์ƒ๊ด€์—†์–ด.

Always ์ •์ฑ… ๋™์ž‘ ํ๋ฆ„ ๐ŸŸข ์‹คํ–‰ ์ค‘ โœ… ์ •์ƒ ์ข…๋ฃŒ (exit code 0) โŒ ๋น„์ •์ƒ ์ข…๋ฃŒ (exit code โ‰  0) ๐Ÿ”„ ์žฌ์‹œ์ž‘! ๋ฐฑ์˜คํ”„ ๋”œ๋ ˆ์ด ํ›„ ์–ด๋–ค ์ด์œ ๋กœ ์ข…๋ฃŒ๋˜๋“  โ†’ ๋ฌด์กฐ๊ฑด ์žฌ์‹œ์ž‘ (Always) ๋‹ค์‹œ Running ์ƒํƒœ๋กœ!
apiVersion: v1
kind: Pod
metadata:
name: always-restart-pod
spec:
restartPolicy: Always
containers:
- name: web-server
image: nginx:1.25
ports:
- containerPort: 80
Always๊ฐ€ ์ ํ•ฉํ•œ ์ƒํ™ฉ

Always ์ •์ฑ…์€ ์žฅ๊ธฐ ์‹คํ–‰ ์„œ๋น„์Šค์— ๋”ฑ์ด์•ผ. ์›น ์„œ๋ฒ„, API ์„œ๋ฒ„, ๋ฉ”์‹œ์ง€ ํ ์ปจ์Šˆ๋จธ์ฒ˜๋Ÿผ "ํ•ญ์ƒ ์‚ด์•„์žˆ์–ด์•ผ ํ•˜๋Š”" ์„œ๋น„์Šค๋“ค์ด ์—ฌ๊ธฐ์— ํ•ด๋‹นํ•ด.

โœ… Always ์ ํ•ฉํ•œ ๊ฒฝ์šฐ

โ€ข ์›น ์„œ๋ฒ„ (nginx, apache)
โ€ข API ์„œ๋ฒ„ (Spring Boot, FastAPI)
โ€ข ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (MySQL, Redis)
โ€ข ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค (Kafka, RabbitMQ)
โ€ข ๋ชจ๋‹ˆํ„ฐ๋ง ์—์ด์ „ํŠธ
โ€ข ์‚ฌ์ด๋“œ์นด ์ปจํ…Œ์ด๋„ˆ
โŒ Always ๋ถ€์ ํ•ฉํ•œ ๊ฒฝ์šฐ

โ€ข ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ ์ž‘์—…
โ€ข ๋ฐ์ดํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜
โ€ข ์ผํšŒ์„ฑ ์ดˆ๊ธฐํ™” ์Šคํฌ๋ฆฝํŠธ
โ€ข ๋””๋ฒ„๊น… ๋ชฉ์  ์ปจํ…Œ์ด๋„ˆ
โ€ข ํฌ๋ก  ์ž‘์—…
โ€ข ์™„๋ฃŒ ํ›„ ์ข…๋ฃŒ๋˜์–ด์•ผ ํ•˜๋Š” ์ž‘์—…
โš ๏ธ ์ฃผ์˜! Deployment, ReplicaSet, StatefulSet, DaemonSet ๊ฐ™์€ ์›Œํฌ๋กœ๋“œ ๋ฆฌ์†Œ์Šค๋Š” ๋ฐ˜๋“œ์‹œ Always๋ฅผ ์จ์•ผ ํ•ด. ์ด ๋ฆฌ์†Œ์Šค๋“ค์€ Always๋งŒ ์ง€์›ํ•˜๊ฑฐ๋“ . OnFailure๋‚˜ Never๋ฅผ ์“ฐ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด!
Always์™€ CrashLoopBackOff์˜ ๊ด€๊ณ„

Always ์ •์ฑ…์„ ์“ธ ๋•Œ ๊ฐ€์žฅ ์ž์ฃผ ๋งˆ์ฃผ์น˜๋Š” ์ƒํ™ฉ์ด ๋ฐ”๋กœ CrashLoopBackOff์•ผ. ์ด๊ฒŒ ๋ญ”์ง€ ์ œ๋Œ€๋กœ ์•Œ์•„๋ณด์ž.

์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ณ„์† ํฌ๋ž˜์‹œ๋˜๋ฉด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ๋ฌดํ•œ์ • ์ฆ‰์‹œ ์žฌ์‹œ์ž‘ํ•˜์ง€ ์•Š์•„. ๋Œ€์‹  ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„(Exponential Backoff) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•ด์„œ ์žฌ์‹œ์ž‘ ๊ฐ„๊ฒฉ์„ ์ ์  ๋Š˜๋ ค๋‚˜๊ฐ€.

์žฌ์‹œ์ž‘ ํšŸ์ˆ˜ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋ˆ„์  ์‹œ๊ฐ„
1๋ฒˆ์งธ 10์ดˆ 10์ดˆ
2๋ฒˆ์งธ 20์ดˆ 30์ดˆ
3๋ฒˆ์งธ 40์ดˆ 70์ดˆ
4๋ฒˆ์งธ 80์ดˆ 150์ดˆ
5๋ฒˆ์งธ ์ดํ›„ ์ตœ๋Œ€ 300์ดˆ(5๋ถ„) ๊ณ„์† ์ฆ๊ฐ€

์ด๋ ‡๊ฒŒ ์žฌ์‹œ์ž‘ ๊ฐ„๊ฒฉ์ด ๋Š˜์–ด๋‚˜๋ฉด์„œ Pod ์ƒํƒœ๊ฐ€ CrashLoopBackOff๋กœ ํ‘œ์‹œ๋ผ. "ํฌ๋ž˜์‹œ ๋ฃจํ”„ ๋ฐฑ์˜คํ”„"๋ž€ "ํฌ๋ž˜์‹œ๊ฐ€ ๋ฐ˜๋ณต๋˜์–ด ๋ฐฑ์˜คํ”„(๋Œ€๊ธฐ) ์ค‘"์ด๋ผ๋Š” ๋œป์ด์•ผ. ์—๋Ÿฌ๊ฐ€ ์•„๋‹ˆ๋ผ ์ƒํƒœ ํ‘œ์‹œ์•ผ!

๐Ÿ’ก CrashLoopBackOff ๋””๋ฒ„๊น… ํŒ
kubectl logs <pod-name> --previous ๋ช…๋ น์–ด๋กœ ์ด์ „ ์ปจํ…Œ์ด๋„ˆ์˜ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด.
kubectl describe pod <pod-name>์œผ๋กœ ์ด๋ฒคํŠธ ํžˆ์Šคํ† ๋ฆฌ๋„ ๋ณผ ์ˆ˜ ์žˆ๊ณ .

๋ฐฑ์˜คํ”„ ํƒ€์ด๋จธ๋Š” ์ปจํ…Œ์ด๋„ˆ๊ฐ€ 10๋ถ„ ์ด์ƒ ์ •์ƒ ์‹คํ–‰๋˜๋ฉด ๋ฆฌ์…‹๋ผ!

โš ๏ธ OnFailure: ์‹คํŒจํ–ˆ์„ ๋•Œ๋งŒ ์‚ด๋ ค์ค„๊ฒŒ
OnFailure์˜ ๋™์ž‘ ์›๋ฆฌ

OnFailure๋Š” ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋น„์ •์ƒ ์ข…๋ฃŒ๋˜์—ˆ์„ ๋•Œ๋งŒ ์žฌ์‹œ์ž‘ํ•ด. "๋น„์ •์ƒ ์ข…๋ฃŒ"์˜ ๊ธฐ์ค€์€ exit code๊ฐ€ 0์ด ์•„๋‹Œ ๊ฒฝ์šฐ์•ผ.

๋ฆฌ๋ˆ…์Šค/์œ ๋‹‰์Šค ์‹œ์Šคํ…œ์—์„œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ exit code๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ:

๐ŸŸข ์ •์ƒ ์ข…๋ฃŒ (exit code 0)

โ€ข ์ž‘์—…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋จ
โ€ข ์˜๋„์ ์œผ๋กœ ์ข…๋ฃŒ๋จ
โ€ข OnFailure: ์žฌ์‹œ์ž‘ โŒ
โ€ข Never: ์žฌ์‹œ์ž‘ โŒ
๐Ÿ”ด ๋น„์ •์ƒ ์ข…๋ฃŒ (exit code โ‰  0)

โ€ข ํ”„๋กœ๊ทธ๋žจ ์—๋Ÿฌ ๋ฐœ์ƒ
โ€ข ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์‹คํŒจ
โ€ข OOM Kill (exit code 137)
โ€ข OnFailure: ์žฌ์‹œ์ž‘ โœ…
โ€ข Never: ์žฌ์‹œ์ž‘ โŒ
apiVersion: v1
kind: Pod
metadata:
name: batch-job-pod
spec:
restartPolicy: OnFailure
containers:
- name: batch-processor
image: my-batch-app:1.0
command: ["python", "process_data.py"]
env:
- name: DATA_SOURCE
value: "s3://my-bucket/data"
OnFailure ์‹ค์ „ ์‹œ๋‚˜๋ฆฌ์˜ค

OnFailure๊ฐ€ ๋น›์„ ๋ฐœํ•˜๋Š” ์ƒํ™ฉ์„ ๊ตฌ์ฒด์ ์œผ๋กœ ์‚ดํŽด๋ณด์ž.

์‹œ๋‚˜๋ฆฌ์˜ค 1: ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ฐฐ์น˜ ์ž‘์—…

๋งค์ผ ๋ฐค 10๋งŒ ๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฐ์น˜ ์ž‘์—…์ด ์žˆ๋‹ค๊ณ  ํ•ด๋ณด์ž. ์ด ์ž‘์—…์€ ์„ฑ๊ณตํ•˜๋ฉด exit code 0์œผ๋กœ ์ข…๋ฃŒ๋˜๊ณ , ์‹คํŒจํ•˜๋ฉด exit code 1๋กœ ์ข…๋ฃŒ๋ผ.

apiVersion: v1
kind: Pod
metadata:
name: nightly-batch
spec:
restartPolicy: OnFailure
containers:
- name: data-processor
image: data-processor:latest
command:
- /bin/sh
- -c
- |
python process.py && echo "์„ฑ๊ณต!" && exit 0
# ์‹คํŒจ ์‹œ exit 1 ๋ฐ˜ํ™˜ โ†’ ์žฌ์‹œ์ž‘
# ์„ฑ๊ณต ์‹œ exit 0 ๋ฐ˜ํ™˜ โ†’ ์žฌ์‹œ์ž‘ ์•ˆ ํ•จ

์ด ๊ฒฝ์šฐ ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๋ฉด Pod๋Š” Completed ์ƒํƒœ๊ฐ€ ๋˜๊ณ  ์žฌ์‹œ์ž‘ํ•˜์ง€ ์•Š์•„. ํ•˜์ง€๋งŒ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋‚˜ ์ผ์‹œ์ ์ธ DB ์—ฐ๊ฒฐ ์‹คํŒจ๋กœ ์ž‘์—…์ด ์‹คํŒจํ•˜๋ฉด ์ž๋™์œผ๋กœ ์žฌ์‹œ์ž‘ํ•ด์„œ ๋‹ค์‹œ ์‹œ๋„ํ•ด. ์™„๋ฒฝํ•˜์ง€ ์•Š์•„? ๐Ÿ˜Š

์‹œ๋‚˜๋ฆฌ์˜ค 2: ์ดˆ๊ธฐํ™” ์ž‘์—… (Init Container ๋Œ€์•ˆ)

apiVersion: v1
kind: Pod
metadata:
name: db-migration-pod
spec:
restartPolicy: OnFailure
containers:
- name: migrator
image: flyway:9.0
command: ["flyway", "migrate"]
env:
- name: FLYWAY_URL
value: "jdbc:postgresql://db:5432/mydb"
- name: FLYWAY_USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
OnFailure์™€ Job ๋ฆฌ์†Œ์Šค์˜ ๊ด€๊ณ„

์‚ฌ์‹ค ์‹ค๋ฌด์—์„œ OnFailure๋ฅผ ๋‹จ๋… Pod์— ์“ฐ๋Š” ๊ฒฝ์šฐ๋Š” ๋งŽ์ง€ ์•Š์•„. ๋Œ€๋ถ€๋ถ„ Job ๋ฆฌ์†Œ์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด. Job์€ ๋ฐฐ์น˜ ์ž‘์—…์„ ๊ด€๋ฆฌํ•˜๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค์ธ๋ฐ, Job์˜ ๊ธฐ๋ณธ restartPolicy๊ฐ€ ๋ฐ”๋กœ OnFailure์•ผ!

apiVersion: batch/v1
kind: Job
metadata:
name: data-migration-job
spec:
completions: 1        # ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒํ•ด์•ผ ํ•  ํšŸ์ˆ˜
parallelism: 1        # ๋™์‹œ์— ์‹คํ–‰ํ•  Pod ์ˆ˜
backoffLimit: 4       # ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜
template:
spec:
restartPolicy: OnFailure  # Job์—์„œ๋Š” OnFailure ๋˜๋Š” Never๋งŒ ๊ฐ€๋Šฅ!
containers:
- name: migrator
image: my-migrator:1.0
command: ["./migrate.sh"]
โš ๏ธ Job์—์„œ Always๋Š” ๊ธˆ์ง€! Job ๋ฆฌ์†Œ์Šค์—์„œ๋Š” restartPolicy: Always๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์–ด. Job์€ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ๋๋‚˜์•ผ ํ•˜๋Š” ๋ฆฌ์†Œ์Šค์ธ๋ฐ, Always๋ฅผ ์“ฐ๋ฉด ์˜์›ํžˆ ์žฌ์‹œ์ž‘ํ•˜๋Š” ๋ชจ์ˆœ์ด ์ƒ๊ธฐ๊ฑฐ๋“ . Job์—์„œ๋Š” OnFailure ๋˜๋Š” Never๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด!
backoffLimit๊ณผ์˜ ์กฐํ•ฉ

OnFailure๋ฅผ Job๊ณผ ํ•จ๊ป˜ ์“ธ ๋•Œ backoffLimit์ด๋ผ๋Š” ์ค‘์š”ํ•œ ์„ค์ •์ด ์žˆ์–ด. ์ด๊ฑด "์ตœ๋Œ€ ๋ช‡ ๋ฒˆ๊นŒ์ง€ ์žฌ์‹œ๋„ํ•  ๊ฑฐ์•ผ?"๋ฅผ ์ •ํ•˜๋Š” ๊ฑฐ์•ผ.

spec:
backoffLimit: 6  # ๊ธฐ๋ณธ๊ฐ’์€ 6
# 6๋ฒˆ ์‹คํŒจํ•˜๋ฉด Job ์ž์ฒด๊ฐ€ Failed ์ƒํƒœ๊ฐ€ ๋จ

backoffLimit์„ ์ดˆ๊ณผํ•˜๋ฉด Job์€ Failed ์ƒํƒœ๊ฐ€ ๋˜๊ณ , ๋” ์ด์ƒ ์žฌ์‹œ๋„ํ•˜์ง€ ์•Š์•„. ์ด๋•Œ ์•Œ๋ฆผ์„ ๋ฐ›์•„์„œ ์ˆ˜๋™์œผ๋กœ ํ™•์ธํ•˜๋Š” ๊ฒŒ ์ข‹์€ ์šด์˜ ๋ฐฉ์‹์ด์•ผ.


๐Ÿšซ Never: ํ•œ ๋ฒˆ ์ฃฝ์œผ๋ฉด ๊ทธ๋ƒฅ ์ฃฝ๋Š” ๊ฑฐ์•ผ
Never์˜ ๋™์ž‘ ์›๋ฆฌ

Never๋Š” ๊ฐ€์žฅ ๋‹จ์ˆœํ•ด. ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์ด์œ  ๋ถˆ๋ฌธํ•˜๊ณ  ์ ˆ๋Œ€ ์žฌ์‹œ์ž‘ํ•˜์ง€ ์•Š์•„. ์ •์ƒ ์ข…๋ฃŒ๋“  ๋น„์ •์ƒ ์ข…๋ฃŒ๋“  ์ƒ๊ด€์—†์ด ๊ทธ๋ƒฅ ๋์ด์•ผ.

Never ์ •์ฑ… ๋™์ž‘ ํ๋ฆ„ ๐ŸŸข ์‹คํ–‰ ์ค‘ โœ… ์ •์ƒ ์ข…๋ฃŒ (exit code 0) โŒ ๋น„์ •์ƒ ์ข…๋ฃŒ (exit code โ‰  0) โœ… Completed ์žฌ์‹œ์ž‘ ์—†์Œ ๐Ÿ’€ Failed ์žฌ์‹œ์ž‘ ์—†์Œ ๐Ÿšซ ์žฌ์‹œ์ž‘ ์ ˆ๋Œ€ ์—†์Œ!
apiVersion: v1
kind: Pod
metadata:
name: debug-pod
spec:
restartPolicy: Never
containers:
- name: debugger
image: busybox:latest
command: ["sh", "-c", "env && ls -la /app && cat /app/config.yaml"]
Never๊ฐ€ ๋น›๋‚˜๋Š” ์ƒํ™ฉ๋“ค

Never๋Š” ์–ธ์ œ ์จ์•ผ ํ• ๊นŒ? ์ƒ๊ฐ๋ณด๋‹ค ๊ฝค ์œ ์šฉํ•œ ์ƒํ™ฉ๋“ค์ด ์žˆ์–ด.

1. ๋””๋ฒ„๊น… ๋ชฉ์ 

ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ํŠน์ • Pod์˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์„ ํ™•์ธํ•˜๊ณ  ์‹ถ์„ ๋•Œ, Never๋กœ ์„ค์ •ํ•œ ์ž„์‹œ Pod๋ฅผ ๋„์›Œ์„œ ํ™•์ธํ•˜๊ณ  ๋ฐ”๋กœ ์ข…๋ฃŒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด. ์žฌ์‹œ์ž‘ ์—†์ด ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋‹ˆ๊นŒ ๊น”๋”ํ•˜์ง€!

# ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋คํ”„์šฉ ๋””๋ฒ„๊ทธ Pod
apiVersion: v1
kind: Pod
metadata:
name: env-debugger
namespace: production
spec:
restartPolicy: Never
containers:
- name: debugger
image: alpine:latest
command: ["sh", "-c", "printenv | sort > /tmp/env.txt && cat /tmp/env.txt"]
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets

2. ๋‹จ๋ฐœ์„ฑ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

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

3. Job์—์„œ์˜ Never ํ™œ์šฉ

apiVersion: batch/v1
kind: Job
metadata:
name: one-time-task
spec:
backoffLimit: 0  # ์žฌ์‹œ๋„ ์—†์Œ
template:
spec:
restartPolicy: Never  # Pod ๋ ˆ๋ฒจ์—์„œ๋„ ์žฌ์‹œ์ž‘ ์—†์Œ
containers:
- name: task
image: my-task:1.0
command: ["./run-once.sh"]

Job์—์„œ restartPolicy: Never์™€ backoffLimit: 0์„ ํ•จ๊ป˜ ์“ฐ๋ฉด "๋”ฑ ํ•œ ๋ฒˆ๋งŒ ์‹œ๋„ํ•˜๊ณ , ์‹คํŒจํ•ด๋„ ์žฌ์‹œ๋„ ์—†์Œ"์ด ๋ผ. ์™„์ „ํ•œ ๋‹จ๋ฐœ์„ฑ ์‹คํ–‰์ด์•ผ!

๐Ÿ’ก Never vs OnFailure ์„ ํƒ ๊ธฐ์ค€
โ€ข Never: ์‹คํŒจํ•ด๋„ ์žฌ์‹œ๋„ ์—†์ด ๊ฒฐ๊ณผ๋ฅผ ์ง์ ‘ ํ™•์ธํ•˜๊ณ  ์‹ถ์„ ๋•Œ
โ€ข OnFailure: ์ผ์‹œ์  ์˜ค๋ฅ˜(๋„คํŠธ์›Œํฌ, DB ์—ฐ๊ฒฐ ๋“ฑ)๊ฐ€ ์žˆ์–ด๋„ ์ž๋™์œผ๋กœ ์žฌ์‹œ๋„ํ•˜๊ธธ ์›ํ•  ๋•Œ

๋ฉฑ๋“ฑ์„ฑ(idempotent)์ด ๋ณด์žฅ๋˜๋Š” ์ž‘์—…์ด๋ผ๋ฉด OnFailure๊ฐ€ ๋” ์•ˆ์ „ํ•ด. ๋ฉฑ๋“ฑ์„ฑ์ด ์—†๋Š” ์ž‘์—…(์˜ˆ: ์ด๋ฉ”์ผ ๋ฐœ์†ก)์ด๋ผ๋ฉด Never๊ฐ€ ๋” ์ ํ•ฉํ•  ์ˆ˜ ์žˆ์–ด.

๐Ÿ”ฌ Pod ์ƒ๋ช…์ฃผ๊ธฐ์™€ restartPolicy์˜ ๊ด€๊ณ„
Pod Phase ์™„์ „ ์ •๋ณต

restartPolicy๋ฅผ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๋ ค๋ฉด Pod์˜ ์ƒ๋ช…์ฃผ๊ธฐ(Lifecycle)๋ฅผ ์•Œ์•„์•ผ ํ•ด. Pod๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ Phase(๋‹จ๊ณ„)๋ฅผ ๊ฑฐ์ณ.

Pod ์ƒ๋ช…์ฃผ๊ธฐ (Phase) ํ๋ฆ„๋„ โณ Pending ์Šค์ผ€์ค„๋ง ๋Œ€๊ธฐ ๐ŸŸข Running ์‹คํ–‰ ์ค‘ โœ… Succeeded ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ ์ •์ƒ ์ข…๋ฃŒ ๐Ÿ’€ Failed ์ปจํ…Œ์ด๋„ˆ ๋น„์ •์ƒ ์ข…๋ฃŒ โ“ Unknown ๋…ธ๋“œ ํ†ต์‹  ๋ถˆ๊ฐ€ restartPolicy ์˜ํ–ฅ Always Succeeded โ†’ ์žฌ์‹œ์ž‘ Failed โ†’ ์žฌ์‹œ์ž‘ OnFailure Succeeded โ†’ ์œ ์ง€ Failed โ†’ ์žฌ์‹œ์ž‘ Never Succeeded โ†’ ์œ ์ง€ Failed โ†’ ์œ ์ง€ Phase๋Š” Pod ์ „์ฒด ์ƒํƒœ ยท ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ(ContainerState)์™€๋Š” ๋ณ„๊ฐœ
Phase ์„ค๋ช… restartPolicy ์˜ํ–ฅ
Pending Pod๊ฐ€ ์ˆ˜๋ฝ๋์ง€๋งŒ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•„์ง ์‹คํ–‰ ์•ˆ ๋จ. ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์ค‘์ด๊ฑฐ๋‚˜ ์Šค์ผ€์ค„๋ง ๋Œ€๊ธฐ ์ค‘. ์˜ํ–ฅ ์—†์Œ
Running Pod๊ฐ€ ๋…ธ๋“œ์— ๋ฐ”์ธ๋”ฉ๋๊ณ , ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ƒ์„ฑ๋จ. ์ตœ์†Œ ํ•˜๋‚˜์˜ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰ ์ค‘์ด๊ฑฐ๋‚˜ ์‹œ์ž‘/์žฌ์‹œ์ž‘ ์ค‘. ์ปจํ…Œ์ด๋„ˆ ์ข…๋ฃŒ ์‹œ ์ •์ฑ… ์ ์šฉ
Succeeded Pod์˜ ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ข…๋ฃŒ๋จ(exit code 0). ์žฌ์‹œ์ž‘๋˜์ง€ ์•Š์Œ. Always๋ฉด ์ด ์ƒํƒœ ์•ˆ ๋จ
Failed Pod์˜ ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒ๋๋Š”๋ฐ, ์ตœ์†Œ ํ•˜๋‚˜๊ฐ€ ์‹คํŒจ๋กœ ์ข…๋ฃŒ๋จ. Always/OnFailure๋ฉด ์ด ์ƒํƒœ ์•ˆ ๋จ
Unknown Pod ์ƒํƒœ๋ฅผ ์•Œ ์ˆ˜ ์—†์Œ. ๋ณดํ†ต ๋…ธ๋“œ์™€์˜ ํ†ต์‹  ์˜ค๋ฅ˜. ์˜ํ–ฅ ์—†์Œ
์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ(ContainerState)๋„ ์•Œ์•„๋‘์ž

Pod Phase์™€ ๋ณ„๊ฐœ๋กœ ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋Š” ์ž์ฒด์ ์ธ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ. kubectl describe pod๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด.

์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ์„ค๋ช…
Waiting ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•„์ง ์‹คํ–‰ ์ค‘์ด ์•„๋‹˜. ์ด๋ฏธ์ง€ ํ’€๋ง, ์‹œํฌ๋ฆฟ ์ ์šฉ ๋“ฑ ๋Œ€๊ธฐ ์ค‘.
Running ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋ฌธ์ œ ์—†์ด ์‹คํ–‰ ์ค‘. startedAt ํƒ€์ž„์Šคํƒฌํ”„ ํฌํ•จ.
Terminated ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰์„ ์™„๋ฃŒํ–ˆ๊ฑฐ๋‚˜ ์–ด๋–ค ์ด์œ ๋กœ ์‹คํŒจํ•จ. exit code, ์‹œ์ž‘/์ข…๋ฃŒ ์‹œ๊ฐ„ ํฌํ•จ.
# ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ํ™•์ธ
kubectl describe pod my-pod

# ์ถœ๋ ฅ ์˜ˆ์‹œ:
# Containers:
#   my-container:
#     State:          Terminated
#       Reason:       Error
#       Exit Code:    1
#       Started:      Mon, 01 Jan 2024 10:00:00 +0000
#       Finished:     Mon, 01 Jan 2024 10:00:05 +0000
#     Last State:     Terminated
#       Reason:       Error
#       Exit Code:    1
#     Ready:          False
#     Restart Count:  3

โš™๏ธ ์‹ค์ „ YAML ๋ ˆ์‹œํ”ผ ๋ชจ์Œ
๋ ˆ์‹œํ”ผ 1: ๊ณ ๊ฐ€์šฉ์„ฑ ์›น ์„œ๋น„์Šค (Always)

์‹ค์ œ ํ”„๋กœ๋•์…˜์—์„œ ์“ธ ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€์˜ YAML์ด์•ผ. Deployment์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด์ด์•ผ.

apiVersion: apps/v1
kind: Deployment
metadata:
name: web-api-deployment
namespace: production
labels:
app: web-api
version: "1.0"
spec:
replicas: 3
selector:
matchLabels:
app: web-api
template:
metadata:
labels:
app: web-api
spec:
restartPolicy: Always  # Deployment๋Š” Always๋งŒ ๊ฐ€๋Šฅ
containers:
- name: api-server
image: my-api:1.0.0
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
๋ ˆ์‹œํ”ผ 2: ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ Job (OnFailure)
apiVersion: batch/v1
kind: Job
metadata:
name: monthly-report-job
namespace: batch
spec:
completions: 1
parallelism: 1
backoffLimit: 3          # ์ตœ๋Œ€ 3๋ฒˆ ์žฌ์‹œ๋„
activeDeadlineSeconds: 3600  # 1์‹œ๊ฐ„ ๋‚ด์— ์™„๋ฃŒ ์•ˆ ๋˜๋ฉด ์‹คํŒจ
template:
metadata:
labels:
job-name: monthly-report
spec:
restartPolicy: OnFailure
containers:
- name: report-generator
image: report-gen:2.1
command: ["python", "-u", "generate_report.py"]
env:
- name: REPORT_MONTH
value: "2024-01"
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-credentials
key: host
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
restartPolicy: OnFailure
๋ ˆ์‹œํ”ผ 3: CronJob์œผ๋กœ ์ฃผ๊ธฐ์  ๋ฐฐ์น˜ (OnFailure)
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-cleanup
namespace: maintenance
spec:
schedule: "0 2 * * *"     # ๋งค์ผ ์ƒˆ๋ฒฝ 2์‹œ
concurrencyPolicy: Forbid  # ์ด์ „ ์ž‘์—…์ด ๋๋‚˜์ง€ ์•Š์œผ๋ฉด ์ƒˆ ์ž‘์—… ์‹œ์ž‘ ์•ˆ ํ•จ
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
backoffLimit: 2
template:
spec:
restartPolicy: OnFailure
containers:
- name: cleanup-worker
image: cleanup:latest
command:
- /bin/sh
- -c
- |
echo "์ •๋ฆฌ ์ž‘์—… ์‹œ์ž‘: $(date)"
python cleanup_old_data.py --days 90
echo "์ •๋ฆฌ ์ž‘์—… ์™„๋ฃŒ: $(date)"
๋ ˆ์‹œํ”ผ 4: ๋””๋ฒ„๊น… Pod (Never)
apiVersion: v1
kind: Pod
metadata:
name: debug-session
namespace: production
annotations:
purpose: "์ž„์‹œ ๋””๋ฒ„๊น… - ์‚ฌ์šฉ ํ›„ ์‚ญ์ œ ํ•„์š”"
spec:
restartPolicy: Never
serviceAccountName: debug-sa
containers:
- name: debugger
image: nicolaka/netshoot:latest  # ๋„คํŠธ์›Œํฌ ๋””๋ฒ„๊น… ๋„๊ตฌ ํฌํ•จ
command: ["sleep", "3600"]       # 1์‹œ๊ฐ„ ๋™์•ˆ ์œ ์ง€
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_PTRACE"]
tolerations:
- operator: "Exists"  # ๋ชจ๋“  ๋…ธ๋“œ์— ์Šค์ผ€์ค„ ๊ฐ€๋Šฅ
# ์‚ฌ์šฉ ํ›„: kubectl delete pod debug-session -n production
๋ ˆ์‹œํ”ผ 5: Init Container์™€ restartPolicy ์กฐํ•ฉ

Init Container๋Š” ๋ฉ”์ธ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹œ์ž‘๋˜๊ธฐ ์ „์— ์‹คํ–‰๋˜๋Š” ํŠน์ˆ˜ ์ปจํ…Œ์ด๋„ˆ์•ผ. Init Container์˜ ์žฌ์‹œ์ž‘ ๋™์ž‘์€ Pod์˜ restartPolicy์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ ธ.

apiVersion: v1
kind: Pod
metadata:
name: app-with-init
spec:
restartPolicy: Always
initContainers:
- name: wait-for-db
image: busybox:latest
command:
- sh
- -c
- |
until nc -z db-service 5432; do
echo "DB ๋Œ€๊ธฐ ์ค‘..."
sleep 2
done
echo "DB ์—ฐ๊ฒฐ ํ™•์ธ!"
- name: run-migrations
image: flyway:9.0
command: ["flyway", "migrate"]
env:
- name: FLYWAY_URL
value: "jdbc:postgresql://db-service:5432/mydb"
containers:
- name: app
image: my-app:1.0
ports:
- containerPort: 8080
๐Ÿ’ก Init Container์™€ restartPolicy
โ€ข Always: Init Container๊ฐ€ ์‹คํŒจํ•˜๋ฉด ์žฌ์‹œ์ž‘. ์„ฑ๊ณตํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์‹œ๋„.
โ€ข OnFailure: Init Container๊ฐ€ ์‹คํŒจํ•˜๋ฉด ์žฌ์‹œ์ž‘. ์„ฑ๊ณตํ•˜๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋กœ.
โ€ข Never: Init Container๊ฐ€ ์‹คํŒจํ•˜๋ฉด Pod ์ „์ฒด๊ฐ€ Failed ์ƒํƒœ.

Init Container๋Š” ํ•ญ์ƒ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰๋˜๊ณ , ์ด์ „ Init Container๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ ๋‹ค์Œ Init Container๊ฐ€ ์‹œ์ž‘๋ผ!

๐Ÿง  ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„(Exponential Backoff) ๊นŠ์ด ํŒŒ๊ธฐ
๋ฐฑ์˜คํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ž€?

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

์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ (Exponential Backoff) ์‹œ๊ฐํ™” 0์ดˆ 50์ดˆ 100์ดˆ 150์ดˆ 200์ดˆ 10์ดˆ 1๋ฒˆ์งธ 20์ดˆ 2๋ฒˆ์งธ 40์ดˆ 3๋ฒˆ์งธ 80์ดˆ 4๋ฒˆ์งธ 160์ดˆ 5๋ฒˆ์งธ 300์ดˆ(์ตœ๋Œ€) 6๋ฒˆ์งธ~ ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ์ง€์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ (์ตœ๋Œ€ 5๋ถ„)

๋ฐฑ์˜คํ”„ ๊ณต์‹์€ ๊ฐ„๋‹จํ•ด: ๋Œ€๊ธฐ ์‹œ๊ฐ„ = min(2^n ร— 10์ดˆ, 300์ดˆ)

# ๋ฐฑ์˜คํ”„ ๊ณ„์‚ฐ ์˜ˆ์‹œ
1๋ฒˆ์งธ ์žฌ์‹œ์ž‘: 2^0 ร— 10 = 10์ดˆ
2๋ฒˆ์งธ ์žฌ์‹œ์ž‘: 2^1 ร— 10 = 20์ดˆ
3๋ฒˆ์งธ ์žฌ์‹œ์ž‘: 2^2 ร— 10 = 40์ดˆ
4๋ฒˆ์งธ ์žฌ์‹œ์ž‘: 2^3 ร— 10 = 80์ดˆ
5๋ฒˆ์งธ ์žฌ์‹œ์ž‘: 2^4 ร— 10 = 160์ดˆ
6๋ฒˆ์งธ ์žฌ์‹œ์ž‘: 2^5 ร— 10 = 320์ดˆ โ†’ 300์ดˆ(์ตœ๋Œ€)๋กœ ์ œํ•œ
7๋ฒˆ์งธ ์ดํ›„: ๊ณ„์† 300์ดˆ ๊ฐ„๊ฒฉ
๋ฐฑ์˜คํ”„ ๋ฆฌ์…‹ ์กฐ๊ฑด

์ค‘์š”ํ•œ ์ ์€ ๋ฐฑ์˜คํ”„ ํƒ€์ด๋จธ๊ฐ€ ๋ฆฌ์…‹๋˜๋Š” ์กฐ๊ฑด์ด์•ผ. ์ปจํ…Œ์ด๋„ˆ๊ฐ€ 10๋ถ„ ์ด์ƒ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉด ๋ฐฑ์˜คํ”„ ์นด์šดํ„ฐ๊ฐ€ ๋ฆฌ์…‹๋ผ. ์ฆ‰, 10๋ถ„ ์ด์ƒ ์‚ด์•„์žˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ์ฃฝ์œผ๋ฉด ์ฒ˜์Œ๋ถ€ํ„ฐ 10์ดˆ ๋Œ€๊ธฐ๋กœ ์‹œ์ž‘ํ•ด.

๐Ÿ”‘ ํ•ต์‹ฌ ํฌ์ธํŠธ
๋ฐฑ์˜คํ”„ ๋ฆฌ์…‹ ์กฐ๊ฑด: ์ปจํ…Œ์ด๋„ˆ๊ฐ€ 10๋ถ„(600์ดˆ) ์ด์ƒ ์ •์ƒ ์‹คํ–‰

์ด ๋•Œ๋ฌธ์— "10๋ถ„๋งˆ๋‹ค ์ฃฝ๋Š”" ์ปจํ…Œ์ด๋„ˆ๋Š” ๋ฐฑ์˜คํ”„๊ฐ€ ๋ฆฌ์…‹๋˜์–ด ๊ณ„์† 10์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ์žฌ์‹œ์ž‘์„ ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ์–ด. ์ด๋Ÿฐ ํŒจํ„ด์„ ๋ฐœ๊ฒฌํ•˜๋ฉด ๊ทผ๋ณธ ์›์ธ์„ ์ฐพ์•„์•ผ ํ•ด!
CrashLoopBackOff ํƒˆ์ถœ ์ „๋žต

CrashLoopBackOff ์ƒํƒœ์—์„œ ๋น ์ ธ๋‚˜์˜ค๋Š” ์‹ค์ „ ์ „๋žต๋“ค์„ ์•Œ์•„๋ณด์ž.

์ „๋žต 1: ๋กœ๊ทธ ํ™•์ธ

# ํ˜„์žฌ ์ปจํ…Œ์ด๋„ˆ ๋กœ๊ทธ
kubectl logs pod-name -c container-name

# ์ด์ „ ์ปจํ…Œ์ด๋„ˆ ๋กœ๊ทธ (ํฌ๋ž˜์‹œ ์ง์ „ ๋กœ๊ทธ)
kubectl logs pod-name -c container-name --previous

# ์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ ์ŠคํŠธ๋ฆฌ๋ฐ
kubectl logs pod-name -f

# ๋งˆ์ง€๋ง‰ 100์ค„๋งŒ
kubectl logs pod-name --tail=100

์ „๋žต 2: Pod ์ด๋ฒคํŠธ ํ™•์ธ

kubectl describe pod pod-name

# Events ์„น์…˜์—์„œ ํ™•์ธ:
# Warning  BackOff    2m    kubelet  Back-off restarting failed container
# Normal   Pulled     5m    kubelet  Successfully pulled image
# Warning  Failed     5m    kubelet  Error: OOMKilled

์ „๋žต 3: ์ž„์‹œ sleep ๋ช…๋ น์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ์œ ์ง€

# ๋””๋ฒ„๊น…์„ ์œ„ํ•ด ์›๋ž˜ ๋ช…๋ น ๋Œ€์‹  sleep์œผ๋กœ ๊ต์ฒด
kubectl patch pod crashing-pod -p '{"spec":{"containers":[{"name":"app","command":["sleep","infinity"]}]}}'

# ๋˜๋Š” ์ƒˆ Pod๋ฅผ sleep์œผ๋กœ ์ƒ์„ฑ
kubectl run debug-pod --image=my-app:1.0 --command -- sleep infinity

# ๊ทธ ๋‹ค์Œ exec๋กœ ๋“ค์–ด๊ฐ€์„œ ์ง์ ‘ ํ™•์ธ
kubectl exec -it debug-pod -- /bin/sh

์ „๋žต 4: ๋ฆฌ์†Œ์Šค ์ œํ•œ ํ™•์ธ

# OOMKilled ํ™•์ธ
kubectl describe pod pod-name | grep -A5 "Last State"

# ์ถœ๋ ฅ ์˜ˆ์‹œ:
# Last State:     Terminated
#   Reason:       OOMKilled  โ† ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ!
#   Exit Code:    137
#
# ํ•ด๊ฒฐ: resources.limits.memory ๊ฐ’์„ ๋Š˜๋ ค์ค˜

๐Ÿ”— ์›Œํฌ๋กœ๋“œ ๋ฆฌ์†Œ์Šค๋ณ„ restartPolicy ์ œ์•ฝ
๊ฐ ๋ฆฌ์†Œ์Šค๊ฐ€ ์ง€์›ํ•˜๋Š” restartPolicy

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ ๋‹ค์–‘ํ•œ ์›Œํฌ๋กœ๋“œ ๋ฆฌ์†Œ์Šค๋“ค์€ ๊ฐ์ž ์ง€์›ํ•˜๋Š” restartPolicy๊ฐ€ ๋‹ฌ๋ผ. ์ด๊ฑธ ๋ชจ๋ฅด๋ฉด YAML ์ž‘์„ฑํ•  ๋•Œ ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚˜๊ฒŒ ๋ผ!

๋ฆฌ์†Œ์Šค ์ข…๋ฅ˜ ์ง€์› restartPolicy ์ด์œ 
Deployment Always๋งŒ ํ•ญ์ƒ ์ง€์ •๋œ ์ˆ˜์˜ Pod๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•จ
ReplicaSet Always๋งŒ ๋ ˆํ”Œ๋ฆฌ์นด ์ˆ˜๋ฅผ ํ•ญ์ƒ ์œ ์ง€ํ•ด์•ผ ํ•จ
StatefulSet Always๋งŒ ์ƒํƒœ ์œ ์ง€ ์„œ๋น„์Šค๋Š” ํ•ญ์ƒ ์‹คํ–‰๋˜์–ด์•ผ ํ•จ
DaemonSet Always๋งŒ ๋ชจ๋“  ๋…ธ๋“œ์—์„œ ํ•ญ์ƒ ์‹คํ–‰๋˜์–ด์•ผ ํ•จ
Job OnFailure, Never ์ž‘์—… ์™„๋ฃŒ ํ›„ ์ข…๋ฃŒ๋˜์–ด์•ผ ํ•จ
CronJob OnFailure, Never Job์„ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ๋™์ผํ•œ ์ œ์•ฝ
๋‹จ๋… Pod Always, OnFailure, Never ์ œ์•ฝ ์—†์Œ
โš ๏ธ ํ”ํ•œ ์‹ค์ˆ˜!
Job์—์„œ restartPolicy: Always๋ฅผ ์“ฐ๋ฉด ์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋‚˜:
The Job "my-job" is invalid: spec.template.spec.restartPolicy: Unsupported value: "Always": supported values: "OnFailure", "Never"


Job ์ž‘์„ฑํ•  ๋•Œ ๊ผญ OnFailure ๋˜๋Š” Never๋ฅผ ์จ์•ผ ํ•ด!
Deployment vs Job: ์–ธ์ œ ๋ญ˜ ์จ์•ผ ํ• ๊นŒ?
Deployment vs Job ์„ ํƒ ๊ฐ€์ด๋“œ ๐Ÿš€ Deployment restartPolicy: Always โœ… ์›น ์„œ๋ฒ„, API ์„œ๋ฒ„ โœ… ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค โœ… ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ”„๋ก์‹œ โœ… ๋ฉ”์‹œ์ง€ ํ ์ปจ์Šˆ๋จธ โœ… ๋ชจ๋‹ˆํ„ฐ๋ง ์—์ด์ „ํŠธ โ†’ 24/7 ํ•ญ์ƒ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์„œ๋น„์Šค โš™๏ธ Job / CronJob restartPolicy: OnFailure / Never โœ… ๋ฐ์ดํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ โœ… ๋ฆฌํฌํŠธ ์ƒ์„ฑ โœ… ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋ฐฐ์น˜ โœ… ๋ฐ์ดํ„ฐ ์ •๋ฆฌ ์ž‘์—… โœ… ์ฃผ๊ธฐ์  ์ง‘๊ณ„ ์ž‘์—… โ†’ ์™„๋ฃŒ ํ›„ ์ข…๋ฃŒ๋˜์–ด์•ผ ํ•˜๋Š” ์ž‘์—…

๐Ÿ›ก๏ธ Liveness Probe์™€ restartPolicy์˜ ์‹œ๋„ˆ์ง€
Probe๊ฐ€ restartPolicy์™€ ๋งŒ๋‚˜๋ฉด?

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—๋Š” ์ปจํ…Œ์ด๋„ˆ์˜ ์ƒํƒœ๋ฅผ ์ฒดํฌํ•˜๋Š” Probe ๊ธฐ๋Šฅ์ด ์žˆ์–ด. ์ด Probe๊ฐ€ restartPolicy์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋ฉด ํ›จ์”ฌ ๊ฐ•๋ ฅํ•œ ์ž๊ฐ€ ์น˜์œ (Self-healing) ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด.

์„ธ ๊ฐ€์ง€ ์ฃผ์š” Probe๋ฅผ ์•Œ์•„๋ณด์ž:

๐Ÿ”ด Liveness Probe

"์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‚ด์•„์žˆ๋‚˜?"๋ฅผ ์ฒดํฌ.
์‹คํŒจํ•˜๋ฉด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์žฌ์‹œ์ž‘.
๋ฐ๋“œ๋ฝ ์ƒํƒœ ๊ฐ์ง€์— ์œ ์šฉ.
๐ŸŸก Readiness Probe

"ํŠธ๋ž˜ํ”ฝ ๋ฐ›์„ ์ค€๋น„๋๋‚˜?"๋ฅผ ์ฒดํฌ.
์‹คํŒจํ•˜๋ฉด ์„œ๋น„์Šค์—์„œ ์ œ์™ธ.
์žฌ์‹œ์ž‘์€ ํ•˜์ง€ ์•Š์Œ.
๐ŸŸข Startup Probe

"์•ฑ์ด ์‹œ์ž‘๋๋‚˜?"๋ฅผ ์ฒดํฌ.
์„ฑ๊ณต ์ „๊นŒ์ง€ ๋‹ค๋ฅธ Probe ๋น„ํ™œ์„ฑํ™”.
๋А๋ฆฐ ์‹œ์ž‘ ์•ฑ์— ์œ ์šฉ.
apiVersion: v1
kind: Pod
metadata:
name: robust-app
spec:
restartPolicy: Always
containers:
- name: app
image: my-app:1.0
ports:
- containerPort: 8080

# ์‹œ์ž‘ ์ฒดํฌ: ์ตœ๋Œ€ 5๋ถ„(30์ดˆ ร— 10ํšŒ) ๋Œ€๊ธฐ
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 10

# ์ƒ์กด ์ฒดํฌ: ์‹คํŒจ ์‹œ ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 0  # startupProbe ์„ฑ๊ณต ํ›„ ์‹œ์ž‘
periodSeconds: 10
failureThreshold: 3     # 3๋ฒˆ ์—ฐ์† ์‹คํŒจ ์‹œ ์žฌ์‹œ์ž‘
timeoutSeconds: 5

# ์ค€๋น„ ์ฒดํฌ: ์‹คํŒจ ์‹œ ์„œ๋น„์Šค์—์„œ ์ œ์™ธ (์žฌ์‹œ์ž‘ ์—†์Œ)
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
failureThreshold: 3
Liveness Probe ์‹คํŒจ ์‹œ ๋™์ž‘ ํ๋ฆ„

Liveness Probe๊ฐ€ ์‹คํŒจํ•˜๋ฉด kubelet์ด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ฐ•์ œ ์ข…๋ฃŒ(kill)ํ•˜๊ณ , restartPolicy์— ๋”ฐ๋ผ ์žฌ์‹œ์ž‘ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ด.

# Liveness Probe ์‹คํŒจ ์ด๋ฒคํŠธ ํ™•์ธ
kubectl describe pod my-pod

# ์ด๋ฒคํŠธ ์˜ˆ์‹œ:
# Warning  Unhealthy  5m  kubelet  Liveness probe failed: HTTP probe failed with statuscode: 503
# Normal   Killing    5m  kubelet  Container app failed liveness probe, will be restarted
# Normal   Pulled     4m  kubelet  Container image "my-app:1.0" already present on machine
# Normal   Created    4m  kubelet  Created container app
# Normal   Started    4m  kubelet  Started container app
๐Ÿ’ก Liveness Probe ์„ค๊ณ„ ํŒ
โ€ข Liveness Probe๋Š” ๊ฐ€๋ณ๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•ด. DB ์ฟผ๋ฆฌ๋‚˜ ์™ธ๋ถ€ ์„œ๋น„์Šค ํ˜ธ์ถœ์€ ํ”ผํ•ด.
โ€ข ์•ฑ ๋‚ด๋ถ€ ์ƒํƒœ(๋ฐ๋“œ๋ฝ, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋“ฑ)๋งŒ ์ฒดํฌํ•˜๋Š” ๊ฒŒ ์ด์ƒ์ .
โ€ข failureThreshold๋ฅผ ๋„ˆ๋ฌด ๋‚ฎ๊ฒŒ ์„ค์ •ํ•˜๋ฉด ์ผ์‹œ์ ์ธ ๋ถ€ํ•˜ ์ƒํ™ฉ์—์„œ ๋ถˆํ•„์š”ํ•œ ์žฌ์‹œ์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด.
โ€ข initialDelaySeconds๋Š” ์•ฑ ์‹œ์ž‘ ์‹œ๊ฐ„๋ณด๋‹ค ์ถฉ๋ถ„ํžˆ ํฌ๊ฒŒ ์„ค์ •ํ•ด์•ผ ํ•ด. (Startup Probe๋ฅผ ์“ฐ๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ๋” ์šฐ์•„ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด!)

๐ŸŽฏ ์‹ค๋ฌด์—์„œ ์ž์ฃผ ํ•˜๋Š” ์‹ค์ˆ˜์™€ ํ•ด๊ฒฐ์ฑ…
์‹ค์ˆ˜ 1: ๋ฐฐ์น˜ ์ž‘์—…์— Always ์‚ฌ์šฉ

๊ฐ€์žฅ ํ”ํ•œ ์‹ค์ˆ˜์•ผ. ๋ฐฐ์น˜ ์ž‘์—…์„ ๋‹จ๋… Pod๋กœ ๋งŒ๋“ค๋ฉด์„œ restartPolicy๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์ธ Always๊ฐ€ ์ ์šฉ๋ผ.

# โŒ ์ž˜๋ชป๋œ ์˜ˆ์‹œ - ์ž‘์—… ์™„๋ฃŒ ํ›„ ๋ฌดํ•œ ์žฌ์‹œ์ž‘!
apiVersion: v1
kind: Pod
metadata:
name: data-processor
spec:
# restartPolicy ์—†์Œ โ†’ ๊ธฐ๋ณธ๊ฐ’ Always ์ ์šฉ!
containers:
- name: processor
image: my-processor:1.0
command: ["python", "process.py"]

---
# โœ… ์˜ฌ๋ฐ”๋ฅธ ์˜ˆ์‹œ
apiVersion: v1
kind: Pod
metadata:
name: data-processor
spec:
restartPolicy: OnFailure  # ๋˜๋Š” Never
containers:
- name: processor
image: my-processor:1.0
command: ["python", "process.py"]
์‹ค์ˆ˜ 2: OOMKilled๋ฅผ ์•ฑ ๋ฒ„๊ทธ๋กœ ์˜คํ•ด

์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ณ„์† ์žฌ์‹œ์ž‘๋˜๋Š”๋ฐ ๋กœ๊ทธ์— ์•„๋ฌด๊ฒƒ๋„ ์—†๋‹ค๋ฉด? OOMKilled์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„. ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์œผ๋กœ OS๊ฐ€ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฐ•์ œ ์ข…๋ฃŒํ•œ ๊ฑฐ์•ผ.

# OOMKilled ํ™•์ธ ๋ฐฉ๋ฒ•
kubectl describe pod my-pod | grep -A 10 "Last State"

# ์ถœ๋ ฅ:
# Last State:     Terminated
#   Reason:       OOMKilled
#   Exit Code:    137    โ† 128 + 9(SIGKILL) = 137
#   Started:      ...
#   Finished:     ...

# ํ•ด๊ฒฐ: ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ ์ฆ๊ฐ€
spec:
containers:
- name: app
resources:
limits:
memory: "1Gi"  # ๊ธฐ์กด 512Mi์—์„œ ์ฆ๊ฐ€
requests:
memory: "512Mi"
์‹ค์ˆ˜ 3: ๋ฉฑ๋“ฑ์„ฑ ์—†๋Š” ์ž‘์—…์— OnFailure ์‚ฌ์šฉ

์ด๋ฉ”์ผ ๋ฐœ์†ก, ๊ฒฐ์ œ ์ฒ˜๋ฆฌ์ฒ˜๋Ÿผ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์ž‘์—…์— OnFailure๋ฅผ ์“ฐ๋ฉด ์žฌ์‹œ๋„ ์‹œ ์ค‘๋ณต ์‹คํ–‰์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด.

# โŒ ์œ„ํ—˜ํ•œ ์˜ˆ์‹œ - ์ด๋ฉ”์ผ์ด ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐœ์†ก๋  ์ˆ˜ ์žˆ์Œ!
apiVersion: batch/v1
kind: Job
metadata:
name: send-newsletter
spec:
template:
spec:
restartPolicy: OnFailure  # ์‹คํŒจ ์‹œ ์žฌ์‹œ๋„ โ†’ ์ด๋ฉ”์ผ ์ค‘๋ณต ๋ฐœ์†ก!
containers:
- name: mailer
image: mailer:1.0

---
# โœ… ์•ˆ์ „ํ•œ ์˜ˆ์‹œ - ๋ฉฑ๋“ฑ์„ฑ ์—†๋Š” ์ž‘์—…์€ Never ์‚ฌ์šฉ
apiVersion: batch/v1
kind: Job
metadata:
name: send-newsletter
spec:
backoffLimit: 0  # ์žฌ์‹œ๋„ ์—†์Œ
template:
spec:
restartPolicy: Never  # ์‹คํŒจํ•ด๋„ ์žฌ์‹œ์ž‘ ์—†์Œ
containers:
- name: mailer
image: mailer:1.0
# ์•ฑ ๋ ˆ๋ฒจ์—์„œ ์ค‘๋ณต ๋ฐฉ์ง€ ๋กœ์ง ๊ตฌํ˜„ ํ•„์š”
์‹ค์ˆ˜ 4: Liveness Probe ๋„ˆ๋ฌด ๊ณต๊ฒฉ์ ์œผ๋กœ ์„ค์ •
# โŒ ๋„ˆ๋ฌด ๊ณต๊ฒฉ์ ์ธ ์„ค์ • - ๋ถ€ํ•˜ ์‹œ ๋ถˆํ•„์š”ํ•œ ์žฌ์‹œ์ž‘ ๋ฐœ์ƒ
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5   # ๋„ˆ๋ฌด ์งง์Œ
periodSeconds: 5          # ๋„ˆ๋ฌด ์ž์ฃผ
failureThreshold: 1       # 1๋ฒˆ๋งŒ ์‹คํŒจํ•ด๋„ ์žฌ์‹œ์ž‘!
timeoutSeconds: 1         # ๋„ˆ๋ฌด ์งง์Œ

---
# โœ… ์ ์ ˆํ•œ ์„ค์ •
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30   # ์•ฑ ์‹œ์ž‘ ์‹œ๊ฐ„ ๊ณ ๋ ค
periodSeconds: 10          # 10์ดˆ๋งˆ๋‹ค ์ฒดํฌ
failureThreshold: 3        # 3๋ฒˆ ์—ฐ์† ์‹คํŒจ ์‹œ ์žฌ์‹œ์ž‘
timeoutSeconds: 5          # 5์ดˆ ํƒ€์ž„์•„์›ƒ
์‹ค์ˆ˜ 5: ์žฌ์‹œ์ž‘ ์ •์ฑ…๊ณผ Pod Disruption Budget ํ˜ผ๋™

restartPolicy๋Š” ์ปจํ…Œ์ด๋„ˆ ๋ ˆ๋ฒจ์˜ ์žฌ์‹œ์ž‘์„ ์ œ์–ดํ•˜์ง€๋งŒ, Pod Disruption Budget(PDB)์€ ํด๋Ÿฌ์Šคํ„ฐ ๋ ˆ๋ฒจ์—์„œ Pod์˜ ๊ฐ€์šฉ์„ฑ์„ ๋ณด์žฅํ•ด. ์ด ๋‘˜์€ ๋‹ค๋ฅธ ๊ฐœ๋…์ด์•ผ!

# PDB: ์ตœ์†Œ 2๊ฐœ์˜ Pod๊ฐ€ ํ•ญ์ƒ ์‹คํ–‰๋˜๋„๋ก ๋ณด์žฅ
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web-api
# ์ด๊ฑด restartPolicy์™€ ๋ณ„๊ฐœ๋กœ ๋™์ž‘ํ•ด!

๐Ÿ“Š restartPolicy ์„ ํƒ ํ”Œ๋กœ์šฐ์ฐจํŠธ
restartPolicy ์„ ํƒ ๊ฐ€์ด๋“œ ์ž‘์—… ์œ ํ˜•์€? 24/7 ํ•ญ์ƒ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์žฅ๊ธฐ ์‹คํ–‰ ์„œ๋น„์Šค์ธ๊ฐ€? โœ… Always Deployment/StatefulSet ๋“ฑ YES ์™„๋ฃŒ ํ›„ ์ข…๋ฃŒ๋˜๋Š” ์ผํšŒ์„ฑ ๋˜๋Š” ๋ฐฐ์น˜ ์ž‘์—…์ธ๊ฐ€? NO ์‹คํŒจ ์‹œ ์ž๋™ ์žฌ์‹œ๋„๊ฐ€ ํ•„์š”ํ•œ๊ฐ€? (๋ฉฑ๋“ฑ์„ฑ ๋ณด์žฅ?) YES โš ๏ธ OnFailure Job + backoffLimit ์„ค์ • YES ๐Ÿšซ Never ๋””๋ฒ„๊น…, ๋‹จ๋ฐœ์„ฑ, ๋ฉฑ๋“ฑ์„ฑ ์—†๋Š” ์ž‘์—… NO

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


๐Ÿ”ง ๊ณ ๊ธ‰ ํŒจํ„ด: restartPolicy ํ™œ์šฉ ์•„ํ‚คํ…์ฒ˜
ํŒจํ„ด 1: Sidecar ํŒจํ„ด๊ณผ Always

์‚ฌ์ด๋“œ์นด ํŒจํ„ด์€ ๋ฉ”์ธ ์ปจํ…Œ์ด๋„ˆ ์˜†์— ๋ณด์กฐ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ถ™์ด๋Š” ํŒจํ„ด์ด์•ผ. ๋กœ๊ทธ ์ˆ˜์ง‘, ํ”„๋ก์‹œ, ๋ชจ๋‹ˆํ„ฐ๋ง ๋“ฑ์— ํ™œ์šฉํ•ด.

apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
restartPolicy: Always  # ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ์— ์ ์šฉ
containers:
# ๋ฉ”์ธ ์•ฑ
- name: main-app
image: my-app:1.0
ports:
- containerPort: 8080

# ๋กœ๊ทธ ์ˆ˜์ง‘ ์‚ฌ์ด๋“œ์นด
- name: log-collector
image: fluentd:v1.16
volumeMounts:
- name: app-logs
mountPath: /var/log/app

# ํ”„๋ก์‹œ ์‚ฌ์ด๋“œ์นด (Envoy)
- name: envoy-proxy
image: envoyproxy/envoy:v1.28
ports:
- containerPort: 9901

volumes:
- name: app-logs
emptyDir: {}
ํŒจํ„ด 2: ์›Œํฌํ”Œ๋กœ์šฐ ํŒจํ„ด (Job ์ฒด์ด๋‹)

์—ฌ๋Ÿฌ Job์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•˜๋Š” ์›Œํฌํ”Œ๋กœ์šฐ ํŒจํ„ด์ด์•ผ. ๊ฐ Job์ด ์™„๋ฃŒ๋˜๋ฉด ๋‹ค์Œ Job์„ ํŠธ๋ฆฌ๊ฑฐํ•ด.

# 1๋‹จ๊ณ„: ๋ฐ์ดํ„ฐ ์ถ”์ถœ
apiVersion: batch/v1
kind: Job
metadata:
name: step1-extract
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: extractor
image: etl:1.0
command: ["python", "extract.py"]

---
# 2๋‹จ๊ณ„: ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ (step1 ์™„๋ฃŒ ํ›„ ์‹คํ–‰)
apiVersion: batch/v1
kind: Job
metadata:
name: step2-transform
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: transformer
image: etl:1.0
command: ["python", "transform.py"]

---
# 3๋‹จ๊ณ„: ๋ฐ์ดํ„ฐ ๋กœ๋“œ (step2 ์™„๋ฃŒ ํ›„ ์‹คํ–‰)
apiVersion: batch/v1
kind: Job
metadata:
name: step3-load
spec:
template:
spec:
restartPolicy: Never  # ๋ฉฑ๋“ฑ์„ฑ ์—†๋Š” ์ž‘์—…
containers:
- name: loader
image: etl:1.0
command: ["python", "load.py"]
ํŒจํ„ด 3: ์ž๊ฐ€ ์น˜์œ  ์‹œ์Šคํ…œ ๊ตฌ์ถ•

restartPolicy + Liveness Probe + PodDisruptionBudget์„ ์กฐํ•ฉํ•ด์„œ ์ง„์ •ํ•œ ์ž๊ฐ€ ์น˜์œ  ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด.

---
# 1. Deployment: ํ•ญ์ƒ 3๊ฐœ ๋ ˆํ”Œ๋ฆฌ์นด ์œ ์ง€
apiVersion: apps/v1
kind: Deployment
metadata:
name: resilient-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
restartPolicy: Always
containers:
- name: app
image: my-app:1.0
livenessProbe:
httpGet:
path: /health
port: 8080
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5

---
# 2. PodDisruptionBudget: ์ตœ์†Œ 2๊ฐœ ํ•ญ์ƒ ์œ ์ง€
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: resilient-app-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: resilient-app

---
# 3. HorizontalPodAutoscaler: ๋ถ€ํ•˜์— ๋”ฐ๋ผ ์ž๋™ ์Šค์ผ€์ผ
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: resilient-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: resilient-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
๐Ÿ’ก ์žฌ๋Šฅ๋„ท์—์„œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ „๋ฌธ๊ฐ€ ์ฐพ๊ธฐ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์„ค์ •์ด ๋ณต์žกํ•˜๊ฒŒ ๋А๊ปด์ง„๋‹ค๋ฉด, ์žฌ๋Šฅ๋„ท์—์„œ DevOps ์ „๋ฌธ๊ฐ€์˜ ๋„์›€์„ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ์–ด. ํด๋Ÿฌ์Šคํ„ฐ ์„ค๊ณ„๋ถ€ํ„ฐ ์šด์˜ ์ž๋™ํ™”๊นŒ์ง€ ๋‹ค์–‘ํ•œ ์ „๋ฌธ๊ฐ€๋“ค์ด ํ™œ๋™ํ•˜๊ณ  ์žˆ๊ฑฐ๋“ !

๐Ÿ“ˆ ๋ชจ๋‹ˆํ„ฐ๋ง๊ณผ ์•Œ๋ฆผ ์„ค์ •
์žฌ์‹œ์ž‘ ํšŸ์ˆ˜ ๋ชจ๋‹ˆํ„ฐ๋ง

restartPolicy๋ฅผ ์ž˜ ์„ค์ •ํ–ˆ๋‹ค๊ณ  ํ•ด๋„, ์‹ค์ œ๋กœ ์–ผ๋งˆ๋‚˜ ์žฌ์‹œ์ž‘์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ด. Prometheus + Grafana ์กฐํ•ฉ์œผ๋กœ ์ด๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์–ด.

# Prometheus ์ฟผ๋ฆฌ: Pod ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜
kube_pod_container_status_restarts_total

# ํŠน์ • ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜
kube_pod_container_status_restarts_total{namespace="production"}

# ์ง€๋‚œ 1์‹œ๊ฐ„ ๋™์•ˆ ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜ ์ฆ๊ฐ€
increase(kube_pod_container_status_restarts_total[1h])

# ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜๊ฐ€ 5 ์ด์ƒ์ธ Pod ์•Œ๋ฆผ
kube_pod_container_status_restarts_total > 5
# Prometheus AlertManager ๊ทœ์น™ ์˜ˆ์‹œ
groups:
- name: pod-restart-alerts
rules:
- alert: PodCrashLooping
expr: |
increase(kube_pod_container_status_restarts_total[15m]) > 3
for: 5m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} ํฌ๋ž˜์‹œ ๋ฃจํ”„ ๊ฐ์ง€"
description: "{{ $labels.namespace }}/{{ $labels.pod }}์˜ {{ $labels.container }} ์ปจํ…Œ์ด๋„ˆ๊ฐ€ 15๋ถ„ ๋‚ด 3๋ฒˆ ์ด์ƒ ์žฌ์‹œ์ž‘๋จ"

- alert: PodFrequentlyRestarting
expr: |
kube_pod_container_status_restarts_total > 10
for: 1m
labels:
severity: critical
annotations:
summary: "Pod {{ $labels.pod }} ๋นˆ๋ฒˆํ•œ ์žฌ์‹œ์ž‘"
description: "์ด ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜: {{ $value }}"
kubectl๋กœ ์žฌ์‹œ์ž‘ ํ˜„ํ™ฉ ๋น ๋ฅด๊ฒŒ ํ™•์ธ
# ๋ชจ๋“  Pod์˜ ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜ ํ™•์ธ
kubectl get pods --all-namespaces | sort -k5 -rn

# ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜๊ฐ€ ๋งŽ์€ Pod ์ฐพ๊ธฐ
kubectl get pods -A -o custom-columns=\
'NAMESPACE:.metadata.namespace,NAME:.metadata.name,RESTARTS:.status.containerStatuses[0].restartCount' \
| sort -k3 -rn | head -20

# ํŠน์ • Pod์˜ ์ƒ์„ธ ์žฌ์‹œ์ž‘ ์ •๋ณด
kubectl get pod my-pod -o jsonpath='{.status.containerStatuses[*].restartCount}'

# ์žฌ์‹œ์ž‘ ์ค‘์ธ Pod๋งŒ ํ•„ํ„ฐ๋ง
kubectl get pods -A --field-selector=status.phase=Running | grep -v "0/\|1/1\|2/2\|3/3"

๐ŸŽ“ ์ •๋ฆฌ: restartPolicy ํ•ต์‹ฌ ์š”์•ฝ
๐ŸŽฏ restartPolicy ํ•ต์‹ฌ ์ •๋ฆฌ ๐Ÿ”„ Always ๊ธฐ๋ณธ๊ฐ’ ์ •์ƒ ์ข…๋ฃŒ โ†’ ์žฌ์‹œ์ž‘ โœ… ๋น„์ •์ƒ ์ข…๋ฃŒ โ†’ ์žฌ์‹œ์ž‘ โœ… ์‚ฌ์šฉ ๋ฆฌ์†Œ์Šค Deployment StatefulSet DaemonSet ์ฃผ์š” ์‚ฌ๋ก€ ์›น์„œ๋ฒ„, API, DB ์žฅ๊ธฐ ์‹คํ–‰ ์„œ๋น„์Šค 24/7 ์šด์˜ ํ•„์š” โš ๏ธ OnFailure ์‹คํŒจ ์‹œ์—๋งŒ ์žฌ์‹œ์ž‘ ์ •์ƒ ์ข…๋ฃŒ โ†’ ์žฌ์‹œ์ž‘ โŒ ๋น„์ •์ƒ ์ข…๋ฃŒ โ†’ ์žฌ์‹œ์ž‘ โœ… ์‚ฌ์šฉ ๋ฆฌ์†Œ์Šค Job CronJob ๋‹จ๋… Pod ์ฃผ์š” ์‚ฌ๋ก€ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ๋ฉฑ๋“ฑ์„ฑ ์žˆ๋Š” ์ž‘์—… ๐Ÿšซ Never ์ ˆ๋Œ€ ์žฌ์‹œ์ž‘ ์•ˆ ํ•จ ์ •์ƒ ์ข…๋ฃŒ โ†’ ์žฌ์‹œ์ž‘ โŒ ๋น„์ •์ƒ ์ข…๋ฃŒ โ†’ ์žฌ์‹œ์ž‘ โŒ ์‚ฌ์šฉ ๋ฆฌ์†Œ์Šค Job ๋‹จ๋… Pod (๋””๋ฒ„๊น…์šฉ) ์ฃผ์š” ์‚ฌ๋ก€ ๋””๋ฒ„๊น… ๋‹จ๋ฐœ์„ฑ ์ž‘์—… ๋ฉฑ๋“ฑ์„ฑ ์—†๋Š” ์ž‘์—… spec.restartPolicy ํ•„๋“œ ยท Pod ๋ ˆ๋ฒจ ์„ค์ • ยท ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ์— ๋™์ผ ์ ์šฉ

์ž, ์ด์ œ restartPolicy์— ๋Œ€ํ•ด ๊ฝค ๊นŠ์ด ํŒŒ๋ดค์–ด! ๋งˆ์ง€๋ง‰์œผ๋กœ ํ•ต์‹ฌ ํฌ์ธํŠธ๋“ค์„ ์ •๋ฆฌํ•ด๋ณผ๊ฒŒ.

๐Ÿ“Œ restartPolicy ํ•ต์‹ฌ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
  • 1 ๊ธฐ๋ณธ๊ฐ’์€ Always - ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด Always๊ฐ€ ์ ์šฉ๋จ
  • 2 Pod ๋ ˆ๋ฒจ ์„ค์ • - ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ์— ๋™์ผํ•˜๊ฒŒ ์ ์šฉ๋จ
  • 3 Deployment/StatefulSet/DaemonSet - Always๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • 4 Job/CronJob - OnFailure ๋˜๋Š” Never๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • 5 ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ - ์žฌ์‹œ์ž‘ ๊ฐ„๊ฒฉ์ด 10์ดˆ โ†’ 20์ดˆ โ†’ 40์ดˆ... ์ตœ๋Œ€ 5๋ถ„
  • 6 ๋ฐฑ์˜คํ”„ ๋ฆฌ์…‹ - 10๋ถ„ ์ด์ƒ ์ •์ƒ ์‹คํ–‰ ์‹œ ์นด์šดํ„ฐ ๋ฆฌ์…‹
  • 7 ๋ฉฑ๋“ฑ์„ฑ ๊ณ ๋ ค - ์ค‘๋ณต ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์ž‘์—…๋งŒ OnFailure ์‚ฌ์šฉ
  • 8 Liveness Probe ์กฐํ•ฉ - ๋ฐ๋“œ๋ฝ ๊ฐ์ง€ + ์ž๋™ ์žฌ์‹œ์ž‘์œผ๋กœ ์ž๊ฐ€ ์น˜์œ  ๊ตฌํ˜„

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ restartPolicy๋Š” ๋‹จ์ˆœํ•ด ๋ณด์ด์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ์‹œ์Šคํ…œ์˜ ์•ˆ์ •์„ฑ๊ณผ ์šด์˜ ํšจ์œจ์„ฑ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์ค‘์š”ํ•œ ์„ค์ •์ด์•ผ. ์ด ๊ธ€์—์„œ ๋ฐฐ์šด ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ฐ ์ƒํ™ฉ์— ๋งž๋Š” ์ •์ฑ…์„ ์„ ํƒํ•˜๋ฉด, ํ›จ์”ฌ ๋” ์•ˆ์ •์ ์ด๊ณ  ํšจ์œจ์ ์ธ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์šด์˜์ด ๊ฐ€๋Šฅํ•ด์งˆ ๊ฑฐ์•ผ! ๐Ÿ’ช

DevOps ๊ด€๋ จ ์ง€์‹์„ ๋” ์Œ“๊ณ  ์‹ถ๋‹ค๋ฉด ์žฌ๋Šฅ๋„ท์˜ ์ง€์‹์ธ์˜ ์ˆฒ์—์„œ ๋‹ค์–‘ํ•œ ์ „๋ฌธ๊ฐ€๋“ค์˜ ๊ธ€์„ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์–ด. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋ฟ๋งŒ ์•„๋‹ˆ๋ผ CI/CD, ํด๋ผ์šฐ๋“œ ์•„ํ‚คํ…์ฒ˜, ์ธํ”„๋ผ ์ž๋™ํ™” ๋“ฑ ๋‹ค์–‘ํ•œ DevOps ์ฃผ์ œ์˜ ์–‘์งˆ์˜ ์ฝ˜ํ…์ธ ๋“ค์ด ๊ฐ€๋“ํ•˜๊ฑฐ๋“ !

๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.