From 24bcf21117ff4c77dd182fa45c056e4767b07c56 Mon Sep 17 00:00:00 2001 From: Diego Caspi Date: Mon, 22 Dec 2025 11:32:01 +0100 Subject: [PATCH 1/5] chore(k8s): support cert-manager Signed-off-by: Diego Caspi --- .../cert-manager/app/clusterissuer.yaml | 20 +++++++++++++ .../cert-manager/app/externalsecret.yaml | 18 ++++++++++++ .../cert-manager/app/helmrelease.yaml | 24 ++++++++++++++++ .../cert-manager/app/kustomization.yaml | 9 ++++++ .../cert-manager/app/ocirepository.yaml | 14 ++++++++++ .../apps/cert-manager/cert-manager/ks.yaml | 28 +++++++++++++++++++ .../apps/cert-manager/kustomization.yaml | 11 ++++++++ 7 files changed, 124 insertions(+) create mode 100644 kubernetes/apps/cert-manager/cert-manager/app/clusterissuer.yaml create mode 100644 kubernetes/apps/cert-manager/cert-manager/app/externalsecret.yaml create mode 100644 kubernetes/apps/cert-manager/cert-manager/app/helmrelease.yaml create mode 100644 kubernetes/apps/cert-manager/cert-manager/app/kustomization.yaml create mode 100644 kubernetes/apps/cert-manager/cert-manager/app/ocirepository.yaml create mode 100644 kubernetes/apps/cert-manager/cert-manager/ks.yaml create mode 100644 kubernetes/apps/cert-manager/kustomization.yaml diff --git a/kubernetes/apps/cert-manager/cert-manager/app/clusterissuer.yaml b/kubernetes/apps/cert-manager/cert-manager/app/clusterissuer.yaml new file mode 100644 index 0000000..efee552 --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/clusterissuer.yaml @@ -0,0 +1,20 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/clusterissuer_v1.json +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-production +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: letsencrypt-production + solvers: + - dns01: + cloudflare: + apiTokenSecretRef: + name: cloudflare-issuer-secret + key: CLOUDFLARE_DNS_TOKEN + selector: + dnsZones: + - dcaspi.dev diff --git a/kubernetes/apps/cert-manager/cert-manager/app/externalsecret.yaml b/kubernetes/apps/cert-manager/cert-manager/app/externalsecret.yaml new file mode 100644 index 0000000..f0ae629 --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/externalsecret.yaml @@ -0,0 +1,18 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: cloudflare-issuer +spec: + secretStoreRef: + kind: ClusterSecretStore + name: onepassword + target: + name: cloudflare-issuer-secret + template: + data: + CLOUDFLARE_DNS_TOKEN: "{{ .CLOUDFLARE_DNS_TOKEN }}" + dataFrom: + - extract: + key: cloudflare diff --git a/kubernetes/apps/cert-manager/cert-manager/app/helmrelease.yaml b/kubernetes/apps/cert-manager/cert-manager/app/helmrelease.yaml new file mode 100644 index 0000000..1ec4fb4 --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/helmrelease.yaml @@ -0,0 +1,24 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: cert-manager +spec: + chartRef: + kind: OCIRepository + name: cert-manager + interval: 1h + values: + crds: + enabled: true + dns01RecursiveNameservers: https://1.1.1.1:443/dns-query,https://1.0.0.1:443/dns-query + dns01RecursiveNameserversOnly: true + prometheus: + enabled: true + servicemonitor: + enabled: true + webhook: + replicaCount: 2 + podDisruptionBudget: + enabled: true diff --git a/kubernetes/apps/cert-manager/cert-manager/app/kustomization.yaml b/kubernetes/apps/cert-manager/cert-manager/app/kustomization.yaml new file mode 100644 index 0000000..152decb --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/kustomization.yaml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./clusterissuer.yaml + - ./externalsecret.yaml + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/cert-manager/cert-manager/app/ocirepository.yaml b/kubernetes/apps/cert-manager/cert-manager/app/ocirepository.yaml new file mode 100644 index 0000000..f6fb09a --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/ocirepository.yaml @@ -0,0 +1,14 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: cert-manager +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: v1.19.2 + url: oci://quay.io/jetstack/charts/cert-manager diff --git a/kubernetes/apps/cert-manager/cert-manager/ks.yaml b/kubernetes/apps/cert-manager/cert-manager/ks.yaml new file mode 100644 index 0000000..13202f0 --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/ks.yaml @@ -0,0 +1,28 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cert-manager +spec: + healthChecks: + - apiVersion: helm.toolkit.fluxcd.io/v2 + kind: HelmRelease + name: cert-manager + namespace: cert-manager + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + name: letsencrypt-production + healthCheckExprs: + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + failed: status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'False') + current: status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'True') + interval: 1h + path: ./kubernetes/apps/cert-manager/cert-manager/app + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: cert-manager diff --git a/kubernetes/apps/cert-manager/kustomization.yaml b/kubernetes/apps/cert-manager/kustomization.yaml new file mode 100644 index 0000000..6d82902 --- /dev/null +++ b/kubernetes/apps/cert-manager/kustomization.yaml @@ -0,0 +1,11 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: cert-manager + +components: + - ../../components/namespace + +resources: + - envoy-gateway/ks.yaml From 3d71bb0f60d20ec4b8e3c113a2a600aa63cfff29 Mon Sep 17 00:00:00 2001 From: Diego Caspi Date: Mon, 22 Dec 2025 11:32:23 +0100 Subject: [PATCH 2/5] chore(k8s): support network cluodflare-dns Signed-off-by: Diego Caspi --- .../cloudflare-dns/app/externalsecret.yaml | 19 ++++++++ .../cloudflare-dns/app/helmrelease.yaml | 46 +++++++++++++++++++ .../cloudflare-dns/app/kustomization.yaml | 9 ++++ .../cloudflare-dns/app/ocirepository.yaml | 14 ++++++ .../apps/network/cloudflare-dns/ks.yaml | 23 ++++++++++ 5 files changed, 111 insertions(+) create mode 100644 kubernetes/apps/network/cloudflare-dns/app/externalsecret.yaml create mode 100644 kubernetes/apps/network/cloudflare-dns/app/helmrelease.yaml create mode 100644 kubernetes/apps/network/cloudflare-dns/app/kustomization.yaml create mode 100644 kubernetes/apps/network/cloudflare-dns/app/ocirepository.yaml create mode 100644 kubernetes/apps/network/cloudflare-dns/ks.yaml diff --git a/kubernetes/apps/network/cloudflare-dns/app/externalsecret.yaml b/kubernetes/apps/network/cloudflare-dns/app/externalsecret.yaml new file mode 100644 index 0000000..f662b11 --- /dev/null +++ b/kubernetes/apps/network/cloudflare-dns/app/externalsecret.yaml @@ -0,0 +1,19 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: cloudflare-dns +spec: + secretStoreRef: + kind: ClusterSecretStore + name: onepassword + target: + name: cloudflare-dns-secret + template: + data: + CF_API_TOKEN: "{{ .CLOUDFLARE_DNS_TOKEN }}" + CF_ZONE_ID: "{{ .CLOUDFLARE_ZONE_ID }}" + dataFrom: + - extract: + key: cloudflare diff --git a/kubernetes/apps/network/cloudflare-dns/app/helmrelease.yaml b/kubernetes/apps/network/cloudflare-dns/app/helmrelease.yaml new file mode 100644 index 0000000..0f8dbbd --- /dev/null +++ b/kubernetes/apps/network/cloudflare-dns/app/helmrelease.yaml @@ -0,0 +1,46 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: &app cloudflare-dns +spec: + chartRef: + kind: OCIRepository + name: cloudflare-dns + interval: 1h + values: + fullnameOverride: *app + provider: + name: cloudflare + env: + - name: &name CF_API_TOKEN + valueFrom: + secretKeyRef: + name: &secret cloudflare-dns-secret + key: *name + - name: &name CF_ZONE_ID + valueFrom: + secretKeyRef: + name: *secret + key: *name + extraArgs: + - --cloudflare-dns-records-per-page=1000 + - --cloudflare-proxied + - --crd-source-apiversion=externaldns.k8s.io/v1alpha1 + - --crd-source-kind=DNSEndpoint + - --gateway-name=envoy-external + - --zone-id-filter=$(CF_ZONE_ID) + triggerLoopOnEvent: true + policy: sync + sources: + - crd + - gateway-httproute + txtOwnerId: default + txtPrefix: k8s. + domainFilters: + - turbo.ac + serviceMonitor: + enabled: true + podAnnotations: + secret.reloader.stakater.com/reload: *secret diff --git a/kubernetes/apps/network/cloudflare-dns/app/kustomization.yaml b/kubernetes/apps/network/cloudflare-dns/app/kustomization.yaml new file mode 100644 index 0000000..12fa436 --- /dev/null +++ b/kubernetes/apps/network/cloudflare-dns/app/kustomization.yaml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ./externalsecret.yaml + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/network/cloudflare-dns/app/ocirepository.yaml b/kubernetes/apps/network/cloudflare-dns/app/ocirepository.yaml new file mode 100644 index 0000000..55a3d3c --- /dev/null +++ b/kubernetes/apps/network/cloudflare-dns/app/ocirepository.yaml @@ -0,0 +1,14 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: cloudflare-dns +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 1.19.0 + url: oci://ghcr.io/home-operations/charts-mirror/external-dns diff --git a/kubernetes/apps/network/cloudflare-dns/ks.yaml b/kubernetes/apps/network/cloudflare-dns/ks.yaml new file mode 100644 index 0000000..278534c --- /dev/null +++ b/kubernetes/apps/network/cloudflare-dns/ks.yaml @@ -0,0 +1,23 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cloudflare-dns +spec: + healthChecks: + - apiVersion: helm.toolkit.fluxcd.io/v2 + kind: HelmRelease + name: cloudflare-dns + namespace: network + - apiVersion: apiextensions.k8s.io/v1 + kind: CustomResourceDefinition + name: dnsendpoints.externaldns.k8s.io + interval: 1h + path: ./kubernetes/apps/network/cloudflare-dns/app + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: network From 310258c234238310784fc800b24cae6a87c6a5f0 Mon Sep 17 00:00:00 2001 From: Diego Caspi Date: Mon, 22 Dec 2025 11:32:33 +0100 Subject: [PATCH 3/5] chore(k8s): support cloudflare-tunnel Signed-off-by: Diego Caspi --- .../cloudflare-tunnel/app/dnsendpoint.yaml | 11 +++ .../cloudflare-tunnel/app/externalsecret.yaml | 19 ++++ .../cloudflare-tunnel/app/helmrelease.yaml | 88 +++++++++++++++++++ .../cloudflare-tunnel/app/kustomization.yaml | 9 ++ .../cloudflare-tunnel/app/ocirepository.yaml | 14 +++ .../apps/network/cloudflare-tunnel/ks.yaml | 20 +++++ 6 files changed, 161 insertions(+) create mode 100644 kubernetes/apps/network/cloudflare-tunnel/app/dnsendpoint.yaml create mode 100644 kubernetes/apps/network/cloudflare-tunnel/app/externalsecret.yaml create mode 100644 kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml create mode 100644 kubernetes/apps/network/cloudflare-tunnel/app/kustomization.yaml create mode 100644 kubernetes/apps/network/cloudflare-tunnel/app/ocirepository.yaml create mode 100644 kubernetes/apps/network/cloudflare-tunnel/ks.yaml diff --git a/kubernetes/apps/network/cloudflare-tunnel/app/dnsendpoint.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/dnsendpoint.yaml new file mode 100644 index 0000000..206750b --- /dev/null +++ b/kubernetes/apps/network/cloudflare-tunnel/app/dnsendpoint.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: externaldns.k8s.io/v1alpha1 +kind: DNSEndpoint +metadata: + name: cloudflare-tunnel +spec: + endpoints: + - dnsName: external.dcaspi.dev + recordType: CNAME + targets: + - ${CLOUDFLARE_TUNNEL_ID}.cfargotunnel.com diff --git a/kubernetes/apps/network/cloudflare-tunnel/app/externalsecret.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/externalsecret.yaml new file mode 100644 index 0000000..a45f668 --- /dev/null +++ b/kubernetes/apps/network/cloudflare-tunnel/app/externalsecret.yaml @@ -0,0 +1,19 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: cloudflare-tunnel +spec: + secretStoreRef: + kind: ClusterSecretStore + name: onepassword + target: + name: cloudflare-tunnel-secret + template: + data: + TUNNEL_TOKEN: |- + {{ toJson (dict "a" .CLOUDFLARE_ACCOUNT_TAG "t" .CLOUDFLARE_TUNNEL_ID "s" .CLOUDFLARE_TUNNEL_SECRET) | b64enc }} + dataFrom: + - extract: + key: cloudflare diff --git a/kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml new file mode 100644 index 0000000..da068ea --- /dev/null +++ b/kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml @@ -0,0 +1,88 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: cloudflare-tunnel +spec: + chartRef: + kind: OCIRepository + name: cloudflare-tunnel + interval: 1h + values: + controllers: + cloudflare-tunnel: + replicas: 1 + strategy: RollingUpdate + annotations: + reloader.stakater.com/auto: "true" + containers: + app: + image: + repository: mirror.gcr.io/cloudflare/cloudflared + tag: 2025.11.1@sha256:89ee50efb1e9cb2ae30281a8a404fed95eb8f02f0a972617526f8c5b417acae2 + env: + NO_AUTOUPDATE: true + TUNNEL_METRICS: 0.0.0.0:8080 + TUNNEL_POST_QUANTUM: true # disable when using http2 + TUNNEL_TRANSPORT_PROTOCOL: quic # http2 + envFrom: + - secretRef: + name: "{{ .Release.Name }}-secret" + args: + - tunnel + - run + probes: + liveness: &probes + enabled: true + custom: true + spec: + httpGet: + path: /ready + port: &port 8080 + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: *probes + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: { drop: ["ALL"] } + resources: + requests: + cpu: 10m + limits: + memory: 256Mi + defaultPodOptions: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + service: + app: + ports: + http: + port: *port + serviceMonitor: + app: + endpoints: + - port: http + configMaps: + config: + data: + config.yaml: |- + ingress: + - hostname: "*.dcaspi.dev" + originRequest: + http2Origin: true + originServerName: external.dcaspi.dev + service: https://envoy-external.{{ .Release.Namespace }}.svc.cluster.local:443 + - service: http_status:404 + persistence: + config-file: + type: configMap + identifier: config + globalMounts: + - path: /etc/cloudflared/config.yaml + subPath: config.yaml diff --git a/kubernetes/apps/network/cloudflare-tunnel/app/kustomization.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/kustomization.yaml new file mode 100644 index 0000000..9040900 --- /dev/null +++ b/kubernetes/apps/network/cloudflare-tunnel/app/kustomization.yaml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./externalsecret.yaml + - ./dnsendpoint.yaml + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/network/cloudflare-tunnel/app/ocirepository.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/ocirepository.yaml new file mode 100644 index 0000000..a8f0140 --- /dev/null +++ b/kubernetes/apps/network/cloudflare-tunnel/app/ocirepository.yaml @@ -0,0 +1,14 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: cloudflare-tunnel +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 4.5.0 + url: oci://ghcr.io/bjw-s-labs/helm/app-template diff --git a/kubernetes/apps/network/cloudflare-tunnel/ks.yaml b/kubernetes/apps/network/cloudflare-tunnel/ks.yaml new file mode 100644 index 0000000..393b42b --- /dev/null +++ b/kubernetes/apps/network/cloudflare-tunnel/ks.yaml @@ -0,0 +1,20 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cloudflare-tunnel +spec: + interval: 1h + path: ./kubernetes/apps/network/cloudflare-tunnel/app + postBuild: + substituteFrom: + - kind: Secret + name: cloudflare-tunnel-id-secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: network + wait: false From a5c5c919bad81ef5d60b46154b60fa6b5cd47415 Mon Sep 17 00:00:00 2001 From: Diego Caspi Date: Mon, 22 Dec 2025 11:32:49 +0100 Subject: [PATCH 4/5] chore(k8s): network envoy gateway Signed-off-by: Diego Caspi --- .../apps/network/envoy-gateway/app/envoy.yaml | 180 ++++++++++++++++++ .../envoy-gateway/app/helmrelease.yaml | 23 +++ .../envoy-gateway/app/kustomization.yaml | 9 + .../envoy-gateway/app/ocirepository.yaml | 14 ++ kubernetes/apps/network/envoy-gateway/ks.yaml | 18 ++ 5 files changed, 244 insertions(+) create mode 100644 kubernetes/apps/network/envoy-gateway/app/envoy.yaml create mode 100644 kubernetes/apps/network/envoy-gateway/app/helmrelease.yaml create mode 100644 kubernetes/apps/network/envoy-gateway/app/kustomization.yaml create mode 100644 kubernetes/apps/network/envoy-gateway/app/ocirepository.yaml create mode 100644 kubernetes/apps/network/envoy-gateway/ks.yaml diff --git a/kubernetes/apps/network/envoy-gateway/app/envoy.yaml b/kubernetes/apps/network/envoy-gateway/app/envoy.yaml new file mode 100644 index 0000000..f166d0d --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/envoy.yaml @@ -0,0 +1,180 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.envoyproxy.io/envoyproxy_v1alpha1.json +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyProxy +metadata: + name: envoy +spec: + logging: + level: + default: info + provider: + type: Kubernetes + kubernetes: + envoyDeployment: + replicas: 1 + container: + imageRepository: mirror.gcr.io/envoyproxy/envoy + resources: + requests: + cpu: 100m + limits: + memory: 1Gi + envoyService: + externalTrafficPolicy: Local + shutdown: + drainTimeout: 180s + telemetry: + metrics: + prometheus: + compression: + type: Gzip + +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/gatewayclass_v1.json +apiVersion: gateway.networking.k8s.io/v1 +kind: GatewayClass +metadata: + name: envoy +spec: + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: envoy + namespace: network + +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/gateway_v1.json +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: envoy-external + annotations: + external-dns.alpha.kubernetes.io/target: &hostname external.dcaspi.dev +spec: + gatewayClassName: envoy + infrastructure: + annotations: + external-dns.alpha.kubernetes.io/hostname: *hostname + # lbipam.cilium.io/ips: 192.168.69.126 + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + - name: https + protocol: HTTPS + port: 443 + allowedRoutes: + namespaces: + from: All + tls: + certificateRefs: + - kind: Secret + name: dcaspi-dev-tls + +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.envoyproxy.io/envoypatchpolicy_v1alpha1.json +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyPatchPolicy +metadata: + name: envoy-external +spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: envoy-external + type: JSONPatch + jsonPatches: + - type: type.googleapis.com/envoy.config.listener.v3.Listener + name: network/envoy-external/https + operation: &operation + op: add + jsonPath: ..filters[*].typed_config.http_filters[?(@.name=="envoy.filters.http.compressor.zstd")].typed_config + value: + "@type": type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor + choose_first: true + compressor_library: + name: envoy.compression.zstd.compressor + typed_config: + "@type": type.googleapis.com/envoy.extensions.compression.zstd.compressor.v3.Zstd + response_direction_config: + remove_accept_encoding_header: true + - type: type.googleapis.com/envoy.config.listener.v3.Listener + name: network/envoy-external/https-quic + operation: *operation + +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.envoyproxy.io/clienttrafficpolicy_v1alpha1.json +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: ClientTrafficPolicy +metadata: + name: envoy +spec: + clientIPDetection: + xForwardedFor: + numTrustedHops: 1 + connection: + bufferLimit: 8Mi + maxAcceptPerSocketEvent: 0 + http2: + initialStreamWindowSize: 2Mi + initialConnectionWindowSize: 32Mi + onInvalidMessage: TerminateStream + http3: {} + targetSelectors: + - group: gateway.networking.k8s.io + kind: Gateway + tcpKeepalive: {} + timeout: + http: + requestReceivedTimeout: 0s + tls: + minVersion: "1.2" + alpnProtocols: + - h2 + - http/1.1 + +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.envoyproxy.io/backendtrafficpolicy_v1alpha1.json +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: BackendTrafficPolicy +metadata: + name: envoy +spec: + compression: + - type: Brotli + - type: Gzip + - type: Zstd + connection: + bufferLimit: 8Mi + targetSelectors: + - group: gateway.networking.k8s.io + kind: Gateway + tcpKeepalive: {} + timeout: + http: + requestTimeout: 0s + +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: https-redirect + annotations: + external-dns.alpha.kubernetes.io/controller: none +spec: + parentRefs: + - name: envoy-external + namespace: network + sectionName: http + rules: + - filters: + - type: RequestRedirect + requestRedirect: + scheme: https + statusCode: 301 diff --git a/kubernetes/apps/network/envoy-gateway/app/helmrelease.yaml b/kubernetes/apps/network/envoy-gateway/app/helmrelease.yaml new file mode 100644 index 0000000..0daaac2 --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/helmrelease.yaml @@ -0,0 +1,23 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: envoy-gateway +spec: + chartRef: + kind: OCIRepository + name: envoy-gateway + interval: 1h + values: + global: + imageRegistry: mirror.gcr.io + config: + envoyGateway: + extensionApis: + enableEnvoyPatchPolicy: true + provider: + type: Kubernetes + kubernetes: + deploy: + type: GatewayNamespace diff --git a/kubernetes/apps/network/envoy-gateway/app/kustomization.yaml b/kubernetes/apps/network/envoy-gateway/app/kustomization.yaml new file mode 100644 index 0000000..7be660f --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/kustomization.yaml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - helmrelease.yaml + - ocirepository.yaml + - envoy.yaml diff --git a/kubernetes/apps/network/envoy-gateway/app/ocirepository.yaml b/kubernetes/apps/network/envoy-gateway/app/ocirepository.yaml new file mode 100644 index 0000000..7e283fe --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/ocirepository.yaml @@ -0,0 +1,14 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: envoy-gateway +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: v1.6.1 + url: oci://mirror.gcr.io/envoyproxy/gateway-helm diff --git a/kubernetes/apps/network/envoy-gateway/ks.yaml b/kubernetes/apps/network/envoy-gateway/ks.yaml new file mode 100644 index 0000000..924901f --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/ks.yaml @@ -0,0 +1,18 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: envoy-gateway +spec: + dependsOn: + - name: certificates-import + interval: 1h + path: ./kubernetes/apps/network/envoy-gateway/app + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: network + wait: false From c1eb53a8ad53427a22799c82bb3621bbdd2e50ea Mon Sep 17 00:00:00 2001 From: Diego Caspi Date: Mon, 22 Dec 2025 11:33:02 +0100 Subject: [PATCH 5/5] chore(k8s): network certificates Signed-off-by: Diego Caspi --- .../certificates/export/certificate.yaml | 27 ++++++++++++++++++ .../certificates/export/kustomization.yaml | 7 +++++ .../certificates/export/pushsecret.yaml | 28 +++++++++++++++++++ kubernetes/apps/network/certificates/ks.yaml | 16 +++++++++++ kubernetes/apps/network/kustomization.yaml | 14 ++++++++++ 5 files changed, 92 insertions(+) create mode 100644 kubernetes/apps/network/certificates/export/certificate.yaml create mode 100644 kubernetes/apps/network/certificates/export/kustomization.yaml create mode 100644 kubernetes/apps/network/certificates/export/pushsecret.yaml create mode 100644 kubernetes/apps/network/certificates/ks.yaml create mode 100644 kubernetes/apps/network/kustomization.yaml diff --git a/kubernetes/apps/network/certificates/export/certificate.yaml b/kubernetes/apps/network/certificates/export/certificate.yaml new file mode 100644 index 0000000..b43d0f8 --- /dev/null +++ b/kubernetes/apps/network/certificates/export/certificate.yaml @@ -0,0 +1,27 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: dcaspi-dev +spec: + secretName: dcaspi-dev-tls + secretTemplate: + annotations: + cert-manager.io/alt-names: "*.dcaspi.dev,dcaspi.dev" + cert-manager.io/certificate-name: dcaspi-dev + cert-manager.io/common-name: dcaspi.dev + cert-manager.io/ip-sans: "" + cert-manager.io/issuer-group: "" + cert-manager.io/issuer-kind: ClusterIssuer + cert-manager.io/issuer-name: letsencrypt-production + cert-manager.io/uri-sans: "" + labels: + controller.cert-manager.io/fao: "true" + issuerRef: + name: letsencrypt-production + kind: ClusterIssuer + commonName: dcaspi.dev + dnsNames: + - dcaspi.dev + - "*.dcaspi.dev" diff --git a/kubernetes/apps/network/certificates/export/kustomization.yaml b/kubernetes/apps/network/certificates/export/kustomization.yaml new file mode 100644 index 0000000..c0dc5ac --- /dev/null +++ b/kubernetes/apps/network/certificates/export/kustomization.yaml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - certificate.yaml diff --git a/kubernetes/apps/network/certificates/export/pushsecret.yaml b/kubernetes/apps/network/certificates/export/pushsecret.yaml new file mode 100644 index 0000000..8c8d5af --- /dev/null +++ b/kubernetes/apps/network/certificates/export/pushsecret.yaml @@ -0,0 +1,28 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/pushsecret_v1alpha1.json +apiVersion: external-secrets.io/v1alpha1 +kind: PushSecret +metadata: + name: dcaspi-dev-tls +spec: + secretStoreRefs: + - name: onepassword + kind: ClusterSecretStore + selector: + secret: + name: dcaspi-dev-tls + template: + data: + tls.crt: '{{ index . "tls.crt" | b64enc }}' + tls.key: '{{ index . "tls.key" | b64enc }}' + data: + - match: + secretKey: &key tls.crt + remoteRef: + remoteKey: turbo-ac-tls + property: *key + - match: + secretKey: &key tls.key + remoteRef: + remoteKey: turbo-ac-tls + property: *key diff --git a/kubernetes/apps/network/certificates/ks.yaml b/kubernetes/apps/network/certificates/ks.yaml new file mode 100644 index 0000000..489f790 --- /dev/null +++ b/kubernetes/apps/network/certificates/ks.yaml @@ -0,0 +1,16 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: certificates-export +spec: + interval: 1h + path: ./kubernetes/apps/network/certificates/export + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: network + wait: false diff --git a/kubernetes/apps/network/kustomization.yaml b/kubernetes/apps/network/kustomization.yaml new file mode 100644 index 0000000..722f5e1 --- /dev/null +++ b/kubernetes/apps/network/kustomization.yaml @@ -0,0 +1,14 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: network + +components: + - ../../components/namespace + +resources: + - envoy-gateway/ks.yaml + - certificates/ks.yaml + - cloudflare-tunnel/ks.yaml + - cloudflare-dns/ks.yaml