Post

[Kubernetes] Rollout & Pod/Container ์žฌ์‹œ์ž‘

๐Ÿ“Œ ๋“ค์–ด๊ฐ€๋ฉฐ

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ํŒŒ๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ต์ฒดํ•˜๋Š” Rollout(๋กค๋ง ์—…๋ฐ์ดํŠธ) ๋ฉ”์ปค๋‹ˆ์ฆ˜๊ณผ, Pod ์žฌ์‹œ์ž‘ vs ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘์˜ ์ฐจ์ด๋ฅผ ์ •๋ฆฌํ•œ๋‹ค. RESTARTSยทAGE๊ฐ€ ์™œ ๋ฐ”๋€Œ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  OOMKilled ๊ฐ™์€ ์žฌ์‹œ์ž‘ ์›์ธ์„ ์–ด๋–ป๊ฒŒ ์ง„๋‹จํ•˜๋Š”์ง€ ์‚ดํŽด๋ณธ๋‹ค.

ํ•ต์‹ฌ ๊ตฌ๋ถ„ โ€” Pod ์žฌ์‹œ์ž‘์€ ํŒŒ๋“œ๋ฅผ ์‚ญ์ œ ํ›„ ์žฌ์ƒ์„ฑ(IPยทAGE ์ดˆ๊ธฐํ™”)์ด๊ณ , ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘์€ ํŒŒ๋“œ๋Š” ์œ ์ง€ํ•œ ์ฑ„ ์ปจํ…Œ์ด๋„ˆ๋งŒ ๋‹ค์‹œ ๋œจ๋Š” ๊ฒƒ(RESTARTS ์ฆ๊ฐ€)์ด๋‹ค. ์›์ธ๊ณผ ์ฆ์ƒ์ด ์™„์ „ํžˆ ๋‹ค๋ฅด๋‹ค.


1. Pod ์žฌ์‹œ์ž‘ vs ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘

flowchart TB
    subgraph PodR["Pod ์žฌ์‹œ์ž‘"]
        A["Pod ์‚ญ์ œ โ†’ ์žฌ์ƒ์„ฑ"] --> B["IPยทAGE ์ดˆ๊ธฐํ™”<br/>RESTARTS=0"]
    end
    subgraph CtnR["์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘"]
        C["์ปจํ…Œ์ด๋„ˆ๋งŒ ์žฌ์‹œ์ž‘"] --> D["IPยทAGE ์œ ์ง€<br/>RESTARTS ๋ˆ„์ โ†‘"]
    end
ํ•ญ๋ชฉPod ์žฌ์‹œ์ž‘์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘
AGE์ดˆ๊ธฐํ™”์œ ์ง€
IP๋ณ€๊ฒฝ์œ ์ง€
RESTARTS0์œผ๋กœ ์ดˆ๊ธฐํ™”๋ˆ„์  ์ฆ๊ฐ€
์›์ธkubectl deleteยท๋…ธ๋“œ ์žฅ์• ยทrolloutOOMKillยทCrashยทProbe ์‹คํŒจ

๐Ÿ’ก ๋””๋ฒ„๊น… ์ฒซ ๋‹จ์ถ”๋Š” kubectl get pods์˜ ๋‘ ์ปฌ๋Ÿผ์ด๋‹ค. AGE๊ฐ€ ์งง์•„์กŒ์œผ๋ฉด Pod ์žฌ์‹œ์ž‘, RESTARTS๋งŒ ์˜ฌ๋ž์œผ๋ฉด ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘์ด๋‹ค. ์ด๊ฒƒ๋งŒ ๋ด๋„ โ€œํŒŒ๋“œ๊ฐ€ ์ƒˆ๋กœ ๋–ด๋Š”์ง€ vs ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ฃฝ๋‹ค ์‚ด์•˜๋Š”์ง€โ€๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.


2. Rollout ๋ฉ”์ปค๋‹ˆ์ฆ˜

spec ๋ณ€๊ฒฝ(์ด๋ฏธ์ง€ยทannotation ๋“ฑ)์„ ๊ฐ์ง€ํ•˜๋ฉด updateStrategy์— ๋”ฐ๋ผ ํŒŒ๋“œ๋ฅผ ์ˆœ์ฐจ ๊ต์ฒดํ•œ๋‹ค.

