Standalone Nginx Ingress

In a multi-AZ deployment, each Kloudfuse cluster requires its own ingress-nginx controller pinned to its availability zone. Because the controller must be independently manageable during a failover, it is installed as a separate Helm release outside the Kloudfuse chart rather than using the bundled ingress-nginx.

Disable the Bundled ingress-nginx

Before installing a standalone controller, disable the ingress-nginx controller that is bundled with the Kloudfuse Helm chart. Add the following to your custom-values.yaml:

ingress-nginx:
  enabled: false
yaml
Only one ingress controller can be active in a Kloudfuse cluster at a time. If you are using Envoy Gateway instead of ingress-nginx, these values are already set by the Envoy Gateway configuration. See Configure Nginx Ingress for details.

Configure the Standalone Controller

Create a values.yaml for the ingress-nginx Helm chart. The controller must be pinned to the target AZ’s node group via affinity and tolerations, and assigned a unique ingressClass name so that Kloudfuse resources target the correct controller.

rbac:
  scope: false
controller:
  resources:
    requests:
      cpu: 10000m
      memory: 15000Mi
  scope:
    enabled: false
  containerName: nginx-controller
  allowSnippetAnnotations: false
  config:
    client-header-buffer-size: "16k"
    large-client-header-buffers: "4 16k"
    proxy-buffer-size: "64k"
    proxy-buffers: "8 64k"
    proxy-busy-buffers-size: "128k"
    location-snippet: |
      if ($request_uri = /) {
        add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
        expires off;
      }
      if ($request_uri ~* \.(?:html|js|css|gif|jpe?g|png)) {
        add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
        expires off;
      }
  addHeaders:
    X-Content-Type-Options: "nosniff"
    X-Frame-Options: "SAMEORIGIN"
    Content-Security-Policy: "default-src 'self' https://*.jsdelivr.net/ https://fonts.googleapis.com/ https://apis.google.com/js/ https://fonts.gstatic.com/ 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:;"
    Strict-Transport-Security: "max-age=31536000; includeSubDomains"
  metrics:
    enabled: true
  extraArgs:
    enable-metrics: true
  podAnnotations:
    prometheus.io/path: /metrics
    prometheus.io/port: "10254"
    prometheus.io/scrape: "true"

  ingressClassResource:
    enabled: true
    name: <az-name>   (1)
  ingressClass: <az-name>
  watchIngressWithoutClass: false
  externalTrafficPolicy: Local
  service:
    enableHttp: false
    loadBalancerIP: "<EXTERNAL_LB_IP>"  (2)
    external:
      enabled: true
    internal:
      enabled: true
      loadBalancerIP: "<INTERNAL_LB_IP>"  (3)
      annotations:
        networking.gke.io/load-balancer-type: "Internal"
        cloud.google.com/load-balancer-type: "Internal"

  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: ng_label
            operator: In
            values:
            - <az-name>
  tolerations:
  - key: "ng_taint"
    operator: "Equal"
    value: "<az-name>"
    effect: "NoSchedule"
yaml
1 az-name: A short identifier for the AZ (for example, az1 or az2). Used as the ingress class name and node affinity label. Must match the node group labels applied to the AZ’s nodes.
2 EXTERNAL_LB_IP: The external static IP address for ingest traffic. Map this to your public DNS hostname (for example, observability-ingest.example.com).
3 INTERNAL_LB_IP: The internal IP address for UI/query traffic. Map this to your internal DNS hostname (for example, observability.example.com).

Install the Standalone Controller

helm upgrade --install <release-name> ingress-nginx/ingress-nginx \ (1)
  --namespace <release-name> --create-namespace \
  --version <version> \ (2)
  -f values.yaml
1 Replace <release-name> with a name that identifies the AZ (for example, ingress-az1 or ingress-az2). Use the same value for both the release name and namespace so each AZ controller is isolated.
2 Replace <version> with the ingress-nginx chart version required for your environment. See the ingress-nginx releases page for available versions.

Repeat this step for each AZ, using a distinct <release-name> and a corresponding values.yaml with the correct AZ-specific settings.