cloudflared: decommission the Cloudflare tunnel ingress #44
@@ -1,15 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cloudflared-config
|
||||
namespace: ingress
|
||||
data:
|
||||
config.yaml: |
|
||||
tunnel: d2386ccd-a665-41e7-8631-603fdafcb006
|
||||
credentials-file: /etc/cloudflared/credentials.json
|
||||
metrics: 0.0.0.0:2000
|
||||
no-autoupdate: true
|
||||
|
||||
ingress:
|
||||
# Catch-all
|
||||
- service: http_status:404
|
||||
@@ -1,56 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cloudflared
|
||||
namespace: ingress
|
||||
labels:
|
||||
app: cloudflared
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cloudflared
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cloudflared
|
||||
spec:
|
||||
containers:
|
||||
- name: cloudflared
|
||||
image: cloudflare/cloudflared:2026.6.1 # {"$imagepolicy": "flux-system:cloudflared"}
|
||||
args:
|
||||
- tunnel
|
||||
- --config
|
||||
- /etc/cloudflared/config.yaml
|
||||
- run
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/cloudflared/config.yaml
|
||||
subPath: config.yaml
|
||||
readOnly: true
|
||||
- name: credentials
|
||||
mountPath: /etc/cloudflared/credentials.json
|
||||
subPath: credentials.json
|
||||
readOnly: true
|
||||
ports:
|
||||
- containerPort: 2000
|
||||
name: metrics
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: metrics
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: cloudflared-config
|
||||
- name: credentials
|
||||
secret:
|
||||
secretName: cloudflared-credentials
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- secret.sops.yaml
|
||||
- configmap.yaml
|
||||
- deployment.yaml
|
||||
@@ -1,23 +0,0 @@
|
||||
apiVersion: ENC[AES256_GCM,data:Knk=,iv:EePXth4ClrsLa/tNd8rKJa0TSpoRppF/UY+vowhbGHI=,tag:K6vVMfB8nlylawgaVJ6IkQ==,type:str]
|
||||
kind: ENC[AES256_GCM,data:Q6eVCfmA,iv:N1nHKbFGcx7m7462eNVeVxrbvap/iiO1g+iafHnupys=,tag:11bX04mASxHDP7kLQENIqw==,type:str]
|
||||
metadata:
|
||||
name: ENC[AES256_GCM,data:3pJApagBL7I11uL12jJQSIf0ggX19og=,iv:6Jw/eXrjE8Xyc/aNKK2tCB9HuLTwq96mt93j7hc+1q8=,tag:Z5whorYxqp0mHl04IPFPYg==,type:str]
|
||||
namespace: ENC[AES256_GCM,data:mzcIBgFCew==,iv:wgUBU2Irb2vOmPcc/Xynnb1Nm5kiWnBKmlwbNrcHSw0=,tag:Beg4WmnK6aiPC3p0/aHzJg==,type:str]
|
||||
type: ENC[AES256_GCM,data:r/eSbu7o,iv:hzwYi1eoVaYzh8hCiKTza6lGfA0NUCMYCqmKnB/Ttac=,tag:URwYkY42hS2OZQwFnQRVVQ==,type:str]
|
||||
stringData:
|
||||
credentials.json: ENC[AES256_GCM,data:znWLH6jv69hlFS4NWF3gnCIHQBwLRGHlWCw23uxSwR6x0drwfx5muMfQpriXwBG6GPKkq6hMb0cej2Whh4E/kj9DkpoEFc5MfVats8dVr18pSI+DmY8JFmcRpcrKb5dmBR3crfOzo4cGXwFJPYzoONCXIfo0k92zNIhBQ/sXIstMFbMjE3Svdxz+z/iV2QeJ8YSDnNRyYr3HY1RvTXdf2Pbe,iv:079x5CbOg/090x/cmZItHdXfp3vSL3WgE67BJQ1cY4Y=,tag:Jt9CDyJQm7wt7AyaZS92KQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1yqjvqkwwwxdj7mr546zfs5ckzuwndp69ya2n2drd4vypwns8w4ys04qfy3
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxQXIreW1nN3dNbU54ZXI0
|
||||
SGVISDBFL3Ric2ovbnJTUjVJb1ZEUFArNlV3CnhibWQvY0RVc2FSWW9lSEFVM1dN
|
||||
THV0cDBqZU9uWTJ1eU00ZlM3Z2RyQU0KLS0tIEp5WlExT3liQmIxTXBTRGU0Sm9D
|
||||
V0RMekxwZ1lLaFRNek1weWNGQkRndWsKjWZTtkUBAS17khEVynekGoP+qf57ZPz1
|
||||
VkWtWrkDmDtmyTVgXMOmlEWJoBmjirMvxLRZ9QBoZCSLOIptTmFkvg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-05T20:18:25Z"
|
||||
mac: ENC[AES256_GCM,data:cTdHAtXgfsfbL83dpJyRZjGzOrk5eIjjpDtSJ3132cyNHw72+cLf1JEkyOG9VecZAkdLQFH1fmuRSnyrGUHRv/yk0dS41BU5XtILQNRYoiNAMC9o/LmdTnl7B6KLAdVP7AzmiV+1bftoZn4C3Nzs52TPxsrtmHd0ToCnPFzlG0c=,iv:p6V8ATSK4NlbvXov4oYbEhdDkChp1SRmetYRL1Z09TI=,tag:kUOwsltBy9vW/h6GSrhR7A==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
@@ -42,7 +42,6 @@ existing `flux-system` GitRepository whose Secret was created by
|
||||
| matter-server | `8.x` | Pre-release filter |
|
||||
| zwave-js-ui | `11.x` | |
|
||||
| wyoming-{whisper,openwakeword,speech-to-phrase} | `3.x` / `2.x` / `1.x` | |
|
||||
| cloudflared | `2026.x` | Calver |
|
||||
| gatus | `5.x` | v-prefix filter |
|
||||
| velero-plugin-for-aws | `1.13.x` | Tight: must match velero server major.minor |
|
||||
| gotenberg | `8.x` | Plain-variant filter (rejects `-libreoffice`/`-chromium`/`-cloudrun`/`-aws-lambda`) |
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImageRepository
|
||||
metadata:
|
||||
name: cloudflared
|
||||
namespace: flux-system
|
||||
spec:
|
||||
image: cloudflare/cloudflared
|
||||
interval: 1h
|
||||
---
|
||||
# Calver: YYYY.M.PATCH. Open-ended floor (>=2026.0.0) so January
|
||||
# rollovers don't silently freeze the policy on the previous year's
|
||||
# top tag. The filterTags regex restricts candidates to bare-numeric
|
||||
# calver triplets, so non-release tags (latest, *-amd64, …) can't slip
|
||||
# through; the floor only guards against rolling back to pre-2026
|
||||
# releases.
|
||||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImagePolicy
|
||||
metadata:
|
||||
name: cloudflared
|
||||
namespace: flux-system
|
||||
spec:
|
||||
imageRepositoryRef:
|
||||
name: cloudflared
|
||||
filterTags:
|
||||
pattern: '^(?P<ver>\d+\.\d+\.\d+)$'
|
||||
extract: '$ver'
|
||||
policy:
|
||||
semver:
|
||||
range: ">=2026.0.0"
|
||||
@@ -4,7 +4,6 @@ resources:
|
||||
- update-automation.yaml
|
||||
- audiobookshelf.yaml
|
||||
- ceph.yaml
|
||||
- cloudflared.yaml
|
||||
- cnpg-barman-plugin.yaml
|
||||
- firefox.yaml
|
||||
- gatus.yaml
|
||||
|
||||
@@ -16,7 +16,7 @@ spec:
|
||||
#
|
||||
# Names not backed by an in-cluster Ingress fall through to the Proxmox
|
||||
# DNS HA VIP (10.2.40.53) — preserving resolution of LXC/VM-hosted
|
||||
# services (gitea, immich, cloudflared, …) without manual enumeration.
|
||||
# services (gitea, immich, …) without manual enumeration.
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
|
||||
@@ -15,7 +15,6 @@ resources:
|
||||
- rook-ceph/
|
||||
- ceph-csi-drivers/
|
||||
- cloudnative-pg/
|
||||
- cloudflared/
|
||||
- netbird-ingress/
|
||||
- coredns-config/
|
||||
- k8s-gateway/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# NetBird mesh ingress — a second, parallel ingress path alongside
|
||||
# cloudflared. This pod enrolls as a NetBird *routing peer* with the
|
||||
# NetBird mesh ingress — the mesh-side ingress path. This pod enrolls as
|
||||
# a NetBird *routing peer* with the
|
||||
# self-hosted management server (netbird.renner.uno) and forwards mesh
|
||||
# traffic to in-cluster services (the routes/nameservers are configured
|
||||
# NetBird-side, pointing at this peer).
|
||||
@@ -19,7 +19,7 @@
|
||||
# --own socket (socket-LB DNAT)--> service ClusterIP/LB VIP
|
||||
#
|
||||
# Egress is locked down by the netbird-ingress-egress CiliumNetworkPolicy
|
||||
# (network-policies/ingress-isolation.yaml), mirroring cloudflared.
|
||||
# (network-policies/ingress-isolation.yaml).
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
|
||||
@@ -1,49 +1,5 @@
|
||||
# Cloudflared can only reach the traefik controller pods (in-cluster
|
||||
# tunnel-to-ingress hop) plus DNS and Cloudflare's edge over UDP/7844
|
||||
# and TCP/443. Cilium's socket-LB DNATs the ClusterIP → pod IP at the
|
||||
# socket layer, so the egress policy sees the pod's container ports —
|
||||
# traefik runs on 8443/8000 internally (Service 443/TCP → targetPort
|
||||
# websecure → containerPort 8443).
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: cloudflared-to-ingress-only
|
||||
namespace: ingress
|
||||
spec:
|
||||
endpointSelector:
|
||||
matchLabels:
|
||||
app: cloudflared
|
||||
egress:
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8443"
|
||||
protocol: TCP
|
||||
- port: "8000"
|
||||
protocol: TCP
|
||||
# Allow DNS resolution
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": kube-system
|
||||
k8s-app: kube-dns
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "53"
|
||||
protocol: UDP
|
||||
# Allow Cloudflare tunnel connections (external)
|
||||
- toEntities:
|
||||
- world
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "7844"
|
||||
protocol: UDP
|
||||
- port: "443"
|
||||
protocol: TCP
|
||||
---
|
||||
# NetBird mesh-ingress routing peer: same egress-lockdown discipline as
|
||||
# cloudflared above. It may reach (a) traefik (by label selector — Cilium
|
||||
# NetBird mesh-ingress routing peer — egress lockdown. It may reach (a)
|
||||
# traefik (by label selector — Cilium
|
||||
# applies LB/DNAT before egress policy, so forwarded mesh→VIP traffic is
|
||||
# enforced on traefik's identity, no static VIP needed); (b) DNS; (c) the
|
||||
# NetBird control/data plane on netbird.renner.uno — mgmt/signal/relay
|
||||
@@ -93,8 +49,8 @@ spec:
|
||||
# Any in-cluster pod may reach traefik (required for east-west OIDC
|
||||
# flows via k8s_gateway — audiobookshelf → Authentik etc.); we don't
|
||||
# enumerate namespaces, which would require policy edits every time a
|
||||
# new app lands. External entry is still bounded by the
|
||||
# Cloudflare-proxied / MetalLB / host probe paths.
|
||||
# new app lands. External entry is now via the NetBird reverse proxy
|
||||
# (over the mesh) and the BGP-advertised LB VIP / host probe paths.
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
|
||||
Reference in New Issue
Block a user