1
spec ๋ณ€๊ฒฝ โ†’ ์ƒˆ Pod ์ƒ์„ฑ โ†’ Running ํ™•์ธ โ†’ ๊ธฐ์กด Pod ์‚ญ์ œ โ†’ ๋ฐ˜๋ณต

kubectl rollout restart๋Š” ํŒŒ๋“œ spec์„ ์ง์ ‘ ์•ˆ ๋ฐ”๊พธ๊ณ  annotation์— ์žฌ์‹œ์ž‘ ์‹œ๊ฐ์„ ์‹ฌ์–ด ๋กค๋ง ์—…๋ฐ์ดํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•œ๋‹ค.

1
2
kubectl rollout restart daemonset calico-node -n kube-system
# annotation: kubectl.kubernetes.io/restartedAt: "..." โ†’ Rolling Update ํŠธ๋ฆฌ๊ฑฐ

3. updateStrategy

Deployment (RollingUpdate)

1
2
3
4
5
6
7
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1   # ๋™์‹œ์— ๋‚ด๋ฆด ์ˆ˜ ์žˆ๋Š” Pod ์ˆ˜
      maxSurge: 1         # ์ถ”๊ฐ€๋กœ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋Š” Pod ์ˆ˜
1
์ƒˆ Pod +1(maxSurge) โ†’ ์ด 6๊ฐœ โ†’ Running ํ™•์ธ โ†’ ๊ธฐ์กด -1(maxUnavailable) โ†’ 5๊ฐœ โ†’ ๋ฐ˜๋ณต

DaemonSet (๋…ธ๋“œ๋‹น 1๊ฐœ)

1
2
3
4
5
6
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1   # ํ•œ ๋ฒˆ์— 1๊ฐœ ๋…ธ๋“œ์”ฉ
      maxSurge: 0         # ๋…ธ๋“œ๋‹น 1๊ฐœ๋ผ Surge ๋ถˆ๊ฐ€
type๋™์ž‘์‚ฌ์šฉ
RollingUpdate์ˆœ์ฐจ ๊ต์ฒด(๊ธฐ๋ณธ)์ผ๋ฐ˜ ์—…๋ฐ์ดํŠธ
OnDelete์ˆ˜๋™ ์‚ญ์ œ ์‹œ๋งŒ ๊ต์ฒด์ˆ˜๋™ ์ œ์–ด

๐Ÿ’ก DaemonSet์€ ๋…ธ๋“œ๋‹น ํŒŒ๋“œ 1๊ฐœ๋ผ maxSurge๊ฐ€ 0์ด๋‹ค(์ถ”๊ฐ€๋กœ ๋„์šธ ์ž๋ฆฌ๊ฐ€ ์—†์Œ). ๊ทธ๋ž˜์„œ ๋ฐ˜๋“œ์‹œ maxUnavailable: 1๋กœ ํ•œ ๋…ธ๋“œ์”ฉ ๊ต์ฒดํ•ด์•ผ ํ•˜๋ฉฐ, calico-node ๊ฐ™์€ ๋„คํŠธ์›Œํฌ DaemonSet์€ ์ด ์„ค์ •์„ ์–ด๊ธฐ๋ฉด ํด๋Ÿฌ์Šคํ„ฐ ๋„คํŠธ์›Œํฌ๊ฐ€ ํ†ต์งธ๋กœ ํ”๋“ค๋ฆฐ๋‹ค.


4. Rollout ๋ช…๋ น์–ด

1
2
3
4
5
6
kubectl rollout restart deployment web-app -n default     # ์žฌ์‹œ์ž‘
kubectl rollout status deployment web-app -n default      # ์ง„ํ–‰ ์ƒํ™ฉ
kubectl rollout pause/resume deployment web-app           # ์ค‘์ง€/์žฌ๊ฐœ
kubectl rollout history deployment web-app                # ์ด๋ ฅ
kubectl rollout undo deployment web-app                   # ๋กค๋ฐฑ
kubectl rollout undo deployment web-app --to-revision=1   # ํŠน์ • ๋ฒ„์ „

5. ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘ ์›์ธ ๋ถ„์„

1
2
3
4
5
# ์žฌ์‹œ์ž‘ ์›์ธ(Last State)
kubectl describe pod <pod> -n <ns> | grep -A 10 "Last State"
# Reason: OOMKilled / Exit Code: 137 ...

