Install the GitLab Operator in a disconnected OpenShift cluster
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed
Install the GitLab Operator and GitLab on an OpenShift cluster that cannot reach public container registries by using the manifest or Helm installation method.
- Copy the container images to a registry inside your network.
- Configure the cluster to pull from that registry.
Installation with the Operator Lifecycle Manager (OLM) is experimental and is not covered by this page.
Before you begin
Before you install the GitLab Operator in a disconnected OpenShift cluster, you need:
- An OpenShift cluster at a supported version.
- A container registry that the cluster nodes can reach, referred to here as
<mirror_registry>. The cluster must trust its TLS certificate. - A host with internet access and the
oc,oc-mirror, andhelmcommand-line tools. If the host cannot reach<mirror_registry>, you also need a host inside your network with the same tools. Use theoc-mirrorplugin v2 to copy the container images to<mirror_registry>. - The other installation prerequisites, such as cert-manager. Their container images must be available to the cluster too. OpenShift Routes need no separate Ingress or Gateway API controller.
- Credentials for
<mirror_registry>in the global cluster pull secret, if the registry requires authentication.
To make the cluster trust the registry certificate, add the certificate authority (CA) to the cluster
image configuration. Use the registry host name as the key. For a registry on a port other than 443,
write the key as <host>..<port>. For more information, see
configuring additional trust stores for image registry access.
oc create configmap mirror-registry-ca \
--namespace openshift-config \
--from-file=<registry_host>=ca.crt
oc patch image.config.openshift.io/cluster --type merge \
--patch '{"spec":{"additionalTrustedCA":{"name":"mirror-registry-ca"}}}'Choose how to redirect container image pulls
The cluster must pull each container image from <mirror_registry> instead of its public registry.
You can redirect pulls in two ways:
- Use an ImageTagMirrorSet. The cluster nodes rewrite the container image names. You change nothing in the GitLab Operator or the GitLab custom resource (CR). This method is the same for the manifest and Helm installation methods.
- Set the container image locations in values. You change the GitLab Operator container image, in the manifest or in the Helm values, and every container image value of the GitLab CR.
Mirror the container images
The GitLab Operator and the GitLab chart pull container images from registry.gitlab.com. The
charts pull container images by tag, so an ImageDigestMirrorSet alone does not redirect them.
Find the GitLab Operator version and the chart version. The chart version is
spec.chart.versionin your GitLab CR. It is one of the versions in theCHART_VERSIONSfile of the GitLab Operator release. The GitLab Operator container image tag is the GitLab Operator version.List the container images the chart needs. Save the content of
spec.chart.valuesfrom your GitLab CR invalues.yaml, with the values from Install GitLab.Render the chart, as the custom images page describes:
helm repo add gitlab https://charts.gitlab.io helm template gitlab gitlab/gitlab --version <chart_version> --values values.yaml \ | grep 'image:' | tr -d '[:blank:]"' | sort --uniqueThe list can include container images that the GitLab Operator does not deploy. The GitLab Operator does not use the chart’s cert-manager or Envoy Gateway. Leave out the
quay.io/jetstackanddocker.io/envoyproxycontainer images.Create an
imageset-config.yamlfile with the GitLab Operator container image and every container image from the previous step. Copy each tag from thehelm templateoutput. Some container images do not use the GitLab version as their tag.This example fits a CR with the container registry, GitLab Exporter, and the agent server for Kubernetes (KAS). It also uses the chart’s self-signed certificate. A CR that turns these off needs fewer container images:
kind: ImageSetConfiguration apiVersion: mirror.openshift.io/v2alpha1 mirror: additionalImages: - name: registry.gitlab.com/gitlab-org/cloud-native/gitlab-operator:<operator_version> - name: registry.gitlab.com/gitlab-org/build/cng/certificates:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/cfssl-self-sign:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-base:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-container-registry:<registry_tag> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-exporter:<exporter_tag> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-kas:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-shell:<gitlab_shell_tag> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-sidekiq-ee:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-toolbox-ee:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-webservice-ee:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/gitlab-workhorse-ee:v<gitlab_version> - name: registry.gitlab.com/gitlab-org/build/cng/kubectl:v<gitlab_version>Copy the container images to your registry:
oc-mirror --v2 --config imageset-config.yaml \ --workspace file://<workspace_dir> docker://<mirror_registry>oc-mirrorkeeps the repository paths. For example, the GitLab Operator container image becomes<mirror_registry>/gitlab-org/cloud-native/gitlab-operator:<operator_version>. It also writes anImageTagMirrorSetto<workspace_dir>/working-dir/cluster-resources/itms-oc-mirror.yaml.If no host can reach both the internet and
<mirror_registry>, mirror through a disk instead. On the host with internet access, write the container images to a directory:oc-mirror --v2 --config imageset-config.yaml file://<archive_dir>Copy the directory to a host that can reach
<mirror_registry>, and run:oc-mirror --v2 --config imageset-config.yaml \ --from file://<archive_dir> docker://<mirror_registry>The
ImageTagMirrorSetis then at<archive_dir>/working-dir/cluster-resources/itms-oc-mirror.yaml. For more information, see mirroring an image set in a fully disconnected environment.
Add the container images of other prerequisites, such as cert-manager or an object storage server, to the same image set.
Redirect pulls with an ImageTagMirrorSet
The ImageTagMirrorSet that oc-mirror generates maps each public repository to its mirror:
apiVersion: config.openshift.io/v1
kind: ImageTagMirrorSet
metadata:
name: itms-generic-0
spec:
imageTagMirrors:
- mirrors:
- <mirror_registry>/gitlab-org/build/cng
source: registry.gitlab.com/gitlab-org/build/cng
- mirrors:
- <mirror_registry>/gitlab-org/cloud-native
source: registry.gitlab.com/gitlab-org/cloud-nativeFor more information, see image registry repository mirroring.
Apply the
ImageTagMirrorSet. If you mirrored directly, use the file in<workspace_dir>:oc apply -f <workspace_dir>/working-dir/cluster-resources/itms-oc-mirror.yamlIf you mirrored through a disk, use the file in
<archive_dir>:oc apply -f <archive_dir>/working-dir/cluster-resources/itms-oc-mirror.yamlWait for the
MachineConfigPoolresources to finish updating. TheUPDATEDcolumn must readTrue.oc get machineconfigpoolOpenShift drains each node to apply the
ImageTagMirrorSet, and can reboot it. Plan for the pods on each node to be evicted and rescheduled.
Then install the GitLab Operator and GitLab.
An ImageDigestMirrorSet redirects only pulls that name a digest. It does not redirect pulls
that name a tag. Add one only for container images that you reference by digest. For example, add one when
you install the GitLab Operator Helm chart with --set image.digest=<digest>.
Install the GitLab Operator
On the host with internet access, download the release manifest. Copy it to a host that can reach the cluster:
curl --fail --location --remote-name \ https://gitlab.com/api/v4/projects/18899486/packages/generic/gitlab-operator/<operator_version>/gitlab-operator-openshift-<operator_version>.yamlCreate the namespace, and apply the manifest:
oc create namespace gitlab-system oc apply -f gitlab-operator-openshift-<operator_version>.yaml
On the host with internet access, download the chart. Copy it to a host that can reach the cluster:
helm pull oci://registry.gitlab.com/charts/charts.gitlab.io/release/gitlab-operator \ --version <operator_version>Install the chart from the file:
helm install gitlab-operator ./gitlab-operator-<operator_version>.tgz \ --create-namespace \ --namespace gitlab-system
Confirm that the GitLab Operator is running:
oc --namespace gitlab-system rollout status deployment/gitlab-controller-managerInstall GitLab
Create the GitLab CR as described in Installing GitLab.
The ImageTagMirrorSet needs no setting in the CR.
The example CR requests certificates from Let’s Encrypt, which a disconnected cluster cannot reach. In GitLab 19.0 and later, the GitLab chart also uses Gateway API and creates no Ingress by default. To serve GitLab through OpenShift Routes with a self-signed certificate, set these values in the CR:
spec:
chart:
values:
global:
ingress:
enabled: true
class: none
configureCertmanager: false
annotations:
route.openshift.io/termination: "edge"
gatewayApi:
enabled: falseOpenShift creates Routes from the Ingress objects that the chart renders.
Set global.hosts.domain to the cluster apps domain, or to a domain that resolves to the OpenShift
router. Routes do not support Git over SSH.
For more information, see OpenShift Routes.
The chart generates a self-signed wildcard certificate, which browsers and Git clients do not trust.
To use a certificate from your own certificate authority, see
use your own wildcard certificate.
The GitLab Operator still creates a cert-manager Issuer for Let’s Encrypt. Its status stays False, and
GitLab does not use it.
Apply the CR:
oc --namespace gitlab-system apply -f mygitlab.yaml
oc --namespace gitlab-system get gitlabWhen the status is Running, the instance is ready.
Redirect pulls with container image values
Use this method when you cannot create an ImageTagMirrorSet. Mirror the container images as described in
Mirror the container images, and do not apply the ImageTagMirrorSet.
Set the GitLab Operator container image
Download the release manifest as described in Install the GitLab Operator. The manifest names the GitLab Operator container image in its
Deployment. Change the registry to<mirror_registry>before you apply the manifest:sed -i.bak \ 's|registry.gitlab.com/gitlab-org/cloud-native/gitlab-operator:|<mirror_registry>/gitlab-org/cloud-native/gitlab-operator:|' \ gitlab-operator-openshift-<operator_version>.yamlConfirm that the manifest names one container image, and that it points to
<mirror_registry>:grep 'image:' gitlab-operator-openshift-<operator_version>.yamlCreate the namespace, and apply the manifest:
oc create namespace gitlab-system oc apply -f gitlab-operator-openshift-<operator_version>.yaml
Download the GitLab Operator chart as described in Install the GitLab Operator.
Install it, and set its container image registry to <mirror_registry>:
helm install gitlab-operator ./gitlab-operator-<operator_version>.tgz \
--create-namespace \
--namespace gitlab-system \
--set image.registry=<mirror_registry>Confirm that the GitLab Operator is running, as described in Install the GitLab Operator.
Set the GitLab container image values
In the GitLab CR, set the repository of every container image the chart renders. The
global.image.registryvalue alone is not enough, because it applies only to the Mailroom chart. Pods that use other container images still pull fromregistry.gitlab.com.This example shows the pattern for the global container images, Gitaly, and Webservice:
spec: chart: values: global: kubectl: image: repository: <mirror_registry>/gitlab-org/build/cng/kubectl certificates: image: repository: <mirror_registry>/gitlab-org/build/cng/certificates gitlabBase: image: repository: <mirror_registry>/gitlab-org/build/cng/gitlab-base gitlab: gitaly: image: repository: <mirror_registry>/gitlab-org/build/cng/gitaly init: image: repository: <mirror_registry>/gitlab-org/build/cng/gitlab-base webservice: image: repository: <mirror_registry>/gitlab-org/build/cng/gitlab-webservice-ee init: image: repository: <mirror_registry>/gitlab-org/build/cng/gitlab-base workhorse: image: <mirror_registry>/gitlab-org/build/cng/gitlab-workhorse-eeRepeat the pattern for the other charts that render container images, such as
gitlab-shell,migrations, andsidekiq. The example values file lists the keys. The self-signed certificate also needsshared-secrets.selfsign.image.repository.In the same CR, set the values from Install GitLab. Render the chart again, and confirm that no container image still points to
registry.gitlab.com. Then apply the CR.
Check that the cluster pulls from the mirror
The pod specifications keep the original container image names when you use an ImageTagMirrorSet. To confirm
the redirect, check the access log of your mirror registry for requests to the mirrored repositories.
To list the pulls the cluster has made, run:
oc --namespace gitlab-system get events --field-selector reason=PulledFix container image pull errors
A pod that cannot pull a container image shows ImagePullBackOff. The event names the container image and the
registry that the node could not reach:
oc --namespace gitlab-system get events --field-selector reason=FailedFailed to pull image "registry.gitlab.com/gitlab-org/cloud-native/gitlab-operator:<operator_version>":
unable to pull image: initializing source docker://registry.gitlab.com/...: pinging container registry
registry.gitlab.com: ...If the event names a public registry, the mirror lacks the container image or no mirror set covers it.
Add the container image to the image set, run oc-mirror again, and check the ImageTagMirrorSet.