socktop-webterm/kubernetes
jasonwitty 634e28113b
All checks were successful
Build and Deploy to K3s / test (push) Successful in 2m6s
Build and Deploy to K3s / lint (push) Successful in 1m33s
Build and Deploy to K3s / build-and-push (push) Successful in 37s
Build and Deploy to K3s / deploy (push) Successful in 1m59s
Update deployment to use version 0.3.5 from Cargo.toml
2025-11-30 09:09:15 -08:00
..
.deploysummary.txt Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
01-configmap.yaml Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
02-secret.yaml Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
03-deployment.yaml Update deployment to use version 0.3.5 from Cargo.toml 2025-11-30 09:09:15 -08:00
04-service.yaml Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
05-ingress.yaml Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
deploy.sh Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
deploy.sh.backup Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
kustomization.yaml Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
monitor-sessions.sh Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
QUICKSTART.md Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
README.md Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
registries.yaml.example Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
setup-kubectl.sh Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
setup-registry.sh Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
test-registry.sh Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00
TLDR.md Initial commit: Socktop WebTerm with k3s deployment 2025-11-28 01:31:33 -08:00

Kubernetes Deployment for Socktop WebTerm

This directory contains Kubernetes manifests for deploying Socktop WebTerm on your k3s cluster.

Overview

The deployment includes:

  • 3 replicas for high availability
  • Host networking to access Raspberry Pi nodes on port 8443
  • Session affinity to maintain terminal connections
  • Traefik Ingress for routing (default with k3s)
  • WebSocket support for terminal connections
  • External SSL termination via NGINX Proxy Manager
  • ConfigMaps for configuration files
  • Secrets for TLS certificates

Prerequisites

  1. k3s cluster running with at least 3 nodes
  2. Traefik Ingress Controller (comes default with k3s)
  3. External NGINX Proxy Manager for SSL termination
  4. DNS records pointing to your external IP:
    • socktop.io → your external IP
    • www.socktop.io → your external IP
    • origin.socktop.io → your external IP
  5. Docker registry access configured for 192.168.1.208:3002
  6. Proxy hosts configured in NGINX Proxy Manager to forward to k3s on port 8080

Installation

Step 1: Configure Docker Registry Access (if needed)

If your k3s nodes need authentication to pull from your Gitea registry:

# Create docker-registry secret
kubectl create secret docker-registry gitea-registry \
  --docker-server=192.168.1.208:3002 \
  --docker-username=YOUR_USERNAME \
  --docker-password=YOUR_PASSWORD \
  --docker-email=your-email@example.com

# Add to deployment (uncomment imagePullSecrets in 03-deployment.yaml)

Step 2: Configure Insecure Registry on k3s Nodes

Since your Gitea registry uses HTTP, configure k3s to allow insecure registries.

On each k3s node, create or edit /etc/rancher/k3s/registries.yaml:

mirrors:
  "192.168.1.208:3002":
    endpoint:
      - "http://192.168.1.208:3002"
configs:
  "192.168.1.208:3002":
    tls:
      insecure_skip_verify: true

Then restart k3s:

# On server node
sudo systemctl restart k3s

# On agent nodes
sudo systemctl restart k3s-agent

Step 3: Create TLS Certificates Secret

Replace the placeholder secret with your actual Raspberry Pi TLS certificates:

kubectl create secret generic socktop-webterm-certs \
  --from-file=rpi-master.pem=/path/to/rpi-master.pem \
  --from-file=rpi-worker-1.pem=/path/to/rpi-worker-1.pem \
  --from-file=rpi-worker-2.pem=/path/to/rpi-worker-2.pem \
  --from-file=rpi-worker-3.pem=/path/to/rpi-worker-3.pem \
  --namespace=default

Or if you don't have certificates yet, the deployment will work without them (secret is optional).

Step 4: Configure External NGINX Proxy Manager

In your NGINX Proxy Manager, create proxy hosts for:

For socktop.io:

  • Domain: socktop.io
  • Scheme: http
  • Forward Hostname/IP: <k3s-node-ip>
  • Forward Port: 8080
  • Enable WebSocket Support: ✓
  • SSL Certificate: Your SSL cert
  • Force SSL: ✓

Repeat for www.socktop.io and origin.socktop.io.

Step 5: Update Configuration (Optional)

Edit 01-configmap.yaml to customize:

  • profiles.json - Add/remove Raspberry Pi nodes
  • alacritty.toml - Adjust terminal appearance
  • catppuccin-frappe.toml - Change color scheme

Step 6: Deploy to Kubernetes

Apply all manifests in order:

# From the kubernetes directory
kubectl apply -f 01-configmap.yaml
kubectl apply -f 02-secret.yaml
kubectl apply -f 03-deployment.yaml
kubectl apply -f 04-service.yaml
kubectl apply -f 05-ingress.yaml

Or apply all at once:

kubectl apply -f .

Step 7: Verify Deployment

Check pod status:

kubectl get pods -l app=socktop-webterm

Expected output:

NAME                                READY   STATUS    RESTARTS   AGE
socktop-webterm-xxxxxxxxxx-xxxxx    1/1     Running   0          30s
socktop-webterm-xxxxxxxxxx-xxxxx    1/1     Running   0          30s
socktop-webterm-xxxxxxxxxx-xxxxx    1/1     Running   0          30s

Check service:

kubectl get svc socktop-webterm

Check ingress:

