131 lines
13 KiB
Markdown
131 lines
13 KiB
Markdown
---
|
|
title: "Kubernetes — Init Containers and One-shot Job for Database Migration"
|
|
source_type: official-doc
|
|
url: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
|
|
archive_url:
|
|
status: raw
|
|
confidence: high
|
|
tags: [ca-skeleton, migration, startup, kubernetes, init-container, job, official-doc]
|
|
related_projects: [ca-skeleton-operational-contract]
|
|
related_branches: [feature-migration-startup-contract, feature-runtime-health-lifecycle-contract]
|
|
created: 2026-05-22
|
|
last_reviewed: 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 `restartPolicy` of 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 `FROM` another image just to use a tool like `sed`, `awk`, `python`, or `dig` during 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) + default `Parallelism: 1` + `backoffLimit` 존재
|
|
- **이 자료가 증명하지 않는 것**:
|
|
- "DB migration 의 공식 권고 패턴이 init container 인지 Job 인지" 의 공식 입장 (본 자료에서 직접 진술 미확보 — `K8S-JOB-C3` / `K8S-INIT-C4` 모두 `needs-confirmation`)
|
|
- `ttlSecondsAfterFinished` 의 정확한 값 / 자동 cleanup 거동
|
|
- Helm `pre-install` / `pre-upgrade` hook 의 정확한 ordering (별도 Helm 공식 문서)
|
|
- Flyway/Liquibase 의 schema lock 이 multi-init-container race 를 안전하게 처리하는지의 외부 증명
|
|
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
|
- 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:
|
|
- [[raw/branch-notes/feature-migration-startup-contract]]
|
|
- [[raw/branch-notes/feature-runtime-health-lifecycle-contract]]
|
|
- 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 옵션으로 인정.
|