Skip to content

feat(networking): Add Envoy Gateway with Gateway API support#2644

Open
dapperdivers wants to merge 2 commits intomainfrom
feat/envoy-gateway-migration
Open

feat(networking): Add Envoy Gateway with Gateway API support#2644
dapperdivers wants to merge 2 commits intomainfrom
feat/envoy-gateway-migration

Conversation

@dapperdivers
Copy link
Owner

🚀 Migration to Envoy Gateway & Gateway API

This PR adds Envoy Gateway v1.0.1 deployment using the Gateway API standard, providing a modern, vendor-neutral alternative to nginx Ingress.

📦 What's Included

Infrastructure Components

  • Envoy Gateway Controller (v1.0.1) deployed via Helm
  • Two GatewayClasses:
    • external-envoy: Public traffic (Cilium LB: 192.168.1.240)
    • internal-envoy: Cluster-internal traffic (Cilium LB: 192.168.1.241)
  • Two Gateways:
    • external-gateway: HTTPS (443) + HTTP (80) with TLS termination
    • internal-gateway: Same pattern for internal services

Application Routes

  • HTTPRoute for derekmackley.com (replaces existing nginx Ingress)
    • Hostnames: derekmackley.com, www.derekmackley.com, resume.derekmackley.com
    • Backend: resume:8080 in selfhosted namespace
    • Security headers included
    • HTTP → HTTPS redirects

Integrations

  • cert-manager: Automatic TLS certificates via Let's Encrypt
  • external-dns: Automatic DNS record creation
  • Cilium LoadBalancer: L2 IPAM with fixed IPs
  • 🔜 Authentik SSO: SecurityPolicy example included (optional)

📊 Resource Allocation

Component Replicas CPU Request CPU Limit Memory Request Memory Limit
Gateway Controller 1 100m 500m 128Mi 512Mi
External Proxy 2 200m 1000m 256Mi 1Gi
Internal Proxy 1 100m 500m 128Mi 512Mi
Total 4 pods 400m 2000m 512Mi 2Gi

🎯 Benefits of Gateway API

  1. Separation of Concerns: Infrastructure (Gateway) vs Application routing (HTTPRoute)
  2. Native Features: Traffic splitting, header manipulation, redirects without annotations
  3. Vendor Neutral: Portable across Envoy, Kong, HAProxy, etc.
  4. Better Multi-tenancy: Fine-grained RBAC per namespace/route
  5. Future-proof: Kubernetes SIG standard, supported by all major vendors

📋 Prerequisites

Before merging, verify:

  • Gateway API CRDs v1.0.0 installed (see deployment steps)
  • cert-manager ClusterIssuer named letsencrypt-production exists
  • external-dns configured to watch gateway-httproute source
  • Cilium LoadBalancer IP pool includes 192.168.1.240-241
  • Resume service exists: kubectl get svc -n selfhosted resume

🚀 Deployment Steps

  1. Install Gateway API CRDs (required first):

    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
  2. Merge this PR - Flux will reconcile automatically

  3. Monitor deployment:

    # Watch Envoy Gateway controller
    kubectl get pods -n envoy-gateway-system -w
    
    # Check GatewayClasses
    kubectl get gatewayclass
    
    # Check Gateways
    kubectl get gateway -n gateway-system
    
    # Check HTTPRoutes
    kubectl get httproute -n selfhosted
  4. Verify LoadBalancer IPs:

    kubectl get svc -n envoy-gateway-system
  5. Test HTTPS access:

    curl -v https://derekmackley.com
    curl -v https://resume.derekmackley.com

🔄 Migration from nginx Ingress

Both can run simultaneously! The new Envoy Gateway will get a different LoadBalancer IP.

  1. Deploy Envoy Gateway (this PR)
  2. Test thoroughly with new Gateway
  3. Update DNS to point to new LoadBalancer IP (192.168.1.240)
  4. Verify traffic flows correctly
  5. Delete old nginx Ingress when ready

