--- # Yeah, I should really turn these into kustomization overlays, huh? # Sounds like problem for future me. # TODO: Turn these into kustomization overlays apiVersion: apps/v1 kind: Deployment metadata: name: cloudflared-mnke namespace: default spec: selector: matchLabels: app: cloudflared-mnke replicas: 3 template: metadata: labels: app: cloudflared-mnke spec: containers: - name: cloudflared image: cloudflare/cloudflared:2025.2.0 resources: requests: memory: "32Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m" args: - tunnel # Points cloudflared to the config file, which configures what # cloudflared will actually do. This file is created by a ConfigMap # below. - --config - /etc/cloudflared/config/config.yaml - run livenessProbe: httpGet: # Cloudflared has a /ready endpoint which returns 200 if and only if # it has an active connection to the edge. path: /ready port: 2000 failureThreshold: 1 initialDelaySeconds: 10 periodSeconds: 10 volumeMounts: - name: config mountPath: /etc/cloudflared/config readOnly: true # Each tunnel has an associated "credentials file" which authorizes machines # to run the tunnel. cloudflared will read this file from its local filesystem, # and it'll be stored in a k8s secret. - name: creds mountPath: /etc/cloudflared/creds readOnly: true volumes: - name: creds secret: secretName: cf-tunnel-creds-mnke # Create a config.yaml file from the ConfigMap below. - name: config configMap: name: cloudflared-mnke namespace: default items: - key: config.yaml path: config.yaml --- apiVersion: v1 kind: ConfigMap metadata: name: cloudflared-mnke namespace: default data: config.yaml: | # Name of the tunnel you want to run tunnel: f0c5cab9-409e-4c9d-b89d-91a1fd6b507a credentials-file: /etc/cloudflared/creds/credentials.json # Serves the metrics server under /metrics and the readiness server under /ready metrics: 0.0.0.0:2000 # Autoupdates applied in a k8s pod will be lost when the pod is removed or restarted, so # autoupdate doesn't make sense in Kubernetes. However, outside of Kubernetes, we strongly # recommend using autoupdate. no-autoupdate: true ingress: # - hostname: blog.mnke.org # service: https://traefik.traefik.svc.cluster.local # originRequest: # Any hosts connecting to the traefik.traefik.svc.cluster.local service # will always present the default traefik cert to cloudflared, which # will be rejected. While we could just set the service to # https://blog.mnke.org and resolve the domain internally to the traefik # LB so the TLS certificate that's presented is the right one, this # means we add an extra dependency on the DNS server at this step and # also the domain resolves to the LB IP, possibly making the pod route # out of the cluster rather than internally. # # We could also split DNS here using a sidecar and have a CNAME from # blog.mnke.org to the traefik service domain (or otherwise make them # resolve the same), but managing LAN DNS records, public DNS records, # and then DNS records here sounds like too much trouble to maintain. # # Maybe it can be easier to manage? [This thread](https://www.reddit.com/r/kubernetes/comments/z2vogg/cloudflare_and_ingressnginx/) # hints at it, but I haven't looked into it too deeply yet. # # Disabling the TLS verification right now seems fine enough # noTLSVerify: true # http2Origin: true # httpHostHeader: blog.mnke.org # Nah, screw it. It's at most like one extra hop away for a much cleaner # configuration. I'm leaving those comments in so I don't forget about this # though. - hostname: blog.mnke.org service: https://blog.mnke.org - hostname: media.mnke.org service: https://media.mnke.org - hostname: up.mnke.org service: https://up.mnke.org - hostname: panel.mnke.org service: https://panel.mnke.org - hostname: vault.mnke.org service: https://vault.mnke.org - hostname: authentik.mnke.org service: https://authentik.mnke.org - hostname: nc.mnke.org service: https://nc.mnke.org - hostname: clotho_moirai.mnke.org service: https://clotho_moirai.mnke.org - hostname: lachesis_moirai.mnke.org service: https://lachesis_moirai.mnke.org - hostname: atropos_moirai.mnke.org service: https://atropos_moirai.mnke.org # This rule matches any traffic which didn't match a previous rule, and responds with HTTP 404. - service: http_status:404 --- apiVersion: v1 kind: Service metadata: name: cloudflared-mnke-metrics namespace: default labels: app: cloudflared-mnke spec: ports: - name: metrics port: 80 protocol: TCP targetPort: 2000 selector: app: cloudflared-mnke --- apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: cloudflared-mnke-metrics namespace: default labels: release: kube-prometheus-stack spec: jobLabel: cloudflared-mnke-metrics selector: matchLabels: app: cloudflared-mnke endpoints: - interval: 30s port: metrics path: /metrics