๐Ÿ“‚ Container & K8S

[K8S] EKS์—์„œ Graceful Shutdown ํ•˜๋Š” ๋ฐฉ๋ฒ•

dhyuck 2026. 9. 5. 22:56
๋ฐ˜์‘ํ˜•

Kubernetes์—์„œ Pod๋Š” ์ผ์‹œ์ ์ธ(ephemeral) ์—”ํ‹ฐํ‹ฐ๋กœ ๊ฐ„์ฃผ๋˜๊ณ  ๋‹ค์–‘ํ•œ ์ด์œ ๋กœ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ Pod์˜ ์ข…๋ฃŒ๋Š” ์˜ˆ์™ธ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ผ Kubernetes์˜ ์ •์ƒ์ ์ธ ๋™์ž‘์ž…๋‹ˆ๋‹ค.

Pod๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ ์ฆ‰์‹œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒํ•˜๋ฉด ์ฒ˜๋ฆฌ ์ค‘์ธ ์š”์ฒญ(in-flight requests)์ด ๊ฐ•์ œ๋กœ ์ค‘๋‹จ๋˜๋ฉด์„œ Timeout์ด๋‚˜ 5xx Error๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋ฅผ ์›ํ™œํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์•ˆ์ •์ ์ธ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๊ณ  ํ›Œ๋ฅญํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ํ•ต์‹ฌ์ ์ธ ์š”์†Œ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— Pod์˜ ์ข…๋ฃŒ ๊ณผ์ •์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ƒˆ๋กœ์šด ์š”์ฒญ์„ ๋ฐ›์ง€ ์•Š๋„๋ก ํ•˜๊ณ , ์ด๋ฏธ ์ฒ˜๋ฆฌ ์ค‘์ธ ์š”์ฒญ์„ ์ •์ƒ์ ์œผ๋กœ ์™„๋ฃŒํ•œ ๋’ค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ๋“ฑ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ์ข…๋ฃŒํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ข…๋ฃŒ ๋ฐฉ์‹์„ Graceful Shutdown์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

Pod ์‚ญ์ œ ์š”์ฒญ์ด Kubernetes API Server๋กœ ์ „๋‹ฌ๋˜๋ฉด API Server๋Š” Pod๋ฅผ ์‚ญ์ œ ๋Œ€์ƒ์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
์ด๋•Œ kubelet์€ ํ•ด๋‹น Pod์˜ ์ปจํ…Œ์ด๋„ˆ ์ข…๋ฃŒ ์ ˆ์ฐจ๋ฅผ ์‹œ์ž‘ํ•˜๊ณ , EndpointSlice Controller๋Š” ์ข…๋ฃŒ ์ค‘์ธ Pod๊ฐ€ ํŠธ๋ž˜ํ”ฝ ๋Œ€์ƒ์—์„œ ์ œ์™ธ๋  ์ˆ˜ ์žˆ๋„๋ก EndpointSlice์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

Graceful Shutdown์„ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ SIGTERM ์ฒ˜๋ฆฌํ•˜๊ธฐ

Kubelet์€ Container Runtime์„ ํ†ตํ•ด ๊ฐ ์ปจํ…Œ์ด๋„ˆ์˜ ๋ฉ”์ธ ํ”„๋กœ์„ธ์Šค(PID 1 ํ”„๋กœ์„ธ์Šค)์— ์ผ๋ฐ˜์ ์œผ๋กœ SIGTERM์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
Kubernetes๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฒ˜๋ฆฌ ์ค‘์ธ ์š”์ฒญ๊ณผ ๊ฐ™์€ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ SIGTERM์„ ๋ฐ›์œผ๋ฉด ์ฒ˜๋ฆฌ ์ค‘์ธ ์š”์ฒญ๊ณผ ์‚ฌ์šฉ ์ค‘์ธ ์ž์›์„ ์ •๋ฆฌํ•œ ๋’ค ์Šค์Šค๋กœ ์ข…๋ฃŒํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
๋งŒ์•ฝ SIGTERM์„ ๋ฌด์‹œํ•˜๊ฑฐ๋‚˜ Grace Period๊ฐ€ ๋งŒ๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒํ•˜์ง€ ๋ชปํ•˜๋ฉด Container Runtime์ด SIGKILL์„ ์ „๋‹ฌํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฐ•์ œ๋กœ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

preStop Hook ์‚ฌ์šฉํ•˜๊ธฐ

