|
| 1 | +--- |
| 2 | +title: "Custom policies" |
| 3 | +weight: 600 |
| 4 | +toc: true |
| 5 | +docs: "DOCS-000" |
| 6 | +--- |
| 7 | + |
| 8 | +## Overview |
| 9 | + |
| 10 | +Custom policies are NGINX Gateway Fabric CRDs (Custom Resource Definitions) that allow users to configure NGINX data plane features that are unavailable in the Gateway API. |
| 11 | +These custom policies follow the Gateway API [Policy Attachment](https://gateway-api.sigs.k8s.io/reference/policy-attachment/) pattern, which allows users to extend the Gateway API functionality by creating implementation-specific policies and attaching them to Kubernetes objects such as HTTPRoutes, Gateways, and Services. |
| 12 | + |
| 13 | +Policies are a Kubernetes object that augments the behavior of an object in a standard way. Policies can be attached to one object ([Direct Policy Attachment](#direct-policy-attachment)) or objects in a hierarchy ([Inherited Policy Attachment](#inherited-policy-attachment)). |
| 14 | +The following table summarizes NGINX Gateway Fabric custom policies: |
| 15 | + |
| 16 | +{{< bootstrap-table "table table-striped table-bordered" >}} |
| 17 | + |
| 18 | +| Policy | Description | Attachment Type | Supported Target Object(s) | Supports Multiple Target Refs | Mergeable | API Version | |
| 19 | +|---------------------------------------------------------------------------------------|---------------------------------------------------------|-----------------|-------------------------------|-------------------------------|-----------|-------------| |
| 20 | +| [ClientSettingsPolicy]({{<relref "/how-to/traffic-management/client-settings.md" >}}) | Configure connection behavior between client and NGINX | Inherited | Gateway, HTTPRoute, GRPCRoute | No | Yes | v1alpha1 | |
| 21 | +| [ObservabilityPolicy]({{<relref "/how-to/monitoring/tracing.md" >}}) | Define settings related to tracing, metrics, or logging | Direct | HTTPRoute, GRPCRoute | Yes | No | v1alpha1 | |
| 22 | + |
| 23 | +{{</bootstrap-table>}} |
| 24 | + |
| 25 | + |
| 26 | +{{< important >}} |
| 27 | +NGINX Gateway Fabric policies do not work with [HTTPRoute matches](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteMatch) with `headers`, `params`, or `method` matchers defined. It will be added in a future release. |
| 28 | +{{< /important >}} |
| 29 | + |
| 30 | +## Terminology |
| 31 | + |
| 32 | +- _Attachment Type_. How the policy attaches to an object. Attachment type can be "direct" or "inherited". |
| 33 | +- _Supported Target Object(s)_. API objects the policy can be applied to. |
| 34 | +- _Supports Multiple Target Refs_. Whether a single policy can target multiple objects. |
| 35 | +- _Mergeable_. Whether policies that target the same object can be merged. |
| 36 | + |
| 37 | +## Direct Policy Attachment |
| 38 | + |
| 39 | +A Direct Policy Attachment is a policy that references a single object, such as a Gateway or HTTPRoute. It is tightly bound to one instance of a particular Kind within a single Namespace or an instance of a single Kind at the cluster-scope. It affects _only_ the object specified in its TargetRef. |
| 40 | + |
| 41 | +This diagram uses a fictional retry policy to show how Direct Policy Attachment works: |
| 42 | + |
| 43 | +{{<img src="img/direct-policy-attachment.png" alt="">}} |
| 44 | + |
| 45 | +The policy targets the HTTPRoute `baz` and sets `retries` to `3` and `timeout` to `60s`. Since this policy is a Direct Policy Attachment, its settings are only applied to the `baz` HTTPRoute. |
| 46 | + |
| 47 | +## Inherited Policy Attachment |
| 48 | + |
| 49 | +Inherited Policy Attachment allows settings to cascade down a hierarchy. The hierarchy for Gateway API resources looks like this: |
| 50 | + |
| 51 | +{{<img src="img/hierarchy.png" alt="">}} |
| 52 | + |
| 53 | +Settings defined in a policy attached to an object in this hierarchy may be inherited by the resources below it. For example, the settings defined in a policy attached to a Gateway may be inherited by all the HTTPRoutes attached to that Gateway. |
| 54 | + |
| 55 | +Settings in an Inherited Policy can be Defaults or Overrides. Defaults set the default value for something and can be overridden by policies on a lower object. Overrides cannot be overridden by lower objects. |
| 56 | +All settings in NGINX Gateway Fabric Inherited Policies are Defaults. |
| 57 | + |
| 58 | +Default values are given precedence from the bottom up. Therefore, a policy setting attached to a Backend will have the highest precedence over the one attached to higher objects. |
| 59 | + |
| 60 | +The following diagram shows how Inherited Policies work in NGINX Gateway Fabric using a fictional retry policy: |
| 61 | + |
| 62 | +{{<img src="img/inherited-policy-attachment.png" alt="">}} |
| 63 | + |
| 64 | +There are three policies defined: |
| 65 | + |
| 66 | +- `dev-policy` that targets the `dev` Gateway |
| 67 | +- `baz-policy` that targets the `baz` HTTPRoute |
| 68 | +- `foo-policy` that targets the `foo` HTTPRoute |
| 69 | + |
| 70 | +The settings in `dev-policy` affect the `dev` Gateway and are inherited by all the HTTPRoutes attached to `dev`. |
| 71 | +The `baz-policy` and `foo-policy` are attached to the `baz` and `foo` HTTPRoutes. Since HTTPRoutes are lower than Gateways in the hierarchy, the settings defined in them override those in the `dev` policy. |
| 72 | +Since the `foo-policy` only defines the `retries` setting, it still inherits the `timeout` setting from `dev-policy`. |
| 73 | +The `bar` HTTPRoute has no policy attached to it and inherits all the settings from `dev-policy`. |
| 74 | + |
| 75 | +## Merging Policies |
| 76 | + |
| 77 | +With some NGINX Gateway Fabric Policies, it is possible to create multiple policies that target the same resource as long as the fields in those policies do not conflict. |
| 78 | + |
| 79 | +For example, consider the following fictional policies: |
| 80 | + |
| 81 | +```yaml |
| 82 | +apiVersion: gateway.nginx.org/v1alpha1 |
| 83 | +kind: ExamplePolicy |
| 84 | +metadata: |
| 85 | + name: retries |
| 86 | +spec: |
| 87 | + targetRef: |
| 88 | + group: gateway.networking.k8s.io |
| 89 | + kind: HTTPRoute |
| 90 | + name: foo |
| 91 | + retries: 10 |
| 92 | +``` |
| 93 | +
|
| 94 | +
|
| 95 | +```yaml |
| 96 | +apiVersion: gateway.nginx.org/v1alpha1 |
| 97 | +kind: ExamplePolicy |
| 98 | +metadata: |
| 99 | + name: timeout |
| 100 | +spec: |
| 101 | + targetRef: |
| 102 | + kind: HTTPRoute |
| 103 | + name: foo |
| 104 | + timeout: 60s |
| 105 | +``` |
| 106 | +
|
| 107 | +The `retries` ExamplePolicy defines the number of retries for the `foo` HTTPRoute, and the `timeout` ExamplePolicy defines the timeout for the `foo` HTTPRoute. |
| 108 | +NGINX Gateway Fabric will merge the fields defined in the policies and apply the following settings to the `foo` HTTPRoute: |
| 109 | + |
| 110 | +```yaml |
| 111 | +retries: 10 |
| 112 | +timeout: 60s |
| 113 | +``` |
| 114 | + |
| 115 | +However, if both policies had the `retries` field set, then the policies cannot be merged. In this case, NGINX Gateway Fabric will choose which policy to configure based on the following criteria (continuing on ties): |
| 116 | + |
| 117 | +1. The oldest policy by creation timestamp |
| 118 | +1. The policy appearing first in alphabetical order by "{namespace}/{name}" |
| 119 | + |
| 120 | +If a policy conflicts with a configured policy, NGINX Gateway Fabric will set the policy `Accepted` status to false with a reason of `Conflicted`. See [Policy Status](#policy-status) for more details. |
| 121 | + |
| 122 | +## Policy Status |
| 123 | + |
| 124 | +NGINX Gateway Fabric sets the [PolicyStatus](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus) on all policies. |
| 125 | + |
| 126 | +`PolicyStatus` fields: |
| 127 | + |
| 128 | +- `ancestors`: describes the status of a route with respect to the ancestor. |
| 129 | + - `ancestorRef`: the object that the policy targets in `spec.targetRef`. |
| 130 | + - `controllerName`: the controller name of NGINX Gateway Fabric. |
| 131 | + - `conditions`: (Condition/Status/Reason): |
| 132 | + - `Accepted/True/Accepted`: the policy is accepted by the ancestor. |
| 133 | + - `Accepted/False/Invalid`: the policy is not accepted because it is semantically or syntactically invalid. |
| 134 | + - `Accepted/False/Conflicted`: the policy is not accepted because it conflicts with another policy. |
| 135 | + - `Accepted/False/TargetNotFound`: the policy is not accepted because it targets a resource that is invalid or does not exist. |
| 136 | + - `Accepted/False/NginxProxyNotSet`: the policy is not accepted because it relies on the NginxProxy configuration which is missing or invalid. |
| 137 | + |
| 138 | +To check the status of a policy, use `kubectl describe`. This example checks the status of the `foo` ObservabilityPolicy, which is accepted: |
| 139 | + |
| 140 | +```shell |
| 141 | +kubectl describe observabilitypolicies.gateway.nginx.org foo -n default |
| 142 | +``` |
| 143 | + |
| 144 | +```text |
| 145 | +Status: |
| 146 | + Ancestors: |
| 147 | + Ancestor Ref: |
| 148 | + Group: gateway.networking.k8s.io |
| 149 | + Kind: HTTPRoute |
| 150 | + Name: foo |
| 151 | + Namespace: default |
| 152 | + Conditions: |
| 153 | + Last Transition Time: 2024-05-23T18:13:03Z |
| 154 | + Message: Policy is accepted |
| 155 | + Observed Generation: 1 |
| 156 | + Reason: Accepted |
| 157 | + Status: True |
| 158 | + Type: Accepted |
| 159 | + Controller Name: gateway.nginx.org/nginx-gateway-controller |
| 160 | +``` |
0 commit comments