📚 Documentation

  • Complete deployment guide: kubernetes/apps/network/external/envoy-gateway/app/README.md
  • Includes troubleshooting, advanced features, and Authentik SSO setup

🔐 Optional: Authentik SSO

A SecurityPolicy example is included but commented out in kustomization.yaml. To enable:

  1. Deploy Authentik with Envoy provider outpost
  2. Uncomment securitypolicy-authentik-example.yaml in kustomization
  3. Apply - all routes through the Gateway will require authentication

🎨 Files Added

kubernetes/apps/network/external/envoy-gateway/
├── app/
│   ├── README.md                                # Full documentation
│   ├── helmrelease.yaml                         # Envoy Gateway + GatewayClasses
│   ├── gateway-external.yaml                    # External Gateway + Certificate
│   ├── gateway-internal.yaml                    # Internal Gateway + Certificate
│   ├── httproute-resume.yaml                    # derekmackley.com routing
│   ├── kustomization.yaml                       # Resource list
│   └── securitypolicy-authentik-example.yaml    # Optional SSO
└── ks.yaml                                      # Flux Kustomization

Note: This PR does NOT remove the existing nginx Ingress. That can be done separately after testing.

cc @dapperdivers

- Add Envoy Gateway v1.0.1 deployment using Gateway API
- Create two GatewayClasses: external-envoy and internal-envoy
- Configure external Gateway for public traffic (HTTPS + TLS)
- Configure internal Gateway for cluster-internal traffic
- Add HTTPRoute for derekmackley.com (replaces nginx Ingress)
  - Routes: derekmackley.com, www.derekmackley.com, resume.derekmackley.com
  - Backend: resume service (port 8080) in selfhosted namespace
- Integrate with cert-manager for automatic TLS certificates
- Integrate with external-dns for automatic DNS records
- Use Cilium L2 LoadBalancer with fixed IPs (192.168.1.240-241)
- Add SecurityPolicy example for future Authentik SSO integration
- Resource allocation: 400m-2000m CPU, 512Mi-2Gi RAM

Gateway API brings:
- Separation of concerns (infrastructure vs application routing)
- Native traffic splitting, header manipulation, and redirects
- Vendor-neutral, standardized API
- Better multi-tenancy and RBAC support

Documentation included in app/README.md
@dunce-bot
Copy link
Contributor

dunce-bot bot commented Mar 13, 2026

--- kubernetes/apps Kustomization: flux-system/cluster-apps Kustomization: network/envoy-gateway

+++ kubernetes/apps Kustomization: flux-system/cluster-apps Kustomization: network/envoy-gateway

@@ -0,0 +1,61 @@

+---
+apiVersion: kustomize.toolkit.fluxcd.io/v1
+kind: Kustomization
+metadata:
+  labels:
+    kustomize.toolkit.fluxcd.io/name: cluster-apps
+    kustomize.toolkit.fluxcd.io/namespace: flux-system
+  name: envoy-gateway
+  namespace: network
+spec:
+  commonMetadata:
+    labels:
+      app.kubernetes.io/name: envoy-gateway
+  decryption:
+    provider: sops
+    secretRef:
+      name: sops-age
+  deletionPolicy: WaitForTermination
+  dependsOn:
+  - name: cert-manager-tls
+    namespace: cert-manager
+  interval: 30m
+  patches:
+  - patch: |-
+      apiVersion: helm.toolkit.fluxcd.io/v2
+      kind: HelmRelease
+      metadata:
+        name: not-used
+      spec:
+        install:
+          crds: CreateReplace
+          remediation:
+            retries: 3
+        upgrade:
+          cleanupOnFail: true
+          crds: CreateReplace
+          remediation:
+            strategy: rollback
+            retries: 3
+    target:
+      group: helm.toolkit.fluxcd.io
+      kind: HelmRelease
+  path: ./kubernetes/apps/network/external/envoy-gateway/app
+  postBuild:
+    substitute:
+      SECRET_DOMAIN_PERSONAL: derekmackley.com
+    substituteFrom:
+    - kind: ConfigMap
+      name: cluster-settings
+    - kind: Secret
+      name: cluster-secrets
+  prune: true
+  retryInterval: 1m
+  sourceRef:
+    kind: GitRepository
+    name: flux-system
+    namespace: flux-system
+  targetNamespace: envoy-gateway-system
+  timeout: 5m
+  wait: false
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HelmRelease: envoy-gateway-system/envoy-gateway

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HelmRelease: envoy-gateway-system/envoy-gateway

