Infrastructure / DevOps

Kubernetes Home Lab

A self-hosted Kubernetes environment built on Ubuntu Server for hands-on experience with container orchestration, networking, infrastructure services, monitoring, and automation.

Platform

Ubuntu Server / MicroK8s

Environment

Self-Hosted

Cluster

Single Node

Status

Active

Overview

Why I Built It

I built this home lab to move beyond learning infrastructure concepts in isolation and gain practical experience designing, deploying, securing, and operating systems that I am responsible for maintaining.

What began as a Ubuntu Server environment for Linux administration and networking has evolved into a self-hosted Kubernetes platform where I can work directly with containerization, service networking, DNS, ingress, TLS, infrastructure automation, monitoring, and application deployment. Because I operate the environment myself, each new capability also requires me to troubleshoot failures, understand dependencies, and make deliberate engineering decisions about how the pieces fit together.

Architecture

Infrastructure Architecture

The environment is built as a layered infrastructure stack, beginning with Ubuntu Server on the physical host and extending through Kubernetes orchestration, container networking, service delivery, DNS, and TLS. Each layer provides capabilities used by the services and applications running above it.

Foundation

Host System

Ubuntu Server provides the Linux foundation for the environment, including system administration, networking, storage, SSH access, and host-level systemd services.

Ubuntu ServerLinuxsystemdSSH

Orchestration

Kubernetes Platform

MicroK8s provides the Kubernetes control plane and orchestration environment used to deploy, manage, and operate containerized workloads across the lab.

MicroK8sKubernetesCalico

Connectivity

Networking & DNS

The environment operates across IPv4 and IPv6 networking, with internal DNS supporting service resolution and AdGuard Home providing network-wide DNS filtering for local clients.

IPv4IPv6DNSAdGuard Home

Service Delivery

Ingress & Load Balancing

Kubernetes Services expose workloads internally while Traefik provides ingress routing and MetalLB supplies load-balancer addressing for services made available on the local network.

TraefikMetalLBIngress

Trust

Security & TLS

An internal certificate authority and cert-manager provide certificate lifecycle management and trusted HTTPS for internal services while keeping certificate issuance under local control.

cert-managerPKITLS

Workloads

Storage & Registry

Persistent storage supports stateful workloads while a private container registry provides an internal source for versioned application images deployed in Kubernetes.

Persistent StorageOCI RegistryDocker

Implementation

Key Engineering Work

01

Kubernetes Infrastructure

Configured and operate a single-node MicroK8s cluster on Ubuntu Server, including Kubernetes DNS, persistent storage, metrics collection, container networking with Calico, and the supporting services required to run containerized workloads.

02

Network-Wide DNS Filtering

Deployed AdGuard Home as a Kubernetes-managed service to provide DNS filtering across the local network while supporting both IPv4 and IPv6 clients.

03

Private Container Registry

Configured an internal HTTPS container registry to store and distribute versioned application images used by Kubernetes deployments within the lab.

04

Ingress & Load Balancing

Implemented Traefik ingress routing with MetalLB to provide controlled access to Kubernetes services from the local network using stable load-balancer addressing.

05

Internal PKI & TLS

Established an internal certificate authority and integrated cert-manager with Kubernetes to automate certificate issuance and provide trusted HTTPS for internal services.

06

Dual-Stack Networking

Configured the server to operate with both IPv4 and IPv6 and validated Kubernetes networking, DNS resolution, and service connectivity across the environment.

07

IPv6 Prefix Monitoring

Built a host-level monitoring solution using a shell script, systemd service, and systemd timer to detect IPv6 prefix changes and send state-aware notifications when network conditions change.

08

Application Deployment

Containerized this portfolio as a production Next.js application and deployed it to Kubernetes using an immutable container image, Deployment, Service, ingress routing, TLS, health probes, resource controls, and container security settings.

Security

Security & Hardening

Security controls are applied across the application, container, Kubernetes, and network layers rather than relying on a single perimeter. The portfolio deployment is configured to reduce unnecessary privileges while maintaining the health and resource controls required for reliable operation.

Container

Least Privilege

The application container runs as a non-root user with privilege escalation disabled and a read-only root filesystem to reduce the writable and privileged attack surface available at runtime.

Kubernetes

Workload Isolation

Automatic service-account token mounting is disabled for the portfolio workload because the application does not require access to the Kubernetes API.

Transport

Trusted HTTPS

Internal services use TLS certificates issued through the lab's private certificate infrastructure, providing encrypted and trusted HTTPS communication within the environment.

Operations

Health & Resource Controls

Readiness and liveness probes monitor application health while CPU and memory requests and limits define expected resource use and help Kubernetes manage the workload predictably.

Deployment

Application Delivery Path

The portfolio follows a container-based deployment path from source code to a running Kubernetes workload. Each stage has a specific responsibility, from producing the application artifact to routing trusted HTTPS traffic to the running container.

01

Source Code

02

Docker Image

03

Private Registry

04

Kubernetes

05

Service

06

Traefik

07

HTTPS

08

Application

Engineering Notes

Decisions & Lessons Learned

Building the lab has required more than deploying individual technologies. Each addition introduced decisions about architecture, security, networking, reliability, and operational complexity. Working through those tradeoffs has been one of the most valuable parts of the project.

01

Platform Selection

Build for the Hardware You Have

I chose a single-node MicroK8s environment to build practical Kubernetes experience on existing hardware without introducing unnecessary infrastructure. The lab is intentionally sized for its current purpose while still exposing me to the core orchestration, networking, storage, and workload-management concepts used by Kubernetes.

02

Networking

Preserve IPv6, Understand It

When IPv6 introduced additional complexity, I chose to understand the behavior rather than disable it. Working through addressing, SLAAC, DNS, routing, and changing ISP prefixes strengthened my understanding of dual-stack networking and led me to build monitoring around conditions I do not directly control.

03

PKI & Network Boundaries

Separate Trust from Exposure

Building an internal certificate authority reinforced that certificate trust and network exposure solve different problems. Internal services can use trusted HTTPS without becoming public services, allowing me to improve transport security while keeping the lab behind its existing network boundary.

04

Automation

Design Automation Around the Boundary

Keeping the container registry private improves the lab's network boundary, but it also affects future CI/CD design. A cloud-hosted runner cannot directly reach an internal-only registry, so deployment automation must account for where the runner executes and which systems it is permitted to reach.