Orchestrating GitLab Development via Lightweight K3s Clusters

The convergence of containerization and orchestration has fundamentally shifted how development environments are constructed. While full-scale Kubernetes distributions provide the robustness required for global-scale production, they often introduce unnecessary overhead for local development, small-team collaboration, or specific platform development tasks. This is where k3s emerges as a critical architectural component. By providing a fully compliant, production-grade Kubernetes distribution packaged as a single 40MB binary, k3s removes the friction associated with Kubernetes deployment. When paired with GitLab—a central pillar of modern DevOps—the result is a highly portable, scalable, and unified management plane that allows developers to mirror production-like environments on modest hardware.

The utility of hosting GitLab on k3s extends beyond mere convenience. It provides a strategic advantage for organizations leveraging Kubernetes for their primary platform development, as it ensures continuity in management operations. By utilizing a single-node k3s cluster on a local machine or a cloud-based virtual machine, developers can establish a comprehensive CI/CD pipeline that integrates seamlessly with the Kubernetes API. This setup is particularly effective for those moving toward GitOps—a paradigm popularized by Weaveworks where the desired state of the cluster is defined in Git, effectively replacing the manual execution of kubectl apply with a simple git push.

Architectural Foundation of K3s and GitLab Integration

K3s is designed specifically to reduce the footprint of Kubernetes without sacrificing the essential features required for container orchestration. Its streamlined nature makes it an ideal host for applications like GitLab, which, while feature-rich, does not always require a sophisticated, multi-master compute cluster to operate effectively for development purposes.

The core value proposition of using k3s for GitLab hosting is the achievement of greater uniformity. By wrapping GitLab in k3s, developers can standardize deployment, monitoring, and management across all stages of the development lifecycle. Whether the environment is a local workstation or a remote VM, the management interface remains the Kubernetes API, ensuring that the transition from a development "sandbox" to a production cluster is logically consistent.

When comparing lightweight Kubernetes distributions, k3s is often viewed as more viable than alternatives like minikube because it closely mimics a production-style deployment. This makes it a superior choice for those seeking to become familiar with single-node clusters while maintaining a path toward higher availability.

Deployment Environments and Infrastructure Requirements

The portability of k3s allows it to be deployed across a vast array of environments. Because it is a Cloud Native and Vendor Neutral solution, the specific cloud provider becomes a high-level business concern rather than a technical limitation.

The following table outlines the compatible environments for a k3s-based GitLab installation:

Environment Type Examples/Providers Use Case
Localhost Physical Workstation, Laptop Local development and rapid prototyping
Cloud VM (Public) Digital Ocean, Linode Small team collaboration, external access
Hyperscale Cloud Google GCP, Amazon AWS, Microsoft Azure Scalable dev/test environments
Bare-Metal Lab Server, On-premise hardware High-performance local control

In terms of hardware requirements, k3s is exceptionally efficient. The distribution requires only 512MB of RAM to run the basic Kubernetes engine, making it accessible for low-spec virtual machines or edge devices.

Local DNS Server Configuration with BIND9

For a GitLab instance to be accessible via a professional domain (e.g., davar.com) rather than a raw IP address, a local DNS server is required. This is typically achieved using BIND9. The setup involves installing the necessary packages and configuring the zone files to map the domain to the k3s node's IP address.

To begin the DNS setup, the following command is used to install the BIND suite:

sudo apt-get install bind9 bind9utils bind9-doc dnsutils

The configuration of the DNS server requires the modification of several key files to handle query forwarding and zone definitions.

The named.conf.options file defines how the server handles requests and where it forwards unknown queries. A standard configuration for a k3s environment looks as follows:

options { directory "/var/cache/bind"; auth-nxdomain no; # conform to RFC1035 listen-on-v6 { any; }; listen-on port 53 { any; }; allow-query { any; }; forwarders { 8.8.8.8; }; recursion yes; };

To define the specific domain and reverse lookup zones, the named.conf.local file is edited. This connects the domain davar.com to a specific master file:

zone "davar.com" { type master; file "/etc/bind/forward.davar.com"; }; zone "0.168.192.in-addr.arpa" { type master; file "/etc/bind/reverse.davar.com"; };

Finally, the reverse data file (e.g., reverse.davar.com) must be configured to ensure that IP addresses can be resolved back to hostnames, which is critical for certain GitLab services and internal Kubernetes communication:

; ; BIND reverse data file for local loopback interface ; $TTL 604800 @ IN SOA davar.com. root.davar.com

K3s Cluster Installation and Node Management

Installing k3s can be performed through several methods depending on whether a manual setup or an automated tool like k3sup is preferred.

Manual Installation Process

For a standard server installation, a one-line curl script is used. To ensure a specific version is installed, the INSTALL_K3S_VERSION variable can be exported beforehand.

bash $ export INSTALL_K3S_VERSION=v1.16.10+k3s1 $ export K3S_CLUSTER_SECRET=$(head -c48 /dev/urandom | base64) $ echo $K3S_CLUSTER_SECRET $ curl -sfL https://get.k3s.io | sh -s – server

For newer versions of k3s (Kubernetes version 1.20 and above), the process is simplified. A user can SSH into the target machine and run:

```bash
$ ssh [email protected] -o IdentitiesOnly=yes

hostnamectl set-hostname kmaster1

curl -sfL https://get.k3s.io | sh -

```

Automated Setup with k3sup

k3sup is an alternative tool that allows for the installation of the cluster and the simultaneous configuration of kubectl on the local machine. This removes the need to manually fetch tokens or configure Kubeconfig files.

To install a cluster using k3sup:

k3sup install --ip $IP --user root

To join an additional worker node to the existing cluster:

k3sup join --ip $AGENT_IP --server-ip $SERVER_IP --user $USER

Kubeconfig Management and Remote Access

To manage a k3s cluster from a local workstation, the configuration file located at /etc/rancher/k3s/k3s.yaml on the server must be retrieved and modified. The default configuration points to 127.0.0.1, which must be replaced with the server's Fully Qualified Domain Name (FQDN) or Public IP.

The following sequence demonstrates the extraction and modification of the config file:

bash $ scp root@VM_PUBLIC_IP_OR_BARE_METAL_IP:/etc/rancher/k3s/k3s.yaml ~/.kube/k8s-c1 $ sed -i .bk "s/default/k8s-c1/" ~/.kube/k8s-c1 $ sed -i .bk "s/127.0.0.1/FQDN/" ~/.kube/k8s-c1

Once the file is modified, the local environment is told to use this specific configuration for all kubectl commands:

$ export KUBECONFIG=~/.kube/k8s-c1

Deploying GitLab via Helm Charts on K3s

The most efficient way to deploy GitLab onto a k3s cluster is through Helm, the package manager for Kubernetes. K3s includes a Helm controller that can deploy charts directly from a YAML manifest.

Helm Chart Configuration

To install GitLab Community Edition (CE), a custom YAML file is created. This file defines the version of the chart, the target namespace, and the specific values required for the GitLab installation.

The following manifest is used to trigger the installation of the GitLab Helm chart into the kube-system namespace:

yaml apiVersion: helm.cattle.io/v1 kind: HelmChart metadata: name: gitlab namespace: kube-system spec: chart: gitlab repo: https://charts.gitlab.io/ targetNamespace: kube-system version: v6.2.2 set: valuesContent: |- global: edition: ce hosts: domain: domain.io https: true externalIP: MY_EXTERNAL_IP ssh: ~ gitlab: name: git.domain.io https: true registry: name: registry.domain.io https: true minio: name: storage.domain.io https: true enabled: true ingress: configureCertmanager: false class: "nginx" enabled: true tls: enabled: true certmanager: install: false nginx-ingress: enabled: true prometheus: install: false redis: install: true postgresql: install: true gitlab-runner: install: false registry: enable: true

Troubleshooting Common Deployment Issues

During the installation of the GitLab Helm chart on k3s, users may encounter specific warnings regarding the HorizontalPodAutoscaler (HPA). A common error message is:

"Event occurred" object="kube-system/gitlab-sidekiq-all-in-1-v2" fieldPath="" kind="HorizontalPodAutoscaler" apiVersion="autoscaling/v2" type="Warning" reason="FailedComputeMetricsReplicas" message="invalid metrics (1 invalid out of 1), first error is: failed to get cpu utilization: unable to get metrics for resource cpu: no metrics returned from resource metrics API"

This error typically indicates that the metrics-server is not yet providing the necessary data to the HPA. However, as long as the pods are in the Running state, the core application remains functional.

Verification of pod status can be performed with:

kubectl get pods -n kube-system

Advanced Network and Security Configurations

Once GitLab is running on k3s, several configuration steps are necessary to ensure full functionality, especially when integrating the cluster back into GitLab's own management interface.

Enabling Local Network Access

A common issue when adding a k3s-based cluster to GitLab is the error: https://dev-k3s.davar.com:6443 is blocked: Requests to the local network are not allowed. This occurs because GitLab's security settings prevent webhooks and services from making requests to local IP ranges by default.

To resolve this, an administrator must perform the following steps within the GitLab UI:

  1. Log in to GitLab using an account with admin privileges.
  2. Navigate to the "Settings" menu.
  3. Select the "Network" section.
  4. Locate the "Outbound requests" configuration.
  5. Check the box labeled "Allow requests to the local network from web hooks and services".
  6. Click "Save changes".

RBAC and Group Integration

To integrate a k3s cluster with a GitLab group (e.g., k8s-development), Role-Based Access Control (RBAC) must be enabled. The integration requires three specific pieces of information from the k3s cluster:

  • The API URL (e.g., https://192.168.99.102:8443).
  • The CA Certificate.
  • The Service Token.

Providing these credentials allows GitLab to communicate directly with the k3s API, enabling the management of Kubernetes resources directly from the GitLab interface.

Expanding the Cluster with Kilo

For users who need to expand their k3s deployment across multiple sites or hybrid environments, Kilo can be used to create a VPN-based Kubernetes cluster. Kilo allows nodes to communicate securely across different networks, reporting as Ready once the VPN setup is complete.

The deployment of Kilo requires the distribution of the k3s.yaml config file to all worker nodes. The file must be modified to replace 127.0.0.1 with the master node's address.

The following command demonstrates how to modify and upload the config to a worker node:

bash $ ssh [email protected] \ sed "s/127.0.0.1/master.c2.example.com/" \ /etc/rancher/k3s/k3s. yaml >k3s.yaml

After the configuration is in place on all nodes, the Kilo manifest is applied:

$ kubectl apply -f https://raw.githubusercontent.com/squat/kilo/master/manifests/kilo-k3s.yaml

CI/CD Integration and GitOps Workflow

Integrating GitLab CI/CD with a k3s cluster allows for a highly automated deployment pipeline. While GitLab offers native Kubernetes integration, a more generic approach involves using kubectl directly within the CI/CD pipeline deployment steps. This ensures that the pipeline remains compatible with any Kubernetes distribution, not just k3s.

The GitOps Transition

The ultimate goal for many teams using k3s and GitLab is the implementation of GitOps. GitOps shifts the focus from imperative commands (like kubectl apply) to declarative state management. In a GitOps workflow, the Kubernetes cluster is continuously synchronized with a Git repository.

Key characteristics of the GitOps approach include:

  • State Definition: The entire cluster state is stored in Git.
  • Automated Reaction: Applications react to git push events.
  • State Reconciliation: Tools ensure the live cluster matches the state described in the Git configuration.

By using k3s to host GitLab, teams can build a recursive loop where GitLab hosts the code, triggers the pipeline, and the pipeline updates the k3s cluster that is hosting the very same GitLab instance.

Comprehensive Technical Specification Summary

The following table summarizes the technical parameters and requirements for the k3s and GitLab ecosystem.

Parameter Specification/Value Impact/Detail
K3s Binary Size 40MB Minimal disk footprint for fast deployment
Minimum RAM 512MB Low resource barrier for local dev environments
Default Config Path /etc/rancher/k3s/k3s.yaml Primary source for cluster authentication
Token Location /var/lib/rancher/k3s/server/node-token Necessary for joining worker nodes manually
Helm Chart Version v6.2.2 (Reference) Specific version used for the GitLab CE deploy
DNS Tooling BIND9 Standard for managing local domain resolution
Network Access Outbound Requests Enabled Required to fix local network block errors

Final Analysis of K3s as a GitLab Host

The adoption of k3s for hosting GitLab represents a strategic move toward infrastructure simplification. By stripping away the unnecessary components of a standard Kubernetes distribution, k3s provides a lean yet powerful environment that is perfectly suited for the demands of GitLab. The ability to run a fully compliant production-grade distribution on 512MB of RAM democratizes access to Kubernetes, allowing individual developers to experiment with complex orchestration without needing massive hardware investments.

The integration of k3s with GitLab creates a synergistic relationship. GitLab provides the management and automation tools, while k3s provides the flexible, portable execution environment. When this is coupled with the GitOps philosophy, the result is a development lifecycle where infrastructure is treated as code, and the "single source of truth" resides entirely within Git.

Furthermore, the use of tools like k3sup and Kilo demonstrates that k3s is not limited to single-node setups. It can scale from a single local process to a hybrid, multi-node cluster spanning different networks, all while maintaining the same management interface. The primary challenge remains the initial configuration of networking and DNS, but once the BIND9 and Kubeconfig hurdles are overcome, the system provides an incredibly stable and portable platform for modern software development. This architectural pattern ensures that the development environment is a mirror of production, reducing "it works on my machine" errors and accelerating the path from commit to deployment.

Sources

  1. k3s-GitLab-development
  2. Setting up a simple CI/CD flow with k3s and gitlab
  3. Install GitLab Community Edition to k3s

Related Posts