@@ -0,0 +1,73 @@

+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: envoy-gateway
+  namespace: envoy-gateway-system
+spec:
+  chart:
+    spec:
+      chart: gateway-helm
+      interval: 12h
+      sourceRef:
+        kind: HelmRepository
+        name: envoy-gateway
+        namespace: flux-system
+      version: v1.0.1
+  install:
+    crds: CreateReplace
+    createNamespace: true
+    remediation:
+      retries: 3
+  interval: 30m
+  upgrade:
+    cleanupOnFail: true
+    crds: CreateReplace
+    remediation:
+      retries: 3
+      strategy: rollback
+  values:
+    config:
+      envoyGateway:
+        extensionManager:
+          resources:
+            limits:
+              cpu: 100m
+              memory: 128Mi
+            requests:
+              cpu: 50m
+              memory: 64Mi
+        gateway:
+          controllerName: gateway.envoyproxy.io/gatewayclass-controller
+        logging:
+          level:
+            default: info
+        provider:
+          kubernetes:
+            watch:
+              namespaces: []
+              type: Namespaces
+          type: Kubernetes
+    deployment:
+      replicas: 1
+      resources:
+        limits:
+          cpu: 500m
+          memory: 512Mi
+        requests:
+          cpu: 100m
+          memory: 128Mi
+    rbac:
+      create: true
+    service:
+      annotations:
+        prometheus.io/port: '8080'
+        prometheus.io/scrape: 'true'
+    serviceAccount:
+      create: true
+      name: envoy-gateway
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HelmRepository: envoy-gateway-system/envoy-gateway

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HelmRepository: envoy-gateway-system/envoy-gateway

@@ -0,0 +1,14 @@

+---
+apiVersion: source.toolkit.fluxcd.io/v1beta2
+kind: HelmRepository
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: envoy-gateway
+  namespace: envoy-gateway-system
+spec:
+  interval: 24h
+  url: https://gateway.envoyproxy.io
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway EnvoyProxy: envoy-gateway-system/external-proxy-config

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway EnvoyProxy: envoy-gateway-system/external-proxy-config

@@ -0,0 +1,39 @@

+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: external-proxy-config
+  namespace: envoy-gateway-system
+spec:
+  provider:
+    kubernetes:
+      envoyDeployment:
+        pod:
+          annotations:
+            prometheus.io/port: '19001'
+            prometheus.io/scrape: 'true'
+          labels:
+            gateway-type: external
+          resources:
+            limits:
+              cpu: 1000m
+              memory: 1Gi
+            requests:
+              cpu: 200m
+              memory: 256Mi
+        replicas: 2
+      envoyService:
+        annotations:
+          external-dns.alpha.kubernetes.io/hostname: gateway...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..
+          io.cilium/lb-ipam-ips: 192.168.1.240
+        type: LoadBalancer
+    type: Kubernetes
+  telemetry:
+    metrics:
+      prometheus:
+        disable: false
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway GatewayClass: envoy-gateway-system/external-envoy

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway GatewayClass: envoy-gateway-system/external-envoy

@@ -0,0 +1,19 @@

