The deployment of GitLab onto a Kubernetes cluster via Helm charts represents a paradigm shift from traditional omnibus installations, moving toward a Cloud Native GitLab (CNG) architecture. This approach is designed to leverage the orchestration capabilities of Kubernetes, providing a scalable and resilient environment for the Free, Premium, and Ultimate tiers of GitLab Self-Managed offerings. Unlike standard application deployments, a production-grade GitLab installation on Kubernetes requires a sophisticated understanding of stateful service management and external dependency integration. The core philosophy of this deployment is the Cloud Native Hybrid reference architecture, which acknowledges that while the application logic and stateless components thrive within Kubernetes pods, the critical stateful data layers must reside on specialized infrastructure to ensure data integrity, high availability, and performance at scale.
Architectural Requirements and Production Constraints
The deployment of GitLab on Kubernetes is not a "one-click" process for production environments. It necessitates a strict adherence to the Cloud Native Hybrid reference architecture. This architecture is predicated on the fact that not all GitLab services are suitable for running within a Kubernetes cluster if production-grade stability is required.
The most critical requirement for any production deployment is the use of external stateful services. The GitLab Helm chart explicitly requires external PostgreSQL, Redis, and object storage.
PostgreSQL and Redis
These services must run outside the Kubernetes cluster on Platform-as-a-Service (PaaS) offerings or dedicated compute instances. The necessity for this external placement is driven by the need to scale and reliably service the diverse and intense workloads associated with production GitLab environments. Running these as pods within the cluster for production is discouraged because it introduces complexities in volume management and database stability that can lead to catastrophic data loss or downtime.Object Storage
For all non-Git repository storage, Cloud PaaS object storage is required. This ensures that artifacts, uploads, and other binary data are stored in a durable, scalable environment that exists independently of the cluster's lifecycle.Non-Production Environments
In contrast to production, the default configuration for evaluation or non-production environments includes bundled versions of these services. For instance, the default configuration utilizes MinIO for object storage. While this allows for rapid testing and evaluation, it is strictly forbidden for production use due to the lack of enterprise-grade durability and scaling.
The impact of these requirements means that an administrator cannot simply run a single command without first provisioning the underlying cloud infrastructure. This creates a dependency chain where the cloud environment (AWS, GCP, Azure) must be prepared before the Helm chart can be successfully deployed.
Deployment Strategy via Helm v3
The deployment process utilizes Helm v3, the package manager for Kubernetes. A critical distinction in Helm v3 is that the release name must be specified as a positional argument on the command line, unless the --generate-name option is invoked.
The deployment sequence begins with the preparation of the Helm repository and the synchronization of the latest chart versions.
helm repo add gitlab https://charts.gitlab.io/
helm repo update
Once the repository is current, the installation is executed using the helm upgrade --install command. This specific command is preferred over a simple install because it allows for seamless updates and ensures that the release is created if it does not already exist.
The standard execution command for a basic deployment is as follows:
helm upgrade --install gitlab gitlab/gitlab \
--timeout 600s \
--set global.hosts.domain=example.com \
--set global.hosts.externalIP=10.10.10.10 \
--set [email protected]
Analysis of the command flags reveals several critical operational details:
The timeout parameter
The--timeout 600sflag is applied to the installation of each individual component and not to the overall installation process. This is a common point of confusion for administrators. If a user sets--timeout=3m(180 seconds), the installation might still take 5 minutes to complete, provided that no single component took longer than 3 minutes to install.Global host settings
The--set global.hosts.domain=example.comflag defines the base domain for the instance. Unless these settings are modified, the default domain for accessing the GitLab instance will begitlab.example.com.External IP and Certification
The--set global.hosts.externalIP=10.10.10.10identifies the entry point for the traffic, while--set [email protected]configures the automated certificate management via cert-manager to ensure encrypted HTTPS traffic.
Edition Selection and Lifecycle Management
GitLab offers different editions of its software, and the Helm chart allows for the selection of the specific version to be deployed.
Enterprise Edition (EE)
By default, the Helm charts deploy the Enterprise Edition. This is the "open core" version of GitLab. It is free to use but includes the capability to upgrade to paid tiers (Premium or Ultimate) to unlock advanced features.Community Edition (CE)
For users who require a version licensed under the MIT Expat license, the Community Edition is available. To deploy this version, the following flag must be added to the installation command:
--set global.edition=ce
- Conversion Process
If an organization deploys the Community Edition and later decides to transition to the Enterprise Edition, a redeployment is required. This is achieved by running the Helm upgrade command without the--set global.edition=ceflag.
Post-Deployment Verification and Initial Access
Once the helm upgrade --install command is executed, the deployment process begins. This process typically takes between 5 to 10 minutes to fully reconcile all Kubernetes resources.
The status of the deployment can be monitored in real-time using the following command in a separate terminal window:
helm status gitlab
Upon completion, the system will output a list of all installed resources. To access the instance, the administrator must visit the domain specified during the installation (e.g., gitlab.example.com).
The initial administrative access is managed via the root user password. There are two scenarios for this password:
- Manual Secret Creation: If the administrator manually created the secret for the initial root password, that password is used for sign-in.
- Automatic Generation: If no secret was provided, GitLab automatically generates a random password for the root user.
To extract the automatically generated password from the Kubernetes secrets, the following command is used (replacing <name> with the release name, such as gitlab):
kubectl get secret <name>-gitlab-initial-root-password -ojsonpath='{.data.password}' | base64 --decode ; echo
Advanced Operational Configuration
For production environments, the use of raw command-line flags is often insufficient for managing complexity. Infrastructure as Code (IaC) is recommended to handle the combination of Helm charts and supplemental cloud infrastructure.
GitLab Environment Toolkit IaC
GitLab provides the GitLab Environment Toolkit, which automates the provisioning of the hybrid cloud architecture.AWS EKS Implementation Pattern
A specific implementation pattern exists for provisioning Cloud Native Hybrid GitLab on AWS EKS. This includes a Bill of Materials (BOM) that has been validated with the GitLab Performance Toolkit and includes AWS Cost Calculator integration for budgetary planning.Zero Downtime Upgrades
To prevent service interruptions during version updates, users must configure rolling update strategies during the initial installation. This ensures that the cluster can transition to a new version of GitLab without taking the entire service offline.Version Pinning
While the latest chart is usually desired, specific versions can be installed using the--versionflag:
--version <installation version>
This is critical for environments where specific GitLab version mappings are required to ensure compatibility between the chart and the application version.
GitLab Runner Deployment on Kubernetes
The GitLab Runner is the agent that executes CI/CD jobs. The official method for deploying this component is through the GitLab Runner Helm chart, which is compatible with GitLab.com, GitLab Self-Managed, and GitLab Dedicated offerings.
The Runner chart is specifically configured to use the Kubernetes executor. This means that for every new CI/CD job triggered, the Runner will provision a new, isolated pod within the specified namespace.
Runner Configuration and Installation
Configuration changes for the runner should not be passed as individual flags but stored in a values.yaml file. This allows for version-controlled configuration.
To install the runner:
helm upgrade --install gitlab-runner gitlab/gitlab-runner \
--namespace <NAMESPACE> \
--version <RUNNER_HELM_CHART_VERSION>
In this context, <NAMESPACE> refers to the Kubernetes namespace designated for the runner, and <RUNNER_HELM_CHART_VERSION> allows the administrator to pin the runner to a specific version rather than using the latest release.
Runner Decommissioning
Uninstalling a GitLab Runner requires a specific sequence to avoid "orphan" jobs or authorization errors.
- Pause the runner within the GitLab UI.
- Ensure all currently executing jobs have reached a completion state.
- Execute the delete command:
helm delete --namespace <NAMESPACE> <RELEASE-NAME>
In this example, <RELEASE-NAME> would be gitlab-runner.
Technical Specification Summary
The following table outlines the requirements and components for a production-grade GitLab Kubernetes deployment.
| Component | Production Requirement | Non-Production / Evaluation | Role |
|---|---|---|---|
| PostgreSQL | External PaaS / Compute | Bundled in-cluster | Primary Database |
| Redis | External PaaS / Compute | Bundled in-cluster | Caching and Queueing |
| Object Storage | External Cloud PaaS | MinIO (Bundled) | Artifacts and Uploads |
| Images | Cloud Native GitLab (CNG) | Cloud Native GitLab (CNG) | Application Logic |
| Architecture | Cloud Native Hybrid | Standard Helm Install | Deployment Pattern |
| Edition | EE or CE | EE or CE | Software License |
Final Analysis of the Cloud Native Hybrid Approach
The transition to a Kubernetes-based deployment for GitLab is not merely a change in hosting but a change in operational philosophy. The "Cloud Native Hybrid" model is a pragmatic admission that the distributed nature of Kubernetes is ideal for the application tier but potentially volatile for the data tier. By offloading PostgreSQL, Redis, and Object Storage to external, managed services, GitLab ensures that the "state" of the system is decoupled from the "execution" of the system.
This decoupling provides several critical advantages:
1. Reliability: Managed databases offer SLAs and backup mechanisms that are superior to manually managed pods.
2. Scalability: External services can be scaled vertically or horizontally without impacting the Kubernetes cluster's resource quotas.
3. Observability: Using standard cloud monitoring for the database and cache layers provides clearer insights into performance bottlenecks.
However, this architecture increases the prerequisite knowledge required by the operator. A "strong working knowledge of Kubernetes" is mandatory because the management and observability concepts differ significantly from traditional omnibus deployments. The use of Helm v3 adds a layer of abstraction that simplifies deployment but requires a disciplined approach to values.yaml management and a clear understanding of how --timeout and --version flags interact with the Kubernetes API.
Ultimately, the success of a GitLab Kubernetes deployment depends on the correct alignment of the external infrastructure with the Helm configuration. Failure to provision the external stateful services before running the helm upgrade --install command will result in a failed deployment or an unstable instance that is unfit for production workloads.