359 lines
9.5 KiB
Markdown
359 lines
9.5 KiB
Markdown
|
|
# 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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 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`:
|
||
|
|
|
||
|
|
```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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
kubectl apply -f .
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 7: Verify Deployment
|
||
|
|
|
||
|
|
Check pod status:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
kubectl get svc socktop-webterm
|
||
|
|
```
|
||
|
|
|
||
|
|
Check ingress:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
kubectl get ingress socktop-webterm
|
||
|
|
```
|
||
|
|
|
||
|
|
View logs:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
kubectl logs -l app=socktop-webterm -f
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 8: Access the Application
|
||
|
|
|
||
|
|
Once deployed and NGINX Proxy Manager is configured, access your terminal at:
|
||
|
|
- https://socktop.io (SSL terminated at NGINX Proxy Manager)
|
||
|
|
- https://www.socktop.io
|
||
|
|
- https://origin.socktop.io
|
||
|
|
|
||
|
|
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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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:**
|
||
|
|
```bash
|
||
|
|
kubectl get ingress socktop-webterm
|
||
|
|
kubectl describe ingress socktop-webterm
|
||
|
|
```
|
||
|
|
|
||
|
|
**Test internal access:**
|
||
|
|
```bash
|
||
|
|
# 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:**
|
||
|
|
```bash
|
||
|
|
kubectl logs -n kube-system deployment/traefik -f
|
||
|
|
```
|
||
|
|
|
||
|
|
**Test WebSocket upgrade:**
|
||
|
|
```bash
|
||
|
|
# Check headers are being passed correctly
|
||
|
|
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" http://<k3s-node>:8080/
|
||
|
|
```
|
||
|
|
|
||
|
|
## Scaling
|
||
|
|
|
||
|
|
Scale up or down:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 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:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
kubectl delete -f .
|
||
|
|
```
|
||
|
|
|
||
|
|
Or individually:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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
|