Cron Jobs
This guide covers configuring the pgt-cronjob Helm chart for deploying scheduled jobs to Kubernetes. The chart creates Kubernetes CronJob resources that run containers on a specified schedule.
Prerequisites
Add the chart as a dependency in your Chart.yaml:
apiVersion: v2
name: my-cronjob
version: 0.0.1
dependencies:
- name: pgt-cronjob
version: 0.0.3
repository: oci://public.ecr.aws/w9m9e0e9/pgt-helm-chartsAfter adding the dependency, run:
helm dependency updateBasic Configuration
Required Fields
pgt-cronjob:
# [Required] CronJob name - used as base name for all K8s resources
name: my-cronjob
# [Required] Organisation name for labeling
organisationName: my-org
# [Required] Cron schedule expression
cronjob:
schedule: "0 * * * *" # Every hour
# [Required] Container image configuration
container:
image:
registry: public.ecr.aws
repository: my-org/my-job
tag: "1.0.0"
resources:
limits:
memory: 512Mi
requests:
memory: 512Mi # Should equal limits for Guaranteed QoS
cpu: 100m
# [Required] ServiceAccount name
serviceAccount:
name: my-cronjob-sa⚠️ Memory Requests and Limits
Always set memory requests equal to memory limits. This ensures your pod receives a Guaranteed Quality of Service (QoS) class, which provides predictable scheduling and OOM kill priority.
Development Environment & Cost Optimization
When deploying CronJobs to non-production environments, consider these settings to reduce costs:
💡 Spot Instances
The
preferSpotInstances: truesetting prefers scheduling your workloads on spot instances when available, which can significantly reduce compute costs. If you're interested in enabling spot instances for your environment, please reach out to the platform team to discuss your requirements and ensure your applications are suitable for spot instance usage.
💰 Cost-Saving Tips for CronJobs
Schedule during off-peak hours: Run jobs during times when cluster resources are less utilised
Reduce frequency in non-prod: If a job runs hourly in production, consider running it daily in development
Right-size resources: Development jobs often need fewer resources than production
Limit job history: Keep fewer completed jobs with
successfulJobsHistoryLimit: 1
🕐 Environment-Specific Schedules
Consider using different schedules per environment:
This reduces unnecessary job executions in development while maintaining production schedules.
Schedule Configuration
Cron Schedule Syntax
The schedule follows standard cron syntax: minute hour day-of-month month day-of-week
Minute
0-59
Minute of the hour
Hour
0-23
Hour of the day
Day of Month
1-31
Day of the month
Month
1-12
Month of the year
Day of Week
0-6
Day of the week (0 = Sunday)
Common Schedule Examples
💡 Cron Schedule Help
Use crontab.guru to build and validate cron expressions.
CronJob Behaviour
Concurrency Policy
Control how the CronJob handles overlapping executions:
Forbid
Skip new job if previous is still running (default)
Allow
Allow concurrent job executions
Replace
Cancel currently running job and start a new one
Job History
Configure how many completed jobs to retain:
Restart Policy
Configure pod restart behaviour on failure:
OnFailure
Restart the container if it exits with a non-zero code (default)
Never
Never restart; create a new pod if the job needs to retry
Container Configuration
Command and Arguments
Override the container's default entrypoint and arguments:
Image Pull Policy
Environment Variables
Direct Environment Variables
Load from ConfigMap or Secret
External Secrets
The pgt-cronjob chart includes pgt-secrets as a subchart for fetching secrets from AWS Secrets Manager or Azure Key Vault. For full configuration options, see the PGT Secrets documentation.
Volume Mounts
Mount ConfigMaps or Secrets as files:
ServiceAccount
Configure a ServiceAccount to allow your CronJob to access cloud resources securely:
For detailed instructions on creating IAM roles and managed identities, see:
AWS IAM Roles (IRSA) - Configure IAM roles for EKS workloads
Azure Workload Identity - Configure managed identities for AKS workloads
Pod Configuration
Labels and Annotations
Tolerations
For scheduling on specific nodes (e.g., Windows nodes):
Prometheus PodMonitor
Enable metrics scraping for CronJobs that expose metrics during execution:
Complete Examples
Data Processing Job
A daily job that processes data from a database:
Cleanup Job
A weekly job that cleans up old resources:
Report Generation Job
A job that generates and emails reports every weekday:
Troubleshooting
Use Argo CD to investigate issues with CronJobs.
Viewing CronJob Status
Navigate to your application in the Argo CD UI
Locate the CronJob resource in the application tree
Click on the CronJob to view its details including:
Last schedule time
Active jobs
Schedule expression
Viewing Job Executions
In the Argo CD application tree, look for Job resources created by the CronJob
Click on a Job to see its status and completion time
Expand the Job to see its Pods
Checking Pod Logs
In the application tree, find the Pod created by a Job
Click on the Pod resource
Select the Logs tab to view container output
Check for errors or unexpected behaviour
Common Issues
Job not running on schedule:
Verify the cron schedule expression is correct
Check if
concurrencyPolicy: Forbidis blocking new jobs because previous jobs are still runningEnsure the CronJob is not suspended
Job failing repeatedly:
Check Pod logs for error messages
Verify secrets and ConfigMaps are correctly configured
Ensure the ServiceAccount has required permissions
Check resource limits aren't too restrictive
Pods stuck in Pending:
Check if the cluster has sufficient resources
Verify node selectors and tolerations match available nodes
Check for PersistentVolumeClaim issues if using volumes
Values Reference
name
string
nil
Required. CronJob name
organisationName
string
nil
Required. Organisation name
cronjob.schedule
string
nil
Required. Cron schedule expression
cronjob.concurrencyPolicy
string
Forbid
Allow, Forbid, or Replace
cronjob.successfulJobsHistoryLimit
int
3
Successful jobs to retain
cronjob.failedJobsHistoryLimit
int
1
Failed jobs to retain
cronjob.restartPolicy
string
OnFailure
OnFailure or Never
affinity.nodeAffinity.preferSpotInstances
bool
false
Prefer scheduling on spot instances
container.image.registry
string
nil
Required. Container registry
container.image.repository
string
nil
Required. Image repository
container.image.tag
string
nil
Required. Image tag
container.imagePullPolicy
string
IfNotPresent
Image pull policy
container.command
list
[]
Container entrypoint override
container.args
list
[]
Container arguments
container.resources.limits.memory
string
1Mi
Memory limit
container.resources.requests.memory
string
1Mi
Memory request
container.resources.requests.cpu
string
1m
CPU request
serviceAccount.name
string
nil
Required. ServiceAccount name
serviceAccount.annotations
object
{}
ServiceAccount annotations
environmentVariables
list
[]
Environment variables
environmentVariablesFrom
list
[]
Load env vars from ConfigMap/Secret
volumes
list
[]
Volume mounts
podMonitor.enabled
bool
false
Enable PodMonitor
podMonitor.path
string
nil
Metrics path
podMonitor.port
string
nil
Metrics port
podMonitor.interval
string
nil
Scrape interval
pgt-secrets.enabled
bool
false
Enable external secrets
Last updated
Was this helpful?