+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: external-envoy
+  namespace: envoy-gateway-system
+spec:
+  controllerName: gateway.envoyproxy.io/gatewayclass-controller
+  description: GatewayClass for external-facing traffic (Envoy Gateway)
+  parametersRef:
+    group: gateway.envoyproxy.io
+    kind: EnvoyProxy
+    name: external-proxy-config
+    namespace: envoy-gateway-system
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway EnvoyProxy: envoy-gateway-system/internal-proxy-config

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway EnvoyProxy: envoy-gateway-system/internal-proxy-config

@@ -0,0 +1,38 @@

+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: internal-proxy-config
+  namespace: envoy-gateway-system
+spec:
+  provider:
+    kubernetes:
+      envoyDeployment:
+        pod:
+          annotations:
+            prometheus.io/port: '19001'
+            prometheus.io/scrape: 'true'
+          labels:
+            gateway-type: internal
+          resources:
+            limits:
+              cpu: 500m
+              memory: 512Mi
+            requests:
+              cpu: 100m
+              memory: 128Mi
+        replicas: 1
+      envoyService:
+        annotations:
+          io.cilium/lb-ipam-ips: 192.168.1.241
+        type: LoadBalancer
+    type: Kubernetes
+  telemetry:
+    metrics:
+      prometheus:
+        disable: false
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway GatewayClass: envoy-gateway-system/internal-envoy

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway GatewayClass: envoy-gateway-system/internal-envoy

@@ -0,0 +1,19 @@

+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: internal-envoy
+  namespace: envoy-gateway-system
+spec:
+  controllerName: gateway.envoyproxy.io/gatewayclass-controller
+  description: GatewayClass for internal cluster traffic (Envoy Gateway)
+  parametersRef:
+    group: gateway.envoyproxy.io
+    kind: EnvoyProxy
+    name: internal-proxy-config
+    namespace: envoy-gateway-system
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Namespace: network/envoy-gateway-system

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Namespace: network/envoy-gateway-system

@@ -0,0 +1,10 @@

+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: envoy-gateway-system
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Certificate: envoy-gateway-system/wildcard-personal-domain

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Certificate: envoy-gateway-system/wildcard-personal-domain

@@ -0,0 +1,19 @@

+---
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: wildcard-personal-domain
+  namespace: envoy-gateway-system
+spec:
+  dnsNames:
+  - ..PLACEHOLDER_SECRET_DOMAIN_PERSONAL..
+  - '*...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+  issuerRef:
+    kind: ClusterIssuer
+    name: letsencrypt-production
+  secretName: wildcard-personal-domain-tls
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Gateway: envoy-gateway-system/external-gateway

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Gateway: envoy-gateway-system/external-gateway

@@ -0,0 +1,36 @@

+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  annotations:
+    external-dns.alpha.kubernetes.io/hostname: '*...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: external-gateway
+  namespace: envoy-gateway-system
+spec:
+  gatewayClassName: external-envoy
+  listeners:
+  - allowedRoutes:
+      namespaces:
+        from: All
+    hostname: '*...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+    name: https
+    port: 443
+    protocol: HTTPS
+    tls:
+      certificateRefs:
+      - kind: Secret
+        name: wildcard-personal-domain-tls
+        namespace: gateway-system
+      mode: Terminate
+  - allowedRoutes:
+      namespaces:
+        from: All
+    hostname: '*...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+    name: http
+    port: 80
+    protocol: HTTP
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HTTPRoute: envoy-gateway-system/https-redirect

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HTTPRoute: envoy-gateway-system/https-redirect

@@ -0,0 +1,24 @@

+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: https-redirect
+  namespace: envoy-gateway-system
+spec:
+  hostnames:
+  - '*...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+  parentRefs:
+  - name: external-gateway
+    namespace: gateway-system
+    sectionName: http
+  rules:
+  - filters:
+    - requestRedirect:
+        scheme: https
+        statusCode: 301
+      type: RequestRedirect
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Certificate: envoy-gateway-system/wildcard-internal-domain

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Certificate: envoy-gateway-system/wildcard-internal-domain

