Vassiliy Yegorov cdfcdac23f
All checks were successful
docker-build / Build image (push) Successful in 39s
git oauth
2025-12-07 20:52:14 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:35:56 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:35:56 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:52:14 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:35:56 +07:00
2025-12-07 20:18:17 +07:00
2025-12-07 20:35:56 +07:00

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:

  1. Clones the specified GitLab repository using credentials from a Secret
  2. Creates either a Job (one-time) or CronJob (scheduled) based on the spec
  3. Executes the specified script from the repository
  4. Manages lifecycle and status updates

Prerequisites

  • Kubernetes cluster (1.24+)
  • kubectl configured
  • GitLab repository with scripts
  • GitLab access token with read permissions

Installation

# 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: https://gitlab.example.com/mygroup/myrepo.git
  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: https://gitlab.example.com/mygroup/myrepo.git
  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 (full URL or relative path like "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/sh or #!/bin/bash shebang
  • Have kubectl binary available (uses bitnami/kubectl:latest image)
  • 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

  1. GitLab Token: Store in Kubernetes Secret, use read-only tokens with minimal scope
  2. Service Account: Grant only necessary permissions for script operations
  3. Network Policies: Restrict pod network access if needed
  4. 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

Description
No description provided
Readme 117 KiB
Languages
Go 79.9%
Makefile 15.9%
Smarty 2.4%
Dockerfile 1.8%