Deployment Runbook¶
Source
The canonical runbook with copy-pasteable commands is deploy/README.md in the repository. This page is a summary for quick reference.
Topology¶
| Component | Where | Notes |
|---|---|---|
| k3s server | master 192.168.137.10 |
control plane (bundled containerd, coexists with Docker) |
| k3s agents | worker1–8 .101–.108 |
|
| Backend (Flask) | every node (DaemonSet) | hostPort 8080 so the sensor keeps posting to :8080 |
| Frontend (nginx) | master | React build, pinned to the master via a nodeSelector |
| MinIO (EC:4) | worker1–8 (StatefulSet) | distributed object storage for images |
| PostgreSQL | master (existing Compose) | reused, not migrated |
| Ingress (Traefik) | master :80 |
one URL for UI + API + images + Prometheus |
Everything is reachable at http://192.168.137.10/.
One-time: SSH key¶
test -f ~/.ssh/ss2026_cluster || \
ssh-keygen -t ed25519 -f ~/.ssh/ss2026_cluster -N "" -C "ss2026-cluster"
for spec in master@192.168.137.10 worker1@192.168.137.101 worker2@192.168.137.102 \
worker3@192.168.137.103 worker4@192.168.137.104 worker5@192.168.137.105 \
worker6@192.168.137.106 worker7@192.168.137.107 worker8@192.168.137.108; do
ssh-copy-id -i ~/.ssh/ss2026_cluster.pub -o StrictHostKeyChecking=no "$spec"
done
1. Install k3s¶
# master
curl -sfL https://get.k3s.io | sh -
sudo cat /var/lib/rancher/k3s/server/node-token # -> $TOKEN
# each worker
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.137.10:6443 K3S_TOKEN=$TOKEN sh -
Verify: sudo k3s kubectl get nodes shows 9 Ready.
2. Local image registry + insecure pull config¶
Add /etc/rancher/k3s/registries.yaml on every node, then restart k3s:
3. Build + push images (run on master)¶
# backend
docker build --provenance=false --sbom=false \
-t 192.168.137.10:5000/sentinel-backend:latest master/server
docker push 192.168.137.10:5000/sentinel-backend:latest
# frontend
( cd frontend && npm ci && npm run build )
cp -r frontend/dist deploy/frontend/dist
docker build --provenance=false --sbom=false \
-t 192.168.137.10:5000/sentinel-frontend:latest deploy/frontend
docker push 192.168.137.10:5000/sentinel-frontend:latest
# minio mirror
docker pull minio/minio:latest
docker tag minio/minio:latest 192.168.137.10:5000/minio:latest
docker push 192.168.137.10:5000/minio:latest
4. Secrets¶
kubectl -n sentinel create secret generic backend-secrets \
--from-literal=PGPASSWORD=events_pw \
--from-literal=MINIO_SECRET_KEY=minioadmin123 \
--from-literal=BOT_TELEGRAM_TOKEN="$BOT_TELEGRAM_TOKEN" \
--from-literal=BOT_TELEGRAM_CHAT_ID="$BOT_TELEGRAM_CHAT_ID"
5. Apply manifests¶
kubectl apply -f deploy/k8s/00-namespace.yaml
kubectl apply -f deploy/k8s/10-minio.yaml
kubectl apply -f deploy/k8s/20-backend.yaml
kubectl apply -f deploy/k8s/30-frontend.yaml
kubectl apply -f deploy/k8s/40-ingress.yaml
6. Verify¶
kubectl -n sentinel get pods -o wide # minio-0..7, backend on all, frontend on master
curl -s http://192.168.137.10/api/stores # {"postgres":true,"minio":true}
curl -s -o /dev/null -w "%{http_code}\n" http://192.168.137.10/ # 200
Running from Windows¶
See the full guide in deploy/README.md — covers ICS setup, PowerShell scp-based deploy, and port-forwarding the dashboard to other devices.
Rollback¶
The Docker Compose monitoring stack, MPI, NFS, and dnsmasq are never touched.