preStop์€ ์ปจํ…Œ์ด๋„ˆ์— SIGTERM์„ ์ „๋‹ฌํ•˜๊ธฐ ์ „์— ์‹คํ–‰๋˜๋Š” Kubernetes Lifecycle Hook์ž…๋‹ˆ๋‹ค. SIGTERM์œผ๋กœ ์ข…๋ฃŒ ์ฒ˜๋ฆฌ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, preStop์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ข…๋ฃŒ API๋‚˜ ๋ช…๋ น์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ, preStop์€ EndpointSlice ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด kube-proxy๋‚˜ Load Balancer๊นŒ์ง€ ์ „ํŒŒ๋˜๊ธฐ ์ „์— ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋จผ์ € ์ข…๋ฃŒ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ผ์ • ์‹œ๊ฐ„ ๋Œ€๊ธฐํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ข…๋ฃŒ ์ค‘์ธ Pod๊ฐ€ ํŠธ๋ž˜ํ”ฝ ๋Œ€์ƒ์—์„œ ์ œ์™ธ๋  ์‹œ๊ฐ„์„ ํ™•๋ณดํ•˜๊ณ , ์ข…๋ฃŒ ๊ณผ์ •์—์„œ ๋ฐœ์ƒ ํ•  ์ˆ˜ ์žˆ๋Š” Timeout์ด๋‚˜ 5xx Error๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

terminationGracePeriodSeconds ์„ค์ •ํ•˜๊ธฐ

terminationGracePeriodSeconds(Grace Period)๋Š” Kubernetes๊ฐ€ Pod์˜ ์ •์ƒ ์ข…๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ตœ๋Œ€ ์‹œ๊ฐ„์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์€ 30์ดˆ์ž…๋‹ˆ๋‹ค. ์ด ์‹œ๊ฐ„์ด ๋งŒ๋ฃŒ๋˜์—ˆ๋Š”๋ฐ๋„ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰ ์ค‘์ด๋ผ๋ฉด SIGKILL์„ ์ „๋‹ฌํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ฐ•์ œ๋กœ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

Grace Period๋Š” SIGTERM์ด ์ „๋‹ฌ๋˜๋Š” ์‹œ์ ์ด ์•„๋‹ˆ๋ผ preStop์ด ์‹คํ–‰๋˜๊ธฐ ์ „๋ถ€ํ„ฐ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ preStop ์‹คํ–‰ ์‹œ๊ฐ„๊ณผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ ์‹œ๊ฐ„์˜ ํ•ฉ์ด terminationGracePeriodSeconds๋ณด๋‹ค ๊ธธ๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ •๋ฆฌ ์ž‘์—…์„ ์™„๋ฃŒํ•˜๊ธฐ ์ „์— SIGKILL์— ์˜ํ•ด ๊ฐ•์ œ๋กœ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ Grace Period๋Š” preStop ์‹คํ–‰ ์‹œ๊ฐ„๊ณผ ์ตœ๋Œ€ in-flight request ์ฒ˜๋ฆฌ ์‹œ๊ฐ„, Connection ๋ฐ ์ž์› ์ •๋ฆฌ ์‹œ๊ฐ„์„ ๋ชจ๋‘ ๊ณ ๋ คํ•˜์—ฌ ์‚ฐ์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

EKS ELB Deregistration Delay ์„ค์ •ํ•˜๊ธฐ

Pod๊ฐ€ ์‚ญ์ œ๋กœ EndpointSlice๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด AWS Load Balancer Controller๋Š” ์ด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  target-type: ip ๋ผ๋ฉด ํ•ด๋‹น Pod IP๋ฅผ Target Group์—์„œ Deregisterํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ Target์ด ์ฆ‰์‹œ Deregister๋˜๋ฉด ์ฒ˜๋ฆฌ ์ค‘์ธ in-flight requests๊ฐ€ ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ์—ฐ๊ฒฐ์ด ์ค‘๋‹จ๋˜์–ด Timeout์ด๋‚˜ 5xx Error๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ Deregistration Delay๋ฅผ ์„ค์ •ํ•˜์—ฌ Target์„ ์ผ์ • ์‹œ๊ฐ„ draining ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ณ , ์ƒˆ๋กœ์šด ์š”์ฒญ์€ ์ „๋‹ฌํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ๊ธฐ์กด ์š”์ฒญ์„ ์ •์ƒ์ ์œผ๋กœ ์™„๋ฃŒํ•  ์‹œ๊ฐ„์„ ํ™•๋ณดํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด target-type: instance์—์„œ๋Š” ELB์˜ Target์ด Worker Node์ด๊ธฐ ๋•Œ๋ฌธ์—, Pod๊ฐ€ ์ข…๋ฃŒ๋˜์–ด๋„ ELB Target์˜ Deregistration์€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Pod ์ข…๋ฃŒ ์‹œ ํ•ด๋‹น Pod๋ฅผ ํŠธ๋ž˜ํ”ฝ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•˜๋Š” ์ฒ˜๋ฆฌ๋Š” ELB๊ฐ€ ์•„๋‹ˆ๋ผ EndpointSlice์™€ kube-proxy๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

Deregistration Delay์™€ terminationGracePeriodSeconds๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๊ณ„์ธต์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
Deregistration Delay๋Š” ELB๊ฐ€ ๊ธฐ์กด ์š”์ฒญ๊ณผ Connection์„ Drainํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์ด๊ณ ,
terminationGracePeriodSeconds๋Š” Kubernetes๊ฐ€ Pod ๋‚ด๋ถ€์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•