Skip to content

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):

flux install \
  --components source-controller,helm-controller \
  --version 2.3.0

Verify:

flux check

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:

kubectl get crd perconapgclusters.pgv2.percona.com

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:

kubectl get crd redis.redis.opstreelabs.in

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:

kubectl get crd elasticsearches.elasticsearch.k8s.elastic.co

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 Deployment with leader election enabled
  • A ServiceAccount and ClusterRole with the minimum RBAC permissions
  • All three CRDs (GitlabInstance, GitlabVersionMap, GitlabProfile) from charts/bnerd-gitlab-operator/crds/

Verify the operator is running:

kubectl get pods -n bnerd-gitlab-operator
# NAME                                       READY   STATUS    RESTARTS   AGE
# bnerd-gitlab-operator-7d9f6c8b4-xk2lp     1/1     Running   0          30s
# 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:

kubectl apply -f examples/versionmap-default.yaml

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.