13 KiB
title, source_type, url, archive_url, status, confidence, tags, related_projects, related_branches, created, last_reviewed
| title | source_type | url | archive_url | status | confidence | tags | related_projects | related_branches | created | last_reviewed | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Kubernetes — Init Containers and One-shot Job for Database Migration | official-doc | https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ | raw | high |
|
|
|
2026-05-22 | 2026-05-27 |
Kubernetes — Init Containers and One-shot Job for Database Migration
Layer:
raw/official-docs/— Kubernetes 공식 문서 (Init Containers + Jobs 절) 발췌. ca-tmpl Group G-D 대안 3 (K8s platform-side migration). multi-instance 환경에서 startup race 회피 패턴의 baseline.
Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| raw/branch-notes/feature-migration-startup-contract | ca-tmpl 의 "multi-instance 에서 app startup runner 를 그대로 확장하지 않고 platform one-shot job 또는 migration lock 검증 필요" 결정의 근거. init container vs 별도 Job 패턴의 공식 차이 |
| raw/branch-notes/feature-runtime-health-lifecycle-contract | init container 가 "always run to completion" + "app container 는 모든 init container 완료 후에만 시작" 보장 — readiness 전에 migration 이 끝났음을 platform 차원에서 강제하는 근거 |
또한 다음 project hub 에서도 인용:
- raw/project-notes/ca-skeleton-operational-contract — migration startup canonical section
컨텍스트 / 왜 저장했는지
ca-tmpl feature-migration-startup-contract는 multi-instance에서 app startup runner를 그대로 확장하지 않고 platform one-shot job 또는 migration lock 검증이 필요하다고 결정. 본 source는 K8s가 제공하는 platform-side 대안의 공식 모델.
출처 / Source
- 원본 URL: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
- 보조 URL: https://kubernetes.io/docs/concepts/workloads/controllers/job/
- 저자/조직: Kubernetes Project (CNCF)
- 발행일: 1.32+ reference (current)
- 마지막 확인일: 2026-05-27
핵심 인용 / Key quotes (verbatim)
A. Init Containers
[§Understanding init containers] "Init containers always run to completion."
[§Understanding init containers] "Each init container must complete successfully before the next one starts."
[§Understanding init containers] "If a Pod's init container fails, the kubelet repeatedly restarts that init container until it succeeds."
[§Understanding init containers — restartPolicy: Never] "However, if the Pod has a
restartPolicyof Never, and an init container fails during startup of that Pod, Kubernetes treats the overall Pod as failed."
[§Using init containers] "Init containers can contain utilities or custom code for setup that are not present in an app image. For example, there is no need to make an image
FROManother image just to use a tool likesed,awk,python, ordigduring setup."
[§Differences from regular containers] "Init containers are exactly like regular containers, except: Init containers always run to completion."
B. Jobs
[§Jobs — definition] "A Job creates one or more Pods and will continue to retry execution of the Pods until a specified number of them successfully terminate. As pods successfully complete, the Job tracks the successful completions. When a specified number of successful completions is reached, the task (ie, Job) is complete."
[§Running an example Job — backoffLimit, parallelism, completions (yaml snippet from official docs)]
backoffLimit: 4가 명시되어 retry 한도를 지정하며,Parallelism: 1+Completions: 1이 default 인 single-pod 패턴.
C. 본 자료가 직접 인용으로는 확보하지 못한 항목 (needs-confirmation)
다음은 ca-tmpl 운영 결정에 자주 인용되나 본 2026-05-27 정독에서 verbatim 확보 못함:
- "Job is suitable for one-shot tasks such as database migration" 류의 공식 문서가 database migration 을 use case 로 직접 명시한 문장 — Jobs 페이지 본문에서 직접 확인되지 않음 (truncated 영역). database migration use-case 는 community/blog 의 통념일 가능성.
ttlSecondsAfterFinished의 정확한 설명 — 페이지 목차에 존재 ("TTL mechanism for finished Jobs") 하나 자동화 fetch 에서 본문 발췌 못함.parallelism의 세 가지 task type (Non-parallel / Parallel with fixed completion count / Parallel with work queue) 의 정확한 분류 진술 — 목차에는 "three main types of task" 까지만 노출.
Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| K8S-INIT-C1 | init container 는 항상 completion 까지 실행되고, 각 init container 는 다음이 시작되기 전에 성공적으로 끝나야 한다 (sequential, must-succeed) | [§Understanding init containers] "Init containers always run to completion." + "Each init container must complete successfully before the next one starts." | official-vendor-doc |
K8s Pod 의 init container 일반 동작 | 여러 replica 의 init container 가 cluster 차원에서 한 번만 실행된다는 뜻은 아님 — pod 단위로 매번 실행 (race 가능성은 별도 K8S-INIT-C4 참조) |
| K8S-INIT-C2 | init container 가 실패하면 kubelet 이 그것을 성공할 때까지 반복 재시작한다. 단 restartPolicy: Never 면 Pod 전체가 failed 처리된다 |
[§Understanding init containers] "If a Pod's init container fails, the kubelet repeatedly restarts that init container until it succeeds." + "if the Pod has a restartPolicy of Never, and an init container fails during startup of that Pod, Kubernetes treats the overall Pod as failed." |
official-vendor-doc |
init container 실패 시 동작 | 무한 retry 가 production 에 안전하다는 뜻 아님 — backoffLimit 은 Job 단의 개념, init container 자체에는 별도 limit 없음 |
| K8S-INIT-C3 | init container 는 app image 에 없는 utility / setup script 를 담을 수 있음 (sed/awk/python/dig 등의 예) — 별도 image 사용 가능 |
[§Using init containers] "Init containers can contain utilities or custom code for setup that are not present in an app image." | official-vendor-doc |
init container 의 image 분리 use-case | "Flyway/Liquibase CLI 를 init container 로 실행하는 것이 공식 권장 패턴이다" 는 직접 진술 아님 — 일반화된 예시만 |
| K8S-INIT-C4 | (해석, 본 자료의 인용에서 직접 도출되지 않음) "init container 는 pod 단위로 실행되므로 multi-replica 환경에서 같은 migration 이 replica 수만큼 실행될 수 있다" — K8S-INIT-C1 의 "each pod" 동작에서 운영적으로 도출되는 결론. 별도 공식 문서 권고 인용 필요 |
(운영 해석) | needs-confirmation |
multi-replica migration race 논의 | 본 페이지가 "use Job instead for migration" 을 공식 권고한다는 인용은 본 정독에서 미확보 |
| K8S-JOB-C1 | Job 은 하나 이상의 Pod 를 생성하여 지정한 수의 성공 종료가 달성될 때까지 실행을 재시도한다. 모든 successful completion 이 누적되면 Job 이 완료된다 | [§Jobs] "A Job creates one or more Pods and will continue to retry execution of the Pods until a specified number of them successfully terminate. ... When a specified number of successful completions is reached, the task (ie, Job) is complete." | official-vendor-doc |
K8s Job controller 일반 동작 | Job 이 schema migration 의 공식 use-case 로 명시되었다는 뜻 아님 — K8S-JOB-C3 참조 |
| K8S-JOB-C2 | Job 의 default 동작은 Parallelism: 1 + Completions: 1 의 single-pod 패턴이며, backoffLimit field 로 retry 한도를 지정한다 (공식 sample 에 backoffLimit: 4) |
[§Running an example Job — official sample] backoffLimit: 4 + describe output 의 "Parallelism: 1 / Completions: 1" |
official-vendor-doc |
Job 의 default single-pod 패턴 | backoffLimit 의 정확한 retry 전략 (exponential backoff timing 등) 은 본 인용 범위 밖 — "Handling Pod and container failures" 별도 |
| K8S-JOB-C3 | (needs-confirmation) "Job is suitable for one-shot tasks such as database migration" 류의 공식 use-case 명시 는 본 2026-05-27 정독에서 verbatim 확보 못함 — 페이지의 다른 섹션 (truncated) 또는 별도 문서에 있을 가능성 |
(인용 미확보) | needs-confirmation |
DB migration 패턴을 K8s 공식이 권고하는지 여부 | 본 시점에는 community/operational best practice 수준의 통념. ca-tmpl 의 "platform one-shot job" 결정의 직접 근거로 인용 시 별도 문서 (Helm hook, kubectl examples 등) 필요 |
Usage Boundaries / 적용 경계
- 이 자료가 직접 증명하는 것:
K8S-INIT-C1/C2/C3: init container 의 정확한 lifecycle (always run to completion, sequential, restart on failure, app image 와 분리된 image 사용 가능)K8S-JOB-C1/C2: Job controller 의 기본 의미 (retry until N successes) + defaultParallelism: 1+backoffLimit존재
- 이 자료가 증명하지 않는 것:
- "DB migration 의 공식 권고 패턴이 init container 인지 Job 인지" 의 공식 입장 (본 자료에서 직접 진술 미확보 —
K8S-JOB-C3/K8S-INIT-C4모두needs-confirmation) ttlSecondsAfterFinished의 정확한 값 / 자동 cleanup 거동- Helm
pre-install/pre-upgradehook 의 정확한 ordering (별도 Helm 공식 문서) - Flyway/Liquibase 의 schema lock 이 multi-init-container race 를 안전하게 처리하는지의 외부 증명
- "DB migration 의 공식 권고 패턴이 init container 인지 Job 인지" 의 공식 입장 (본 자료에서 직접 진술 미확보 —
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
- ca-tmpl 의 "init container vs 별도 Job" 선택 기준 (예: 단일 replica 면 init OK, multi-replica 면 Job 강제)
K8S-JOB-C3의 공식 use-case 인용 보강 (kubernetes.io 의 "Running an Example Job" 외 페이지에서 DB migration 직접 언급 확인)- Argo CD / Flux 등 GitOps 도구의 Job hook ordering 실제 동작
- migration Job 실패 시 application Deployment 가 자동으로 rollout 차단되는지의 platform-별 거동
메모 / Notes (내 프로젝트 해석)
본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
- 적용 시나리오: multi-instance deployment (HPA, Rolling update) 환경에서 schema migration 동시 실행 race를 피하고 싶을 때.
- 두 가지 패턴:
- Init container: pod 단위로 migration 실행. ca-tmpl 관점에서는 multi-replica에서 race 발생 가능 (모든 pod이 동시에 startup → init container도 동시에 migration 시도). Flyway/Liquibase의 schema lock이 race를 처리하지만 timeout / deadlock 부담.
- One-shot Job: deploy 직전에 단일 Job으로 migration을 1회만 실행 → application pod은 migration이 완료된 schema에 대해 startup. race 없음.
- 장점 (Job 방식):
- migration이 app deploy lifecycle과 분리 → rollback 시 app만 이전 버전으로 되돌릴 수 있음 (schema는 forward-only).
- migration 실패 시 app pod이 deploy되기 전에 차단 가능.
- 단점:
- GitOps / Helm 운영 복잡도 증가 (Job 정의 + hook ordering).
- migration이 deploy 외부에서 실행되므로 app 코드와 schema 버전 binding이 약해질 수 있음 (
backoffLimit,ttlSecondsAfterFinished등 fine-tuning 필요).
- ca-tmpl과의 일치점:
- ca-tmpl의 "multi-instance에서 app startup runner를 그대로 확장하지 않고 platform one-shot job 또는 migration lock 검증이 필요"와 직접 정합.
- "concurrent startup race" 테스트 계약 — Job 방식이면 구조적으로 race 없음.
- ca-tmpl과의 차이: ca-tmpl은 Flyway app startup runner를 default로 두되 multi-instance 시 platform job 또는 lock 검증을 요구. K8s Job은 이 요구를 충족하는 평행 대안.
Related / 관련
- 같은 주제 다른 official-doc:
- raw/official-docs/migration-flyway-official-concepts-and-repair — Group G-D 채택안 (Flyway)
- raw/official-docs/migration-liquibase-official-changelog-xml-yaml — Group G-D 대안 2 (Liquibase)
- raw/official-docs/migration-atlas-schema-as-code — Group G-D 대안 4 (Atlas)
- 적용 branch-note:
- canonical contract:
- raw/project-notes/ca-skeleton-operational-contract — migration startup canonical section
- 대안 그룹: Group G-D — Migration startup. 본 source의 위치: 대안 3 — K8s init container / Separate migration Job. ca-tmpl 채택 안 함 (default), multi-instance 옵션으로 인정.