Installation¶
This page covers installing the cluster prerequisites and the bnerd-gitlab-operator itself.
Cluster prerequisites¶
The operator depends on several external controllers. Install them once per cluster before installing the operator. All are optional depending on which features you use, with one hard requirement: Flux.
1. Flux CD (required)¶
The operator emits HelmRelease (helm.toolkit.fluxcd.io/v2beta1) and HelmRepository (source.toolkit.fluxcd.io/v1beta2) resources. Flux's source-controller and helm-controller must be running to apply them.
Install Flux 2.3.x (the version that serves the v2beta1 HelmRelease API):
Verify:
Flux version and HelmRelease API version
The operator targets helm.toolkit.fluxcd.io/v2beta1. Flux 2.3.x serves this API. Newer Flux releases (2.4+) may deprecate v2beta1 in favour of v2; check the Flux changelog before upgrading Flux on a cluster running this operator.
2. Percona PostgreSQL Operator (for managed Postgres)¶
Required when any GitlabInstance uses spec.postgres.managed: true. Install the Percona PG Operator into its own namespace:
# Via Helm
helm repo add percona https://percona.github.io/percona-helm-charts/
helm install pg-operator percona/pg-operator \
--namespace pgo \
--create-namespace
Verify:
3. OT-Container-Kit redis-operator (for managed Redis)¶
Required when any GitlabInstance uses spec.redis.managed: true.
helm repo add ot-helm https://ot-container-kit.github.io/helm-charts/
helm install redis-operator ot-helm/redis-operator \
--namespace ot-operators \
--create-namespace
Verify:
OT-Container-Kit v0.25.0 readiness quirk
OT-Container-Kit v0.25.0 ships an empty RedisStatus struct; the status.readyReplicas field is pruned by the API server. The operator detects this and falls back to inspecting the underlying StatefulSet's readyReplicas instead. No configuration needed — this is handled transparently.
4. ECK — Elastic Cloud on Kubernetes (for managed Elasticsearch, EE only)¶
Required only when deploying GitLab Enterprise Edition with managed Elasticsearch (spec.elasticsearch.managed: true).
kubectl create -f https://download.elastic.co/downloads/eck/2.12.1/crds.yaml
kubectl apply -f https://download.elastic.co/downloads/eck/2.12.1/operator.yaml
Verify:
Installing the operator¶
helm install bnerd-gitlab-operator charts/bnerd-gitlab-operator \
--namespace bnerd-gitlab-operator \
--create-namespace \
--set image.tag=0.1.0-beta
The Helm chart installs:
- The operator
Deploymentwith leader election enabled - A
ServiceAccountandClusterRolewith the minimum RBAC permissions - All three CRDs (
GitlabInstance,GitlabVersionMap,GitlabProfile) fromcharts/bnerd-gitlab-operator/crds/
Verify the operator is running:
# Build and apply via kustomize
make deploy IMG=git.bnerd.net/cloud/operators/bnerd-gitlab-operator:0.1.0-beta
This applies the manifests in config/manager/ using kustomize and sets the operator image. CRDs from config/crd/bases/ are applied first.
Useful for development or when you want to run directly from a repository checkout without packaging a Helm chart.
Applying the default GitlabVersionMap¶
The GitlabVersionMap named default is required for version resolution. Apply it once per cluster after installing the operator:
The default map covers the GitLab 17.x → 19.x upgrade path, including all required upgrade stops. See Version Map Reference for the full ladder.
Verifying the installation¶
# Operator pod
kubectl get pods -n bnerd-gitlab-operator
# CRDs registered
kubectl get crd | grep k8s.bnerd.com
# Default version map
kubectl get glvm default
# Operator logs (no errors expected)
kubectl logs -n bnerd-gitlab-operator deploy/bnerd-gitlab-operator --tail=50
RBAC summary¶
The operator requires cluster-level read access to CRDs (for capability gating) and namespace-level create/update/delete access for Secrets, PerconaPGCluster, Redis CRs, ECK Elasticsearch, and Flux HelmRelease/HelmRepository resources. The full role is in config/rbac/role.yaml.
The operator runs with a non-root UID (65532) and a read-only root filesystem by default.