Files
home-network-k3s-impl/platform/vpn-egress/gluetun-gateway.yaml
T

134 lines
6.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
# Gluetun — the single shared in-cluster VPN egress gateway (ADR-0013): PIA over OpenVPN-UDP, with
# Gluetun's built-in kill-switch/firewall (fail-closed), health checks, auto-reconnect, and native
# port forwarding for qBittorrent. `vpn`-class pods are steered through this gateway (see README.md
# "Egress steering" — the Cilium-native mechanism, pending live validation with PIA creds).
#
# Credentials: the `pia-credentials` SOPS Secret (keys: username, password). Gluetun uses PIA's
# username/password (via OPENVPN_USER/OPENVPN_PASSWORD) to authenticate to PIA. Gluetun ships PIA's
# OpenVPN server configs, so no manual `.ovpn` is needed (ADR-0013 amendment: OpenVPN-UDP — Gluetun
# does NOT support PIA over WireGuard).
apiVersion: apps/v1
kind: Deployment
metadata:
name: gluetun
namespace: vpn-egress
labels:
app: gluetun
spec:
replicas: 1 # ONE shared tunnel (ADR-0013). Active/standby is a later enhancement.
strategy:
type: Recreate # a tunnel is a singleton — never run two overlapping during a rollout
selector:
matchLabels:
app: gluetun
template:
metadata:
labels:
app: gluetun
spec:
initContainers:
# gluetun's BUNDLED PIA server list is STALE (retired 46.246.x IPs → timeouts; current PIA Sweden
# is 158.173.x), and UPDATER_PERIOD only refreshes AFTER the tunnel is ready (chicken-and-egg). So
# fetch PIA's CURRENT list into the shared /gluetun volume BEFORE the main container starts.
- name: update-servers
image: qmcgaw/gluetun:v3.41.0
args: ["update", "-enduser", "-providers", "private internet access"]
resources:
requests: { cpu: 25m, memory: 32Mi }
limits: { memory: 128Mi }
volumeMounts:
- name: gluetun-data
mountPath: /gluetun
containers:
- name: gluetun
image: qmcgaw/gluetun:v3.41.0 # pinned; Renovate bumps. PIA is OpenVPN-only in Gluetun
# (WireGuard for PIA is unsupported upstream — ADR-0013
# amendment; thrnz/docker-wireguard-pia is the WG fallback).
securityContext:
capabilities:
add: ["NET_ADMIN"] # required for the tunnel + firewall
env:
- name: VPN_SERVICE_PROVIDER
value: "private internet access"
- name: VPN_TYPE
value: "openvpn" # OpenVPN-UDP — satisfies "protocol != TCP" (R-NET); ADR-0013 amended
- name: OPENVPN_ENDPOINT_PORT
value: "8080" # NOT 1197: with live servers, PIA's replies FROM src-port 1197 get
# no return here — the home OpenVPN server / port-forward on 1197
# appears to swallow them. 8080 avoids that (PIA serves it too).
# Fresh server list comes from the update-servers initContainer (see above). UPDATER_PERIOD then
# keeps it fresh for long-running pods (gluetun docs: >=360h to be nice to the provider API):
- name: UPDATER_PERIOD
value: "720h"
# Pod MTU is 1450 (Cilium VXLAN: 1500 − 50 encap; node/host/WAN are 1500). Shrink OpenVPN so
# DATA-channel packets fit (the handshake is small so this wasn't the connect blocker, but the
# data channel needs it). Hardcoded strings (int-coercion gotcha). See DECISIONS-LOG.
- name: OPENVPN_MTU
value: "1350"
- name: OPENVPN_MSSFIX
value: "1350"
# PIA credentials from the SOPS secret (Gluetun's PIA OpenVPN creds env):
- name: OPENVPN_USER
valueFrom:
secretKeyRef:
name: pia-credentials
key: username
- name: OPENVPN_PASSWORD
valueFrom:
secretKeyRef:
name: pia-credentials
key: password
- name: SERVER_REGIONS
value: "${PIA_REGION}" # cluster-vars: a PF-CAPABLE PIA region (ADR-0013 PF caveat)
- name: VPN_PORT_FORWARDING
value: "on" # PIA native port forwarding for qBittorrent
- name: FIREWALL
value: "on" # KILL-SWITCH: block all egress except the tunnel (fail-closed, R-NET-06)
- name: FIREWALL_OUTBOUND_SUBNETS
value: "${CLUSTER_POD_CIDR}" # allow steered client pods (pod CIDR) to route out via the tunnel
- name: DOT
value: "off" # DNS via cluster CoreDNS, not Gluetun's DoT
ports:
- name: control
containerPort: 8000 # Gluetun control API (health + forwarded-port lookup)
livenessProbe:
httpGet: { path: /v1/openvpn/status, port: 8000 } # Gluetun control API health
initialDelaySeconds: 20
periodSeconds: 30
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 160Mi
volumeMounts:
- name: tun
mountPath: /dev/net/tun
- name: gluetun-data
mountPath: /gluetun # shared with update-servers initContainer (fresh servers.json)
volumes:
- name: tun
hostPath:
path: /dev/net/tun
type: CharDevice
- name: gluetun-data
emptyDir: {}
---
# Control API Service — the port-sync helper (qbittorrent-natmap, README) reads the PIA-assigned
# forwarded port from here; also used for tunnel-state health/alerting (ADR-0013 "alert on tunnel state").
apiVersion: v1
kind: Service
metadata:
name: gluetun-control
namespace: vpn-egress
labels:
app: gluetun
spec:
selector:
app: gluetun
ports:
- name: control
port: 8000
targetPort: 8000