Migrate a GitLab resource to a GitLabCore resource
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed
- Status: Experiment
Use kubectl bridge migrate to move an instance from a GitLab resource (apps.gitlab.com/v1beta1)
to a GitLabCore resource (apps.gitlab.com/v2alpha1) of the same name. After the migration, you
manage the instance in Bridge.
The command deletes the GitLab resource, then creates the GitLabCore resource. The instance is
down from the delete until the GitLabCore resource is available.
Bridge is an experiment in an early development phase. Migrate only an instance you can afford to lose.
Data the migration keeps
The migration keeps:
- The Gitaly volumes, and with them the Git repositories.
- The Secrets the GitLab chart generated, such as the Rails secrets and the root password.
- The external PostgreSQL, Redis, and object storage, and the data in them.
- The Gateways, EnvoyProxies, and
LoadBalancerServices, so the instance keeps its IP addresses. - The cert-manager issuers, so certificates keep being issued and renewed.
The migration removes:
- The bundled Prometheus and its metrics history. A
GitLabCoreresource always turns it off. - The other volume claims the
GitLabresource owns, such as the Toolbox scratch volumes. - The
app.kubernetes.iolabels the Operator adds to every object of aGitLabresource. The labels yourGitLabresource sets itself stay.
The command lists what it removes before it changes anything.
How the command drafts the GitLabCore resource
The command drafts a GitLabCore resource that renders the same chart values as the GitLab
resource:
spec.versionpins the chart version theGitLabresource runs, with theStatictype. To follow GitLab releases after the migration, change the version type.- A setting moves into a structured field, such as
spec.domain, only when the chart values stay the same. Every other setting stays inspec.chart.values. - Custom certificate authorities (
global.certificates.customCAs) move intospec.certificates. A list the field cannot hold stays inspec.chart.values, and the command lists it underTrust:. - The Gateway API setup stays in the chart values. The command leaves
spec.networkingunset, because its modes would change the Gateway the instance runs on. - The Operator generates the shared Secrets through a
GitLabSecretsresource instead of the shared secrets Job. It keeps every existing Secret, and adds only missing keys. - OpenBao and the AI gateway stay off, as they were under the
GitLabresource.
The command prints every difference from the GitLab resource, grouped by topic, such as
Monitoring:, Persistence:, Secrets:, or Labels:.
Prerequisites
- An Operator with Bridge enabled (
bridge.enabledset totrue) that watches the namespace of theGitLabresource, and has finished rolling out. For more information, see Try Bridge in a development environment. - The
v2alpha1custom resource definitions in the cluster. - The
kubectl bridgeplugin, built from the same branch as the Operator image. The draft uses the chart defaults of the plugin version. If the versions of the plugin and the Operator cannot be compared, the command warns. If they can be compared and differ, the command stops. - A
GitLabresource that runs GitLab chart 10.5.0 or later, is in theRunningphase with theAvailablecondition, and is not upgrading. - The
GitLabresource does not use the bundled NGINX Ingress (nginx-ingress.enabledornginx-ingress-geo.enabled), because aGitLabCoreresource always turns it off. - The
GitLabresource does not request cert-manager certificates for its Ingresses (global.ingress.configureCertmanager). - No
GitLabCoreresource of the same name exists in the namespace. - Your kubeconfig identity has the permissions the command needs.
- If Argo CD, Flux, or Helm manages the
GitLabresource, remove it from that tool first. Otherwise, the tool creates theGitLabresource again, and two Operator controllers compete for the instance.
Optional. Back up the instance before you migrate it.
Permissions the command needs
The command acts as your kubeconfig identity. In the namespace of the GitLab resource, it needs:
| Resources | Verbs |
|---|---|
gitlabs.apps.gitlab.com | get, patch, delete |
gitlabcores.apps.gitlab.com | get, create |
| ConfigMaps | get, create |
| Pods and PersistentVolumeClaims | list |
| Services, and the Gateways, EnvoyProxies, and cert-manager Issuers of the instance | list, patch |
To check the Operator, the command also lists Deployments in all namespaces. Without that permission, the command cannot check the Operator, and warns instead.
Review the draft
Run the command with --dry-run. The command checks the instance, prints the GitLabCore
resource it drafts, and changes nothing:
kubectl bridge migrate <gitlab_name> --namespace <namespace> --dry-runThe output lists:
- The structured fields the draft moved settings into.
- The differences from the
GitLabresource. - The warnings you must accept, such as the volume claims the delete removes.
- The blockers. The command does not migrate an instance while any blocker remains.
Resolve every blocker, and run the command again until the output lists none.
Migrate the instance
Run the command without
--dry-run:kubectl bridge migrate <gitlab_name> --namespace <namespace>Accept each warning, then confirm the delete of the
GitLabresource.
The command then:
- Stores the
GitLabresource, its UID, and the draft in the ConfigMap<gitlab_name>-v1beta1-migration. - Adds the annotation
apps.gitlab.com/migrate-to: GitLabCoreto theGitLabresource, and waits until the resource reports theMigratingcondition. From then on, the Operator stops applying theGitLabresource. - Removes the owner reference to the
GitLabresource from the objects the migration keeps. - Deletes the
GitLabresource, and waits until the resource and the pods of the instance are gone. - Creates the
GitLabCoreresource, and waits until it is available.
To skip the prompts, for example in a script, add --yes. By default, the command waits up to 30
minutes for the GitLab resource to be deleted, and again for the GitLabCore resource to
become available. To change that limit, use --timeout.
For all options, run kubectl bridge migrate --help.
After the migration, the ConfigMap stays in the namespace. You need it to hand the instance back.
Continue an interrupted migration
If the command stops, for example at a timeout, it undoes nothing. Run the same command again. The
command continues from the ConfigMap, and asks for confirmation again while the GitLab
resource still exists.
Cancel a migration before the delete
While the GitLab resource still exists, you can hand the instance back to it. Remove
the annotation, and delete the ConfigMap:
kubectl annotate gitlab <gitlab_name> --namespace <namespace> apps.gitlab.com/migrate-to-
kubectl delete configmap <gitlab_name>-v1beta1-migration --namespace <namespace>The Operator removes the Migrating condition and manages the GitLab resource again.
Hand the instance back to the GitLab resource
The command does not hand a migrated instance back. The ConfigMap keeps the GitLab resource as it
was before the migration, so you can restore it by hand.
Deleting the GitLabCore resource deletes every object it manages, except volume claims and
Secrets. That includes the Gateways and LoadBalancer Services it took over, so the IP addresses
of the instance change. The cert-manager issuers the migration kept stay.
To hand the instance back:
Save the
GitLabresource from the ConfigMap:kubectl get configmap <gitlab_name>-v1beta1-migration --namespace <namespace> \ --output jsonpath='{.data.gitlab\.yaml}' > gitlab.yamlDelete the
GitLabCoreresource, and wait until it is gone:kubectl delete gitlabcore <gitlab_name> --namespace <namespace> --waitCreate the
GitLabresource again:kubectl apply --filename gitlab.yamlDelete the ConfigMap, so that a later migration starts from the new
GitLabresource:kubectl delete configmap <gitlab_name>-v1beta1-migration --namespace <namespace>