@@ -0,0 +1,19 @@

+---
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: wildcard-internal-domain
+  namespace: envoy-gateway-system
+spec:
+  dnsNames:
+  - internal...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..
+  - '*.internal...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+  issuerRef:
+    kind: ClusterIssuer
+    name: letsencrypt-production
+  secretName: wildcard-internal-domain-tls
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Gateway: envoy-gateway-system/internal-gateway

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway Gateway: envoy-gateway-system/internal-gateway

@@ -0,0 +1,34 @@

+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: internal-gateway
+  namespace: envoy-gateway-system
+spec:
+  gatewayClassName: internal-envoy
+  listeners:
+  - allowedRoutes:
+      namespaces:
+        from: All
+    hostname: '*.internal...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+    name: https
+    port: 443
+    protocol: HTTPS
+    tls:
+      certificateRefs:
+      - kind: Secret
+        name: wildcard-internal-domain-tls
+        namespace: gateway-system
+      mode: Terminate
+  - allowedRoutes:
+      namespaces:
+        from: All
+    hostname: '*.internal...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+    name: http
+    port: 80
+    protocol: HTTP
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HTTPRoute: envoy-gateway-system/internal-https-redirect

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HTTPRoute: envoy-gateway-system/internal-https-redirect

@@ -0,0 +1,24 @@

+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: internal-https-redirect
+  namespace: envoy-gateway-system
+spec:
+  hostnames:
+  - '*.internal...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..'
+  parentRefs:
+  - name: internal-gateway
+    namespace: gateway-system
+    sectionName: http
+  rules:
+  - filters:
+    - requestRedirect:
+        scheme: https
+        statusCode: 301
+      type: RequestRedirect
+
--- kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HTTPRoute: envoy-gateway-system/resume-site

+++ kubernetes/apps/network/external/envoy-gateway/app Kustomization: network/envoy-gateway HTTPRoute: envoy-gateway-system/resume-site

@@ -0,0 +1,43 @@

+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  annotations:
+    external-dns.alpha.kubernetes.io/hostname: ..PLACEHOLDER_SECRET_DOMAIN_PERSONAL..,www...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..,resume...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..
+  labels:
+    app.kubernetes.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/name: envoy-gateway
+    kustomize.toolkit.fluxcd.io/namespace: network
+  name: resume-site
+  namespace: envoy-gateway-system
+spec:
+  hostnames:
+  - ..PLACEHOLDER_SECRET_DOMAIN_PERSONAL..
+  - www...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..
+  - resume...PLACEHOLDER_SECRET_DOMAIN_PERSONAL..
+  parentRefs:
+  - name: external-gateway
+    namespace: gateway-system
+    sectionName: https
+  rules:
+  - backendRefs:
+    - name: resume
+      namespace: selfhosted
+      port: 8080
+    filters:
+    - responseHeaderModifier:
+        add:
+        - name: X-Frame-Options
+          value: DENY
+        - name: X-Content-Type-Options
+          value: nosniff
+        - name: X-XSS-Protection
+          value: 1; mode=block
+        - name: Referrer-Policy
+          value: strict-origin-when-cross-origin
+      type: ResponseHeaderModifier
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+

- Fix LB IPs: 10.100.0.31/32 (matches IPAM pool, not 192.168.1.x)
- Remove targetNamespace from ks.yaml (resources span multiple namespaces)
- Use OCIRepository pattern (matches cluster convention)
- Use HelmRelease v2 API (not v2beta1)
- Remove duplicate Kustomization from network/external/ks.yaml
- Remove inline postBuild (cluster-level substituteFrom handles it)
- Simplify Gateway listeners (no hardcoded hostnames on Gateway)
- Remove README and SecurityPolicy example (add later)
- Use cert-manager.io/cluster-issuer annotation on Gateway
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant