Files
k8s-starter-pack/apps/qbittorrent/deployment.yaml
T

155 lines
5.2 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: qbittorrent
namespace: qbittorrent
spec:
# qBittorrent has one writable configuration volume and one Proton port
# forwarding lease, so upgrades replace the Pod rather than overlap two.
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: qbittorrent
template:
metadata:
labels:
app: qbittorrent
spec:
# The SOPS-managed Secret is read-only, but Hotio writes Proton's current
# forwarded port beside wg0.conf. Copy the secret into a writable emptyDir
# without ever storing the plaintext WireGuard key in Git.
initContainers:
- name: prepare-wireguard-config
image: busybox:1.37.0
command:
- sh
- -ec
- >-
cp /vpn-secret/wg0.conf /wireguard/wg0.conf &&
chmod 0600 /wireguard/wg0.conf
volumeMounts:
- name: wireguard-secret
mountPath: /vpn-secret
readOnly: true
- name: wireguard-runtime
mountPath: /wireguard
containers:
- name: qbittorrent
image: ghcr.io/hotio/qbittorrent:release
imagePullPolicy: Always
# Hotio automatically permits the Pod's directly attached /24 but
# rejects that same subnet in VPN_LAN_NETWORK. Add every *other* /24
# from this cluster's 10.244.0.0/21 Pod range at runtime so traffic
# from ingress-nginx and media apps works regardless of scheduling.
command:
- /bin/sh
- -ec
- |
own_octet="${POD_IP#10.244.}"
own_octet="${own_octet%%.*}"
case "$own_octet" in
0|1|2|3|4|5|6|7) ;;
*) echo "Unexpected Pod IP: $POD_IP" >&2; exit 1 ;;
esac
for octet in 0 1 2 3 4 5 6 7; do
if [ "$octet" != "$own_octet" ]; then
VPN_LAN_NETWORK="${VPN_LAN_NETWORK},10.244.${octet}.0/24"
fi
done
export VPN_LAN_NETWORK
exec /init
securityContext:
# Hotio needs this capability to create the WireGuard interface,
# routes, firewall rules, and VPN kill switch inside the Pod.
capabilities:
add:
- NET_ADMIN
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: PUID
value: "1000"
- name: PGID
value: "1000"
- name: UMASK
value: "002"
- name: TZ
value: Europe/London
- name: WEBUI_PORTS
value: 8080/tcp
- name: VPN_ENABLED
value: "true"
- name: VPN_CONF
value: wg0
- name: VPN_PROVIDER
value: proton
# Permit the physical LAN to reach the Web UI/API without allowing
# ordinary internet traffic to bypass the VPN. Do not add the
# Kubernetes Pod CIDR here: Hotio detects the Pod's attached network
# itself and rejects an overlapping VPN_LAN_NETWORK route.
- name: VPN_LAN_NETWORK
value: 10.10.0.0/16
- name: VPN_LAN_LEAK_ENABLED
value: "false"
# Proton assigns a dynamic inbound port through NAT-PMP. Hotio
# renews it and updates qBittorrent's listening port automatically.
- name: VPN_AUTO_PORT_FORWARD
value: "true"
- name: VPN_HEALTHCHECK_ENABLED
value: "true"
- name: VPN_NAMESERVERS
value: wg
ports:
- name: http
containerPort: 8080
protocol: TCP
# Proton must negotiate a forwarded port before qBittorrent starts
# its Web UI, so avoid expected connection-refused events during that
# normal initialization window.
startupProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 36
readinessProbe:
httpGet:
path: /
port: http
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet:
path: /
port: http
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
volumeMounts:
- name: qbittorrent-config
mountPath: /config
- name: wireguard-runtime
mountPath: /config/wireguard
- name: torrents
mountPath: /data/torrents
volumes:
- name: qbittorrent-config
persistentVolumeClaim:
claimName: qbittorrent-config
- name: wireguard-secret
secret:
secretName: qbittorrent-wireguard
- name: wireguard-runtime
emptyDir: {}
- name: torrents
nfs:
server: nas.ahmza.com
path: /srv/media/torrents