Files
infrastructure/servers/legion/k8s/fornax/worker/base/deployment.yaml
T
Will Anderson ef8dc293e5 Set HEALTH_ICMP_TARGET_IPS to WireGuard gateway for periodic health check
ProtonVPN does not NAT ICMP to external IPs (1.1.1.1, 8.8.8.8), causing
the periodic small health check to always fail and restart the VPN loop.
10.2.0.1 (WireGuard gateway) responds to ICMP at ~28ms and remains
reachable as long as the WireGuard tunnel itself is up.
2026-04-14 22:08:40 -05:00

193 lines
6.7 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: fornax-worker-WORKER_ID
namespace: media
labels:
app: fornax-worker-WORKER_ID
app.kubernetes.io/part-of: fornax
app.kubernetes.io/component: worker
spec:
replicas: 1
selector:
matchLabels:
app: fornax-worker-WORKER_ID
template:
metadata:
labels:
app: fornax-worker-WORKER_ID
spec:
initContainers:
- name: tun-setup
image: busybox:latest
securityContext:
privileged: true
command:
- sh
- -c
- >-
mkdir -p /dev/net &&
[ -c /dev/net/tun ] || mknod /dev/net/tun c 10 200 &&
chmod 666 /dev/net/tun &&
sysctl -w net.ipv6.conf.all.disable_ipv6=1 || true &&
ip route flush table 51820 2>/dev/null || true &&
ip rule del priority 101 2>/dev/null || true &&
ip rule del table 51820 2>/dev/null || true
- name: qbt-config-patch
image: busybox:latest
command:
- sh
- -c
- |
CONF=/config/qBittorrent/qBittorrent.conf
HASH='@ByteArray(HqYj1eGsdXlQ4CSy597Y9A==:J9hsJIlU5FYfHb5rY5qQoIpVpTijryS/H+CE07oMtplL/ytneBVFd2tfVJtqGjhdht8tEi4wmqSSlqTgEu444w==)'
mkdir -p /config/qBittorrent
if [ -f "$CONF" ]; then
if grep -q "Password_PBKDF2" "$CONF"; then
sed -i "s|WebUI\\\\Password_PBKDF2=.*|WebUI\\\\Password_PBKDF2=\"$HASH\"|" "$CONF"
else
sed -i "/^\\[Preferences\\]/a WebUI\\\\Password_PBKDF2=\"$HASH\"" "$CONF"
fi
fi
echo "Password hash set."
volumeMounts:
- mountPath: /config
name: config
containers:
- name: gluetun
image: ghcr.io/qdm12/gluetun:latest
imagePullPolicy: Always
securityContext:
capabilities:
add:
- NET_ADMIN
env:
- name: VPN_SERVICE_PROVIDER
value: custom
- name: VPN_TYPE
value: wireguard
- name: WIREGUARD_PRIVATE_KEY
valueFrom:
secretKeyRef:
name: fornax-worker-WORKER_ID-secrets
key: PROTONVPN_PRIVATE_KEY
- name: WIREGUARD_PUBLIC_KEY
value: PLACEHOLDER_PUBLIC_KEY
- name: WIREGUARD_ADDRESSES
value: 10.2.0.2/32
- name: WIREGUARD_ENDPOINT_IP
value: PLACEHOLDER_ENDPOINT_IP
- name: WIREGUARD_ENDPOINT_PORT
value: "51820"
- name: DOT
value: "off"
- name: DNS_UPSTREAM_RESOLVER_TYPE
value: "plain"
- name: DNS_UPSTREAM_PLAIN_ADDRESSES
value: "10.43.0.10:53"
- name: HEALTH_TARGET_ADDRESS
value: "api.protonvpn.ch:443,account.proton.me:443"
- name: HEALTH_ICMP_TARGET_IPS
value: "10.2.0.1"
- name: FIREWALL_OUTBOUND_SUBNETS
value: 10.42.0.0/16,10.43.0.0/16
ports:
- containerPort: 8888
name: proxy
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 200m
memory: 512Mi
volumeMounts:
- mountPath: /tmp/gluetun
name: gluetun-data
- name: portforward-helper
image: alpine:latest
imagePullPolicy: Always
env:
- name: COORDINATOR_URL
value: "https://fornax.neuralplatform.ai"
- name: WORKER_ID
value: "WORKER_ID"
command:
- sh
- -c
- |
until apk add -q curl 2>/dev/null; do sleep 5; done
echo "Watching /tmp/gluetun/forwarded_port for assigned port..."
TTL=300
while true; do
if [ -f /tmp/gluetun/forwarded_port ]; then
PORT=$(cat /tmp/gluetun/forwarded_port)
if [ -n "$PORT" ] && [ "$PORT" != "0" ]; then
echo "$(date): Forwarded port: $PORT - updating qBittorrent"
curl -s -c /tmp/qbt.txt -X POST http://localhost:8080/api/v2/auth/login \
-d "username=admin&password=adminadmin" >/dev/null 2>&1
curl -s -b /tmp/qbt.txt -X POST http://localhost:8080/api/v2/app/setPreferences \
-d "json={\"listen_port\":$PORT,\"random_port\":false}" >/dev/null 2>&1
echo "$(date): qBittorrent listen port set to $PORT"
# Notify coordinator of port lease
if [ -n "$COORDINATOR_URL" ] && [ -n "$WORKER_ID" ]; then
curl -s -X POST "$COORDINATOR_URL/api/v2/workers/$WORKER_ID/port-lease" \
-H "Content-Type: application/json" \
-d "{\"port\": $PORT, \"ttlSeconds\": $TTL}" >/dev/null 2>&1 || true
echo "$(date): Coordinator notified of port $PORT (TTL: ${TTL}s)"
fi
else
echo "$(date): Port file empty, waiting..."
fi
else
echo "$(date): Waiting for gluetun to write port file..."
fi
sleep 45
done
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 50m
memory: 96Mi
volumeMounts:
- mountPath: /tmp/gluetun
name: gluetun-data
- name: qbittorrent
image: lscr.io/linuxserver/qbittorrent:latest
imagePullPolicy: Always
env:
- name: PUID
value: "1000"
- name: PGID
value: "1000"
- name: TZ
value: America/Chicago
- name: WEBUI_PORT
value: "8080"
ports:
- containerPort: 8080
name: webui
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 1Gi
volumeMounts:
- mountPath: /config
name: config
- mountPath: /media
name: media
volumes:
- name: gluetun-data
emptyDir: {}
- name: config
persistentVolumeClaim:
claimName: fornax-worker-WORKER_ID-config
- name: media
persistentVolumeClaim:
claimName: media-data