# Data plane configuration Type of document: How-to guide Product: F5 NGINX Gateway Fabric > Dynamically update global NGINX data plane configuration for NGINX Gateway Fabric. --- Learn how to dynamically update the NGINX Gateway Fabric global data plane configuration. ## Overview NGINX Gateway Fabric can dynamically update the global data plane configuration without restarting. The data plane configuration contains configuration for NGINX that is not available using the standard Gateway API resources. This includes options such as configuring an OpenTelemetry collector, disabling HTTP/2, changing the IP family, and setting the NGINX error log level. It also contains options for [updating the NGINX Deployment and Service config](#configure-infrastructure-related-settings), either through native fields or patches. The data plane configuration is stored in the `NginxProxy` custom resource, which is a namespace-scoped resource that can be attached to a GatewayClass or Gateway. When attached to a GatewayClass, the fields in the NginxProxy affect all Gateways that belong to the GatewayClass. When attached to a Gateway, the fields in the NginxProxy only affect the Gateway. If a GatewayClass and its Gateway both specify an NginxProxy, the GatewayClass NginxProxy provides defaults that can be overridden by the Gateway NginxProxy. See the [Merging Semantics](#merging-semantics) section for more detail. **For a full list of configuration options that can be set, see the `NginxProxy spec` in the [API reference](/ngf/reference/api.md).** --- ## Merging Semantics NginxProxy resources are merged when a GatewayClass and a Gateway reference different NginxProxy resources. For fields that are bools, integers, and strings: - If a field on the Gateway's NginxProxy is unspecified (`nil`), the Gateway __inherits__ the value of the field in the GatewayClass's NginxProxy. - If a field on the Gateway's NginxProxy is specified, its value __overrides__ the value of the field in the GatewayClass's NginxProxy. For array fields: - If the array on the Gateway's NginxProxy is unspecified (`nil`), the Gateway __inherits__ the entire array in the GatewayClass's NginxProxy. - If the array on the Gateway's NginxProxy is empty, it __overrides__ the entire array in the GatewayClass's NginxProxy, effectively unsetting the field. - If the array on the Gateway's NginxProxy is specified and not empty, it __overrides__ the entire array in the GatewayClass's NginxProxy. ### Merging Examples This section contains examples of how NginxProxy resources are merged when they are attached to both a Gateway and its GatewayClass. #### Disable HTTP/2 for a Gateway A GatewayClass references the following NginxProxy which explicitly allows HTTP/2 traffic and sets the IPFamily to ipv4: ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: gateway-class-enable-http2 namespace: default spec: ipFamily: "ipv4" disableHTTP: false ``` To disable HTTP/2 traffic for a particular Gateway, reference the following NginxProxy in the Gateway's spec: ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: gateway-disable-http namespace: default spec: disableHTTP: true ``` These NginxProxy resources are merged and the following settings are applied to the Gateway: ```yaml ipFamily: "ipv4" disableHTTP: true ``` #### Change Telemetry configuration for a Gateway A GatewayClass references the following NginxProxy which configures telemetry: ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: gateway-class-telemetry namespace: default spec: telemetry: exporter: endpoint: "my.telemetry.collector:9000" interval: "60s" batchSize: 20 serviceName: "my-company" spanAttributes: - key: "company-key" value: "company-value" ``` To change the telemetry configuration for a particular Gateway, reference the following NginxProxy in the Gateway's spec: ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: gateway-telemetry-service-name namespace: default spec: telemetry: exporter: batchSize: 50 batchCount: 5 serviceName: "my-app" spanAttributes: - key: "app-key" value: "app-value" ``` These NginxProxy resources are merged and the following settings are applied to the Gateway: ```yaml telemetry: exporter: endpoint: "my.telemetry.collector:9000" interval: "60s" batchSize: 50 batchCount: 5 serviceName: "my-app" spanAttributes: - key: "app-key" value: "app-value" ``` #### Disable Tracing for a Gateway A GatewayClass references the following NginxProxy which configures telemetry: ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: gateway-class-telemetry namespace: default spec: telemetry: exporter: endpoint: "my.telemetry.collector:9000" interval: "60s" serviceName: "my-company" ``` To disable tracing for a particular Gateway, reference the following NginxProxy in the Gateway's spec: ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: gateway-disable-tracing namespace: default spec: telemetry: disabledFeatures: - DisableTracing ``` These NginxProxy resources are merged and the following settings are applied to the Gateway: ```yaml telemetry: exporter: endpoint: "my.telemetry.collector:9000" interval: "60s" serviceName: "my-app" disabledFeatures: - DisableTracing ``` --- ## Configuring the GatewayClass NginxProxy on install By default, an `NginxProxy` resource is created in the same namespace where NGINX Gateway Fabric is installed, attached to the GatewayClass. You can set configuration options in the `nginx` Helm value section, and the resource will be created and attached using the set values. You can also [manually create and attach](#manually-creating-nginxProxies) specific `NginxProxy` resources to target different Gateways. When installed using the Helm chart, the NginxProxy resource is named `-proxy-config` and is created in the release Namespace. **For a full list of configuration options that can be set, see the `NginxProxy spec` in the [API reference](/ngf/reference/api.md).** **Note:** Some global configuration also requires an [associated policy](/ngf/overview/custom-policies.md) to fully enable a feature (such as [tracing](/ngf/monitoring/tracing.md), for example). --- ## Manually Creating NginxProxies The following command creates a basic `NginxProxy` configuration in the `default` namespace that sets the IP family to `ipv4` instead of the default value of `dual`: ```yaml kubectl apply -f - < ``` Replace `` with the name of your Gateway. This will open your default editor, allowing you to add the following to the `spec`: ```yaml infrastructure: parametersRef: group: gateway.nginx.org kind: NginxProxy name: ngf-proxy-config ``` **Note:** The `NginxProxy` resource must reside in the same namespace as the Gateway it is attached to. After updating, you can check the status of the Gateway to see if the configuration is valid: ```shell kubectl describe gateway ``` ```text ... Status: Conditions: ... Message: parametersRef resource is resolved Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs ``` If everything is valid, the `ResolvedRefs` condition should be `True`. Otherwise, you will see an `InvalidParameters` condition in the status. --- ## Configure the data plane log level You can use the `NginxProxy` resource to dynamically configure the log level. The following command creates a basic `NginxProxy` configuration that sets the log level to `warn` instead of the default value of `info`: ```yaml kubectl apply -f - < ``` Confirm a PodDisruptionBudget exists for each NGINX Deployment. Each one reports its configured `minAvailable` or `maxUnavailable` and the number of voluntary disruptions it currently allows. This check matters most for a DaemonSet data plane. Setting the field on a DaemonSet produces no PodDisruptionBudget, and the control plane reports no error. The list is how you confirm one was created. The exactly-one-of mistake fails differently, and it is not silent. If you set both or neither of `minAvailable` and `maxUnavailable`, the API server rejects the `NginxProxy`. The `kubectl apply` or `kubectl edit` command then fails at apply time. To view the full list of configuration options, see the `NginxProxy spec` in the [API reference](/ngf/reference/api.md). --- ### Patch data plane Service, Deployment, and DaemonSet NGINX Gateway Fabric supports advanced customization of the data plane Service, Deployment, and DaemonSet objects using patches in the `NginxProxy` resource. This allows you to apply Kubernetes-style patches to these resources, enabling custom labels, annotations, or other modifications that are not directly exposed via the NginxProxy spec. #### Supported Patch Types You can specify one or more patches for each of the following resources: - `spec.kubernetes.service.patches` - `spec.kubernetes.deployment.patches` - `spec.kubernetes.daemonSet.patches` Each patch has two fields: - `type`: The patch type. Supported values are: - `StrategicMerge` (default): Strategic merge patch (Kubernetes default for most resources) - `Merge`: JSON merge patch (RFC 7386) - `JSONPatch`: JSON patch (RFC 6902) - `value`: The patch data. For `StrategicMerge` and `Merge`, this should be a JSON object. For `JSONPatch`, this should be a JSON array of patch operations. Patches are applied in the order they appear in the array. Later patches can override fields set by earlier patches. **Which patch type should I use?** - **StrategicMerge** is the default and most user-friendly for Kubernetes-native resources like Deployments and Services. It understands lists and merges fields intelligently (for example, merging containers by name). Use this for most use cases. - **Merge** (JSON Merge Patch) is simpler and works well for basic object merges, but does not handle lists or complex merging. Use this if you want to replace entire fields or for non-Kubernetes-native resources. - **JSONPatch** is the most powerful and flexible, allowing you to add, remove, or replace specific fields using RFC 6902 operations. Use this for advanced or fine-grained changes, but it is more verbose and error-prone. If unsure, start with StrategicMerge. Use JSONPatch only if you need to surgically modify fields that cannot be addressed by the other patch types. Patches are applied after all other NginxProxy configuration is rendered. Invalid patches will result in a validation error and will not be applied. #### Example: Configure Service with session affinity ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: ngf-proxy-patch-service spec: kubernetes: service: patches: - type: StrategicMerge value: spec: sessionAffinity: ClientIP sessionAffinityConfig: clientIP: timeoutSeconds: 300 ``` #### Example: Configure Deployment with custom strategy ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: ngf-proxy-patch-deployment spec: kubernetes: deployment: patches: - type: Merge value: spec: strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 2 ``` #### Example: Use JSONPatch to configure DaemonSet host networking and priority ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: ngf-proxy-patch-daemonset spec: kubernetes: daemonSet: patches: - type: JSONPatch value: - op: add path: /spec/template/spec/hostNetwork value: true - op: add path: /spec/template/spec/dnsPolicy value: "ClusterFirstWithHostNet" - op: add path: /spec/template/spec/priorityClassName value: "system-node-critical" ``` #### Example: Multiple patches, later patch overrides earlier ```yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: name: ngf-proxy-multi-patch spec: kubernetes: service: patches: - type: StrategicMerge value: spec: sessionAffinity: ClientIP publishNotReadyAddresses: false - type: StrategicMerge value: spec: sessionAffinity: None publishNotReadyAddresses: true ``` In this example, the final Service will have `sessionAffinity: None` and `publishNotReadyAddresses: true` because the second patch overrides the values from the first patch.