kubectl logs <pod> -n <ns> --previous          # ์ด์ „ ์ปจํ…Œ์ด๋„ˆ ๋กœ๊ทธ
์›์ธ์ฆ์ƒ์กฐ์น˜
OOMKilledExit Code 137Memory Limit ์ฆ๊ฐ€
CrashLoopBackOffExit Code 1๋กœ๊ทธ ํ™•์ธยท์ฝ”๋“œ ์ˆ˜์ •
Liveness Probe ์‹คํŒจprobe failedProbe ์„ค์ • ์ ๊ฒ€
๋…ธ๋“œ ๋ฆฌ์†Œ์Šค ๋ถ€์กฑ๋‹ค์ˆ˜ Pod ๋™์‹œ ์žฌ์‹œ์ž‘kubectl top nodes

โš ๏ธ Exit Code 137 = OOMKilled(๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ ๊ฐ•์ œ ์ข…๋ฃŒ)๋‹ค. RESTARTS๊ฐ€ ๊ณ„์† ์˜ค๋ฅด๋ฉด ์‹ญ์ค‘ํŒ”๊ตฌ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์ด๋‹ˆ, kubectl top pod๋กœ ์‚ฌ์šฉ๋Ÿ‰์„ ๋ณด๊ณ  limits.memory๋ฅผ ์˜ฌ๋ฆฐ๋‹ค.


6. ์•ˆ์ „ ์„ค์ • ์ฃผ์˜์‚ฌํ•ญ

โš ๏ธ maxUnavailable์„ ํฌ๊ฒŒ ์žก์ง€ ๋ง ๊ฒƒ. replicas 5์— maxUnavailable: 5๋ฉด ์ „๋ถ€ ๋™์‹œ์— ๋‚ด๋ ค๊ฐ€ ์„œ๋น„์Šค๊ฐ€ ์ค‘๋‹จ๋œ๋‹ค. maxUnavailable: 1๋กœ ์ตœ์†Œ ๊ฐ€์šฉ์„ฑ์„ ์ง€ํ‚จ๋‹ค.

โš ๏ธ readinessProbe๋Š” ํ•„์ˆ˜. Probe๊ฐ€ ์—†์œผ๋ฉด ์ƒˆ ํŒŒ๋“œ๊ฐ€ ์ค€๋น„๋„ ์•ˆ ๋œ ์ƒํƒœ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ฐ›์•„ ๋กค๋ง ์ค‘ ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค. /health ๊ฐ™์€ ์ค€๋น„ ์ƒํƒœ ๊ฒฝ๋กœ๋ฅผ ๋ฐ˜๋“œ์‹œ ๋‘”๋‹ค.

1
2
3
4
5
6
readinessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5

๐Ÿ“ ์ •๋ฆฌ

1
2
3
4
5
6
Rollout & ์žฌ์‹œ์ž‘
โ”œโ”€ ๊ตฌ๋ถ„   Pod ์žฌ์‹œ์ž‘(IPยทAGE ์ดˆ๊ธฐํ™”) vs ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘(RESTARTSโ†‘)
โ”œโ”€ ๋™์ž‘   spec ๋ณ€๊ฒฝ โ†’ updateStrategy ์ˆœ์ฐจ ๊ต์ฒด
โ”œโ”€ ์ „๋žต   maxUnavailable:1 / DaemonSet์€ maxSurge:0
โ”œโ”€ ์ง„๋‹จ   describe(Last State) ยท logs --previous
โ””โ”€ ์•ˆ์ „   readinessProbe ํ•„์ˆ˜
๊ฐœ๋…ํ•œ ์ค„ ์ •์˜
Rollout์ˆœ์ฐจ ๋ฌด์ค‘๋‹จ ๊ต์ฒด
RESTARTS 137OOMKilled(๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ)
maxUnavailable๋™์‹œ ์ค‘๋‹จ ํ—ˆ์šฉ ์ˆ˜

Rollout์˜ ํ•ต์‹ฌ์€ ์ƒˆ ํŒŒ๋“œ๋ฅผ ํ™•์ธํ•˜๋ฉฐ ๊ธฐ์กด ํŒŒ๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ด๊ณ , ์•ˆ์ „์˜ ํ•ต์‹ฌ์€ maxUnavailable: 1 + readinessProbe๋‹ค. ์žฌ์‹œ์ž‘ ๋ฌธ์ œ๋Š” AGE/RESTARTS ๋‘ ์ปฌ๋Ÿผ๊ณผ Last State๋กœ ๋น ๋ฅด๊ฒŒ ์ง„๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ”— ์ฐธ๊ณ 

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.