Initial commit: Socktop WebTerm with k3s deployment

- Multi-architecture Docker image (ARM64 + AMD64)
- Kubernetes manifests for 3-replica deployment
- Traefik ingress configuration
- NGINX Proxy Manager integration
- ConfigMap-based configuration
- Automated build and deployment scripts
- Session monitoring tools
This commit is contained in:
2025-11-28 01:31:33 -08:00
parent 627073ef2d
commit 6e48c095ab
68 changed files with 12391 additions and 1007 deletions
+72
View File
@@ -0,0 +1,72 @@
╔═══════════════════════════════════════════════════════════════════════╗
║ Socktop WebTerm - Kubernetes Deployment Files ║
║ Ready for k3s Cluster with Traefik ║
╚═══════════════════════════════════════════════════════════════════════╝
📁 KUBERNETES MANIFESTS (Deploy in order)
├─ 01-configmap.yaml Config files (profiles, alacritty, theme)
├─ 02-secret.yaml TLS certificates placeholder
├─ 03-deployment.yaml 3 replicas, host network, resource limits
├─ 04-service.yaml ClusterIP with session affinity
└─ 05-ingress.yaml Traefik ingress for 3 domains (HTTP only)
🛠️ DEPLOYMENT TOOLS
├─ deploy.sh ⭐ Automated deployment script (USE THIS!)
├─ kustomization.yaml Kustomize configuration
└─ registries.yaml.example k3s registry config template
📚 DOCUMENTATION
├─ INDEX.md 📍 Start here - Overview & navigation
├─ QUICKSTART.md ⚡ 5-minute deployment guide
├─ README.md 📖 Comprehensive guide & troubleshooting
├─ CHECKLIST.md ✅ Pre-deployment verification
└─ NGINX-PROXY-MANAGER.md 🔧 External proxy configuration guide
🚀 QUICK DEPLOY
1. Configure k3s registry: See registries.yaml.example
2. Run: ./deploy.sh
3. Configure NGINX Proxy Manager: See NGINX-PROXY-MANAGER.md
4. Access: https://socktop.io
🔧 KEY FEATURES
• 3 replicas across k3s nodes
• Host networking for Pi access (192.168.1.101-104:8443)
• Session affinity for terminal connections
• Traefik ingress (default with k3s)
• External SSL termination via NGINX Proxy Manager
• WebSocket support for terminals
• Containerized agent on port 3001
⚠️ IMPORTANT SETUP STEPS
1. Configure /etc/rancher/k3s/registries.yaml on ALL k3s nodes
2. Deploy to k3s cluster (./deploy.sh)
3. Configure NGINX Proxy Manager:
- Create proxy hosts for each domain
- Point to k3s-node-ip:8080
- Enable WebSocket support
- Add SSL certificates
- See NGINX-PROXY-MANAGER.md for details
4. Point DNS to NGINX Proxy Manager external IP
📊 RESOURCE REQUIREMENTS (Total for 3 replicas)
• CPU: 1.5 cores (request), 6 cores (limit)
• RAM: 768 MB (request), 3 GB (limit)
🌐 TRAFFIC FLOW
Internet (HTTPS:443)
NGINX Proxy Manager (SSL termination)
↓ (HTTP)
k3s Traefik Ingress (port 8080)
Socktop WebTerm Service
Pods (3 replicas with host networking)
🌐 DOMAINS (Configure in NGINX Proxy Manager)
• socktop.io → k3s-node:8080
• www.socktop.io → k3s-node:8080
• origin.socktop.io → k3s-node:8080
✅ All files ready for deployment to k3s cluster!
SSL handled externally via NGINX Proxy Manager on port 8080
+177
View File
@@ -0,0 +1,177 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: socktop-webterm-config
data:
profiles.json: |
{
"profiles": {
"local": {
"url": "ws://127.0.0.1:3001/ws"
},
"rpi-master": {
"url": "wss://192.168.1.101:8443/ws",
"tls_ca": "/home/socktop/.config/socktop/certs/rpi-master.pem",
"metrics_interval_ms": 1000,
"processes_interval_ms": 5000
},
"rpi-worker-1": {
"url": "wss://192.168.1.102:8443/ws",
"tls_ca": "/home/socktop/.config/socktop/certs/rpi-worker-1.pem",
"metrics_interval_ms": 1000,
"processes_interval_ms": 5000
},
"rpi-worker-2": {
"url": "wss://192.168.1.103:8443/ws",
"tls_ca": "/home/socktop/.config/socktop/certs/rpi-worker-2.pem",
"metrics_interval_ms": 1000,
"processes_interval_ms": 5000
},
"rpi-worker-3": {
"url": "wss://192.168.1.104:8443/ws",
"tls_ca": "/home/socktop/.config/socktop/certs/rpi-worker-3.pem",
"metrics_interval_ms": 1000,
"processes_interval_ms": 5000
}
},
"version": 0
}
alacritty.toml: |
import = [
"~/.config/alacritty/catppuccin-frappe.toml",
]
[window]
decorations = "None"
decorations_theme_variant = "Dark"
dynamic_padding = true
opacity = 0.85
blur = true
startup_mode = "Windowed"
padding.x = 12
padding.y = 12
[window.dimensions]
columns = 120
lines = 36
[scrolling]
history = 10000
multiplier = 3
[font]
size = 12.0
[font.normal]
family = "FiraCode Nerd Font"
style = "Regular"
[font.bold]
family = "FiraCode Nerd Font"
style = "Bold"
[font.italic]
family = "FiraCode Nerd Font"
style = "Italic"
[font.bold_italic]
family = "FiraCode Nerd Font"
style = "Bold Italic"
[colors]
draw_bold_text_with_bright_colors = true
[cursor]
style.shape = "Block"
style.blinking = "On"
vi_mode_style.shape = "Block"
blink_interval = 750
blink_timeout = 5
unfocused_hollow = true
thickness = 0.15
[mouse]
hide_when_typing = false
[bell]
animation = "EaseOutExpo"
duration = 0
color = "#ffffff"
[selection]
save_to_clipboard = true
[terminal]
osc52 = "CopyPaste"
catppuccin-frappe.toml: |
# Catppuccin Frappe color scheme for Alacritty
[colors.primary]
background = "#303446"
foreground = "#c6d0f5"
dim_foreground = "#838ba7"
bright_foreground = "#c6d0f5"
[colors.cursor]
text = "#303446"
cursor = "#f2d5cf"
[colors.vi_mode_cursor]
text = "#303446"
cursor = "#babbf1"
[colors.search.matches]
foreground = "#303446"
background = "#a5adce"
[colors.search.focused_match]
foreground = "#303446"
background = "#a6d189"
[colors.footer_bar]
foreground = "#303446"
background = "#a5adce"
[colors.hints.start]
foreground = "#303446"
background = "#e5c890"
[colors.hints.end]
foreground = "#303446"
background = "#a5adce"
[colors.selection]
text = "#303446"
background = "#f2d5cf"
[colors.normal]
black = "#51576d"
red = "#e78284"
green = "#a6d189"
yellow = "#e5c890"
blue = "#8caaee"
magenta = "#f4b8e4"
cyan = "#81c8be"
white = "#b5bfe2"
[colors.bright]
black = "#626880"
red = "#e78284"
green = "#a6d189"
yellow = "#e5c890"
blue = "#8caaee"
magenta = "#f4b8e4"
cyan = "#81c8be"
white = "#a5adce"
[colors.dim]
black = "#51576d"
red = "#e78284"
green = "#a6d189"
yellow = "#e5c890"
blue = "#8caaee"
magenta = "#f4b8e4"
cyan = "#81c8be"
white = "#b5bfe2"
+23
View File
@@ -0,0 +1,23 @@
apiVersion: v1
kind: Secret
metadata:
name: socktop-webterm-certs
type: Opaque
data:
# Base64 encoded TLS CA certificates for your Raspberry Pi nodes
# Replace these with your actual base64-encoded certificate files
# To encode: cat cert.pem | base64 -w 0
# Example placeholder - replace with your actual certificates:
# rpi-master.pem: LS0tLS1CRUdJTi...
# rpi-worker-1.pem: LS0tLS1CRUdJTi...
# rpi-worker-2.pem: LS0tLS1CRUdJTi...
# rpi-worker-3.pem: LS0tLS1CRUdJTi...
# To create this secret with your actual certificates, run:
# 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 \
# --dry-run=client -o yaml | kubectl apply -f -
+99
View File
@@ -0,0 +1,99 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: socktop-webterm
labels:
app: socktop-webterm
spec:
replicas: 3
selector:
matchLabels:
app: socktop-webterm
template:
metadata:
labels:
app: socktop-webterm
spec:
# Use host network to access Raspberry Pi nodes on port 8443
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
containers:
- name: webterm
image: 192.168.1.208:3002/jason/socktop-webterm:0.2.2
imagePullPolicy: Always
ports:
- name: http
containerPort: 8082
protocol: TCP
- name: agent
containerPort: 3001
protocol: TCP
env:
- name: TERM
value: "xterm-256color"
- name: TZ
value: "America/New_York"
- name: RUST_LOG
value: "info"
resources:
limits:
cpu: "2000m"
memory: "1Gi"
requests:
cpu: "500m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /
port: 8082
initialDelaySeconds: 10
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 8082
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
volumeMounts:
- name: config
mountPath: /home/socktop/.config/socktop/profiles.json
subPath: profiles.json
- name: config
mountPath: /home/socktop/.config/alacritty/alacritty.toml
subPath: alacritty.toml
- name: config
mountPath: /home/socktop/.config/alacritty/catppuccin-frappe.toml
subPath: catppuccin-frappe.toml
- name: certs
mountPath: /home/socktop/.config/socktop/certs
readOnly: true
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: false
volumes:
- name: config
configMap:
name: socktop-webterm-config
- name: certs
secret:
secretName: socktop-webterm-certs
optional: true
restartPolicy: Always
+23
View File
@@ -0,0 +1,23 @@
apiVersion: v1
kind: Service
metadata:
name: socktop-webterm
labels:
app: socktop-webterm
spec:
type: ClusterIP
ports:
- name: http
port: 8082
targetPort: 8082
protocol: TCP
- name: agent
port: 3001
targetPort: 3001
protocol: TCP
selector:
app: socktop-webterm
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
+44
View File
@@ -0,0 +1,44 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: socktop-webterm
labels:
app: socktop-webterm
spec:
ingressClassName: traefik
defaultBackend:
service:
name: socktop-webterm
port:
number: 8082
rules:
- host: socktop.io
http:
paths:
- backend:
service:
name: socktop-webterm
port:
number: 8082
path: /
pathType: Prefix
- host: www.socktop.io
http:
paths:
- backend:
service:
name: socktop-webterm
port:
number: 8082
path: /
pathType: Prefix
- host: origin.socktop.io
http:
paths:
- backend:
service:
name: socktop-webterm
port:
number: 8082
path: /
pathType: Prefix
+216
View File
@@ -0,0 +1,216 @@
# Pre-Deployment Checklist for Socktop WebTerm on k3s
Use this checklist to ensure your k3s cluster is properly configured before deploying Socktop WebTerm.
## Infrastructure Requirements
### k3s Cluster
- [ ] k3s cluster is installed and running
- [ ] At least 3 nodes available (for spreading 3 replicas)
- [ ] `kubectl` is installed and configured
- [ ] Can run `kubectl get nodes` successfully
- [ ] Traefik ingress controller is running (default with k3s)
- [ ] Nodes have sufficient resources:
- [ ] 1.5+ CPU cores available per node
- [ ] 768+ MB RAM available per node
### Network Access
- [ ] k3s nodes can reach Raspberry Pi nodes on port 8443
- [ ] 192.168.1.101:8443 (rpi-master)
- [ ] 192.168.1.102:8443 (rpi-worker-1)
- [ ] 192.168.1.103:8443 (rpi-worker-2)
- [ ] 192.168.1.104:8443 (rpi-worker-3)
- [ ] Test with: `curl -k https://192.168.1.101:8443/health`
### DNS Configuration
- [ ] DNS records point to your external NGINX Proxy Manager IP:
- [ ] socktop.io → external IP
- [ ] www.socktop.io → external IP
- [ ] origin.socktop.io → external IP
- [ ] DNS propagation is complete (test with `nslookup socktop.io`)
## Required k3s Components
### Traefik Ingress Controller
- [ ] Traefik is running (comes default with k3s)
- [ ] Check with: `kubectl get pods -n kube-system | grep traefik`
- [ ] Traefik is accessible on port 80 (HTTP)
### External NGINX Proxy Manager
- [ ] External NGINX Proxy Manager is configured
- [ ] SSL certificates are set up in Proxy Manager
- [ ] Proxy hosts configured for:
- [ ] socktop.io → k3s-node-ip:8080
- [ ] www.socktop.io → k3s-node-ip:8080
- [ ] origin.socktop.io → k3s-node-ip:8080
- [ ] WebSocket support enabled in proxy hosts
- [ ] SSL termination happens at NGINX Proxy Manager
## Docker Registry Access
### Gitea Registry Configuration
- [ ] Gitea registry is accessible at 192.168.1.208:3002
- [ ] Test with: `curl http://192.168.1.208:3002/v2/`
- [ ] Image exists: `192.168.1.208:3002/jason/socktop-webterm:0.2.0`
### Insecure Registry Configuration (REQUIRED)
Since Gitea uses HTTP, you MUST configure k3s to allow insecure registries.
**On EACH k3s node** (both server and agents):
- [ ] Created `/etc/rancher/k3s/registries.yaml` with:
```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
```
- [ ] Restarted k3s services:
- [ ] Server: `sudo systemctl restart k3s`
- [ ] Agents: `sudo systemctl restart k3s-agent`
- [ ] Test image pull: `docker pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0`
## TLS Certificates (Optional but Recommended)
### Raspberry Pi TLS Certificates
If you want to connect to Pi nodes via TLS:
- [ ] Have TLS CA certificates for each Pi node:
- [ ] rpi-master.pem
- [ ] rpi-worker-1.pem
- [ ] rpi-worker-2.pem
- [ ] rpi-worker-3.pem
- [ ] Certificate files are accessible on your local machine
- [ ] Know the full path to each certificate file
**Note:** If you don't have these yet, the deployment will still work, but you won't be able to connect to Pi nodes via TLS WebSocket.
## Configuration Files
### profiles.json
- [ ] Reviewed `kubernetes/01-configmap.yaml`
- [ ] Updated Raspberry Pi IP addresses if different
- [ ] Updated port numbers if different
- [ ] Updated certificate paths if different
### alacritty.toml
- [ ] Reviewed terminal configuration in `kubernetes/01-configmap.yaml`
- [ ] Adjusted font size/family if desired
- [ ] Adjusted transparency/blur settings if desired
## Deployment Files Ready
- [ ] All manifest files are present:
- [ ] `01-configmap.yaml`
- [ ] `02-secret.yaml`
- [ ] `03-deployment.yaml`
- [ ] `04-service.yaml`
- [ ] `05-ingress.yaml`
- [ ] `deploy.sh` script is executable: `chmod +x deploy.sh`
## Security Considerations
- [ ] Understand that `hostNetwork: true` reduces pod isolation
- [ ] Cluster network is trusted (not exposed to public internet directly)
- [ ] TLS certificates will be stored as Kubernetes secrets
- [ ] Consider implementing authentication (OAuth2 Proxy, etc.)
- [ ] Rate limiting is configured in ingress (100 rps by default)
## Resource Planning
With 3 replicas, total resource requirements:
- **CPU**: 1.5 cores requested, 6 cores limit
- **Memory**: 768 MB requested, 3 GB limit
- [ ] Your cluster has sufficient resources
- [ ] Check with: `kubectl describe nodes`
## Backup Plan
- [ ] Know how to view logs: `kubectl logs -l app=socktop-webterm`
- [ ] Know how to delete deployment: `kubectl delete -f kubernetes/`
- [ ] Have access to Docker logs on k3s nodes if needed
## Pre-Deployment Test Commands
Run these commands to verify everything is ready:
```bash
# Check cluster access
kubectl cluster-info
# Check nodes
kubectl get nodes
# Check Traefik ingress controller
kubectl get pods -n kube-system | grep traefik
# Check Traefik service
kubectl get svc -n kube-system traefik
# Test registry access from a node
ssh <your-k3s-node>
docker pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0
# Test network access to Pi nodes
curl -k https://192.168.1.101:8443/health
```
## Ready to Deploy?
If all items above are checked ✓, you're ready to deploy!
### Choose your deployment method:
**Option 1: Automated (Recommended)**
```bash
cd kubernetes
./deploy.sh
```
**Option 2: Manual**
```bash
cd kubernetes
kubectl apply -f .
```
**Option 3: Kustomize**
```bash
cd kubernetes
kubectl apply -k .
```
## Post-Deployment Verification
After deployment, verify:
```bash
# Check pods are running
kubectl get pods -l app=socktop-webterm
# Check service is created
kubectl get svc socktop-webterm
# Check ingress is configured
kubectl get ingress socktop-webterm
# View logs
kubectl logs -l app=socktop-webterm -f
```
Configure your external NGINX Proxy Manager to forward traffic, then access:
- https://socktop.io (SSL terminated at NGINX Proxy Manager)
- https://www.socktop.io
- https://origin.socktop.io
## Troubleshooting
If something goes wrong, see:
- `QUICKSTART.md` - Common issues and quick fixes
- `README.md` - Detailed troubleshooting guide
- Pod logs: `kubectl logs -l app=socktop-webterm`
- Pod events: `kubectl describe pods -l app=socktop-webterm`
+287
View File
@@ -0,0 +1,287 @@
# Next Steps - Ready to Run After Registry Setup
## Step 1: Verify All Nodes Have the Image
Once all nodes finish pulling, verify:
```bash
# Check each node has the image cached
ssh pi@192.168.1.101 'sudo k3s crictl images | grep socktop'
ssh pi@192.168.1.102 'sudo k3s crictl images | grep socktop'
ssh pi@192.168.1.104 'sudo k3s crictl images | grep socktop'
# Should show:
# 192.168.1.208:3002/jason/socktop-webterm 0.2.0 <image-id> <size> <time>
```
## Step 2: Setup kubectl (if not done yet)
```bash
cd kubernetes
./setup-kubectl.sh
# Enter: 192.168.1.101 (your k3s server IP)
# Choose: Option 2 (save as separate file)
# Export for current session
export KUBECONFIG=~/.kube/config-k3s
# Test connection
kubectl get nodes
```
**Expected output:**
```
NAME STATUS ROLES AGE VERSION
rpi-master Ready control-plane,master 30d v1.28.x+k3s1
rpi-worker-1 Ready <none> 30d v1.28.x+k3s1
rpi-worker-2 Ready <none> 30d v1.28.x+k3s1
rpi-worker-3 Ready <none> 30d v1.28.x+k3s1
```
## Step 3: Deploy to k3s
```bash
./deploy.sh
```
**Script will ask:**
- Namespace: Press Enter for `default` or type custom name
- TLS certificates: Skip if you don't have Pi certificates yet
**Expected output:**
```
=== Socktop WebTerm - Kubernetes Deployment Script ===
✓ Connected to Kubernetes cluster
Current context: default
Enter namespace to deploy to (default: default):
Target namespace: default
Applying ConfigMap...
✓ ConfigMap applied
Applying Secret...
✓ Secret applied
Applying Deployment...
✓ Deployment applied
Applying Service...
✓ Service applied
Applying Ingress...
✓ Ingress applied
=== Deployment Complete! ===
Waiting for pods to be ready...
(This may take a minute while images are pulled)
✓ All pods are ready!
Pods:
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
```
## Step 4: Verify Deployment
```bash
# Check pods are running
kubectl get pods -l app=socktop-webterm -o wide
# Check which nodes they're on
kubectl get pods -l app=socktop-webterm -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName,STATUS:.status.phase
# Check service
kubectl get svc socktop-webterm
# Check ingress
kubectl get ingress socktop-webterm
# View logs
kubectl logs -l app=socktop-webterm --tail=20
```
## Step 5: Test Internal Access
From any k3s node:
```bash
# Test HTTP access
curl -I http://localhost:8080 -H "Host: socktop.io"
# Should return HTTP 200 OK
```
## Step 6: Configure NGINX Proxy Manager
See `NGINX-PROXY-MANAGER.md` for full details.
**Quick setup:**
1. **Log into NGINX Proxy Manager** (http://your-proxy-manager:81)
2. **Add Proxy Host → socktop.io**
- Domain Names: `socktop.io`
- Scheme: `http`
- Forward Hostname/IP: `192.168.1.101` (any k3s node)
- Forward Port: `8080`
- ✅ Websockets Support: ON
- Block Common Exploits: ON
**SSL Tab:**
- SSL Certificate: Select/create Let's Encrypt cert
- Force SSL: ON
- HTTP/2 Support: ON
**Advanced Tab:**
```nginx
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
```
3. **Repeat for www.socktop.io and origin.socktop.io**
## Step 7: Test External Access
```bash
# Test from external network or your local machine
curl -I https://socktop.io
# Should return HTTP 200 OK with SSL
```
Open browser:
- https://socktop.io
- Should see the webterm interface
- Check browser console (F12) → Network tab
- Look for WebSocket connection with status "101 Switching Protocols"
## Step 8: Test Terminal Functionality
In the browser:
1. Select "local" profile (containerized agent on port 3001)
2. Terminal should connect and show prompt
3. Try running commands: `ls`, `pwd`, `uname -a`
4. Test with Pi profiles if you have TLS certs configured
## Troubleshooting Quick Reference
### Pods not starting
```bash
kubectl describe pods -l app=socktop-webterm
kubectl logs -l app=socktop-webterm --tail=50
```
### ImagePullBackOff
```bash
# Check if image is on the node
kubectl get pods -l app=socktop-webterm -o wide
# Note which node
ssh pi@<node-ip> 'sudo k3s crictl images | grep socktop'
```
### 502 Bad Gateway
```bash
# Check pods are running
kubectl get pods -l app=socktop-webterm
# Check service endpoints
kubectl get endpoints socktop-webterm
# Test from k3s node
ssh pi@192.168.1.101 'curl http://localhost:8080 -H "Host: socktop.io"'
```
### WebSocket not connecting
- Check NGINX Proxy Manager has WebSocket Support enabled
- Check Advanced config includes upgrade headers
- Check browser console for specific errors
## Useful Commands
```bash
# Watch pod status
kubectl get pods -l app=socktop-webterm -w
# Stream logs from all pods
kubectl logs -l app=socktop-webterm -f
# Scale up
kubectl scale deployment socktop-webterm --replicas=5
# Scale down
kubectl scale deployment socktop-webterm --replicas=2
# Restart deployment (e.g., after config change)
kubectl rollout restart deployment socktop-webterm
# View rollout status
kubectl rollout status deployment socktop-webterm
# Update image to new version
kubectl set image deployment/socktop-webterm \
webterm=192.168.1.208:3002/jason/socktop-webterm:0.3.0
# Delete deployment
kubectl delete -f .
```
## Performance Testing
Once running:
```bash
# Check resource usage
kubectl top pods -l app=socktop-webterm
# Check pod distribution across nodes
kubectl get pods -l app=socktop-webterm -o wide
# Watch metrics
watch -n 2 'kubectl top pods -l app=socktop-webterm'
```
## Success Indicators
✅ 3 pods in Running state
✅ Service has 3 endpoints
✅ Ingress created successfully
✅ Can curl http://localhost:8080 from k3s node
✅ NGINX Proxy Manager forwards traffic
✅ Can access https://socktop.io in browser
✅ WebSocket connects (check browser console)
✅ Terminal sessions work
✅ Can switch between profiles
## Next Steps After Deployment
1. Monitor performance under load
2. Test failover (kill a pod, see if traffic continues)
3. Test session affinity (refresh page, stay on same pod)
4. Configure monitoring/alerting (optional)
5. Set up backup strategy for configs (optional)
6. Document your NGINX Proxy Manager config
## All Done! 🎉
Your Socktop WebTerm should now be:
- Running on 3 pods
- Distributed across k3s nodes
- Accessible via https://socktop.io
- Load balanced by Traefik
- SSL terminated at NGINX Proxy Manager
- Ready for production use!
+307
View File
@@ -0,0 +1,307 @@
# Socktop WebTerm - Kubernetes Deployment Guide
Complete Kubernetes deployment manifests and tools for running Socktop WebTerm on your k3s cluster.
## 📁 Files Overview
### Core Manifests (Deploy in Order)
1. **`01-configmap.yaml`** - Configuration files (profiles.json, alacritty.toml, theme)
2. **`02-secret.yaml`** - TLS certificates for Raspberry Pi nodes (placeholder)
3. **`03-deployment.yaml`** - Main deployment with 3 replicas, host networking
4. **`04-service.yaml`** - Service with session affinity for terminal connections
5. **`05-ingress.yaml`** - Ingress with TLS, WebSocket support, and multiple domains
### Deployment Tools
- **`deploy.sh`** - Automated deployment script (recommended)
- **`kustomization.yaml`** - Kustomize configuration for advanced deployments
### Documentation
- **`INDEX.md`** - This file - overview and quick navigation
- **`QUICKSTART.md`** - Get running in 5 minutes
- **`README.md`** - Comprehensive deployment guide
- **`CHECKLIST.md`** - Pre-deployment checklist
## 🚀 Quick Start
### Fastest Way to Deploy
```bash
cd kubernetes
./deploy.sh
```
The script handles everything automatically!
### Manual Deployment
```bash
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 all at once:
```bash
kubectl apply -f .
```
## 📋 Prerequisites
Before deploying, ensure you have:
- ✅ k3s cluster running (3+ nodes recommended)
- ✅ kubectl configured
- ✅ Traefik Ingress Controller (default with k3s)
- ✅ External NGINX Proxy Manager for SSL termination
- ✅ DNS records pointing to external IP (socktop.io, www.socktop.io, origin.socktop.io)
- ✅ Insecure registry configured for `192.168.1.208:3002`
- ✅ Proxy hosts configured in NGINX Proxy Manager to forward to k3s on port 8080
**See `CHECKLIST.md` for complete pre-deployment verification.**
## 🔧 Configuration Overview
### Deployment Specs
- **Replicas**: 3 (adjust in `03-deployment.yaml`)
- **Image**: `192.168.1.208:3002/jason/socktop-webterm:0.2.0`
- **Networking**: Host network mode (for accessing Pi nodes on port 8443)
- **Resources**: 500m-2000m CPU, 256Mi-1Gi RAM per pod
- **Health Checks**: HTTP liveness and readiness probes
### Exposed Services
- **Port 8082**: WebTerm HTTP interface
- **Port 3001**: Containerized socktop-agent
### Ingress Configuration
- **Ingress Controller**: Traefik (default with k3s)
- **Domains**: socktop.io, www.socktop.io, origin.socktop.io
- **TLS**: Terminated at external NGINX Proxy Manager (not in cluster)
- **WebSocket**: Supported by default in Traefik
- **Session Affinity**: Configured in Service (ClientIP)
### ConfigMap Contents
- `profiles.json` - Connection profiles for local and 4 Pi nodes
- `alacritty.toml` - Terminal emulator configuration
- `catppuccin-frappe.toml` - Color scheme
## 📚 Documentation Guide
### Start Here
1. **`CHECKLIST.md`** - Verify all prerequisites are met
2. **`QUICKSTART.md`** - Deploy in 5 minutes
3. **`README.md`** - Deep dive into configuration and troubleshooting
### Common Tasks
**First Time Deployment**
→ Read `CHECKLIST.md` then run `./deploy.sh`
**Quick Deploy**
→ See `QUICKSTART.md`
**Troubleshooting**
→ See `QUICKSTART.md` (common issues) or `README.md` (comprehensive guide)
**Update Configuration**
→ Edit ConfigMap: `kubectl edit configmap socktop-webterm-config`
→ Restart: `kubectl rollout restart deployment socktop-webterm`
**Update Image Version**
`kubectl set image deployment/socktop-webterm webterm=192.168.1.208:3002/jason/socktop-webterm:NEW_VERSION`
**Scale Replicas**
`kubectl scale deployment socktop-webterm --replicas=5`
## 🛠️ Common Commands
```bash
# Check deployment status
kubectl get pods -l app=socktop-webterm
# View logs
kubectl logs -l app=socktop-webterm -f
# Check ingress
kubectl get ingress socktop-webterm
# Check certificate status
kubectl get certificate socktop-webterm-tls
# Describe deployment
kubectl describe deployment socktop-webterm
# Scale up
kubectl scale deployment socktop-webterm --replicas=5
# Update image
kubectl set image deployment/socktop-webterm webterm=192.168.1.208:3002/jason/socktop-webterm:0.3.0
# Restart deployment
kubectl rollout restart deployment socktop-webterm
# Delete everything
kubectl delete -f .
```
## 🌐 Access URLs
After deployment and configuring NGINX Proxy Manager, 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 (port 8080) → k3s Traefik (HTTP) → Service → Pods**
## ⚙️ Architecture Highlights
### Host Networking
- Uses `hostNetwork: true` to directly access Pi nodes on port 8443
- Each pod binds to host network interface
- Containerized agent runs on port 3001 (not 3000) to avoid conflicts
### High Availability
- 3 replicas for redundancy
- k3s spreads pods across available nodes
- Session affinity keeps users on same pod
- If a pod fails, traffic routes to healthy pods
### WebSocket Support
- Ingress configured for WebSocket upgrades
- Long connection timeouts (3600s)
- Proper headers for terminal connections
### Security
- Non-root user inside container
- Read-only certificate mounts
- Security context with dropped capabilities
- TLS for external access
- Rate limiting enabled
## 🔍 Monitoring & Debugging
### Check Resource Usage
```bash
kubectl top pods -l app=socktop-webterm
```
### View Pod Distribution
```bash
kubectl get pods -l app=socktop-webterm -o wide
```
### Check Events
```bash
kubectl get events --sort-by='.lastTimestamp' | grep socktop
```
### Test Pi Connectivity
```bash
kubectl exec -it deployment/socktop-webterm -- curl -k https://192.168.1.101:8443/health
```
## 📦 What's Included
```
kubernetes/
├── 01-configmap.yaml # Configuration files
├── 02-secret.yaml # TLS certificates (placeholder)
├── 03-deployment.yaml # Main deployment (3 replicas)
├── 04-service.yaml # Service with session affinity
├── 05-ingress.yaml # Ingress with TLS and WebSocket
├── deploy.sh # Automated deployment script
├── kustomization.yaml # Kustomize configuration
├── CHECKLIST.md # Pre-deployment checklist
├── QUICKSTART.md # 5-minute quick start
├── README.md # Comprehensive guide
└── INDEX.md # This file
```
## 🚨 Important Notes
1. **Insecure Registry**: You MUST configure `/etc/rancher/k3s/registries.yaml` on all k3s nodes to allow pulling from `192.168.1.208:3002`
2. **DNS Configuration**: Ensure socktop.io domains point to your external NGINX Proxy Manager IP, not cluster IP
3. **External Proxy**: Configure NGINX Proxy Manager to forward traffic to k3s nodes on port 8080 with WebSocket support enabled
4. **SSL Termination**: SSL/TLS is handled by NGINX Proxy Manager, not in the k8s cluster
5. **TLS Certificates**: The `02-secret.yaml` is a placeholder for Pi node certificates. Use `deploy.sh` or manually create the secret
6. **Host Network**: Using `hostNetwork: true` reduces isolation but is required to reach Pi nodes
7. **Session Affinity**: Crucial for maintaining terminal connections - don't disable!
## 🆘 Need Help?
### Quick Fixes
See **`QUICKSTART.md`** for common issues and solutions
### Detailed Troubleshooting
See **`README.md`** for comprehensive troubleshooting guide
### Verify Prerequisites
Run through **`CHECKLIST.md`** to ensure everything is configured
### Check Logs
```bash
kubectl logs -l app=socktop-webterm --tail=100
```
### Describe Resources
```bash
kubectl describe deployment socktop-webterm
kubectl describe pods -l app=socktop-webterm
```
## 📈 Performance & Scaling
### Default Configuration
- 3 replicas
- 500m CPU request, 2000m limit per pod
- 256Mi RAM request, 1Gi limit per pod
### Scaling Up
```bash
kubectl scale deployment socktop-webterm --replicas=5
```
### Resource Adjustment
Edit `03-deployment.yaml` resources section, then:
```bash
kubectl apply -f 03-deployment.yaml
```
## 🔐 Security Considerations
- Run as non-root user inside container
- Drop unnecessary capabilities
- Use secrets for sensitive data (certificates)
- Enable TLS for external access
- Implement rate limiting
- Consider adding authentication layer (OAuth2 Proxy)
- Use network policies to restrict pod-to-pod traffic
## ✅ Success Indicators
Deployment is successful when:
- All 3 pods show `Running` status
- Service has endpoints: `kubectl get endpoints socktop-webterm`
- Ingress has an address: `kubectl get ingress socktop-webterm`
- Certificate shows `Ready=True`: `kubectl get certificate socktop-webterm-tls`
- Can access https://socktop.io in browser
- Terminal sessions work correctly
## 📝 Version Information
- **Application Version**: 0.2.0
- **Container Image**: 192.168.1.208:3002/jason/socktop-webterm:0.2.0
- **Kubernetes API Version**: apps/v1, networking.k8s.io/v1
- **Ingress Controller**: Traefik (default with k3s)
- **SSL Termination**: External NGINX Proxy Manager
---
**Ready to deploy?** Start with `CHECKLIST.md``./deploy.sh` → Profit! 🎉
+215
View File
@@ -0,0 +1,215 @@
# Setting Up kubectl for k3s
Since your kubectl config is empty, you need to configure it to connect to your k3s cluster.
## Quick Setup (Automated)
```bash
cd kubernetes
./setup-kubectl.sh
```
The script will:
1. Ask for your k3s server IP
2. Retrieve the kubeconfig from the server via SSH
3. Modify it to use the correct server IP
4. Save it to your local machine
5. Test the connection
### Example Run:
```bash
$ ./setup-kubectl.sh
Enter k3s server IP address: 192.168.1.101
Enter SSH username for k3s server (default: ubuntu): ubuntu
Fetching kubeconfig from k3s server...
✓ Retrieved kubeconfig from server
Choose how to save the kubeconfig:
1) Replace ~/.kube/config
2) Save as ~/.kube/config-k3s (separate file, safer)
3) Merge with existing ~/.kube/config
Enter choice (1/2/3, default: 2): 2
✓ Saved to ~/.kube/config-k3s
To use this config, run:
export KUBECONFIG=~/.kube/config-k3s
```
## Manual Setup
If you prefer to do it manually:
### Step 1: Get kubeconfig from k3s server
```bash
# SSH to your k3s server node
ssh ubuntu@192.168.1.101 # use your server IP
# View the kubeconfig
sudo cat /etc/rancher/k3s/k3s.yaml
```
### Step 2: Copy to your local machine
```bash
# On your local machine
mkdir -p ~/.kube
# Copy the config (replace 192.168.1.101 with your k3s server IP)
scp ubuntu@192.168.1.101:/tmp/k3s-config.yaml ~/.kube/config-k3s
# Or manually copy the content
nano ~/.kube/config-k3s
# Paste the content from previous step
```
### Step 3: Modify server IP
Edit the file and change the server IP from `127.0.0.1` to your actual k3s server IP:
```bash
nano ~/.kube/config-k3s
```
Change:
```yaml
server: https://127.0.0.1:6443
```
To:
```yaml
server: https://192.168.1.101:6443 # use your actual IP
```
### Step 4: Set KUBECONFIG
```bash
export KUBECONFIG=~/.kube/config-k3s
```
Make it permanent by adding to your shell config:
**For bash (~/.bashrc):**
```bash
echo 'export KUBECONFIG=~/.kube/config-k3s' >> ~/.bashrc
source ~/.bashrc
```
**For zsh (~/.zshrc):**
```bash
echo 'export KUBECONFIG=~/.kube/config-k3s' >> ~/.zshrc
source ~/.zshrc
```
**For fish (~/.config/fish/config.fish):**
```fish
echo 'set -gx KUBECONFIG ~/.kube/config-k3s' >> ~/.config/fish/config.fish
```
### Step 5: Test connection
```bash
kubectl get nodes
```
You should see your k3s nodes listed!
## Verify Setup
After configuration, verify everything works:
```bash
# Check contexts
kubectl config get-contexts
# Should show something like:
# CURRENT NAME CLUSTER AUTHINFO NAMESPACE
# * default default default
# Check nodes
kubectl get nodes
# Should show your k3s nodes:
# NAME STATUS ROLES AGE VERSION
# rpi-master Ready control-plane,master 30d v1.28.2+k3s1
# rpi-worker-1 Ready <none> 30d v1.28.2+k3s1
# rpi-worker-2 Ready <none> 30d v1.28.2+k3s1
# Check cluster info
kubectl cluster-info
```
## Troubleshooting
### Cannot connect to k3s server
**Error:** `Unable to connect to the server: dial tcp 192.168.1.101:6443: i/o timeout`
**Fix:**
- Verify the IP address is correct
- Check if port 6443 is accessible: `nc -zv 192.168.1.101 6443`
- Check firewall rules on k3s server
- Ensure k3s is running: `ssh ubuntu@192.168.1.101 'sudo systemctl status k3s'`
### Permission denied
**Error:** `error: You must be logged in to the server (Unauthorized)`
**Fix:**
- The kubeconfig may not have been copied correctly
- Re-run the setup script or manually copy the config again
### Wrong server IP
If you need to change the server IP:
```bash
nano ~/.kube/config-k3s
# Change the server: line to the correct IP
```
## Next Steps
Once kubectl is configured:
```bash
# 1. Configure registry on all k3s nodes
./setup-registry.sh
# 2. Deploy Socktop WebTerm
./deploy.sh
```
## Complete Workflow Example
```bash
# Setup kubectl
cd kubernetes
./setup-kubectl.sh
# Enter: 192.168.1.101 (your k3s server IP)
# Choose option 2 (save as separate file)
# Set environment variable for current session
export KUBECONFIG=~/.kube/config-k3s
# Verify connection
kubectl get nodes
# Configure registry
./setup-registry.sh
# Enter all node IPs
# Deploy
./deploy.sh
# Choose namespace: default
# Check status
kubectl get pods -l app=socktop-webterm
# Done!
```
+311
View File
@@ -0,0 +1,311 @@
# NGINX Proxy Manager Configuration for Socktop WebTerm
This guide explains how to configure your external NGINX Proxy Manager to route traffic to your k3s Socktop WebTerm deployment.
## Overview
Since your ISP restricts incoming ports, you're using an external NGINX Proxy Manager to:
- Terminate SSL/TLS connections
- Route traffic on port 8080 to your k3s cluster
- Handle WebSocket upgrades for terminal connections
## Architecture
```
Internet (HTTPS:443)
External NGINX Proxy Manager
↓ (SSL Termination)
k3s Traefik Ingress (HTTP:8080)
Socktop WebTerm Service
Pods (3 replicas)
```
## Prerequisites
- [ ] NGINX Proxy Manager installed and accessible
- [ ] SSL certificates ready (Let's Encrypt or custom)
- [ ] k3s cluster deployed with Socktop WebTerm
- [ ] Know your k3s node IP addresses
- [ ] DNS records pointing to your external NGINX Proxy Manager
## Configuration Steps
### Step 1: Get Your k3s Node IP
Find the IP address of any k3s node (Traefik runs on all nodes with k3s):
```bash
kubectl get nodes -o wide
```
Note any node's INTERNAL-IP (e.g., `192.168.1.101`).
### Step 2: Verify Traefik is Running
```bash
kubectl get svc -n kube-system traefik
```
You should see Traefik listening on port 80.
### Step 3: Create Proxy Host for socktop.io
In NGINX Proxy Manager web UI:
1. **Go to**: Proxy Hosts → Add Proxy Host
2. **Details Tab**:
- **Domain Names**: `socktop.io`
- **Scheme**: `http` (NOT https - SSL terminates at proxy)
- **Forward Hostname / IP**: `192.168.1.101` (your k3s node IP)
- **Forward Port**: `8080`
- **Cache Assets**: ☐ (unchecked)
- **Block Common Exploits**: ☑ (checked)
- **Websockets Support**: ☑ (IMPORTANT - check this!)
- **Access List**: None (or your preference)
3. **SSL Tab**:
- **SSL Certificate**: Select or create new Let's Encrypt certificate
- **Force SSL**: ☑ (checked)
- **HTTP/2 Support**: ☑ (checked)
- **HSTS Enabled**: ☑ (optional but recommended)
- **HSTS Subdomains**: ☐ (unless you want this)
4. **Advanced Tab** (optional but recommended):
```nginx
# Increase timeouts for long-running terminal connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
# WebSocket upgrade headers (should be set automatically, but just in case)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Pass through real client IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
```
5. Click **Save**
### Step 4: Create Proxy Host for www.socktop.io
Repeat Step 3 with:
- **Domain Names**: `www.socktop.io`
- All other settings identical
### Step 5: Create Proxy Host for origin.socktop.io
Repeat Step 3 with:
- **Domain Names**: `origin.socktop.io`
- All other settings identical
## Verify Configuration
### Test 1: Check HTTP Forward
From your local machine:
```bash
curl http://<k3s-node-ip>:8080 -H "Host: socktop.io"
```
Should return the webterm HTML page.
### Test 2: Check HTTPS via Proxy
```bash
curl -I https://socktop.io
```
Should return `200 OK` with SSL certificate.
### Test 3: Check WebSocket Support
In your browser's developer console (F12), check the Network tab when connecting to the terminal. You should see:
- WebSocket connection established
- Status: `101 Switching Protocols`
## Troubleshooting
### 502 Bad Gateway
**Cause**: NGINX Proxy Manager can't reach k3s
**Fix**:
- Verify k3s node IP is correct
- Check port 8080 is accessible: `curl http://<node-ip>:8080`
- Ensure firewall allows traffic from proxy to k3s
- Check Traefik is running: `kubectl get pods -n kube-system | grep traefik`
### SSL Certificate Error
**Cause**: SSL certificate not properly configured
**Fix**:
- Verify DNS points to NGINX Proxy Manager IP
- Wait for Let's Encrypt validation (can take a few minutes)
- Check NGINX Proxy Manager logs for certificate errors
### WebSocket Connection Fails
**Cause**: WebSocket support not enabled or timeouts too short
**Fix**:
- Enable "Websockets Support" checkbox in proxy host
- Add custom nginx configuration with longer timeouts (see Step 3, Advanced tab)
- Check browser console for specific WebSocket errors
### Terminal Disconnects After 60 Seconds
**Cause**: Default proxy timeouts are too short
**Fix**: Add to Advanced tab in proxy host:
```nginx
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
```
### Can Access HTTP but not HTTPS
**Cause**: DNS records still point to old IP or wrong IP
**Fix**:
- Verify DNS with: `nslookup socktop.io`
- Should return your external NGINX Proxy Manager IP
- Wait for DNS propagation (up to 24 hours, usually minutes)
## Load Balancing (Optional)
If you want to load balance across multiple k3s nodes:
### Option 1: Use Multiple Upstream Servers in Advanced Config
```nginx
# Add to Advanced tab
upstream k3s_backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.104:8080;
}
# Then change proxy_pass to use upstream
proxy_pass http://k3s_backend;
```
### Option 2: Use k3s LoadBalancer Service
Change the Service type in `04-service.yaml` to `LoadBalancer` and use the assigned external IP.
## Security Best Practices
1. **Enable Force SSL**: Always redirect HTTP to HTTPS
2. **Enable HSTS**: Tells browsers to always use HTTPS
3. **Enable Block Common Exploits**: Provides basic protection
4. **Add Access List**: Restrict by IP if possible
5. **Use Strong SSL**: Enable HTTP/2, disable old TLS versions
6. **Keep Timeouts Reasonable**: 3600s (1 hour) for terminal sessions
## Example Complete Advanced Configuration
For best results, use this in the Advanced tab:
```nginx
# Timeouts for long-running connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
keepalive_timeout 3600s;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Pass through client information
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# Buffering (disable for WebSockets)
proxy_buffering off;
# Security headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
```
## Testing Checklist
After configuration, verify:
- [ ] Can access https://socktop.io and see login/terminal page
- [ ] Can access https://www.socktop.io (same result)
- [ ] Can access https://origin.socktop.io (same result)
- [ ] SSL certificate shows as valid (no browser warnings)
- [ ] Terminal connections work and stay connected
- [ ] WebSocket shows as connected in browser dev tools
- [ ] Can switch between different profiles
- [ ] Terminal sessions survive page refresh (with session affinity)
## Monitoring
### Check NGINX Proxy Manager Logs
In NGINX Proxy Manager UI:
- Go to proxy host → Click on host → View logs
### Check k3s Side
```bash
# Check ingress
kubectl get ingress socktop-webterm
# Check service endpoints
kubectl get endpoints socktop-webterm
# Check pod logs
kubectl logs -l app=socktop-webterm -f
```
## Common Traffic Flow Issues
| Symptom | Likely Cause | Check |
|---------|--------------|-------|
| 404 Not Found | Traefik routing issue | `kubectl describe ingress socktop-webterm` |
| 502 Bad Gateway | Can't reach k3s | Firewall, k3s node IP, port 8080 |
| 503 Service Unavailable | Pods not ready | `kubectl get pods -l app=socktop-webterm` |
| SSL Error | Certificate issue | NGINX Proxy Manager SSL tab |
| WebSocket fails | WS not enabled | Enable WebSocket support checkbox |
## Summary
Your complete setup should be:
1. **DNS**: socktop.io → Your external IP (NGINX Proxy Manager)
2. **NGINX Proxy Manager**:
- Listens on 443 (HTTPS)
- Terminates SSL
- Forwards to k3s-node:8080 (HTTP)
- WebSocket support enabled
3. **k3s Traefik**:
- Receives HTTP on port 8080
- Routes to socktop-webterm service
4. **Service**:
- Routes to healthy pods
- Session affinity enabled
5. **Pods**:
- 3 replicas running webterm
- Host network for Pi access
All working? You should now have a secure, load-balanced terminal interface! 🎉
+260
View File
@@ -0,0 +1,260 @@
# Socktop WebTerm - Kubernetes Quick Start
Get your terminal interface running on k3s in 5 minutes!
## Prerequisites Checklist
- [ ] k3s cluster running
- [ ] kubectl configured and working
- [ ] DNS records for socktop.io pointing to your cluster
- [ ] Nginx Ingress Controller installed on k3s
- [ ] cert-manager installed (for automatic HTTPS)
## Quick Deploy
### Option 1: Automated Deploy Script
```bash
cd kubernetes
./deploy.sh
```
The script will:
1. Check your cluster connection
2. Optionally configure TLS certificates for Pi nodes
3. Deploy all manifests
4. Wait for pods to be ready
5. Show you status and access URLs
### Option 2: Manual Deploy
```bash
cd kubernetes
# Apply all manifests
kubectl apply -f .
# Watch deployment progress
kubectl get pods -l app=socktop-webterm -w
```
### Option 3: Using Kustomize
```bash
cd kubernetes
# Deploy with kustomize
kubectl apply -k .
# Or customize on the fly
kubectl apply -k . --replicas=5
```
## Verify Deployment
```bash
# Check if pods are running
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
```
## Access Your Terminal
Open your browser to:
- **https://socktop.io**
- **https://www.socktop.io**
- **https://origin.socktop.io**
## Common Issues
### 1. ImagePullBackOff Error
Your k3s nodes can't pull from the Gitea registry.
**Fix:** Configure insecure registry on each k3s node:
```bash
# On each k3s node, create /etc/rancher/k3s/registries.yaml
sudo tee /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
"192.168.1.208:3002":
endpoint:
- "http://192.168.1.208:3002"
configs:
"192.168.1.208:3002":
tls:
insecure_skip_verify: true
EOF
# Restart k3s
sudo systemctl restart k3s # on server
sudo systemctl restart k3s-agent # on agents
```
### Can't Access via HTTPS
Check your external NGINX Proxy Manager configuration.
**Verify:**
- Proxy host is configured correctly
- Points to k3s node IP on port 8080
- SSL certificate is valid
- WebSocket support is enabled
- DNS records point to your external IP
### 3. 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, your k3s nodes may not be able to reach the Pi network.
### 4. 502 Bad Gateway
Pods aren't ready yet or have crashed.
**Check logs:**
```bash
kubectl logs -l app=socktop-webterm --tail=100
```
## Configuration
### Update Profiles (Add/Remove Pi Nodes)
```bash
# Edit the ConfigMap
kubectl edit configmap socktop-webterm-config
# Restart pods to pick up changes
kubectl rollout restart deployment socktop-webterm
```
### Scale Up/Down
```bash
# Scale to 5 replicas
kubectl scale deployment socktop-webterm --replicas=5
# Scale to 1 replica
kubectl scale deployment socktop-webterm --replicas=1
```
### Update to New Version
After publishing a new image version:
```bash
# Update image tag
kubectl set image deployment/socktop-webterm \
webterm=192.168.1.208:3002/jason/socktop-webterm:0.3.0
# Or force re-pull latest
kubectl rollout restart deployment socktop-webterm
```
## Monitoring
### View Logs
```bash
# All pods
kubectl logs -l app=socktop-webterm -f
# Specific pod
kubectl logs socktop-webterm-xxxxxxxxxx-xxxxx -f
# Previous crashed pod
kubectl logs socktop-webterm-xxxxxxxxxx-xxxxx --previous
```
### Resource Usage
```bash
# CPU and memory usage
kubectl top pods -l app=socktop-webterm
# Detailed pod info
kubectl describe deployment socktop-webterm
```
### Check Ingress
```bash
# View ingress details
kubectl describe ingress socktop-webterm
# Check if external IP is assigned
kubectl get ingress socktop-webterm
```
## Cleanup
### Remove Everything
```bash
cd kubernetes
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
```
## Performance Testing
With 3 replicas across your k3s cluster:
1. **Load Distribution**: k3s will spread pods across nodes
2. **Session Affinity**: Each user sticks to the same pod
3. **High Availability**: If a pod crashes, others handle traffic
4. **Horizontal Scaling**: Add more replicas for more capacity
Monitor performance:
```bash
# Watch resource usage
kubectl top pods -l app=socktop-webterm
# See which nodes pods are on
kubectl get pods -l app=socktop-webterm -o wide
```
## Next Steps
- Set up monitoring with Prometheus/Grafana
- Configure backup for any stateful data
- Add authentication layer (OAuth2 Proxy)
- Set up log aggregation (Loki/ELK)
- Configure network policies for security
## Need Help?
**Check deployment status:**
```bash
kubectl get all -l app=socktop-webterm
```
**Describe resources:**
```bash
kubectl describe deployment socktop-webterm
kubectl describe pods -l app=socktop-webterm
```
**View events:**
```bash
kubectl get events --sort-by='.lastTimestamp' | grep socktop
```
**Full README:** See `README.md` for detailed documentation.
+359
View File
@@ -0,0 +1,359 @@
# 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
+476
View File
@@ -0,0 +1,476 @@
# Socktop WebTerm - Complete Setup Guide
This guide covers the complete setup process for deploying Socktop WebTerm to your k3s cluster.
## Prerequisites
- ✅ k3s cluster running (3+ nodes recommended)
- ✅ kubectl installed on your local machine
- ✅ SSH access to all k3s nodes
- ✅ Image published to Gitea registry: `192.168.1.208:3002/jason/socktop-webterm:0.2.0`
- ✅ External NGINX Proxy Manager configured
## Step-by-Step Setup
### Step 0: Configure kubectl Context
Before deploying, make sure kubectl is configured to connect to your k3s cluster.
#### Option A: Using your k3s kubeconfig
From your k3s server node:
```bash
# On k3s server node, get the kubeconfig
sudo cat /etc/rancher/k3s/k3s.yaml
```
Copy this content to your local machine:
```bash
# On your local machine
mkdir -p ~/.kube
nano ~/.kube/config-k3s
# Paste the content and modify the server IP from 127.0.0.1 to your k3s server IP
```
Example modification:
```yaml
# Change this:
server: https://127.0.0.1:6443
# To this (use your k3s server IP):
server: https://192.168.1.101:6443
```
#### Option B: Merge with existing kubeconfig
If you already have a kubectl config:
```bash
# Backup existing config
cp ~/.kube/config ~/.kube/config.backup
# Add k3s config as a new context
export KUBECONFIG=~/.kube/config:~/.kube/config-k3s
kubectl config view --flatten > ~/.kube/config-merged
mv ~/.kube/config-merged ~/.kube/config
```
#### Verify Connection
```bash
# List available contexts
kubectl config get-contexts
# Switch to k3s context (replace with your context name)
kubectl config use-context default
# Test connection
kubectl get nodes
# You should see your k3s nodes listed
```
Expected output:
```
NAME STATUS ROLES AGE VERSION
rpi-master Ready control-plane,master 30d v1.28.2+k3s1
rpi-worker-1 Ready <none> 30d v1.28.2+k3s1
rpi-worker-2 Ready <none> 30d v1.28.2+k3s1
```
### Step 1: Configure k3s Insecure Registry
Your Gitea registry uses HTTP (not HTTPS), so you need to configure k3s to allow "insecure" registries.
#### Automated Method (Recommended)
Use the provided script to configure all nodes:
```bash
cd kubernetes
./setup-registry.sh
```
The script will:
1. Ask for your k3s node IP addresses
2. Ask for SSH username (default: ubuntu)
3. Copy the registry config to each node
4. Restart k3s services
5. Test image pulling
#### Manual Method
If the script doesn't work or you prefer manual setup:
**For each k3s node**, do the following:
1. **SSH to the node:**
```bash
ssh ubuntu@192.168.1.101 # replace with your node IP
```
2. **Create the k3s config directory:**
```bash
sudo mkdir -p /etc/rancher/k3s
```
3. **Create the registries.yaml file:**
```bash
sudo nano /etc/rancher/k3s/registries.yaml
```
4. **Paste this content:**
```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
```
5. **Save and exit** (Ctrl+O, Enter, Ctrl+X)
6. **Restart k3s:**
```bash
# On server nodes
sudo systemctl restart k3s
# On agent/worker nodes
sudo systemctl restart k3s-agent
```
7. **Verify the service is running:**
```bash
sudo systemctl status k3s # on server
sudo systemctl status k3s-agent # on agents
```
8. **Test image pull:**
```bash
sudo k3s crictl pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0
```
**Repeat for ALL k3s nodes** (both server and agents).
#### Troubleshooting Registry Setup
**Problem: systemctl restart fails**
```bash
# Check logs
sudo journalctl -u k3s -n 50 # on server
sudo journalctl -u k3s-agent -n 50 # on agents
# Look for syntax errors in registries.yaml
sudo cat /etc/rancher/k3s/registries.yaml
```
**Problem: Image pull fails**
```bash
# Test registry access from node
curl http://192.168.1.208:3002/v2/
# Should return {} or a Docker registry response
```
**Problem: Permission denied**
```bash
# Ensure correct permissions
sudo chmod 644 /etc/rancher/k3s/registries.yaml
sudo chown root:root /etc/rancher/k3s/registries.yaml
```
### Step 2: Deploy to k3s
Once all nodes are configured, deploy the application:
#### Using the Automated Script
```bash
cd kubernetes
./deploy.sh
```
The script will:
1. Check kubectl connection
2. Show current context
3. Ask for target namespace (default: `default`)
4. Create namespace if needed
5. Optionally configure Pi TLS certificates
6. Deploy all manifests
7. Wait for pods to be ready
8. Show status and helpful commands
#### Manual Deployment
If you prefer to deploy manually:
```bash
# Deploy to default namespace
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 deploy to custom namespace
kubectl create namespace socktop
kubectl apply -f . -n socktop
```
#### Verify Deployment
```bash
# Check pods
kubectl get pods -l app=socktop-webterm -n default
# Expected output (3 pods):
# 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 -n default
# Check ingress
kubectl get ingress socktop-webterm -n default
```
#### Common Deployment Issues
**Pods stuck in ImagePullBackOff:**
- Registry not configured on all nodes
- Go back to Step 1 and verify each node
**Pods stuck in Pending:**
- Not enough resources
- Check: `kubectl describe pods -l app=socktop-webterm -n default`
**Pods in CrashLoopBackOff:**
- Check logs: `kubectl logs -l app=socktop-webterm -n default --tail=100`
### Step 3: Configure External NGINX Proxy Manager
See `NGINX-PROXY-MANAGER.md` for detailed instructions.
Quick summary:
1. **Log into NGINX Proxy Manager web UI**
2. **Create proxy host for socktop.io:**
- Domain: `socktop.io`
- Scheme: `http`
- Forward Hostname/IP: `192.168.1.101` (any k3s node IP)
- Forward Port: `8080`
- ✅ Enable WebSocket Support
- SSL: Select/create certificate
- ✅ Force SSL
3. **Repeat for www.socktop.io and origin.socktop.io**
4. **Advanced config (optional but recommended):**
```nginx
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
### Step 4: Test Access
1. **Test internal access (from k3s node):**
```bash
curl http://localhost:8080 -H "Host: socktop.io"
```
2. **Test external access:**
- Open browser to https://socktop.io
- Should see the webterm interface
- Check browser console (F12) for WebSocket connection
3. **Test terminal functionality:**
- Select a profile (local or a Pi node)
- Terminal should connect and be interactive
## Complete Example Walkthrough
Here's a complete example from start to finish:
```bash
# 1. Configure kubectl
export KUBECONFIG=~/.kube/config
kubectl config use-context default
kubectl get nodes # verify connection
# 2. Navigate to kubernetes directory
cd /path/to/webterm/kubernetes
# 3. Configure registry on all nodes
./setup-registry.sh
# Enter node IPs: 192.168.1.101, 192.168.1.102, 192.168.1.104
# Enter SSH user: ubuntu
# 4. Wait for script to complete (will test image pull)
# 5. Deploy to k3s
./deploy.sh
# Choose namespace: default (or create new one)
# Skip TLS cert config if you don't have Pi certs yet
# 6. Wait for deployment to complete
# 7. Verify pods are running
kubectl get pods -l app=socktop-webterm -n default
# 8. Configure NGINX Proxy Manager (see NGINX-PROXY-MANAGER.md)
# 9. Test access
curl -I https://socktop.io
# 10. Open browser and test
# https://socktop.io
```
## Kubernetes Context Quick Reference
### View Available Contexts
```bash
kubectl config get-contexts
```
### Switch Context
```bash
kubectl config use-context <context-name>
```
### View Current Context
```bash
kubectl config current-context
```
### Set Default Namespace
```bash
kubectl config set-context --current --namespace=socktop
```
### View Cluster Info
```bash
kubectl cluster-info
```
## Node Configuration Quick Reference
### Check k3s Service Status
```bash
# On server node
sudo systemctl status k3s
# On agent/worker node
sudo systemctl status k3s-agent
```
### View k3s Logs
```bash
sudo journalctl -u k3s -f # server
sudo journalctl -u k3s-agent -f # agent
```
### Verify Registry Config
```bash
sudo cat /etc/rancher/k3s/registries.yaml
```
### Test Image Pull
```bash
sudo k3s crictl pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0
```
### List Images on Node
```bash
sudo k3s crictl images | grep socktop
```
## Helpful kubectl Commands
```bash
# Get all resources in namespace
kubectl get all -n default
# Describe deployment
kubectl describe deployment socktop-webterm -n default
# View pod logs
kubectl logs -l app=socktop-webterm -n default -f
# Execute command in pod
kubectl exec -it deployment/socktop-webterm -n default -- /bin/bash
# Port forward for testing
kubectl port-forward svc/socktop-webterm 8082:8082 -n default
# Then access http://localhost:8082
# Scale deployment
kubectl scale deployment socktop-webterm --replicas=5 -n default
# Restart deployment
kubectl rollout restart deployment socktop-webterm -n default
# View rollout status
kubectl rollout status deployment socktop-webterm -n default
# Delete everything
kubectl delete -f . -n default
```
## Summary Checklist
- [ ] kubectl configured and connected to k3s cluster
- [ ] Registry config copied to ALL k3s nodes
- [ ] k3s services restarted on all nodes
- [ ] Image pull tested successfully on at least one node
- [ ] Deployed to k3s using deploy.sh or manual kubectl apply
- [ ] Pods showing as Running (3/3)
- [ ] Service has endpoints
- [ ] Ingress created successfully
- [ ] NGINX Proxy Manager configured with 3 proxy hosts
- [ ] DNS pointing to NGINX Proxy Manager
- [ ] Can access https://socktop.io in browser
- [ ] WebSocket connections working
- [ ] Terminal sessions functional
## Next Steps
Once deployed successfully:
1. **Monitor Performance**: `kubectl top pods -l app=socktop-webterm -n default`
2. **Check Logs**: Look for any errors or warnings
3. **Test Load Balancing**: Verify traffic distributes across 3 pods
4. **Configure Monitoring**: Set up Prometheus/Grafana if desired
5. **Add Alerts**: Configure alerts for pod failures
## Getting Help
If you encounter issues:
1. Check `TROUBLESHOOTING.md` (if exists) or `README.md`
2. View pod logs: `kubectl logs -l app=socktop-webterm -n default`
3. Describe pods: `kubectl describe pods -l app=socktop-webterm -n default`
4. Check events: `kubectl get events -n default --sort-by='.lastTimestamp'`
5. Verify registry config on all nodes
6. Check NGINX Proxy Manager logs
## Additional Resources
- `QUICKSTART.md` - Fast deployment guide
- `README.md` - Comprehensive documentation
- `CHECKLIST.md` - Pre-deployment verification
- `NGINX-PROXY-MANAGER.md` - Proxy configuration guide
- `INDEX.md` - File overview and navigation
+71
View File
@@ -0,0 +1,71 @@
# TL;DR - Quick Setup for Busy People
## Prerequisites
- k3s cluster running
- SSH access to k3s nodes
## Setup (6 commands)
```bash
cd kubernetes
# 0. Setup kubectl (if not configured yet)
./setup-kubectl.sh
# Enter your k3s server IP when prompted
# Choose option 2 (save as separate file)
export KUBECONFIG=~/.kube/config-k3s
# 1. Configure registry on all k3s nodes
./setup-registry.sh
# Enter your node IPs when prompted
# 2. Deploy to k3s
./deploy.sh
# Press Enter to use 'default' namespace
# 3. Wait for pods
kubectl get pods -l app=socktop-webterm -w
# 4. Get a k3s node IP
kubectl get nodes -o wide
# 5. Configure NGINX Proxy Manager:
# - Create proxy host for socktop.io
# - Forward to: <k3s-node-ip>:8080
# - Enable WebSocket Support
# - Add SSL certificate
# - Repeat for www.socktop.io and origin.socktop.io
```
## Access
https://socktop.io
## Troubleshooting
**kubectl not configured?**
```bash
./setup-kubectl.sh
export KUBECONFIG=~/.kube/config-k3s
```
**Pods not starting?**
```bash
kubectl logs -l app=socktop-webterm --tail=50
kubectl describe pods -l app=socktop-webterm
```
**ImagePullBackOff?**
- Registry config missing on a node
- Re-run `./setup-registry.sh`
**502 Bad Gateway?**
- NGINX Proxy Manager can't reach k3s
- Verify k3s node IP and port 8080
**WebSocket failing?**
- Enable WebSocket Support in NGINX Proxy Manager
- Add timeouts to Advanced config
## Done!
See `KUBECTL-SETUP.md` for kubectl details.
See `SETUP-GUIDE.md` for detailed walkthrough.
+220
View File
@@ -0,0 +1,220 @@
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== Socktop WebTerm - Kubernetes Deployment Script ===${NC}"
echo ""
# Check if kubectl is available
if ! command -v kubectl &> /dev/null; then
echo -e "${RED}Error: kubectl is not installed or not in PATH${NC}"
exit 1
fi
# Check if we can connect to the cluster
if ! kubectl cluster-info &> /dev/null; then
echo -e "${RED}Error: Cannot connect to Kubernetes cluster${NC}"
echo "Make sure your kubeconfig is set up correctly"
echo ""
echo "Available contexts:"
kubectl config get-contexts
exit 1
fi
# Show current context
CURRENT_CONTEXT=$(kubectl config current-context)
echo -e "${GREEN}✓ Connected to Kubernetes cluster${NC}"
echo -e "${BLUE}Current context:${NC} $CURRENT_CONTEXT"
echo ""
# Ask for namespace
read -p "Enter namespace to deploy to (default: default): " NAMESPACE
NAMESPACE=${NAMESPACE:-default}
echo -e "${BLUE}Target namespace:${NC} $NAMESPACE"
echo ""
# Create namespace if it doesn't exist
if ! kubectl get namespace "$NAMESPACE" &> /dev/null; then
echo -e "${YELLOW}Namespace '$NAMESPACE' does not exist.${NC}"
read -p "Create it? (y/N): " create_ns
if [[ "$create_ns" =~ ^[Yy]$ ]]; then
kubectl create namespace "$NAMESPACE"
echo -e "${GREEN}✓ Namespace created${NC}"
else
echo -e "${RED}Deployment cancelled${NC}"
exit 1
fi
fi
echo ""
# Get the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Check if manifest files exist
REQUIRED_FILES=(
"01-configmap.yaml"
"02-secret.yaml"
"03-deployment.yaml"
"04-service.yaml"
"05-ingress.yaml"
)
echo -e "${YELLOW}Checking for required manifest files...${NC}"
for file in "${REQUIRED_FILES[@]}"; do
if [ ! -f "$SCRIPT_DIR/$file" ]; then
echo -e "${RED}Error: Missing required file: $file${NC}"
exit 1
fi
echo -e "${GREEN}${NC} Found $file"
done
echo ""
# Ask user if they want to configure TLS certificates
echo -e "${YELLOW}=== TLS Certificate Configuration ===${NC}"
echo "Do you have TLS certificates for your Raspberry Pi nodes?"
echo "(If not, the deployment will work but won't be able to connect to Pi nodes via TLS)"
echo ""
read -p "Path to folder containing .pem certificates (or press Enter to skip): " CERT_FOLDER
if [ -n "$CERT_FOLDER" ]; then
# Remove trailing slash if present
CERT_FOLDER="${CERT_FOLDER%/}"
# Check if folder exists
if [ ! -d "$CERT_FOLDER" ]; then
echo -e "${RED}Error: Directory not found: $CERT_FOLDER${NC}"
exit 1
fi
# Find all .pem files in the folder
PEM_FILES=$(find "$CERT_FOLDER" -maxdepth 1 -name "*.pem" -type f)
if [ -z "$PEM_FILES" ]; then
echo -e "${RED}Error: No .pem files found in $CERT_FOLDER${NC}"
exit 1
fi
echo ""
echo -e "${YELLOW}Found certificates:${NC}"
echo "$PEM_FILES" | while read file; do
echo " - $(basename "$file")"
done
echo ""
echo -e "${YELLOW}Creating secret with TLS certificates...${NC}"
# Build kubectl command with all .pem files
CMD="kubectl create secret generic socktop-webterm-certs --namespace=$NAMESPACE --dry-run=client -o yaml"
while IFS= read -r file; do
filename=$(basename "$file")
CMD="$CMD --from-file=$filename=$file"
done <<< "$PEM_FILES"
# Execute and apply
eval "$CMD" | kubectl apply -f -
echo -e "${GREEN}✓ TLS certificates configured${NC}"
else
echo -e "${YELLOW}Skipping TLS certificate configuration${NC}"
echo "The deployment will use the placeholder secret from 02-secret.yaml"
fi
echo ""
echo -e "${YELLOW}=== Deploying to Kubernetes ===${NC}"
echo ""
# Function to apply manifest with namespace override
apply_manifest() {
local file=$1
local description=$2
echo -e "${BLUE}Applying $description...${NC}"
# Use kubectl apply with namespace flag - this overrides any namespace in the manifest
kubectl apply -f "$SCRIPT_DIR/$file" -n "$NAMESPACE"
echo -e "${GREEN}$description applied${NC}"
echo ""
}
# Apply manifests in order
apply_manifest "01-configmap.yaml" "ConfigMap"
apply_manifest "02-secret.yaml" "Secret"
apply_manifest "03-deployment.yaml" "Deployment"
apply_manifest "04-service.yaml" "Service"
apply_manifest "05-ingress.yaml" "Ingress"
echo -e "${GREEN}=== Deployment Complete! ===${NC}"
echo ""
# Wait for pods to be ready
echo -e "${YELLOW}Waiting for pods to be ready...${NC}"
echo "(This may take a minute while images are pulled)"
echo ""
if kubectl wait --for=condition=ready pod -l app=socktop-webterm -n "$NAMESPACE" --timeout=300s 2>/dev/null; then
echo ""
echo -e "${GREEN}✓ All pods are ready!${NC}"
else
echo ""
echo -e "${YELLOW}Warning: Pods took longer than expected to start${NC}"
echo "Check status with: kubectl get pods -l app=socktop-webterm -n $NAMESPACE"
fi
echo ""
echo -e "${GREEN}=== Deployment Status ===${NC}"
echo ""
# Show deployment status
echo -e "${BLUE}Pods:${NC}"
kubectl get pods -l app=socktop-webterm -n "$NAMESPACE"
echo ""
echo -e "${BLUE}Service:${NC}"
kubectl get svc socktop-webterm -n "$NAMESPACE"
echo ""
echo -e "${BLUE}Ingress:${NC}"
kubectl get ingress socktop-webterm -n "$NAMESPACE"
echo ""
echo -e "${GREEN}=== Access Information ===${NC}"
echo ""
echo "Your application will be available at:"
echo -e " ${YELLOW}https://socktop.io${NC}"
echo -e " ${YELLOW}https://www.socktop.io${NC}"
echo -e " ${YELLOW}https://origin.socktop.io${NC}"
echo ""
echo "Note: SSL is terminated at your external NGINX Proxy Manager."
echo "Configure your proxy hosts to forward traffic to k3s on port 8080."
echo "See NGINX-PROXY-MANAGER.md for details."
echo ""
echo -e "${GREEN}=== Useful Commands ===${NC}"
echo ""
echo "View logs:"
echo -e " ${BLUE}kubectl logs -l app=socktop-webterm -n $NAMESPACE -f${NC}"
echo ""
echo "Check pod status:"
echo -e " ${BLUE}kubectl get pods -l app=socktop-webterm -n $NAMESPACE${NC}"
echo ""
echo "Describe deployment:"
echo -e " ${BLUE}kubectl describe deployment socktop-webterm -n $NAMESPACE${NC}"
echo ""
echo "Scale deployment:"
echo -e " ${BLUE}kubectl scale deployment socktop-webterm --replicas=5 -n $NAMESPACE${NC}"
echo ""
echo "Update image:"
echo -e " ${BLUE}kubectl set image deployment/socktop-webterm webterm=192.168.1.208:3002/jason/socktop-webterm:0.2.0 -n $NAMESPACE${NC}"
echo ""
echo "Delete deployment:"
echo -e " ${BLUE}kubectl delete -f $SCRIPT_DIR -n $NAMESPACE${NC}"
echo ""
echo -e "${GREEN}Done!${NC}"
+217
View File
@@ -0,0 +1,217 @@
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== Socktop WebTerm - Kubernetes Deployment Script ===${NC}"
echo ""
# Check if kubectl is available
if ! command -v kubectl &> /dev/null; then
echo -e "${RED}Error: kubectl is not installed or not in PATH${NC}"
exit 1
fi
# Check if we can connect to the cluster
if ! kubectl cluster-info &> /dev/null; then
echo -e "${RED}Error: Cannot connect to Kubernetes cluster${NC}"
echo "Make sure your kubeconfig is set up correctly"
echo ""
echo "Available contexts:"
kubectl config get-contexts
exit 1
fi
# Show current context
CURRENT_CONTEXT=$(kubectl config current-context)
echo -e "${GREEN}✓ Connected to Kubernetes cluster${NC}"
echo -e "${BLUE}Current context:${NC} $CURRENT_CONTEXT"
echo ""
# Ask for namespace
read -p "Enter namespace to deploy to (default: default): " NAMESPACE
NAMESPACE=${NAMESPACE:-default}
echo -e "${BLUE}Target namespace:${NC} $NAMESPACE"
echo ""
# Create namespace if it doesn't exist
if ! kubectl get namespace "$NAMESPACE" &> /dev/null; then
echo -e "${YELLOW}Namespace '$NAMESPACE' does not exist.${NC}"
read -p "Create it? (y/N): " create_ns
if [[ "$create_ns" =~ ^[Yy]$ ]]; then
kubectl create namespace "$NAMESPACE"
echo -e "${GREEN}✓ Namespace created${NC}"
else
echo -e "${RED}Deployment cancelled${NC}"
exit 1
fi
fi
echo ""
# Get the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Check if manifest files exist
REQUIRED_FILES=(
"01-configmap.yaml"
"02-secret.yaml"
"03-deployment.yaml"
"04-service.yaml"
"05-ingress.yaml"
)
echo -e "${YELLOW}Checking for required manifest files...${NC}"
for file in "${REQUIRED_FILES[@]}"; do
if [ ! -f "$SCRIPT_DIR/$file" ]; then
echo -e "${RED}Error: Missing required file: $file${NC}"
exit 1
fi
echo -e "${GREEN}✓${NC} Found $file"
done
echo ""
# Ask user if they want to configure TLS certificates
echo -e "${YELLOW}=== TLS Certificate Configuration ===${NC}"
echo "Do you have TLS certificates for your Raspberry Pi nodes?"
echo "(If not, the deployment will work but won't be able to connect to Pi nodes via TLS)"
echo ""
read -p "Do you want to configure TLS certificates now? (y/N): " configure_certs
if [[ "$configure_certs" =~ ^[Yy]$ ]]; then
echo ""
echo -e "${YELLOW}Please provide paths to your certificate files:${NC}"
read -p "Path to rpi-master.pem: " master_cert
read -p "Path to rpi-worker-1.pem: " worker1_cert
read -p "Path to rpi-worker-2.pem: " worker2_cert
read -p "Path to rpi-worker-3.pem: " worker3_cert
# Verify files exist
for cert in "$master_cert" "$worker1_cert" "$worker2_cert" "$worker3_cert"; do
if [ ! -f "$cert" ]; then
echo -e "${RED}Error: Certificate file not found: $cert${NC}"
exit 1
fi
done
echo ""
echo -e "${YELLOW}Creating secret with TLS certificates...${NC}"
kubectl create secret generic socktop-webterm-certs \
--from-file=rpi-master.pem="$master_cert" \
--from-file=rpi-worker-1.pem="$worker1_cert" \
--from-file=rpi-worker-2.pem="$worker2_cert" \
--from-file=rpi-worker-3.pem="$worker3_cert" \
--namespace="$NAMESPACE" \
--dry-run=client -o yaml | kubectl apply -f -
echo -e "${GREEN}✓ TLS certificates configured${NC}"
else
echo -e "${YELLOW}Skipping TLS certificate configuration${NC}"
echo "The deployment will use the placeholder secret from 02-secret.yaml"
fi
echo ""
echo -e "${YELLOW}=== Deploying to Kubernetes ===${NC}"
echo ""
# Apply manifests in order
echo -e "${BLUE}Applying ConfigMap...${NC}"
kubectl apply -f "$SCRIPT_DIR/01-configmap.yaml" -n "$NAMESPACE"
echo -e "${GREEN}✓ ConfigMap applied${NC}"
echo ""
echo -e "${BLUE}Applying Secret...${NC}"
kubectl apply -f "$SCRIPT_DIR/02-secret.yaml" -n "$NAMESPACE"
echo -e "${GREEN}✓ Secret applied${NC}"
echo ""
echo -e "${BLUE}Applying Deployment...${NC}"
kubectl apply -f "$SCRIPT_DIR/03-deployment.yaml" -n "$NAMESPACE"
echo -e "${GREEN}✓ Deployment applied${NC}"
echo ""
echo -e "${BLUE}Applying Service...${NC}"
kubectl apply -f "$SCRIPT_DIR/04-service.yaml" -n "$NAMESPACE"
echo -e "${GREEN}✓ Service applied${NC}"
echo ""
echo -e "${BLUE}Applying Ingress...${NC}"
kubectl apply -f "$SCRIPT_DIR/05-ingress.yaml" -n "$NAMESPACE"
echo -e "${GREEN}✓ Ingress applied${NC}"
echo ""
echo -e "${GREEN}=== Deployment Complete! ===${NC}"
echo ""
# Wait for pods to be ready
echo -e "${YELLOW}Waiting for pods to be ready...${NC}"
echo "(This may take a minute while images are pulled)"
echo ""
if kubectl wait --for=condition=ready pod -l app=socktop-webterm -n "$NAMESPACE" --timeout=300s; then
echo ""
echo -e "${GREEN}✓ All pods are ready!${NC}"
else
echo ""
echo -e "${YELLOW}Warning: Pods took longer than expected to start${NC}"
echo "Check status with: kubectl get pods -l app=socktop-webterm -n $NAMESPACE"
fi
echo ""
echo -e "${GREEN}=== Deployment Status ===${NC}"
echo ""
# Show deployment status
echo -e "${BLUE}Pods:${NC}"
kubectl get pods -l app=socktop-webterm -n "$NAMESPACE"
echo ""
echo -e "${BLUE}Service:${NC}"
kubectl get svc socktop-webterm -n "$NAMESPACE"
echo ""
echo -e "${BLUE}Ingress:${NC}"
kubectl get ingress socktop-webterm -n "$NAMESPACE"
echo ""
echo -e "${GREEN}=== Access Information ===${NC}"
echo ""
echo "Your application will be available at:"
echo -e " ${YELLOW}https://socktop.io${NC}"
echo -e " ${YELLOW}https://www.socktop.io${NC}"
echo -e " ${YELLOW}https://origin.socktop.io${NC}"
echo ""
echo "Note: SSL is terminated at your external NGINX Proxy Manager."
echo "Configure your proxy hosts to forward traffic to k3s on port 8080."
echo "See NGINX-PROXY-MANAGER.md for details."
echo ""
echo -e "${GREEN}=== Useful Commands ===${NC}"
echo ""
echo "View logs:"
echo -e " ${BLUE}kubectl logs -l app=socktop-webterm -n $NAMESPACE -f${NC}"
echo ""
echo "Check pod status:"
echo -e " ${BLUE}kubectl get pods -l app=socktop-webterm -n $NAMESPACE${NC}"
echo ""
echo "Describe deployment:"
echo -e " ${BLUE}kubectl describe deployment socktop-webterm -n $NAMESPACE${NC}"
echo ""
echo "Scale deployment:"
echo -e " ${BLUE}kubectl scale deployment socktop-webterm --replicas=5 -n $NAMESPACE${NC}"
echo ""
echo "Update image:"
echo -e " ${BLUE}kubectl set image deployment/socktop-webterm webterm=192.168.1.208:3002/jason/socktop-webterm:0.2.0 -n $NAMESPACE${NC}"
echo ""
echo "Delete deployment:"
echo -e " ${BLUE}kubectl delete -f $SCRIPT_DIR -n $NAMESPACE${NC}"
echo ""
echo -e "${GREEN}Done!${NC}"
+41
View File
@@ -0,0 +1,41 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
name: socktop-webterm
namespace: default
# Common labels applied to all resources
commonLabels:
app: socktop-webterm
managed-by: kustomize
# Resources to deploy
resources:
- 01-configmap.yaml
- 02-secret.yaml
- 03-deployment.yaml
- 04-service.yaml
- 05-ingress.yaml
# Namespace for all resources
namespace: default
# Images to use (can be overridden)
images:
- name: 192.168.1.208:3002/jason/socktop-webterm
newTag: "0.2.0"
# ConfigMap generator options
generatorOptions:
disableNameSuffixHash: true
# Replicas (can be overridden with kubectl apply -k . --replicas=5)
replicas:
- name: socktop-webterm
count: 3
# Common annotations
commonAnnotations:
version: "0.2.0"
description: "Socktop WebTerm - Terminal interface for monitoring"
+122
View File
@@ -0,0 +1,122 @@
#!/bin/bash
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Configuration
NAMESPACE="socktop"
LABEL="app=socktop-webterm"
REFRESH_INTERVAL=5
echo -e "${GREEN}=== Socktop WebTerm Session Monitor ===${NC}"
echo ""
echo "Monitoring namespace: $NAMESPACE"
echo "Refresh interval: ${REFRESH_INTERVAL}s"
echo "Press Ctrl+C to exit"
echo ""
# Function to get connection count from a pod
get_connections() {
local pod=$1
kubectl exec -n "$NAMESPACE" "$pod" -- netstat -tn 2>/dev/null | \
grep :8082 | grep ESTABLISHED | wc -l
}
# Function to get recent timeout events
get_timeout_events() {
kubectl logs -n "$NAMESPACE" -l "$LABEL" --tail=50 --since=60s 2>/dev/null | \
grep -i "timeout\|idle\|disconnect" | tail -10
}
# Function to get active terminal sessions
get_active_terminals() {
kubectl logs -n "$NAMESPACE" -l "$LABEL" --tail=100 --since=300s 2>/dev/null | \
grep "Started Terminal" | wc -l
}
# Function to get stopped terminal sessions
get_stopped_terminals() {
kubectl logs -n "$NAMESPACE" -l "$LABEL" --tail=100 --since=300s 2>/dev/null | \
grep "Stopping Terminal" | wc -l
}
# Main monitoring loop
while true; do
clear
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ Socktop WebTerm - Session Monitor ║${NC}"
echo -e "${CYAN}$(date '+%Y-%m-%d %H:%M:%S')${NC}"
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo ""
# Get pod information
echo -e "${BLUE}Pods:${NC}"
kubectl get pods -n "$NAMESPACE" -l "$LABEL" -o wide 2>/dev/null
echo ""
# Get connection counts per pod
echo -e "${BLUE}Active WebSocket Connections per Pod:${NC}"
TOTAL_CONNECTIONS=0
PODS=$(kubectl get pods -n "$NAMESPACE" -l "$LABEL" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null)
if [ -z "$PODS" ]; then
echo -e "${RED} No pods found${NC}"
else
for pod in $PODS; do
CONN_COUNT=$(get_connections "$pod")
TOTAL_CONNECTIONS=$((TOTAL_CONNECTIONS + CONN_COUNT))
if [ "$CONN_COUNT" -gt 0 ]; then
echo -e " ${GREEN}$pod: $CONN_COUNT connections${NC}"
else
echo -e " ${YELLOW}$pod: $CONN_COUNT connections${NC}"
fi
done
echo ""
echo -e "${CYAN}Total Active Connections: $TOTAL_CONNECTIONS${NC}"
fi
echo ""
# Session statistics (last 5 minutes)
echo -e "${BLUE}Session Statistics (last 5 minutes):${NC}"
STARTED=$(get_active_terminals)
STOPPED=$(get_stopped_terminals)
echo -e " ${GREEN}Sessions started: $STARTED${NC}"
echo -e " ${YELLOW}Sessions stopped: $STOPPED${NC}"
echo ""
# Recent timeout events
echo -e "${BLUE}Recent Timeout/Disconnect Events (last 60 seconds):${NC}"
EVENTS=$(get_timeout_events)
if [ -z "$EVENTS" ]; then
echo -e " ${GREEN}No timeout events${NC}"
else
echo "$EVENTS" | while IFS= read -r line; do
if echo "$line" | grep -qi "timeout"; then
echo -e " ${RED}$line${NC}"
elif echo "$line" | grep -qi "disconnect"; then
echo -e " ${YELLOW}$line${NC}"
else
echo -e " $line"
fi
done
fi
echo ""
# Resource usage
echo -e "${BLUE}Resource Usage:${NC}"
kubectl top pods -n "$NAMESPACE" -l "$LABEL" 2>/dev/null || echo " (metrics-server not available)"
echo ""
echo -e "${CYAN}───────────────────────────────────────────────────────────────${NC}"
echo -e "Refreshing in ${REFRESH_INTERVAL}s... (Ctrl+C to exit)"
sleep "$REFRESH_INTERVAL"
done
+44
View File
@@ -0,0 +1,44 @@
# /etc/rancher/k3s/registries.yaml
#
# This file configures k3s to allow pulling images from insecure (HTTP) registries.
# Copy this file to /etc/rancher/k3s/registries.yaml on EACH k3s node (server and agents).
#
# After creating this file, restart k3s:
# - On server: sudo systemctl restart k3s
# - On agents: sudo systemctl restart k3s-agent
#
# For more information: https://docs.k3s.io/installation/private-registry
mirrors:
# Configure mirror for your Gitea registry
"192.168.1.208:3002":
endpoint:
- "http://192.168.1.208:3002"
configs:
# Allow insecure connection to Gitea registry (HTTP instead of HTTPS)
"192.168.1.208:3002":
tls:
insecure_skip_verify: true
# Optional: Add authentication if your registry requires it
# auth:
# username: your-username
# password: your-password
# Example: If you have multiple registries
# mirrors:
# "registry1.example.com:5000":
# endpoint:
# - "http://registry1.example.com:5000"
# "registry2.example.com:5000":
# endpoint:
# - "https://registry2.example.com:5000"
#
# configs:
# "registry1.example.com:5000":
# tls:
# insecure_skip_verify: true
# "registry2.example.com:5000":
# auth:
# username: user
# password: pass
+222
View File
@@ -0,0 +1,222 @@
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== kubectl Configuration Setup for k3s ===${NC}"
echo ""
echo "This script will help you configure kubectl to connect to your k3s cluster."
echo ""
# Check if kubectl is installed
if ! command -v kubectl &> /dev/null; then
echo -e "${RED}Error: kubectl is not installed${NC}"
echo ""
echo "Install kubectl first:"
echo " https://kubernetes.io/docs/tasks/tools/"
exit 1
fi
echo -e "${GREEN}✓ kubectl is installed${NC}"
echo ""
# Ask for k3s server details
echo -e "${YELLOW}Step 1: k3s Server Information${NC}"
echo ""
read -p "Enter k3s server IP address: " K3S_SERVER_IP
if [ -z "$K3S_SERVER_IP" ]; then
echo -e "${RED}Error: Server IP cannot be empty${NC}"
exit 1
fi
read -p "Enter SSH username for k3s server (default: ubuntu): " SSH_USER
SSH_USER=${SSH_USER:-ubuntu}
echo ""
echo -e "${YELLOW}Step 2: Retrieving kubeconfig from k3s server${NC}"
echo ""
# Check if we can SSH to the server
if ! ssh -q -o ConnectTimeout=5 -o BatchMode=yes ${SSH_USER}@${K3S_SERVER_IP} exit 2>/dev/null; then
echo -e "${YELLOW}⚠ Cannot SSH with key-based auth to ${SSH_USER}@${K3S_SERVER_IP}${NC}"
echo -e "${YELLOW} You may need to enter password...${NC}"
echo ""
fi
# Get the kubeconfig from k3s server
echo "Fetching kubeconfig from k3s server..."
KUBECONFIG_CONTENT=$(ssh ${SSH_USER}@${K3S_SERVER_IP} "sudo cat /etc/rancher/k3s/k3s.yaml" 2>/dev/null)
if [ $? -ne 0 ]; then
echo -e "${RED}✗ Failed to retrieve kubeconfig from server${NC}"
echo ""
echo "Please check:"
echo " - SSH access to ${K3S_SERVER_IP}"
echo " - k3s is installed on the server"
echo " - You have sudo access"
exit 1
fi
echo -e "${GREEN}✓ Retrieved kubeconfig from server${NC}"
echo ""
# Modify the server IP in the kubeconfig
echo "Modifying server IP from 127.0.0.1 to ${K3S_SERVER_IP}..."
MODIFIED_KUBECONFIG=$(echo "$KUBECONFIG_CONTENT" | sed "s|server: https://127.0.0.1:6443|server: https://${K3S_SERVER_IP}:6443|g")
echo -e "${GREEN}✓ Server IP updated${NC}"
echo ""
# Ask where to save the config
echo -e "${YELLOW}Step 3: Save Configuration${NC}"
echo ""
echo "Choose how to save the kubeconfig:"
echo " 1) Replace ~/.kube/config (WARNING: This will overwrite existing config!)"
echo " 2) Save as ~/.kube/config-k3s (separate file, safer)"
echo " 3) Merge with existing ~/.kube/config (recommended if you have other clusters)"
echo ""
read -p "Enter choice (1/2/3, default: 2): " SAVE_CHOICE
SAVE_CHOICE=${SAVE_CHOICE:-2}
case $SAVE_CHOICE in
1)
# Replace existing config
mkdir -p ~/.kube
# Backup existing config if it exists
if [ -f ~/.kube/config ]; then
BACKUP_FILE=~/.kube/config.backup.$(date +%Y%m%d-%H%M%S)
echo "Backing up existing config to $BACKUP_FILE"
cp ~/.kube/config "$BACKUP_FILE"
fi
echo "$MODIFIED_KUBECONFIG" > ~/.kube/config
chmod 600 ~/.kube/config
echo -e "${GREEN}✓ Saved to ~/.kube/config${NC}"
KUBECONFIG_PATH="~/.kube/config"
;;
2)
# Save as separate file
mkdir -p ~/.kube
echo "$MODIFIED_KUBECONFIG" > ~/.kube/config-k3s
chmod 600 ~/.kube/config-k3s
echo -e "${GREEN}✓ Saved to ~/.kube/config-k3s${NC}"
echo ""
echo "To use this config, run:"
echo -e " ${YELLOW}export KUBECONFIG=~/.kube/config-k3s${NC}"
echo ""
echo "Or add to your shell profile (~/.bashrc, ~/.zshrc, ~/.config/fish/config.fish):"
echo -e " ${YELLOW}export KUBECONFIG=~/.kube/config-k3s${NC}"
KUBECONFIG_PATH="~/.kube/config-k3s"
export KUBECONFIG=~/.kube/config-k3s
;;
3)
# Merge with existing config
mkdir -p ~/.kube
if [ ! -f ~/.kube/config ]; then
echo "No existing config found, creating new one..."
echo "$MODIFIED_KUBECONFIG" > ~/.kube/config
chmod 600 ~/.kube/config
echo -e "${GREEN}✓ Saved to ~/.kube/config${NC}"
else
echo "Merging with existing config..."
# Save k3s config to temp file
echo "$MODIFIED_KUBECONFIG" > /tmp/k3s-config.yaml
# Backup existing config
BACKUP_FILE=~/.kube/config.backup.$(date +%Y%m%d-%H%M%S)
echo "Backing up existing config to $BACKUP_FILE"
cp ~/.kube/config "$BACKUP_FILE"
# Merge configs
KUBECONFIG=~/.kube/config:/tmp/k3s-config.yaml kubectl config view --flatten > /tmp/config-merged.yaml
# Replace original config
mv /tmp/config-merged.yaml ~/.kube/config
chmod 600 ~/.kube/config
# Clean up
rm /tmp/k3s-config.yaml
echo -e "${GREEN}✓ Merged and saved to ~/.kube/config${NC}"
fi
KUBECONFIG_PATH="~/.kube/config"
;;
*)
echo -e "${RED}Invalid choice${NC}"
exit 1
;;
esac
echo ""
echo -e "${YELLOW}Step 4: Testing Connection${NC}"
echo ""
# Test the connection
if kubectl cluster-info &> /dev/null; then
echo -e "${GREEN}✓ Successfully connected to k3s cluster!${NC}"
echo ""
# Show cluster info
echo -e "${BLUE}Cluster Information:${NC}"
kubectl cluster-info
echo ""
# Show nodes
echo -e "${BLUE}Nodes:${NC}"
kubectl get nodes
echo ""
# Show contexts
echo -e "${BLUE}Available Contexts:${NC}"
kubectl config get-contexts
echo ""
else
echo -e "${RED}✗ Failed to connect to k3s cluster${NC}"
echo ""
echo "Troubleshooting:"
echo " - Verify k3s server IP: ${K3S_SERVER_IP}"
echo " - Check if port 6443 is accessible"
echo " - Test with: nc -zv ${K3S_SERVER_IP} 6443"
exit 1
fi
echo -e "${GREEN}=== Setup Complete! ===${NC}"
echo ""
echo "Your kubectl is now configured to connect to k3s at ${K3S_SERVER_IP}"
echo ""
echo "Useful commands:"
echo -e " ${BLUE}kubectl get nodes${NC} - List cluster nodes"
echo -e " ${BLUE}kubectl get pods --all-namespaces${NC} - List all pods"
echo -e " ${BLUE}kubectl config get-contexts${NC} - View available contexts"
echo -e " ${BLUE}kubectl config current-context${NC} - View current context"
echo ""
if [ "$SAVE_CHOICE" = "2" ]; then
echo "Remember to set KUBECONFIG environment variable:"
echo -e " ${YELLOW}export KUBECONFIG=~/.kube/config-k3s${NC}"
echo ""
fi
echo "Next steps:"
echo " 1. Run: cd kubernetes"
echo " 2. Run: ./setup-registry.sh (configure registry on all nodes)"
echo " 3. Run: ./deploy.sh (deploy Socktop WebTerm)"
echo ""
echo -e "${GREEN}Done!${NC}"
+217
View File
@@ -0,0 +1,217 @@
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== k3s Insecure Registry Configuration Script ===${NC}"
echo ""
echo "This script will configure your k3s nodes to allow pulling images"
echo "from your Gitea registry at 192.168.1.208:3002"
echo ""
# Get the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Check if registries.yaml.example exists
if [ ! -f "$SCRIPT_DIR/registries.yaml.example" ]; then
echo -e "${RED}Error: registries.yaml.example not found!${NC}"
exit 1
fi
echo -e "${YELLOW}Step 1: Configure k3s Nodes${NC}"
echo ""
echo "You need to configure the following on EACH k3s node:"
echo " 1. Copy registries.yaml to /etc/rancher/k3s/registries.yaml"
echo " 2. Restart k3s or k3s-agent service"
echo ""
# Ask user for node IPs
echo -e "${YELLOW}Enter your k3s node IP addresses:${NC}"
echo "(Press Enter after each IP, then type 'done' when finished)"
echo ""
NODE_IPS=()
while true; do
read -p "Node IP (or 'done'): " node_ip
if [ "$node_ip" = "done" ]; then
break
fi
if [ -n "$node_ip" ]; then
NODE_IPS+=("$node_ip")
echo -e "${GREEN} ✓ Added: $node_ip${NC}"
fi
done
if [ ${#NODE_IPS[@]} -eq 0 ]; then
echo -e "${RED}Error: No node IPs provided${NC}"
exit 1
fi
echo ""
echo -e "${GREEN}Node IPs to configure:${NC}"
for ip in "${NODE_IPS[@]}"; do
echo " - $ip"
done
echo ""
# Ask for SSH user
read -p "SSH username for nodes (default: ubuntu): " ssh_user
ssh_user=${ssh_user:-ubuntu}
echo ""
echo -e "${YELLOW}Step 2: Configure Registry on Each Node${NC}"
echo ""
# Function to configure a node
configure_node() {
local node_ip=$1
local ssh_user=$2
echo -e "${BLUE}Configuring node: $node_ip${NC}"
# Check if we can SSH to the node
if ! ssh -q -o ConnectTimeout=5 -o BatchMode=yes ${ssh_user}@${node_ip} exit; then
echo -e "${YELLOW} ⚠ Cannot SSH with key-based auth to ${ssh_user}@${node_ip}${NC}"
echo -e "${YELLOW} You may need to enter password...${NC}"
fi
# Create the directory
echo " Creating /etc/rancher/k3s directory..."
ssh ${ssh_user}@${node_ip} "sudo mkdir -p /etc/rancher/k3s" || {
echo -e "${RED} ✗ Failed to create directory${NC}"
return 1
}
# Copy the registries.yaml file
echo " Copying registries.yaml..."
scp "$SCRIPT_DIR/registries.yaml.example" ${ssh_user}@${node_ip}:/tmp/registries.yaml || {
echo -e "${RED} ✗ Failed to copy file${NC}"
return 1
}
# Move to correct location with sudo
ssh ${ssh_user}@${node_ip} "sudo mv /tmp/registries.yaml /etc/rancher/k3s/registries.yaml" || {
echo -e "${RED} ✗ Failed to move file${NC}"
return 1
}
# Set correct permissions
ssh ${ssh_user}@${node_ip} "sudo chmod 644 /etc/rancher/k3s/registries.yaml" || {
echo -e "${YELLOW} ⚠ Warning: Could not set permissions${NC}"
}
# Verify file exists
echo " Verifying configuration..."
if ssh ${ssh_user}@${node_ip} "sudo test -f /etc/rancher/k3s/registries.yaml"; then
echo -e "${GREEN} ✓ Configuration file installed${NC}"
else
echo -e "${RED} ✗ Configuration file not found after installation${NC}"
return 1
fi
# Detect if this is a server or agent node
echo " Detecting node type..."
if ssh ${ssh_user}@${node_ip} "sudo systemctl list-units --full --all | grep -q k3s.service"; then
NODE_TYPE="server"
SERVICE_NAME="k3s"
elif ssh ${ssh_user}@${node_ip} "sudo systemctl list-units --full --all | grep -q k3s-agent.service"; then
NODE_TYPE="agent"
SERVICE_NAME="k3s-agent"
else
echo -e "${YELLOW} ⚠ Could not detect node type, assuming agent${NC}"
NODE_TYPE="agent"
SERVICE_NAME="k3s-agent"
fi
echo -e " Node type: ${BLUE}${NODE_TYPE}${NC}"
# Restart the service
echo " Restarting ${SERVICE_NAME} service..."
if ssh ${ssh_user}@${node_ip} "sudo systemctl restart ${SERVICE_NAME}"; then
echo -e "${GREEN} ✓ Service restarted successfully${NC}"
else
echo -e "${RED} ✗ Failed to restart service${NC}"
echo -e "${YELLOW} You may need to restart manually:${NC}"
echo -e "${YELLOW} ssh ${ssh_user}@${node_ip} 'sudo systemctl restart ${SERVICE_NAME}'${NC}"
return 1
fi
# Wait a moment for service to stabilize
sleep 2
# Check service status
echo " Checking service status..."
if ssh ${ssh_user}@${node_ip} "sudo systemctl is-active --quiet ${SERVICE_NAME}"; then
echo -e "${GREEN} ✓ Service is running${NC}"
else
echo -e "${RED} ✗ Service is not running!${NC}"
echo -e "${YELLOW} Check logs with: ssh ${ssh_user}@${node_ip} 'sudo journalctl -u ${SERVICE_NAME} -n 50'${NC}"
return 1
fi
# Test registry access (with patience for large image)
echo " Testing registry access..."
echo -e " ${BLUE}Note: Image is ~1-2GB, this may take 1-3 minutes on first pull${NC}"
if ssh ${ssh_user}@${node_ip} "timeout 300 sudo k3s crictl pull 192.168.1.208:3002/jason/socktop-webterm:0.2.0 2>&1" | grep -q "Image is up to date\|Successfully pulled"; then
echo -e "${GREEN} ✓ Successfully pulled image from registry!${NC}"
else
echo -e "${YELLOW} ⚠ Could not confirm image pull (may already be cached or need credentials)${NC}"
echo -e "${YELLOW} You can verify manually: ssh ${ssh_user}@${node_ip} 'sudo k3s crictl images | grep socktop'${NC}"
fi
echo -e "${GREEN}✓ Node $node_ip configured successfully!${NC}"
echo ""
return 0
}
# Configure each node
FAILED_NODES=()
for node_ip in "${NODE_IPS[@]}"; do
if ! configure_node "$node_ip" "$ssh_user"; then
FAILED_NODES+=("$node_ip")
fi
done
echo ""
echo -e "${GREEN}=== Configuration Summary ===${NC}"
echo ""
if [ ${#FAILED_NODES[@]} -eq 0 ]; then
echo -e "${GREEN}✓ All nodes configured successfully!${NC}"
echo ""
echo "Your k3s cluster is now configured to pull images from:"
echo -e " ${BLUE}192.168.1.208:3002${NC}"
echo ""
echo "You can now deploy Socktop WebTerm with:"
echo -e " ${YELLOW}cd kubernetes${NC}"
echo -e " ${YELLOW}./deploy.sh${NC}"
else
echo -e "${RED}✗ Some nodes failed to configure:${NC}"
for node in "${FAILED_NODES[@]}"; do
echo -e " ${RED}- $node${NC}"
done
echo ""
echo "Please configure these nodes manually:"
echo ""
echo "1. SSH to the node:"
echo -e " ${YELLOW}ssh ${ssh_user}@<node-ip>${NC}"
echo ""
echo "2. Create the directory:"
echo -e " ${YELLOW}sudo mkdir -p /etc/rancher/k3s${NC}"
echo ""
echo "3. Copy the registries.yaml file:"
echo -e " ${YELLOW}scp registries.yaml.example ${ssh_user}@<node-ip>:/tmp/registries.yaml${NC}"
echo -e " ${YELLOW}ssh ${ssh_user}@<node-ip> 'sudo mv /tmp/registries.yaml /etc/rancher/k3s/registries.yaml'${NC}"
echo ""
echo "4. Restart k3s:"
echo -e " ${YELLOW}sudo systemctl restart k3s${NC} # on server nodes"
echo -e " ${YELLOW}sudo systemctl restart k3s-agent${NC} # on agent nodes"
fi
echo ""
echo -e "${GREEN}Done!${NC}"
+80
View File
@@ -0,0 +1,80 @@
#!/bin/bash
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}=== Registry Connectivity Test ===${NC}"
echo ""
REGISTRY="192.168.1.208:3002"
IMAGE="jason/socktop-webterm:0.2.0"
echo "Testing connection to Gitea registry at $REGISTRY"
echo ""
# Test 1: HTTP connectivity
echo -e "${YELLOW}Test 1: HTTP GET to /v2/${NC}"
if curl -f -s -m 5 "http://$REGISTRY/v2/" > /dev/null; then
echo -e "${GREEN}✓ Registry API is accessible${NC}"
else
echo -e "${RED}✗ Cannot access registry API${NC}"
echo "Try: curl -v http://$REGISTRY/v2/"
fi
echo ""
# Test 2: Check if image exists
echo -e "${YELLOW}Test 2: Check if image exists${NC}"
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" "http://$REGISTRY/v2/$IMAGE/manifests/0.2.0")
if [ "$RESPONSE" = "200" ] || [ "$RESPONSE" = "401" ]; then
echo -e "${GREEN}✓ Image endpoint responds (HTTP $RESPONSE)${NC}"
else
echo -e "${RED}✗ Image not found (HTTP $RESPONSE)${NC}"
fi
echo ""
# Test 3: Check /etc/rancher/k3s/registries.yaml
echo -e "${YELLOW}Test 3: Check registries.yaml${NC}"
if [ -f /etc/rancher/k3s/registries.yaml ]; then
echo -e "${GREEN}✓ registries.yaml exists${NC}"
echo "Content:"
cat /etc/rancher/k3s/registries.yaml
else
echo -e "${RED}✗ registries.yaml not found${NC}"
fi
echo ""
# Test 4: Check k3s service
echo -e "${YELLOW}Test 4: Check k3s service${NC}"
if systemctl is-active --quiet k3s; then
echo -e "${GREEN}✓ k3s service is running${NC}"
elif systemctl is-active --quiet k3s-agent; then
echo -e "${GREEN}✓ k3s-agent service is running${NC}"
else
echo -e "${RED}✗ k3s service is not running${NC}"
fi
echo ""
# Test 5: Try docker pull (if docker is installed)
echo -e "${YELLOW}Test 5: Try docker pull${NC}"
if command -v docker &> /dev/null; then
echo "Attempting docker pull (timeout 10s)..."
timeout 10 docker pull "$REGISTRY/$IMAGE" 2>&1 | tail -5
else
echo "Docker not installed, skipping"
fi
echo ""
echo -e "${BLUE}=== Recommendations ===${NC}"
echo ""
echo "If registry.yaml exists but pull hangs:"
echo " 1. Restart k3s: sudo systemctl restart k3s"
echo " 2. Check k3s logs: sudo journalctl -u k3s -n 50"
echo ""
echo "If image endpoint returns 401:"
echo " - This is normal - registry requires auth"
echo " - k3s should handle this automatically"
echo ""