kubectl get ingress socktop-webterm

View logs:

kubectl logs -l app=socktop-webterm -f

Step 8: Access the Application

Once deployed and NGINX Proxy Manager is configured, access your terminal at:

Traffic flow: Internet → NGINX Proxy Manager (SSL) → k3s:8080 (HTTP) → Traefik → Service → Pods

Architecture

Host Networking

The deployment uses hostNetwork: true to allow containers to access your Raspberry Pi nodes on port 8443 directly. This means:

  • Each pod binds to the host's network interface
  • Pods can reach 192.168.1.101:8443, 192.168.1.102:8443, etc.
  • The containerized socktop-agent runs on port 3001 (not 3000)

Session Affinity

The Service uses sessionAffinity: ClientIP and the Ingress uses cookie-based affinity to ensure:

  • Terminal sessions stay connected to the same pod
  • WebSocket connections don't get routed to different pods
  • Session timeout is set to 3 hours (10800 seconds)

Replicas and Load Balancing

With 3 replicas and hostNetwork: true:

  • k3s will spread pods across available nodes (if you have 3+ nodes)
  • If you have fewer nodes, multiple pods may share nodes
  • Each pod has its own socktop-agent on port 3001
  • Traefik balances HTTP requests across all pods
  • NGINX Proxy Manager forwards external traffic to Traefik on port 8080

Configuration Updates

To update configuration without restarting pods:

# Edit the ConfigMap
kubectl edit configmap socktop-webterm-config

# Force pods to reload (rolling restart)
kubectl rollout restart deployment socktop-webterm

Troubleshooting

Pods in ImagePullBackOff

Check if nodes can access the Gitea registry:

# On any k3s node
docker pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0

If it fails, verify /etc/rancher/k3s/registries.yaml is configured correctly.

Pods in CrashLoopBackOff

Check pod logs:

kubectl logs -l app=socktop-webterm --tail=100

Common issues:

  • Missing configuration files
  • Port conflicts (if hostNetwork is used)
  • Resource limits too low

Can't Connect to Raspberry Pi Nodes

Test from within a pod:

kubectl exec -it deployment/socktop-webterm -- curl -k https://192.168.1.101:8443/health

If this fails:

  • Verify hostNetwork: true is set in deployment
  • Check if your k3s nodes can reach the Raspberry Pi IPs
  • Verify TLS certificates are correct

Can't Access via HTTPS

SSL is terminated at your external NGINX Proxy Manager, not in the cluster.

Check external NGINX Proxy Manager:

  • Verify proxy host configuration
  • Check SSL certificate is valid
  • Ensure WebSocket support is enabled
  • Verify forwarding to correct k3s node IP on port 8080
  • Check DNS points to external IP, not cluster IP

Check Traefik ingress:

kubectl get ingress socktop-webterm
kubectl describe ingress socktop-webterm

Test internal access:

# From a k3s node
curl http://localhost:8080

WebSocket Connections Failing

WebSocket support must be enabled in two places:

  1. External NGINX Proxy Manager - Enable WebSocket support in proxy host settings
  2. Traefik - Should handle WebSockets by default

Check Traefik logs:

kubectl logs -n kube-system deployment/traefik -f

Test WebSocket upgrade:

# Check headers are being passed correctly
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" http://<k3s-node>:8080/

Scaling

Scale up or down:

# Scale to 5 replicas
kubectl scale deployment socktop-webterm --replicas=5

# Scale down to 2 replicas
kubectl scale deployment socktop-webterm --replicas=2

Updating the Image

After publishing a new version to Gitea:

# Update to specific version
kubectl set image deployment/socktop-webterm webterm=192.168.1.208:3002/jason/socktop-webterm:0.3.0

# Or force pull latest
kubectl rollout restart deployment socktop-webterm

Uninstalling

Remove all resources:

kubectl delete -f .

Or individually:

kubectl delete ingress socktop-webterm
kubectl delete service socktop-webterm
kubectl delete deployment socktop-webterm
kubectl delete configmap socktop-webterm-config
kubectl delete secret socktop-webterm-certs

Resource Usage

Each pod uses:

  • CPU: 500m request, 2000m limit
  • Memory: 256Mi request, 1Gi limit

With 3 replicas:

  • Total CPU: 1500m request, 6000m limit
  • Total Memory: 768Mi request, 3Gi limit

Adjust in 03-deployment.yaml based on your cluster capacity and workload.

Security Considerations

  1. Host Network: Using hostNetwork: true reduces isolation. Ensure your cluster network is trusted.
  2. TLS Certificates: Store Pi certificates as Kubernetes secrets, not in ConfigMaps.
  3. External SSL: SSL is terminated at NGINX Proxy Manager before reaching the cluster.
  4. Authentication: Consider adding authentication layer in NGINX Proxy Manager or as a k8s middleware.
  5. Network Policies: Implement NetworkPolicies to restrict pod-to-pod communication.
  6. Port Exposure: Only port 8080 needs to be accessible from NGINX Proxy Manager, not from public internet.

Support

For issues specific to:

  • Kubernetes deployment: Check logs and events with kubectl describe
  • Container build: Refer to main repository documentation
  • k3s configuration: Consult k3s documentation at https://docs.k3s.io
  • Traefik ingress: Check Traefik logs in kube-system namespace
  • External proxy: Verify NGINX Proxy Manager configuration and SSL certificates