All checks were successful
docker-build / Build image (push) Successful in 9s
6.5 KiB
6.5 KiB
GitLab Job Runner Operator
Kubernetes operator for executing code from GitLab repositories as one-time Jobs or scheduled CronJobs.
Features
- Execute scripts from GitLab repositories as Kubernetes Jobs
- Schedule recurring executions using CronJobs
- Secure credential management through Kubernetes Secrets
- Support for custom container images and service accounts
- Automatic cleanup with finalizers
Architecture
The operator watches for GitlabJobRunner custom resources and:
- Clones the specified GitLab repository using credentials from a Secret
- Creates either a Job (one-time) or CronJob (scheduled) based on the spec
- Executes the specified script from the repository
- Manages lifecycle and status updates
Prerequisites
- Kubernetes cluster (1.24+)
- kubectl configured
- GitLab repository with scripts
- GitLab access token with read permissions
Installation
Using Helm (Recommended)
# Install from local chart
helm install gitlab-job-runner ./helm/gitlab-job-runner \
--namespace gitlab-job-runner-system \
--create-namespace
# Or with custom values
helm install gitlab-job-runner ./helm/gitlab-job-runner \
--namespace gitlab-job-runner-system \
--create-namespace \
--set image.repository=your-registry/gitlab-job-runner \
--set image.tag=0.1.0
Using Make
# Apply CRDs
make install
# Deploy operator
make deploy IMG=your-registry/gitlab-job-runner:latest
Create GitLab Credentials Secret
kubectl create secret generic gitlab-credentials \
--from-literal=GITLAB_URL=https://gitlab.example.com \
--from-literal=GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
Create Service Account for Script Execution
If your scripts need to interact with Kubernetes API:
kubectl apply -f config/samples/example_serviceaccount.yaml
Usage
One-time Job Example
apiVersion: batch.rml.ru/v1alpha1
kind: GitlabJobRunner
metadata:
name: cleanup-job
spec:
gitlabSecretRef: gitlab-credentials
repositoryURL: mygroup/myrepo
branch: main
scriptPath: scripts/cleanup.sh
serviceAccountName: backup-sa
CronJob Example
apiVersion: batch.rml.ru/v1alpha1
kind: GitlabJobRunner
metadata:
name: backup-cronjob
spec:
schedule: "0 2 * * *"
gitlabSecretRef: gitlab-credentials
repositoryURL: mygroup/myrepo
branch: main
scriptPath: scripts/backup.sh
serviceAccountName: backup-sa
suspend: false
concurrencyPolicy: Forbid
Apply the Resource
kubectl apply -f your-gitlabjobrunner.yaml
Custom Resource Specification
GitlabJobRunnerSpec
| Field | Type | Required | Description |
|---|---|---|---|
schedule |
string | No | Cron schedule for recurring jobs. If empty, runs as one-time Job |
gitlabSecretRef |
string | Yes | Name of Secret containing GITLAB_URL and GITLAB_TOKEN |
repositoryURL |
string | Yes | GitLab repository path (e.g., "group/project") |
branch |
string | No | Git branch to checkout (default: "main") |
scriptPath |
string | Yes | Relative path to script in repository |
image |
string | No | Container image for git clone (default: "bitnami/git:latest") |
serviceAccountName |
string | No | ServiceAccount for pod execution (default: "default") |
suspend |
boolean | No | Suspend CronJob execution (CronJobs only) |
concurrencyPolicy |
string | No | How to handle concurrent executions: Forbid, Allow, Replace (default: Forbid) |
GitlabJobRunnerStatus
| Field | Type | Description |
|---|---|---|
conditions |
[]Condition | Current state conditions |
lastScheduleTime |
Time | Last time job was scheduled (CronJobs) |
activeJobName |
string | Name of currently running job |
Script Requirements
Your script in the GitLab repository should:
- Be executable (
chmod +x) - Use
#!/bin/shor#!/bin/bashshebang - Have kubectl binary available (uses
bitnami/kubectl:latestimage) - Use service account permissions for Kubernetes operations
Example Script
#!/bin/bash
set -e
# Wait for resource deletion
kubectl delete deployment old-app --ignore-not-found=true
kubectl wait --for=delete deployment/old-app --timeout=300s
# Apply new resources
kubectl apply -f manifests/new-app.yaml
kubectl wait --for=condition=available deployment/new-app --timeout=300s
echo "Deployment complete"
Development
Prerequisites
- Go 1.24+
- Kubebuilder
- Docker
Build
# Generate CRDs and manifests
make generate
make manifests
# Build operator image
make docker-build IMG=your-registry/gitlabjobrunner-operator:latest
# Push image
make docker-push IMG=your-registry/gitlabjobrunner-operator:latest
Testing
# Run tests
make test
# Run e2e tests
make test-e2e
Monitoring
The operator exposes metrics on port 8443 (HTTPS) by default:
- Custom resource reconciliation metrics
- Job/CronJob creation status
- GitLab access errors
Security Considerations
- GitLab Token: Store in Kubernetes Secret, use read-only tokens with minimal scope
- Service Account: Grant only necessary permissions for script operations
- Network Policies: Restrict pod network access if needed
- Image Security: Use trusted container images, enable image scanning
Troubleshooting
Check Operator Logs
kubectl logs -n cronjob-restore-system deployment/cronjob-restore-controller-manager
Check Job/CronJob Status
kubectl get jobs,cronjobs
kubectl describe job <job-name>
Check GitlabJobRunner Status
kubectl get gitlabjobrunner
kubectl describe gitlabjobrunner <name>
Common Issues
- Git clone fails: Verify GitLab credentials in Secret
- Script not found: Check repositoryURL, branch, and scriptPath
- Permission denied: Ensure ServiceAccount has necessary RBAC permissions
- CronJob not triggering: Verify schedule syntax and suspend field
License
Apache License 2.0