Cloud Native Hybrid GitLab Kubernetes Deployment

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 600s flag 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.com flag defines the base domain for the instance. Unless these settings are modified, the default domain for accessing the GitLab instance will be gitlab.example.com.

  • External IP and Certification
    The --set global.hosts.externalIP=10.10.10.10 identifies 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=ce flag.

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:

  1. Manual Secret Creation: If the administrator manually created the secret for the initial root password, that password is used for sign-in.
  2. 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 --version flag:

--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.

  1. Pause the runner within the GitLab UI.
  2. Ensure all currently executing jobs have reached a completion state.
  3. 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.

Sources

  1. Deploy the GitLab Helm chart
  2. Installing GitLab by using Helm
  3. GitLab Runner Helm chart

Related Posts