GitLab

Git path: charts/all/gitlab-operator/

GitLab (GitLab Operator, standard profile) is the in-cluster SCM on the hub. Developer Hub scaffolder publishes projects here (via publish:github with GitLab host integration), GitLab Runner executes Tekton-related CI jobs, and DevSpaces clones from GitLab on the hub while workspaces run on spokes.

What ships

Resource Purpose
GitLab Operator Subscription gitlab-operator-kubernetes (community-operators, channel stable, Automatic InstallPlan)
GitLab CR Namespace gitlab — chart 9.11.6, webservice (min 3 / max 8), gitaly, PostgreSQL, bundled MinIO, Container Registry
GitLab Runner Controlled by runnerEnabled: true/false in values (default false if namespace gitlab-runner removed)
Route https://gitlab.apps.<hub-domain> via route-gitlab-apps.yaml (canonical workshop URL)
Istio Gateway gitlab-gateway in namespace gitlab — dedicated Gateway + HTTPRoute with LFS/upload 120s timeout and KAS WebSocket routing
Route (gateway) https://gitlab-gw.apps.<hub-domain> — edge TLS → Istio gateway
PostSync gitlab-workshop-bootstrap Groups ws-user1ws-userN, developer-hub, app-of-apps, workshop-demos
PostSync gitlab-token-setup PAT → GITLAB_TOKEN in developer-hub-oidc-auth for scaffolder API

Workshop scaling (for ~50 concurrent users)

Component min max CPU req/limit Memory limit
webservice 3 8 1 / 3 5 Gi
sidekiq 2 6 500m / 2 4 Gi
gitlab-shell 2 5

Override in charts/all/gitlab-operator/values.yaml under gitlab.webservice, gitlab.sidekiq, gitlab.gitlabShell.

GitLab Runner (runnerEnabled flag)

Runner resources (OperatorGroup, Subscription, Runner CR, Role, RoleBinding) are all guarded by:

# charts/all/gitlab-operator/values.yaml
runnerEnabled: false   # set true to enable (namespace gitlab-runner must exist first)

Bootstrap job also skips the gitlab-runner-token secret when the namespace is absent.

Workshop users authenticate to GitLab with the same credentials as Developer Hub (Keycloak / userN / Welcome123!) until OmniAuth is fully wired.

Scaffolder integration

Templates publish to:

gitlab.apps.<hub-domain>?owner=ws-<user>&repo=<name>-<targetCluster>

Developer Hub proxies GitLab for delete and webhook actions at /api/proxy/gitlab.

Operator discovery

GitLab is deployed via OLM operators. Catalog entities reference source with:

annotations:
  backstage.io/source-location: url:https://gitlab.apps.<hub-domain>/ws-<user>/<repo>

Verify

oc get gitlab -n gitlab
oc get runners -n gitlab-runner
oc get route -n gitlab
curl -skI "https://gitlab.apps.<hub-domain>/"
curl -sk -H "PRIVATE-TOKEN: <token>" "https://gitlab.apps.<hub-domain>/api/v4/version"

Kairos SmartScalingPolicies for GitLab

Four SmartScalingPolicy CRs in kairos-system (label kairos.io/policy-type: workshop-platform) make GitLab resources visible in the Kairos Console UI and auto-tune resources under workshop load:

Policy Target Trigger
gitlab-webservice-workshop webservice CPU >75% → +30% (max 3), mem >80% → +25% (max 5Gi)
gitlab-sidekiq-workshop sidekiq CPU >70% → +50% (max 2), mem >85% → +20% (max 4Gi)
gitlab-kas-workshop kas CPU >60% → +25%
gitlab-registry-workshop registry CPU >70% → +30%, mem >80% → +20%

Policies are defined in charts/all/kairos/templates/gitlab-scaling-policies.yaml.

Dedicated Istio Gateway

charts/all/gitlab-operator/templates/gitlab-gateway.yaml creates an Istio mesh entrypoint for GitLab:

[user] → OpenShift Route (edge TLS) → gitlab-gateway-istio (ClusterIP)
       → HTTPRoute → gitlab-webservice-default:8080

HTTPRoute rules:

  • /info/lfs, /upload → webservice (120s timeout for Git LFS and large pushes)
  • /-/kubernetes → gitlab-kas:8154 (KAS WebSocket for DevSpaces)
  • / → webservice (60s default)

The canonical gitlab-apps Route is still present for direct route access. The gateway route gitlab-gw.apps.* adds Istio observability.

Troubleshooting

Symptom Fix
GitLab pods Pending Hub undersized — use 4×16/64 workers; check PVC storage class
ConfigError object storage / connection empty Chart enables bundled MinIO (global.minio.enabled: true); do not disable MinIO without external S3
Route 503 but pods Running Operator route is gitlab-gitlab.apps.*; workshop URL is gitlab.apps.* — confirm route/gitlab-apps exists
Argo gitlab-operator SyncFailed on GitLab CR Expected until GitLab Operator CSV installs (SkipDryRunOnMissingResource on CR); subscriptions sync at wave 2
Argo gitlab-operator Missing (Runner resources) gitlab-runner namespace missing — set runnerEnabled: false in values; remove stuck finalizer: oc patch runner.apps.gitlab.com gitlab-runner -n gitlab-runner --type json -p '[{"op":"remove","path":"/metadata/finalizers"}]'
Argo operation stuck on Subscription/gitlab-runner-operator Terminate: oc patch application gitlab-operator -n openshift-gitops --type merge -p '{"operation":null}' then re-sync
InstallPlan Manual / operator never installs values.yaml sets installPlanApproval: Automatic for both GitLab subscriptions
Scaffolder publish 404 Confirm ws-<owner> group exists; re-run gitlab-workshop-bootstrap
Bootstrap fails with Forbidden on gitlab-runner-token gitlab-runner namespace missing — already guarded with namespace check in chart; delete old failed job pods
Runner not picking jobs Check gitlab-runner-token Secret and Runner CR tags include openshift
GITLAB_TOKEN invalid Re-run PostSync gitlab-token-setup in developer-hub (skips with exit 0 if GitLab not deployed yet)

Documentation

Next: Scaffolding for group naming and template catalog URL.