From daac05e7e819f443964189d231dd1b08a7422d08 Mon Sep 17 00:00:00 2001 From: Keith Jackson Date: Sat, 12 Sep 2026 16:25:20 -0500 Subject: [PATCH] feat(bulk): prod mounts the NFS export through pfSense's WAN address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The operator added the pfSense port-forward, so BULK_NFS_SERVER is no longer a placeholder. Prod gets 192.168.2.102 (pfSense WAN, DNAT tcp/2049 -> 192.168.1.9); dev stays on the base 192.168.1.9 because it is already on pfSense's LAN. This value could not be left as a placeholder safely: spec.nfs.server is unvalidated by Kubernetes, so the PV would be created, the PVC would BIND, and the failure would only surface as four pods stuck in ContainerCreating. Verified from k3s-prod-1 before committing, deliberately as uid 1000 rather than root (the export carries no_root_squash, so a root write proves nothing, and LSIO images default to PUID 911 which would go Ready and then fail every import EACCES): mount negotiated nfs4 vers=4.1 proto=tcp, write succeeded, and ln() across downloads/ -> tv/ gave link count 2 — real hardlinks, so no silent copy-then-delete. The Nextcloud export was additionally tightened to server-side ro= for prod's three nodes; a write as root is refused. Its content is config/, config_old/ and config_backup/ with no data/ directory, so it is an archive, not a live data store. Co-Authored-By: Claude Opus 5 --- clusters/prod/kustomization.yaml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/clusters/prod/kustomization.yaml b/clusters/prod/kustomization.yaml index 697297f..92ee79c 100644 --- a/clusters/prod/kustomization.yaml +++ b/clusters/prod/kustomization.yaml @@ -431,7 +431,22 @@ patches: # where these manifests are meant to be proven first. - op: replace path: /data/BULK_NFS_SERVER - value: "TBD-PROD-BULK-NFS-SERVER" + # 192.168.2.102 is pfSense's WAN address, which DNATs tcp/2049 through to the Proxmox + # host's REAL address 192.168.1.9 on pfSense's LAN. Prod sits on the WAN side and cannot + # reach 192.168.1.9 directly, so the cluster mounts the NAT address. Dev is on the LAN and + # keeps the base value 192.168.1.9. + # + # PROVEN from k3s-prod-1 on 2026-09-12, not inferred: + # - mount of 192.168.2.102:/mnt/Storage/plex negotiated nfs4 vers=4.1 proto=tcp + # - a write as uid 1000 succeeded. Tested as 1000 and NOT root deliberately: the export + # carries no_root_squash, so a root write would have passed and proved nothing, while + # LSIO images default to PUID 911 and would have gone Ready then failed every import + # with EACCES. The tree is 0755 1000:3000, so uid 1000 is the only writer. + # - ln() across downloads/ -> tv/ returned link count 2 (same inode), so the arrs get + # real atomic moves instead of silently degrading to copy-then-delete on EXDEV. + # pfSense DNATs WITHOUT source NAT (the host logs prod's own node addresses as the peer), + # so the ZFS export ACL names 192.168.2.10/.11/.12 directly rather than one translated IP. + value: "192.168.2.102" # ========================================================================================== # OFF-CLUSTER DR TARGET — Cloudflare R2 (operator, 2026-09-05; bucket + token 2026-09-07). # ==========================================================================================