feat: update JDownloader deployment for VLAN 50 migration with enhanced network configuration and egress guard
Some checks failed
validate / lint (push) Failing after 1s
Some checks failed
validate / lint (push) Failing after 1s
This commit is contained in:
parent
2f7ec5f5b1
commit
756fa120b3
@ -1,6 +1,25 @@
|
|||||||
# Apply: kubectl apply -f manifests/media/jdownloader.yaml
|
# Apply: kubectl apply -f manifests/media/jdownloader.yaml
|
||||||
# Delete: kubectl delete -f manifests/media/jdownloader.yaml
|
# Delete: kubectl delete -f manifests/media/jdownloader.yaml
|
||||||
# Description: JDownloader deployment with Ingress at jdownloader.home.arpa.
|
# Description: JDownloader deployment with Ingress at jdownloader.home.arpa.
|
||||||
|
#
|
||||||
|
# *** VLAN 50 MIGRATION — DO NOT PUSH TO main WITHOUT SEPARATE, EXPLICIT
|
||||||
|
# APPROVAL — AND ONLY AFTER qBittorrent (manifests/media/
|
||||||
|
# qbittorrent.yaml) HAS BEEN LIVE, VALIDATED, AND SOAKED. plan.md is
|
||||||
|
# explicit: migrate qBittorrent first, soak, then JDownloader,
|
||||||
|
# independently soaked — do not batch them. ***
|
||||||
|
# Same VLAN 50/Multus design as qbittorrent.yaml (see that file's header
|
||||||
|
# for the full precondition list — pia-gateway, vlan50-parent, and
|
||||||
|
# manifests/multus/ all applied and verified first). One difference:
|
||||||
|
# JDownloader has no reliably-persistent, file-editable interface-bind
|
||||||
|
# setting the way qBittorrent's qBittorrent.conf does (its own
|
||||||
|
# preferences aren't a simple INI this repo can safely patch), so this
|
||||||
|
# migration relies on the network-namespace egress guard alone for
|
||||||
|
# enforcement, exactly as plan.md anticipates for JDownloader
|
||||||
|
# specifically ("application-level interface binding may be weaker or
|
||||||
|
# unavailable... the namespace egress guard is mandatory").
|
||||||
|
# `media` has selfHeal+automated sync already configured — pushing this
|
||||||
|
# file deploys it immediately. Rollback copy, not synced by any
|
||||||
|
# Application: manifests/media/rollback/jdownloader-gluetun.yaml.
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@ -17,66 +36,65 @@ spec:
|
|||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: jdownloader
|
app: jdownloader
|
||||||
|
annotations:
|
||||||
|
k8s.v1.cni.cncf.io/networks: |
|
||||||
|
[{"name": "vlan50", "namespace": "downloads", "interface": "net1", "ips": ["10.10.50.11/24"]}]
|
||||||
spec:
|
spec:
|
||||||
|
# Hard-pinned to nik-debian, not just node-role: storage — see
|
||||||
|
# qbittorrent.yaml for why.
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
node-role: storage
|
node-role: storage
|
||||||
containers:
|
kubernetes.io/hostname: nik-debian
|
||||||
- name: gluetun
|
# No cluster DNS/CoreDNS resolution needed or provided here — see
|
||||||
image: qmcgaw/gluetun:v3.41
|
# qbittorrent.yaml for the full reasoning (identical here: this pod
|
||||||
|
# never looks up an in-cluster service by name).
|
||||||
|
dnsPolicy: None
|
||||||
|
dnsConfig:
|
||||||
|
nameservers:
|
||||||
|
- "10.10.40.53"
|
||||||
|
initContainers:
|
||||||
|
# NET_ADMIN lives here ONLY. No qBittorrent-style config-bind
|
||||||
|
# sibling init container — see this file's header for why
|
||||||
|
# JDownloader relies on the egress guard alone.
|
||||||
|
- name: vlan50-egress-guard
|
||||||
|
image: nicolaka/netshoot:v0.11
|
||||||
|
command: ["/bin/sh", "/scripts/guard.sh"]
|
||||||
|
env:
|
||||||
|
- name: VLAN50_GATEWAY
|
||||||
|
value: "10.10.50.1"
|
||||||
|
- name: TECHNITIUM_IP
|
||||||
|
value: "10.10.40.53"
|
||||||
|
- name: POD_CIDR
|
||||||
|
value: "10.42.0.0/16"
|
||||||
|
- name: SERVICE_CIDR
|
||||||
|
value: "10.43.0.0/16"
|
||||||
|
- name: NODE_IP
|
||||||
|
value: "10.10.40.20"
|
||||||
|
- name: EXPECTED_VLAN50_IP
|
||||||
|
value: "10.10.50.11"
|
||||||
securityContext:
|
securityContext:
|
||||||
capabilities:
|
capabilities:
|
||||||
add:
|
drop: ["ALL"]
|
||||||
- NET_ADMIN
|
# NET_RAW alongside NET_ADMIN: the guard script's
|
||||||
env:
|
# arping-based duplicate-address and gateway-reachability
|
||||||
- name: VPN_SERVICE_PROVIDER
|
# checks need it — see
|
||||||
value: private internet access
|
# vlan50-egress-guard-script.yaml's header comment.
|
||||||
- name: VPN_TYPE
|
add: ["NET_ADMIN", "NET_RAW"]
|
||||||
value: openvpn
|
|
||||||
- name: SERVER_REGIONS
|
|
||||||
value: JP Tokyo,Taiwan,Hong Kong
|
|
||||||
# value: US Seattle,US Oregon,US Silicon Valley
|
|
||||||
- name: OPENVPN_USER
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: pia-credentials
|
|
||||||
key: OPENVPN_USER
|
|
||||||
- name: OPENVPN_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: pia-credentials
|
|
||||||
key: OPENVPN_PASSWORD
|
|
||||||
- name: FIREWALL_OUTBOUND_SUBNETS
|
|
||||||
value: "10.42.0.0/16,10.43.0.0/16,10.10.40.0/24"
|
|
||||||
- name: BLOCK_IPV6
|
|
||||||
value: "on"
|
|
||||||
startupProbe:
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- /gluetun-entrypoint
|
|
||||||
- healthcheck
|
|
||||||
periodSeconds: 10
|
|
||||||
failureThreshold: 60
|
|
||||||
livenessProbe:
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- /gluetun-entrypoint
|
|
||||||
- healthcheck
|
|
||||||
periodSeconds: 30
|
|
||||||
failureThreshold: 3
|
|
||||||
readinessProbe:
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- /gluetun-entrypoint
|
|
||||||
- healthcheck
|
|
||||||
periodSeconds: 10
|
|
||||||
failureThreshold: 3
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: tun
|
- name: guard-script
|
||||||
mountPath: /dev/net/tun
|
mountPath: /scripts
|
||||||
|
containers:
|
||||||
- name: jdownloader
|
- name: jdownloader
|
||||||
image: jlesage/jdownloader-2:latest
|
image: jlesage/jdownloader-2:latest
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 5800
|
- containerPort: 5800
|
||||||
|
# No securityContext capability restriction here, deliberately
|
||||||
|
# — jlesage/jdownloader-2 uses the same docker-baseimage-gui
|
||||||
|
# PUID/GID pattern as linuxserver's images (USER_ID/GROUP_ID
|
||||||
|
# below): starts as root, its own init chowns /config to the
|
||||||
|
# requested uid/gid and drops privileges from there. See
|
||||||
|
# qbittorrent.yaml's app container for the fuller version of
|
||||||
|
# this reasoning — same conclusion, same kind of image.
|
||||||
env:
|
env:
|
||||||
- name: USER_ID
|
- name: USER_ID
|
||||||
value: "1000"
|
value: "1000"
|
||||||
@ -112,6 +130,12 @@ spec:
|
|||||||
image: python:3.12-alpine
|
image: python:3.12-alpine
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9667
|
- containerPort: 9667
|
||||||
|
# Unlike the jdownloader container above, this is a plain
|
||||||
|
# Python base image with no PUID/GID privilege-drop machinery
|
||||||
|
# to preserve — dropping all capabilities here is safe.
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 5m
|
cpu: 5m
|
||||||
@ -149,8 +173,10 @@ spec:
|
|||||||
|
|
||||||
# .torrent files aren't handled by JDownloader's crawler (no BT
|
# .torrent files aren't handled by JDownloader's crawler (no BT
|
||||||
# plugin), so fetch the raw file ourselves instead of writing a
|
# plugin), so fetch the raw file ourselves instead of writing a
|
||||||
# crawljob. This container shares gluetun's netns, so the fetch
|
# crawljob. This container shares the pod's network namespace
|
||||||
# is still VPN-routed same as JDownloader's own downloads.
|
# (and its vlan50-egress-guard init container's routes/rules),
|
||||||
|
# so the fetch is still VPN-routed same as JDownloader's own
|
||||||
|
# downloads.
|
||||||
if basename.lower().endswith('.torrent'):
|
if basename.lower().endswith('.torrent'):
|
||||||
safe_name = basename.replace('/', '_').replace('\\', '_')
|
safe_name = basename.replace('/', '_').replace('\\', '_')
|
||||||
try:
|
try:
|
||||||
@ -183,10 +209,6 @@ spec:
|
|||||||
|
|
||||||
http.server.HTTPServer(('0.0.0.0', 9667), Handler).serve_forever()
|
http.server.HTTPServer(('0.0.0.0', 9667), Handler).serve_forever()
|
||||||
volumes:
|
volumes:
|
||||||
- name: tun
|
|
||||||
hostPath:
|
|
||||||
path: /dev/net/tun
|
|
||||||
type: CharDevice
|
|
||||||
- name: config
|
- name: config
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /data/jdownloader
|
path: /data/jdownloader
|
||||||
@ -195,6 +217,10 @@ spec:
|
|||||||
hostPath:
|
hostPath:
|
||||||
path: /mnt/storage/dl
|
path: /mnt/storage/dl
|
||||||
type: Directory
|
type: Directory
|
||||||
|
- name: guard-script
|
||||||
|
configMap:
|
||||||
|
name: vlan50-egress-guard-script
|
||||||
|
defaultMode: 365 # octal 0555, r-xr-xr-x
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user