From 0502dead686f9881b9341f2c71b7453077d1a4a5 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Sun, 22 Mar 2026 00:44:23 -0700 Subject: [PATCH] docs(devops): add Docker Desktop K8s as primary local option alongside K3s --- docs/devops/SINGLE_VM_DEPLOYMENT.md | 91 ++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/docs/devops/SINGLE_VM_DEPLOYMENT.md b/docs/devops/SINGLE_VM_DEPLOYMENT.md index ee243329..7d2fe3ce 100644 --- a/docs/devops/SINGLE_VM_DEPLOYMENT.md +++ b/docs/devops/SINGLE_VM_DEPLOYMENT.md @@ -116,11 +116,25 @@ Create a **unified** `docker-compose.ecosystem.yml` that brings everything up. -### Phase 2: K3s (single-node Kubernetes) +### Phase 2: Local Kubernetes (Docker Desktop or K3s) -[K3s](https://k3s.io/) is a lightweight, certified Kubernetes distro that runs on a single node. It gives you **real** `kubectl`, Helm, Ingress, and CRDs — identical APIs to production EKS/AKS/GKE. +Two options for single-node K8s — both give you **real** `kubectl`, Helm, Ingress, and CRDs identical to production AKS/EKS/GKE. -**Why K3s over minikube/kind?** +#### Option A: Docker Desktop Kubernetes (recommended for Mac/Windows dev) + +Docker Desktop includes a built-in **kind** (Kubernetes IN Docker) cluster. Enable it in Docker Desktop → Settings → Kubernetes → Enable Kubernetes. + +- **Zero install** — checkbox in Docker Desktop, K8s v1.31+ included +- **Images shared** — `docker build` images are immediately available to K8s (no import step!) +- **GUI dashboard** — Docker Desktop shows Deployments, Pods, Services, Ingresses, ConfigMaps, Secrets +- **kubectl pre-configured** — context `docker-desktop` auto-created +- **Helm works** — install via `brew install helm` +- **Best for:** Mac/Windows local development, quick iteration, visual debugging +- **Limitation:** Single-node only, can't add workers (use K3s for multi-node practice) + +#### Option B: K3s (recommended for Linux VMs / multi-node practice) + +[K3s](https://k3s.io/) is a lightweight, certified Kubernetes distro. - Production-grade (CNCF certified, used by Rancher) - Single binary, ~70 MB, installs in 30 seconds @@ -128,6 +142,7 @@ Create a **unified** `docker-compose.ecosystem.yml` that brings everything up. - Built-in local-path StorageClass - Runs as systemd service (survives reboot) - Can scale to multi-node later by just joining worker nodes +- **Best for:** Linux VMs, Hetzner/cloud deployment, multi-node scaling practice --- @@ -637,12 +652,12 @@ helm create bytelyst-ecosystem ## 7. Scaling Path: Single VM → Multi-Node ``` -Phase 1: Docker Compose Phase 2: K3s (1 node) -┌─────────────────────┐ ┌──────────────────────┐ -│ Single VM │ → │ Single VM + K3s │ -│ docker compose up │ │ kubectl apply -k │ -│ ~25 containers │ │ ~25 pods │ -└─────────────────────┘ └──────────────────────┘ +Phase 1: Docker Compose Phase 2: Local K8s (1 node) +┌─────────────────────┐ ┌──────────────────────────────┐ +│ Single VM / Mac │ → │ Docker Desktop K8s (kind) │ +│ docker compose up │ │ or K3s on Linux VM │ +│ ~25 containers │ │ kubectl apply -k · ~25 pods │ +└─────────────────────┘ └──────────────────────────────┘ │ ▼ Phase 3: K3s (3 nodes) Phase 4: Managed K8s @@ -653,7 +668,9 @@ Phase 3: K3s (3 nodes) Phase 4: Managed K8s └──────────────────────┘ └──────────────────────┘ ``` -**Adding a worker node to K3s is one command:** +**Docker Desktop K8s → K3s migration:** Same manifests, just change `kubectl` context. + +**Adding a worker node to K3s (Phase 3) is one command:** ```bash # On the worker VM: @@ -710,10 +727,14 @@ docker compose -f docker-compose.ecosystem.yml logs -f platform-service # Tear down docker compose -f docker-compose.ecosystem.yml down -# ── Phase 2: K3s ────────────────────────────────────── -# Build + load images into K3s containerd +# ── Phase 2a: Docker Desktop Kubernetes (Mac) ──────── +# Enable K8s: Docker Desktop → Settings → Kubernetes → Enable +# Verify: +kubectl config use-context docker-desktop +kubectl get nodes # Should show: docker-desktop Ready control-plane + +# Build images (Docker Desktop shares images with K8s — no import needed!) docker build -t bytelyst/platform-service:latest ./learning_ai_common_plat/services/platform-service -sudo k3s ctr images import <(docker save bytelyst/platform-service:latest) # Deploy all kubectl apply -k k8s/ @@ -723,6 +744,17 @@ kubectl get pods -A # Port-forward for local access kubectl port-forward svc/platform-service 4003:4003 -n bytelyst-platform + +# Or view everything in Docker Desktop GUI → Kubernetes tab + +# ── Phase 2b: K3s (Linux VM) ───────────────────────── +# Build + load images into K3s containerd +docker build -t bytelyst/platform-service:latest ./learning_ai_common_plat/services/platform-service +sudo k3s ctr images import <(docker save bytelyst/platform-service:latest) + +# Deploy (same manifests as Docker Desktop!) +kubectl apply -k k8s/ +kubectl get pods -A ``` --- @@ -1147,29 +1179,52 @@ ByteLyst already uses AKV in production (platform-service) — the CSI driver pa ### 13.11 Local K8s Development Script Template -A good local K8s deploy script should handle: +A good local K8s deploy script should handle both Docker Desktop K8s (kind) and K3s: ```bash #!/usr/bin/env bash # deploy-local-k8s.sh — Full local K8s deployment for ByteLyst ecosystem +# Works with both Docker Desktop Kubernetes and K3s. set -euo pipefail NAMESPACE="bytelyst" ACTION="${1:-deploy}" # deploy | teardown +# Detect K8s runtime +detect_runtime() { + local ctx + ctx=$(kubectl config current-context 2>/dev/null || echo "") + if [[ "$ctx" == "docker-desktop" ]]; then + echo "docker-desktop" # kind cluster inside Docker Desktop + elif command -v k3s &>/dev/null; then + echo "k3s" + else + echo "unknown" + fi +} + case "$ACTION" in deploy) + RUNTIME=$(detect_runtime) + echo "Detected K8s runtime: $RUNTIME" + # 1. Build all Docker images + echo "Building images..." for svc in platform-service extraction-service mcp-server; do docker build -t bytelyst/$svc:local ./learning_ai_common_plat/services/$svc done - # 2. Load images into K3s containerd (not needed with Docker Desktop) - if command -v k3s &>/dev/null; then + # 2. Load images into K8s runtime + if [[ "$RUNTIME" == "docker-desktop" ]]; then + echo "Docker Desktop: images are already available to K8s (shared daemon)." + elif [[ "$RUNTIME" == "k3s" ]]; then + echo "K3s: importing images into containerd..." for img in $(docker images --format '{{.Repository}}:{{.Tag}}' | grep bytelyst); do sudo k3s ctr images import <(docker save "$img") done + else + echo "WARNING: Unknown K8s runtime. You may need to load images manually." fi # 3. Create namespace + secrets @@ -1186,9 +1241,13 @@ case "$ACTION" in # 5. Wait + verify kubectl rollout status deploy -n "$NAMESPACE" --timeout=120s + echo "" echo "All pods:" kubectl get pods -n "$NAMESPACE" echo "" + if [[ "$RUNTIME" == "docker-desktop" ]]; then + echo "View in Docker Desktop: Kubernetes tab → namespace: $NAMESPACE" + fi echo "Port-forward: kubectl port-forward svc/platform-service 4003:4003 -n $NAMESPACE" ;;