✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Batch Manifest Management

Kubernetes Batch Manifest Management streamlines deploying and managing multiple workloads through automated, scalable, and consistent manifest handling across clusters.

Kubernetes Batch Manifest Management is the discipline of authoring, organizing, versioning, and applying the YAML (or JSON) manifests that define Job and CronJob resources across a codebase and a cluster's lifecycle. While an individual Job or CronJob manifest is a single, largely self-contained document, batch manifest management concerns the practices that keep those manifests correct, consistent, and maintainable as the number of batch workloads in an organization grows from a handful of one-off scripts to a fleet of scheduled, parameterized, environment-specific workloads.

Because batch manifests tend to proliferate faster than long-running service manifests — every new scheduled report, migration, or data pipeline typically needs its own Job or CronJob definition — manifest management practices that work well for a small number of Deployments often need deliberate adaptation to scale cleanly for batch workloads.


Manifest Organization

Directory Structure

A common pattern groups batch manifests by domain or team rather than by resource kind, since a single logical workload (a nightly reconciliation job) is often represented by exactly one Job or CronJob manifest, plus any supporting ConfigMaps or Secrets it depends on — keeping those together aids readability more than grouping all CronJobs in one directory regardless of purpose.

manifests/
  reporting/
    nightly-report-cronjob.yaml
    nightly-report-configmap.yaml
  data-migration/
    schema-migration-job.yaml

Separating Job Templates from One-Off Parameters

For Jobs created ad hoc (database migrations, one-time backfills) rather than on a recurring schedule, it is common to template the manifest and generate a parameterized instance at apply time (embedding a timestamp or a specific input range in the name and environment variables), rather than hand-editing a static manifest for every run.


Templating Tools

Helm

Helm charts are widely used to templatize batch manifests across environments, parameterizing image tags, resource requests, schedules, and environment-specific variables (like target database connection strings) through values.yaml, while keeping the core Job or CronJob structure defined once in the chart's templates.

# templates/cronjob.yaml (excerpt)
spec:
  schedule: {{ .Values.schedule | quote }}
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: worker
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

Kustomize

Kustomize overlays are a common alternative for batch manifests that are mostly identical across environments but need small, targeted differences (a different schedule in staging versus production, a different resource limit), using a base manifest with patches per overlay rather than full templating.

# overlays/production/patch-schedule.yaml
- op: replace
  path: /spec/schedule
  value: "0 3 * * *"

Raw YAML with CI-Driven Substitution

Smaller batch workload fleets sometimes forgo a templating engine entirely, keeping raw YAML manifests and relying on CI/CD pipeline steps (environment variable substitution via envsubst, or a lightweight script) to inject environment-specific values before kubectl apply, trading some flexibility for a simpler mental model.


Manifest Validation

Schema Validation Before Apply

kubectl apply --dry-run=server -f nightly-report-cronjob.yaml
kubectl apply --validate=strict -f nightly-report-cronjob.yaml

Server-side dry runs catch schema errors (an invalid field, a typo in restartPolicy) before they reach the cluster, which is particularly valuable for CronJob manifests where an error might not surface until the next scheduled tick fires, long after the manifest was applied.

Linting for Batch-Specific Pitfalls

Automated linting (via tools like kubeconform or custom policy checks in CI) commonly targets batch-specific mistakes: a Job missing restartPolicy: Never or OnFailure (which is otherwise a valid Pod spec field but invalid for Job templates), a CronJob without any ttlSecondsAfterFinished or history limits configured, or a backoffLimit left at its permissive default for a workload where retries are expensive.


Version Control Practices

Immutability of Applied Job Specs

Because most fields of an existing Job's template cannot be edited after creation, changes to a Job manifest tracked in version control typically require deleting and recreating the Job (or, for CronJob-managed Jobs, simply waiting for the next scheduled tick to pick up the updated jobTemplate) rather than an in-place kubectl apply updating a running Job.

Change Review for Schedule and Concurrency Fields

Because schedule, concurrencyPolicy, and backoffLimit changes directly affect production behavior (how often a workload runs, whether overlapping runs are permitted), these fields are commonly called out for extra scrutiny in code review on batch manifest pull requests, distinct from more routine changes like image tag bumps.


Example: A Parameterized CronJob Manifest

apiVersion: batch/v1
kind: CronJob
metadata:
  name: codartium-{{ .Values.name }}
  labels:
    app: codartium
    managed-by: helm
spec:
  schedule: {{ .Values.schedule | quote }}
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      backoffLimit: {{ .Values.backoffLimit | default 3 }}
      ttlSecondsAfterFinished: 86400
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: worker
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"