diff --git a/README.md b/README.md new file mode 100644 index 0000000..ba1b8e4 --- /dev/null +++ b/README.md @@ -0,0 +1,122 @@ +# Severed Infra: Cloud-Native Home Lab + +This repository contains the Infrastructure-as-Code (IaC) and manifest definitions for **Severed**, a modern blog and +observability stack running on Kubernetes (K3d). It demonstrates how to decouple configuration from code, automate +observability, and secure internal services—all running locally on your laptop. + +## Architecture + +The stack is designed to mimic a real-world AWS/Cloud environment but optimized for local development using **K3d** (k3s +in Docker). + +**The Stack:** + +* **Cluster:** K3d (Lightweight Kubernetes). +* **Ingress Controller:** Traefik (Routing `*.localhost` domains). +* **Application:** Jekyll Static Site served via Nginx (ConfigMap injected). +* **Observability (LGTM Stack):** +* **L**oki (Logs). +* **G**rafana (Visualizations & Dashboards-as-Code). +* **T**empo (Tracing - *Planned*). +* **M**onitoring / Prometheus (Metrics). +* **Agent:** Grafana Alloy (OpenTelemetry Collector) running as a DaemonSet. + +## Repository Structure + +```text +Severed-Infra/ +├── apps/ # Application Manifests +│ ├── severed-blog.yaml # Deployment + Service +│ ├── severed-blog-config.yaml # Nginx ConfigMap (Decoupled Config) +│ └── severed-ingress.yaml # Routing Rules (blog.localhost) +├── infra/ # Infrastructure & Observability +│ ├── alloy-agent.yaml # DaemonSet for Metrics/Logs Collection +│ ├── alloy-env.yaml # Environment Variables +│ └── observer/ # The Observability Stack +│ ├── loki.yaml # Log Aggregation +│ ├── prometheus.yaml # Metric Storage +│ ├── grafana.yaml # Dashboard UI (Stateless) +│ └── dashboard-json.yaml # "Cluster Health" Dashboard as Code +└── namespaces.yaml +``` + +## Quick Start + +### 1. Prerequisites + +Ensure you have the following installed: + +* [Docker Desktop](https://www.docker.com/) +* [K3d](https://k3d.io/) (`brew install k3d`) +* `kubectl` (`brew install kubectl`) + +### 2. Boot the Cluster + +Create a cluster with port mapping for the Ingress controller: + +```bash +k3d cluster create severed-cluster -p "8080:80@loadbalancer" +``` + +### 3. Deploy Infrastructure (Observability) + +Spin up the database backends (Loki/Prometheus) and the UI (Grafana). + +```bash +# 1. Create the secret for Grafana Admin +kubectl create secret generic grafana-secrets \ + --namespace monitoring \ + --from-literal=admin-user=admin \ + --from-literal=admin-password=severed_secure_password + +# 2. Deploy the stack +kubectl apply -f infra/observer/ + +# 3. Deploy the Collector Agent (Alloy) +kubectl apply -f infra/alloy-setup.yaml +``` + +### 4. Deploy the Application + +Deploy the blog and its routing rules. + +```bash +kubectl apply -f apps/ +``` + +## Access Points + +| Service | URL | Credentials / Notes | +|------------------|------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------| +| **Severed Blog** | [http://blog.localhost:8080](https://www.google.com/search?q=http://blog.localhost:8080) | Public Access | +| **Grafana** | [http://grafana.localhost:8080](https://www.google.com/search?q=http://grafana.localhost:8080) | **User:** `admin` / **Pass:** `severed_secure_password`

*(Anonymous View Access Enabled)* | +| **Prometheus** | *Internal Only* | Accessed via Alloy/Grafana | +| **Loki** | *Internal Only* | Accessed via Alloy/Grafana | + +## Observability Features + +This stack uses **Grafana Alloy** to automatically scrape metrics and tail logs from all pods. + +* **Cluster Health Dashboard:** Pre-provisioned "Infrastructure as Code." No manual setup required. +* Real-time **CPU/Memory** usage per node. +* **Disk Usage** monitoring (filtering out overlay/tmpfs noise). +* **RPS & Error Rates** derived directly from Nginx logs using LogQL. +* **Log Relabeling:** Alloy automatically promotes hidden K8s metadata (like `app=severed-blog`) into searchable Loki + labels. + +## Engineering Decisions + +* **ConfigMaps vs. Rebuilds:** The Nginx configuration is injected via a ConfigMap (`apps/blog-config.yaml`). We can + tweak caching headers or routing rules without rebuilding the Docker image. +* **Host Networking Fix:** Alloy runs with `hostNetwork: true` to scrape node metrics but uses + `dnsPolicy: ClusterFirstWithHostNet` to ensure it can still resolve internal K8s services (`loki.monitoring.svc`). +* **Security:** Grafana admin credentials are stored in Kubernetes Secrets, not plaintext YAML. Anonymous access is + restricted to `Viewer` role only. + +--- + +### Future Roadmap + +* [ ] Add Cert-Manager for TLS (HTTPS). +* [ ] Implement ArgoCD for automated GitOps syncing. +* [ ] Move to a physical Home Server.