2026
Inception of Things
A 42 system administration project that builds up Kubernetes in stages: a two-node K3s cluster on Vagrant VMs, three apps behind one ingress, GitOps with Argo CD, and a bonus with a self-hosted GitLab.
My role
Two-person 1337 project. My teammate and I built every part together.
Context
Part of the 42 curriculum, it introduces Kubernetes fundamentals through progressive stages, covering containerization, orchestration and GitOps on lightweight Kubernetes distributions.
Problem
Kubernetes has many moving parts. The project teaches them one stage at a time: first a cluster, then routing traffic to applications, then deploying from a Git repository with no manual steps.
What I built
Part 1: K3s on two Vagrant VMs
Two Debian 11 VMs with static IPs run a minimal cluster, one K3s server and one agent. The agent joins with a token shared through the Vagrant shared folder, and cluster traffic uses the dedicated eth1 interface. Both nodes reach Ready, and pods schedule across them.
Part 2: three apps behind one ingress
One VM runs three nginx apps on the stock nginx:1.27-alpine image, with their HTML injected from ConfigMaps. A single Ingress routes by Host header: app1.com goes to one pod, app2.com to three load-balanced replicas, and everything else to a third app.
Part 3: GitOps with K3d and Argo CD
K3d runs the K3s nodes as Docker containers. Argo CD, in its own namespace, watches a public GitHub repository and deploys the application into a dev namespace, with automated pruning, self-healing and a three-minute sync interval. Pushing to the repository deploys to the cluster, with no manual kubectl apply.
Bonus: self-hosted GitLab
GitLab CE, installed with a Helm chart, runs in the cluster next to Argo CD, and Argo CD reaches it through in-cluster DNS. After GitLab starts, the script pauses so you can create the project and push the manifests with git subtree. The result is a fully self-contained GitOps pipeline.
Architecture
Each stage is its own directory (p1, p2, p3 and bonus) with scripts and configuration. Parts 1 and 2 use Vagrant VMs running K3s. Part 3 and the bonus use K3d, which runs K3s inside Docker. Traefik, the default ingress controller in K3s, routes the traffic. Argo CD keeps the cluster in the state the Git repository describes. Everything is defined as code: Vagrantfiles, shell scripts and Kubernetes manifests.
Key decisions and trade-offs
Inject each app's HTML with a ConfigMap instead of building custom images.
Trade-off: Changing a page means changing a ConfigMap, not rebuilding an image, and all three apps share one stock image. The cost is that the content lives in cluster configuration, not in a versioned image.
Turn on automated pruning and self-healing in Argo CD.
Trade-off: The cluster always converges on what Git says, so a manual change gets reverted. The cost is that nobody can hotfix the cluster by hand; every fix has to go through the repository.
Run GitLab inside the cluster for the bonus.
Trade-off: The pipeline no longer depends on an outside Git host. The cost is a manual step: the script pauses so you can create the project and push the manifests yourself.
Outcome
Each stage ships with checks for node readiness, pod scheduling, network configuration, ingress routing and application responsiveness. A push to the Git repository now deploys to the cluster with no manual kubectl apply.
Stack
- Vagrant
- K3s
- K3d
- Docker
- Argo CD
- Traefik
- Helm
- GitLab
- Shell scripting